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.dev/sumo
3 // Copyright (C) 2001-2024 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) {
57  out.writeAttr(SUMO_ATTR_ID, s->getID());
58  for (auto item : s->getConstraints()) {
59  for (MSRailSignalConstraint* c : item.second) {
60  c->write(out, item.first);
61  }
62  }
63  out.closeTag();
64  }
65  }
66  }
68 }
69 
70 void
73 }
74 
75 void
77  for (MSRailSignal* s : MSRailSignalControl::getInstance().getSignals()) {
78  s->removeConstraints();
79  }
80 }
81 
82 
83 std::string
84 MSRailSignalConstraint::getVehID(const std::string& tripID) {
86  for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
87  SUMOVehicle* veh = i->second;
88  if (veh->getParameter().getParameter("tripId") == tripID) {
89  return veh->getID();
90  }
91  }
92  return "";
93 }
94 
95 // ===========================================================================
96 // MSRailSignalConstraint_Predecessor method definitions
97 // ===========================================================================
98 MSRailSignalConstraint_Predecessor::MSRailSignalConstraint_Predecessor(ConstraintType type, const MSRailSignal* signal, const std::string& tripId, int limit, bool active) :
100  myTripId(tripId),
101  myLimit(limit),
102  myAmActive(active),
103  myFoeSignal(signal) {
104  for (const auto& lv : signal->getLinks()) {
105  for (const MSLink* link : lv) {
106  MSLane* lane = link->getViaLaneOrLane();
107  PassedTracker* pt = nullptr;
108  if (myTrackerLookup.count(lane) == 0) {
109  pt = new PassedTracker(lane);
110  myTrackerLookup[lane] = pt;
111  } else {
112  pt = myTrackerLookup[lane];
113  }
114  pt->raiseLimit(limit);
115  myTrackers.push_back(pt);
116  }
117  }
118 
119 }
120 
121 void
123  for (auto item : myTrackerLookup) {
124  delete item.second;
125  }
126  myTrackerLookup.clear();
127 }
128 
129 void
131  for (auto item : myTrackerLookup) {
132  item.second->saveState(out);
133  }
134 }
135 
136 void
138  bool ok;
139  const std::string laneID = attrs.getString(SUMO_ATTR_LANE);
140  const int index = attrs.get<int>(SUMO_ATTR_INDEX, nullptr, ok);
141  const std::vector<std::string>& tripIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_STATE, nullptr, ok);
142  MSLane* lane = MSLane::dictionary(laneID);
143  if (lane == nullptr) {
144  throw ProcessError(TLF("Unknown lane '%' in loaded state.", laneID));
145  }
146  if (myTrackerLookup.count(lane) == 0) {
147  WRITE_WARNINGF(TL("Unknown tracker lane '%' in loaded state."), laneID);
148  return;
149  }
150  PassedTracker* tracker = myTrackerLookup[lane];
151  tracker->loadState(index, tripIDs);
152 }
153 
154 
155 void
157  for (auto item : myTrackerLookup) {
158  item.second->clearState();
159  }
160 }
161 
162 
163 bool
165  if (!myAmActive) {
166  return true;
167  }
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  std::string params = "";
199  for (auto item : getParametersMap()) {
200  params += ("\n key=" + item.first + " value=" + item.second);
201  }
202  return (toString(getTag()) + " " + myTripId + vehID + " at signal " + myTrackers.front()->getLane()->getEdge().getFromJunction()->getID()
203  + " passed=" + StringUtils::prune(toString(myTrackers.front()->myPassed)) + passedIDs2 + params);
204 }
205 
206 // ===========================================================================
207 // MSRailSignalConstraint_Predecessor::PassedTracker method definitions
208 // ===========================================================================
209 
211  MSMoveReminder("PassedTracker_" + lane->getID(), lane, true),
212  myPassed(1, ""),
213  myLastIndex(-1)
214 { }
215 
216 bool
218  myLastIndex = (myLastIndex + 1) % myPassed.size();
219  myPassed[myLastIndex] = veh.getParameter().getParameter("tripId", veh.getID());
220 #ifdef DEBUG_PASSED
221  if (myLane->getID() == DEBUG_LANE) {
222  std::cout << SIMTIME << " hasPassed " << veh.getID() << " tripId=" << veh.getParameter().getParameter("tripId", veh.getID()) << " index=" << myLastIndex << "\n";
223  }
224 #endif
225  return true;
226 }
227 
228 void
230  while (limit > (int)myPassed.size()) {
231  myPassed.insert(myPassed.begin() + (myLastIndex + 1), "");
232  }
233 #ifdef DEBUG_PASSED
234  if (myLane->getID() == DEBUG_LANE) {
235  std::cout << " raiseLimit=" << limit << "\n";
236  }
237 #endif
238 }
239 
240 bool
241 MSRailSignalConstraint_Predecessor::PassedTracker::hasPassed(const std::string& tripId, int limit) const {
242  if (myLastIndex < 0) {
243  return false;
244  }
245  int i = myLastIndex;
246  while (limit > 0) {
247  if (myPassed[i] == tripId) {
248  return true;
249  }
250  if (i == 0) {
251  i = (int)myPassed.size() - 1;
252  } else {
253  i--;
254  }
255  limit--;
256  }
257  return false;
258 }
259 
260 void
262  myPassed = std::vector<std::string>(myPassed.size());
263  myLastIndex = 0;
264 }
265 
266 void
268  const std::string state = toString(myPassed.back() == ""
269  ? std::vector<std::string>(myPassed.begin(), myPassed.begin() + (myLastIndex + 1))
270  // wrapped around
271  : myPassed);
272  // no need to save state if no vehicles have passed this tracker
273  if (state != "") {
275  out.writeAttr(SUMO_ATTR_LANE, getLane()->getID());
276  out.writeAttr(SUMO_ATTR_INDEX, myLastIndex);
277  out.writeAttr(SUMO_ATTR_STATE, state);
278  out.closeTag();
279  }
280 }
281 
282 void
283 MSRailSignalConstraint_Predecessor::PassedTracker::loadState(int index, const std::vector<std::string>& tripIDs) {
284  raiseLimit((int)tripIDs.size());
285  for (int i = 0; i < (int)tripIDs.size(); i++) {
286  myPassed[i] = tripIDs[i];
287  }
288 #ifdef DEBUG_PASSED
289  if (myLane->getID() == DEBUG_LANE) {
290  std::cout << " loadState limit=" << tripIDs.size() << " index=" << index << "\n";
291  for (int i = 0; i < (int)myPassed.size(); i++) {
292  std::cout << " i=" << i << " passed=" << myPassed[i] << "\n";
293  }
294  }
295 #endif
296  myLastIndex = index;
297 }
298 
299 
300 void
301 MSRailSignalConstraint_Predecessor::write(OutputDevice& out, const std::string& tripId) const {
302  out.openTag(getTag());
303  out.writeAttr(SUMO_ATTR_TRIP_ID, tripId);
306  if (myLimit > 1) {
308  }
309  if (!myAmActive) {
311  }
312  writeParams(out);
313  out.closeTag();
314 }
315 
316 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
#define SIMTIME
Definition: SUMOTime.h:62
@ SUMO_TAG_RAILSIGNAL_CONSTRAINTS
Constraints on switching a rail signal.
@ SUMO_TAG_RAILSIGNAL_CONSTRAINT_TRACKER
Saved state for constraint tracker.
@ 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.
@ SUMO_ATTR_ACTIVE
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:84
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:2375
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:182
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:378
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.
MSRailSignalConstraint_Predecessor(ConstraintType type, const MSRailSignal *signal, const std::string &tripId, int limit, bool active)
Constructor.
const MSRailSignal * myFoeSignal
store the foe signal (for TraCI access)
bool cleared() const
whether the constraint has been met
bool myAmActive
Whether this constraint is currently active.
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
void write(OutputDevice &out, const std::string &tripId) const
const int myLimit
the number of passed vehicles within which tripId must have occured
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.
static void clearAll()
Remove all constraints before quick-loading state.
static void cleanup()
clean up state
virtual void write(OutputDevice &out, const std::string &tripId) const =0
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:60
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:254
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.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
void writeParams(OutputDevice &device) const
write Params in the given outputdevice
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
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:56