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-2020 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 
25 #include <microsim/MSLane.h>
26 #include <microsim/MSEdge.h>
27 #include <microsim/MSLink.h>
28 #include <microsim/MSNet.h>
30 #include "MSRailSignal.h"
31 #include "MSRailSignalConstraint.h"
32 
33 //#define DEBUG_PASSED
34 //#define DEBUG_LANE
35 
36 // ===========================================================================
37 // static value definitions
38 // ===========================================================================
39 std::map<const MSLane*, MSRailSignalConstraint_Predecessor::PassedTracker*> MSRailSignalConstraint_Predecessor::myTrackerLookup;
40 
41 // ===========================================================================
42 // MSRailSignalConstraint method definitions
43 // ===========================================================================
44 void
47 }
48 
49 void
52 }
53 
54 void
57 }
58 
59 std::string
60 MSRailSignalConstraint::getVehID(const std::string& tripID) {
62  for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
63  SUMOVehicle* veh = i->second;
64  if (veh->getParameter().getParameter("tripId") == tripID) {
65  return veh->getID();
66  }
67  }
68  return "";
69 }
70 
71 // ===========================================================================
72 // MSRailSignalConstraint_Predecessor method definitions
73 // ===========================================================================
74 MSRailSignalConstraint_Predecessor::MSRailSignalConstraint_Predecessor(const MSRailSignal* signal, const std::string& tripId, int limit) :
75  myTripId(tripId),
76  myLimit(limit) {
77  for (const auto& lv : signal->getLinks()) {
78  for (const MSLink* link : lv) {
79  MSLane* lane = link->getViaLaneOrLane();
80  PassedTracker* pt = nullptr;
81  if (myTrackerLookup.count(lane) == 0) {
82  pt = new PassedTracker(lane);
83  myTrackerLookup[lane] = pt;
84  } else {
85  pt = myTrackerLookup[lane];
86  }
87  pt->raiseLimit(limit);
88  myTrackers.push_back(pt);
89  }
90  }
91 
92 }
93 
94 void
96  for (auto item : myTrackerLookup) {
97  delete item.second;
98  }
99  myTrackerLookup.clear();
100 }
101 
102 void
104  for (auto item : myTrackerLookup) {
105  item.second->saveState(out);
106  }
107 }
108 
109 void
111  bool ok;
112  const std::string laneID = attrs.getString(SUMO_ATTR_LANE);
113  const int index = attrs.get<int>(SUMO_ATTR_INDEX, "", ok);
114  std::vector<std::string> tripIDs = attrs.getStringVector(SUMO_ATTR_STATE);
115  MSLane* lane = MSLane::dictionary(laneID);
116  if (lane == nullptr) {
117  throw ProcessError("Unknown lane '" + laneID + "' in loaded state");
118  }
119  if (myTrackerLookup.count(lane) == 0) {
120  WRITE_WARNINGF("Unknown tracker lane '%' in loaded state", laneID);
121  return;
122  }
123  PassedTracker* tracker = myTrackerLookup[lane];
124  tracker->loadState(index, tripIDs);
125 }
126 
127 
128 void
130  for (auto item : myTrackerLookup) {
131  item.second->clearState();
132  }
133 }
134 
135 
136 bool
138  for (PassedTracker* pt : myTrackers) {
139  if (pt->hasPassed(myTripId, myLimit)) {
140  return true;
141  }
142  }
143  return false;
144 }
145 
146 std::string
148  // try to retrieve vehicle id that belongs to myTripId
149  // this may be slow so it should only be used for debugging
150  std::string vehID = getVehID(myTripId);
151  if (vehID != "") {
152  vehID = " (" + vehID + ")";
153  }
154  std::vector<std::string> passedIDs;
155  for (const std::string& passedTripID : myTrackers.front()->myPassed) {
156  if (passedTripID == "") {
157  continue;
158  }
159  const std::string passedID = getVehID(passedTripID);
160  if (passedID != "") {
161  passedIDs.push_back(passedID);
162  }
163  }
164  std::string passedIDs2 = "";
165  if (passedIDs.size() > 0) {
166  passedIDs2 = " (" + toString(passedIDs) + ")";
167  }
168  return ("predecessor " + myTripId + vehID + " at signal " + myTrackers.front()->getLane()->getEdge().getFromJunction()->getID()
169  + " passed=" + toString(myTrackers.front()->myPassed) + passedIDs2);
170 }
171 
172 // ===========================================================================
173 // MSRailSignalConstraint_Predecessor::PassedTracker method definitions
174 // ===========================================================================
175 
177  MSMoveReminder("PassedTracker_" + lane->getID(), lane, true),
178  myPassed(1, ""),
179  myLastIndex(-1)
180 { }
181 
182 bool
184  myLastIndex = (myLastIndex + 1) % myPassed.size();
185  myPassed[myLastIndex] = veh.getParameter().getParameter("tripId", veh.getID());
186 #ifdef DEBUG_PASSED
187  if (myLane->getID() == DEBUG_LANE) {
188  std::cout << SIMTIME << " hasPassed " << veh.getID() << " tripId=" << veh.getParameter().getParameter("tripId", veh.getID()) << " index=" << myLastIndex << "\n";
189  }
190 #endif
191  return true;
192 }
193 
194 void
196  while (limit > (int)myPassed.size()) {
197  myPassed.insert(myPassed.begin() + (myLastIndex + 1), "");
198  }
199 #ifdef DEBUG_PASSED
200  if (myLane->getID() == DEBUG_LANE) {
201  std::cout << " raiseLimit=" << limit << "\n";
202  }
203 #endif
204 }
205 
206 bool
207 MSRailSignalConstraint_Predecessor::PassedTracker::hasPassed(const std::string& tripId, int limit) const {
208  if (myLastIndex < 0) {
209  return false;
210  }
211  int i = myLastIndex;
212  while (limit > 0) {
213  if (myPassed[i] == tripId) {
214  return true;
215  }
216  if (i == 0) {
217  i = (int)myPassed.size() - 1;
218  } else {
219  i--;
220  }
221  limit--;
222  }
223  return false;
224 }
225 
226 void
228  myPassed = std::vector<std::string>(myPassed.size());
229  myLastIndex = 0;
230 }
231 
232 void
234  const std::string state = toString(myPassed.back() == ""
235  ? std::vector<std::string>(myPassed.begin(), myPassed.begin() + myLastIndex + 1)
236  // wrapped around
237  : myPassed);
238  // no need to save state if no vehicles have passed this tracker
239  if (state != "") {
241  out.writeAttr(SUMO_ATTR_LANE, getLane()->getID());
242  out.writeAttr(SUMO_ATTR_INDEX, myLastIndex);
243  out.writeAttr(SUMO_ATTR_STATE, state);
244  out.closeTag();
245  }
246 }
247 
248 void
249 MSRailSignalConstraint_Predecessor::PassedTracker::loadState(int index, const std::vector<std::string>& tripIDs) {
250  raiseLimit((int)tripIDs.size());
251  for (int i = 0; i < (int)tripIDs.size(); i++) {
252  myPassed[i] = tripIDs[i];
253  }
254 #ifdef DEBUG_PASSED
255  if (myLane->getID() == DEBUG_LANE) {
256  std::cout << " loadState limit=" << tripIDs.size() << " index=" << index << "\n";
257  for (int i = 0; i < (int)myPassed.size(); i++) {
258  std::cout << " i=" << i << " passed=" << myPassed[i] << "\n";
259  }
260  }
261 #endif
262  myLastIndex = index;
263 }
264 
265 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:277
#define SIMTIME
Definition: SUMOTime.h:60
@ SUMO_TAG_RAILSIGNAL_CONSTRAINT_TRACKER
Saved state for constraint tracker.
@ SUMO_ATTR_LANE
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_STATE
The state of a link.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
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:1908
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:171
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:371
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.
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.
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 cleanup()
clean up state
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:73
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
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:239
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
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:58