Eclipse SUMO - Simulation of Urban MObility
MSRailSignalConstraint.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // A constraint on rail signal switching
19 /****************************************************************************/
20 #include <config.h>
21 #include <cassert>
22 #include <utility>
23 
26 #include <microsim/MSLane.h>
27 #include <microsim/MSEdge.h>
28 #include <microsim/MSLink.h>
29 #include <microsim/MSNet.h>
31 #include "MSRailSignal.h"
32 #include "MSRailSignalConstraint.h"
33 #include "MSRailSignalControl.h"
34 
35 //#define DEBUG_PASSED
36 //#define DEBUG_LANE
37 
38 // ===========================================================================
39 // static value definitions
40 // ===========================================================================
41 std::map<const MSLane*, MSRailSignalConstraint_Predecessor::PassedTracker*> MSRailSignalConstraint_Predecessor::myTrackerLookup;
42 
43 // ===========================================================================
44 // MSRailSignalConstraint method definitions
45 // ===========================================================================
46 void
49 }
50 
51 void
53  if (OptionsCont::getOptions().getBool("save-state.constraints")) {
54  for (MSRailSignal* s : MSRailSignalControl::getInstance().getSignals()) {
55  if (s->getConstraints().size() > 0 || s->getInsertionConstraints().size() > 0) {
57  out.writeAttr(SUMO_ATTR_ID, s->getID());
58  for (auto item : s->getConstraints()) {
59  for (MSRailSignalConstraint* c : item.second) {
60  c->write(out, SUMO_TAG_PREDECESSOR, item.first);
61  }
62  }
63  for (auto item : s->getInsertionConstraints()) {
64  for (MSRailSignalConstraint* c : item.second) {
65  c->write(out, SUMO_TAG_INSERTION_PREDECESSOR, item.first);
66  }
67  }
68  out.closeTag();
69  }
70  }
71  }
73 }
74 
75 void
78 }
79 
80 void
82  for (MSRailSignal* s : MSRailSignalControl::getInstance().getSignals()) {
83  s->removeConstraints();
84  }
85 }
86 
87 
88 std::string
89 MSRailSignalConstraint::getVehID(const std::string& tripID) {
91  for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
92  SUMOVehicle* veh = i->second;
93  if (veh->getParameter().getParameter("tripId") == tripID) {
94  return veh->getID();
95  }
96  }
97  return "";
98 }
99 
100 // ===========================================================================
101 // MSRailSignalConstraint_Predecessor method definitions
102 // ===========================================================================
103 MSRailSignalConstraint_Predecessor::MSRailSignalConstraint_Predecessor(const MSRailSignal* signal, const std::string& tripId, int limit) :
104  myTripId(tripId),
105  myLimit(limit),
106  myFoeSignal(signal) {
107  for (const auto& lv : signal->getLinks()) {
108  for (const MSLink* link : lv) {
109  MSLane* lane = link->getViaLaneOrLane();
110  PassedTracker* pt = nullptr;
111  if (myTrackerLookup.count(lane) == 0) {
112  pt = new PassedTracker(lane);
113  myTrackerLookup[lane] = pt;
114  } else {
115  pt = myTrackerLookup[lane];
116  }
117  pt->raiseLimit(limit);
118  myTrackers.push_back(pt);
119  }
120  }
121 
122 }
123 
124 void
126  for (auto item : myTrackerLookup) {
127  delete item.second;
128  }
129  myTrackerLookup.clear();
130 }
131 
132 void
134  for (auto item : myTrackerLookup) {
135  item.second->saveState(out);
136  }
137 }
138 
139 void
141  bool ok;
142  const std::string laneID = attrs.getString(SUMO_ATTR_LANE);
143  const int index = attrs.get<int>(SUMO_ATTR_INDEX, "", ok);
144  std::vector<std::string> tripIDs = attrs.getStringVector(SUMO_ATTR_STATE);
145  MSLane* lane = MSLane::dictionary(laneID);
146  if (lane == nullptr) {
147  throw ProcessError("Unknown lane '" + laneID + "' in loaded state");
148  }
149  if (myTrackerLookup.count(lane) == 0) {
150  WRITE_WARNINGF("Unknown tracker lane '%' in loaded state", laneID);
151  return;
152  }
153  PassedTracker* tracker = myTrackerLookup[lane];
154  tracker->loadState(index, tripIDs);
155 }
156 
157 
158 void
160  for (auto item : myTrackerLookup) {
161  item.second->clearState();
162  }
163 }
164 
165 
166 bool
168  for (PassedTracker* pt : myTrackers) {
169  if (pt->hasPassed(myTripId, myLimit)) {
170  return true;
171  }
172  }
173  return false;
174 }
175 
176 std::string
178  // try to retrieve vehicle id that belongs to myTripId
179  // this may be slow so it should only be used for debugging
180  std::string vehID = getVehID(myTripId);
181  if (vehID != "") {
182  vehID = " (" + vehID + ")";
183  }
184  std::vector<std::string> passedIDs;
185  for (const std::string& passedTripID : myTrackers.front()->myPassed) {
186  if (passedTripID == "") {
187  continue;
188  }
189  const std::string passedID = getVehID(passedTripID);
190  if (passedID != "") {
191  passedIDs.push_back(passedID);
192  }
193  }
194  std::string passedIDs2 = "";
195  if (passedIDs.size() > 0) {
196  passedIDs2 = " (" + toString(passedIDs) + ")";
197  }
198  return ("predecessor " + myTripId + vehID + " at signal " + myTrackers.front()->getLane()->getEdge().getFromJunction()->getID()
199  + " passed=" + StringUtils::prune(toString(myTrackers.front()->myPassed)) + passedIDs2);
200 }
201 
202 // ===========================================================================
203 // MSRailSignalConstraint_Predecessor::PassedTracker method definitions
204 // ===========================================================================
205 
207  MSMoveReminder("PassedTracker_" + lane->getID(), lane, true),
208  myPassed(1, ""),
209  myLastIndex(-1)
210 { }
211 
212 bool
214  myLastIndex = (myLastIndex + 1) % myPassed.size();
215  myPassed[myLastIndex] = veh.getParameter().getParameter("tripId", veh.getID());
216 #ifdef DEBUG_PASSED
217  if (myLane->getID() == DEBUG_LANE) {
218  std::cout << SIMTIME << " hasPassed " << veh.getID() << " tripId=" << veh.getParameter().getParameter("tripId", veh.getID()) << " index=" << myLastIndex << "\n";
219  }
220 #endif
221  return true;
222 }
223 
224 void
226  while (limit > (int)myPassed.size()) {
227  myPassed.insert(myPassed.begin() + (myLastIndex + 1), "");
228  }
229 #ifdef DEBUG_PASSED
230  if (myLane->getID() == DEBUG_LANE) {
231  std::cout << " raiseLimit=" << limit << "\n";
232  }
233 #endif
234 }
235 
236 bool
237 MSRailSignalConstraint_Predecessor::PassedTracker::hasPassed(const std::string& tripId, int limit) const {
238  if (myLastIndex < 0) {
239  return false;
240  }
241  int i = myLastIndex;
242  while (limit > 0) {
243  if (myPassed[i] == tripId) {
244  return true;
245  }
246  if (i == 0) {
247  i = (int)myPassed.size() - 1;
248  } else {
249  i--;
250  }
251  limit--;
252  }
253  return false;
254 }
255 
256 void
258  myPassed = std::vector<std::string>(myPassed.size());
259  myLastIndex = 0;
260 }
261 
262 void
264  const std::string state = toString(myPassed.back() == ""
265  ? std::vector<std::string>(myPassed.begin(), myPassed.begin() + (myLastIndex + 1))
266  // wrapped around
267  : myPassed);
268  // no need to save state if no vehicles have passed this tracker
269  if (state != "") {
271  out.writeAttr(SUMO_ATTR_LANE, getLane()->getID());
272  out.writeAttr(SUMO_ATTR_INDEX, myLastIndex);
273  out.writeAttr(SUMO_ATTR_STATE, state);
274  out.closeTag();
275  }
276 }
277 
278 void
279 MSRailSignalConstraint_Predecessor::PassedTracker::loadState(int index, const std::vector<std::string>& tripIDs) {
280  raiseLimit((int)tripIDs.size());
281  for (int i = 0; i < (int)tripIDs.size(); i++) {
282  myPassed[i] = tripIDs[i];
283  }
284 #ifdef DEBUG_PASSED
285  if (myLane->getID() == DEBUG_LANE) {
286  std::cout << " loadState limit=" << tripIDs.size() << " index=" << index << "\n";
287  for (int i = 0; i < (int)myPassed.size(); i++) {
288  std::cout << " i=" << i << " passed=" << myPassed[i] << "\n";
289  }
290  }
291 #endif
292  myLastIndex = index;
293 }
294 
295 
296 void
297 MSRailSignalConstraint_Predecessor::write(OutputDevice& out, SumoXMLTag tag, const std::string& tripId) const {
298  out.openTag(tag);
299  out.writeAttr(SUMO_ATTR_TRIP_ID, tripId);
302  if (myLimit > 1) {
304  }
305  out.closeTag();
306 }
307 
308 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:281
#define SIMTIME
Definition: SUMOTime.h:60
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_RAILSIGNAL_CONSTRAINTS
Constraints on switching a rail signal.
@ SUMO_TAG_INSERTION_PREDECESSOR
Predecessor constraint on insertion before rail signal.
@ SUMO_TAG_RAILSIGNAL_CONSTRAINT_TRACKER
Saved state for constraint tracker.
@ SUMO_TAG_PREDECESSOR
Predecessor constraint on switching a rail signal.
@ SUMO_ATTR_LANE
@ SUMO_ATTR_LIMIT
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_TRIP_ID
@ SUMO_ATTR_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_FOES
@ SUMO_ATTR_ID
@ SUMO_ATTR_STATE
The state of a link.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1991
Something on a lane to be noticed about vehicle movement.
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:174
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:376
bool hasPassed(const std::string &tripId, int limit) const
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
tracks vehicles that passed this link (entered the next lane)
void loadState(int index, const std::vector< std::string > &tripIDs)
loads the current passed states into the given stream
void clearState()
Clear all passed states before quick-loading state.
void saveState(OutputDevice &out)
Saves the current passed states into the given stream.
const MSRailSignal * myFoeSignal
store the foe signal (for TraCI access)
void write(OutputDevice &out, SumoXMLTag tag, const std::string &tripId) const
bool cleared() const
whether the constraint has been met
static void loadState(const SUMOSAXAttributes &attrs)
loads the constraint state from the given attrs
static void saveState(OutputDevice &out)
Saves the current constraint states into the given stream.
const std::string myTripId
id of the predecessor that must already have passed
static void clearState()
Clear all constraint states before quick-loading state.
static std::map< const MSLane *, PassedTracker * > myTrackerLookup
std::vector< PassedTracker * > myTrackers
the tracker object for this constraint
const int myLimit
the number of passed vehicles within which tripId must have occured
MSRailSignalConstraint_Predecessor(const MSRailSignal *signal, const std::string &tripId, int limit)
Constructor.
A base class for constraints.
static void saveState(OutputDevice &out)
Saves the current constraint states into the given stream.
static std::string getVehID(const std::string &tripID)
static void clearState()
Clear all constraint states before quick-loading state.
virtual void write(OutputDevice &out, SumoXMLTag tag, const std::string &tripId) const =0
static void clearAll()
Remove all constraints before quick-loading state.
static void cleanup()
clean up state
static MSRailSignalControl & getInstance()
A signal for rails.
Definition: MSRailSignal.h:46
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
The class responsible for building and deletion of vehicles.
std::map< std::string, SUMOVehicle * >::const_iterator constVehIt
Definition of the internal vehicles map iterator.
constVehIt loadedVehBegin() const
Returns the begin of the internal vehicle map.
constVehIt loadedVehEnd() const
Returns the end of the internal vehicle map.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:248
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
Encapsulated SAX-Attributes.
const std::vector< std::string > getStringVector(int attr) const
Tries to read given attribute assuming it is a string vector.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
Representation of a vehicle, person, or container.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
Representation of a vehicle.
Definition: SUMOVehicle.h:60
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
Definition: StringUtils.cpp:48