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-2023 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"
33#include "MSRailSignalControl.h"
34
35//#define DEBUG_PASSED
36//#define DEBUG_LANE
37
38// ===========================================================================
39// static value definitions
40// ===========================================================================
41std::map<const MSLane*, MSRailSignalConstraint_Predecessor::PassedTracker*> MSRailSignalConstraint_Predecessor::myTrackerLookup;
42
43// ===========================================================================
44// MSRailSignalConstraint method definitions
45// ===========================================================================
46void
49}
50
51void
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
70void
73}
74
75void
77 for (MSRailSignal* s : MSRailSignalControl::getInstance().getSignals()) {
78 s->removeConstraints();
79 }
80}
81
82
83std::string
84MSRailSignalConstraint::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// ===========================================================================
98MSRailSignalConstraint_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
121void
123 for (auto item : myTrackerLookup) {
124 delete item.second;
125 }
126 myTrackerLookup.clear();
127}
128
129void
131 for (auto item : myTrackerLookup) {
132 item.second->saveState(out);
133 }
134}
135
136void
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
155void
157 for (auto item : myTrackerLookup) {
158 item.second->clearState();
159 }
160}
161
162
163bool
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
176std::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
216bool
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
228void
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
240bool
241MSRailSignalConstraint_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
260void
262 myPassed = std::vector<std::string>(myPassed.size());
263 myLastIndex = 0;
264}
265
266void
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
282void
283MSRailSignalConstraint_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
300void
301MSRailSignalConstraint_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:271
#define TL(string)
Definition: MsgHandler.h:287
#define TLF(string,...)
Definition: MsgHandler.h:288
#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:2325
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:183
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:380
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 & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
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:62
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
Definition: StringUtils.cpp:56