Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MSDriveWay.h
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2002-2025 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 sequende of rail tracks (lanes) that may be used as a "set route" (Fahrstraße)
19/****************************************************************************/
20#pragma once
21#include <config.h>
22
23#include <utils/common/Named.h>
25#include <microsim/MSRoute.h>
26
27// ===========================================================================
28// class declarations
29// ===========================================================================
30class SUMOVehicle;
31class MSLane;
32class MSLink;
33class MSRailSignal;
34
35// ===========================================================================
36// class definitions
37// ===========================================================================
41class MSDriveWay : public MSMoveReminder, public Named {
42public:
43 typedef std::pair<const SUMOVehicle* const, const MSLink::ApproachingVehicleInformation> Approaching;
44 typedef std::set<const MSLane*, ComparatorNumericalIdLess> LaneSet;
45 typedef std::map<const MSLane*, int, ComparatorNumericalIdLess> LaneVisitedMap;
46
47 struct VehicleEvent {
48 VehicleEvent(SUMOTime _time, bool _isEntry, const std::string& _id, Notification _reason):
49 time(_time), isEntry(_isEntry), id(_id), reason(_reason) {}
51 bool isEntry;
52 std::string id;
54 };
55
56 /* The driveways (Fahrstrassen) for each link index of MSRailSignal
57 * Each link index has at least one driveway
58 * A driveway describes one possible route that passes the signal up to
59 * the next secure point
60 * When a signal guards a switch (indirect guard) that signal stores two
61 * or more driveways
62 */
63 MSDriveWay(const MSLink* origin, const std::string& id, bool temporary = false);
64
66 virtual ~MSDriveWay();
67
68 static void cleanup();
69
70 static void clearState();
71
72 static bool haveDriveWays() {
73 return myGlobalDriveWayIndex > 0;
74 }
75
76 static const MSDriveWay* retrieveDepartDriveWay(const MSEdge* edge, const std::string& id);
77
78 bool notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* enteredLane);
79 bool notifyLeave(SUMOTrafficObject& veh, double lastPos, Notification reason, const MSLane* enteredLane = 0);
80 bool notifyLeaveBack(SUMOTrafficObject& veh, Notification reason, const MSLane* leftLane);
82
84 bool flankConflict(const MSDriveWay& other) const;
85
87 bool crossingConflict(const MSDriveWay& other) const;
88
90 bool bidiBlockedBy(const MSDriveWay& other) const;
91
93 bool bidiBlockedByEnd(const MSDriveWay& other) const;
94
96 bool forwardRouteConflict(std::set<const MSEdge*> forward, const MSDriveWay& other, bool secondCheck = false);
97
99 bool conflictLaneOccupied(bool store = true, const SUMOVehicle* ego = nullptr) const;
100
102 bool foeDriveWayOccupied(bool store, const SUMOVehicle* ego, MSEdgeVector& occupied) const;
103
105 bool foeDriveWayApproached() const;
106
108 bool reserve(const Approaching& closest, MSEdgeVector& occupied);
109
111 void writeBlocks(OutputDevice& od) const;
112 void writeBlockVehicles(OutputDevice& od) const;
113
114 const std::vector<const MSEdge*>& getRoute() const {
115 return myRoute;
116 }
117
118 const std::vector<const MSLane*>& getFlank() const {
119 return myFlank;
120 }
121
122 const std::vector<const MSLane*>& getBidi() const {
123 return myBidi;
124 }
125
126 const std::vector<MSLink*>& getConflictLinks() const {
127 return myConflictLinks;
128 }
129
130 int getNumericalID() const {
131 return myNumericalID;
132 }
133
134 const std::vector<VehicleEvent>& getEvents() const {
135 return myVehicleEvents;
136 }
137
138 void setEvents(const std::vector<VehicleEvent>& events) {
139 myVehicleEvents = events;
140 }
141
142 void setVehicle(const std::string& vehID) {
143 myFirstVehicle = vehID;
144 }
145
146 const std::vector<MSDriveWay*>& getFoes() const {
147 return myFoes;
148 }
149
150 const std::vector<const MSLane*>& getForward() const {
151 return myForward;
152 }
153
155 bool match(MSRouteIterator firstIt, MSRouteIterator endIt) const;
156
157 void addDWDeadlock(const std::vector<const MSDriveWay*>& deadlockFoes);
158
159 bool isDepartDriveway() const {
160 return myOrigin == nullptr;
161 };
162
163 const MSLink* getOrigin() const {
164 return myOrigin;
165 }
166
168 bool hasTrain(SUMOVehicle* veh) const;
169
170 const std::vector<MSDriveWay*>& getSubDriveWays() const {
171 return mySubDriveWays;
172 }
173
174 static void init();
175
176 static bool hasRS(const MSEdge* cur, const MSEdge* next);
177
179 static bool mustYield(const Approaching& veh, const Approaching& foe);
180
182 static MSDriveWay* buildDriveWay(const std::string& id, const MSLink* link, MSRouteIterator first, MSRouteIterator end);
183
185 static std::string getClickableTLLinkID(const MSLink* link);
186
187 static const MSDriveWay* getDepartureDriveway(const SUMOVehicle* veh, bool init = false);
188
189 static void writeDepatureBlocks(OutputDevice& od, bool writeVehicles);
190
192 static void saveState(OutputDevice& out);
193 static void loadState(const SUMOSAXAttributes& attrs, int tag);
194
195protected:
196
199
202
205
207 std::vector<const MSEdge*> myRoute;
208
211
214
224
225 /* @brief the actual driveway part up to the next railsignal (halting position)
226 * This must be free of other trains */
227 std::vector<const MSLane*> myForward;
228
229 /* @brief the list of bidirectional edges that can enter the forward
230 * section and which must also be free of traffic
231 * (up to the first element that could give protection) */
232 std::vector<const MSLane*> myBidi;
233
234 /* @brief the list of bidirectional edges that can enter the forward
235 * section and which might contain deadlock-relevant traffic */
236 std::vector<const MSLane*> myBidiExtended;
237
238 /* @brief the list of edges that merge with the forward section
239 * (found via backward search, up to the first element that could give protection) */
240 std::vector<const MSLane*> myFlank;
241
243 std::vector<const MSLane*> myConflictLanes;
244
245 /* The conflict links for this block
246 * Conflict resolution must be performed if vehicles are approaching the
247 * current link and any of the conflict links */
248 std::vector<MSLink*> myConflictLinks;
249
251 bool hasLinkConflict(const Approaching& closest, const MSLink* foeLink) const;
252
254 bool overlap(const MSDriveWay& other) const;
255
256 /* @brief determine route that identifies this driveway (a subset of the
257 * vehicle route)
258 * collects:
259 * myRoute
260 * myForward
261 * myBidi
262 * myProtectedBidi
263 *
264 * returns edge that is assumed to safe from oncoming-deadlock or nullptr
265 */
266 void buildRoute(const MSLink* origin, MSRouteIterator next, MSRouteIterator end, LaneVisitedMap& visited, std::set<MSLink*>&);
267
268 /* @brief find switches that threaten this driveway
269 * @param[out] flankSwitches collect the switches
270 */
271 void checkFlanks(const MSLink* originLink, const std::vector<const MSLane*>& lanes, const LaneVisitedMap& visited, bool allFoes, std::set<MSLink*>& flankSwitches) const;
272
273 /* @brief find links that cross the driveway without entering it
274 * @param[out] flankSwitches collect the switches
275 */
276 void checkCrossingFlanks(MSLink* dwLink, const LaneVisitedMap& visited, std::set<MSLink*>& flankSwitches) const;
277
278 /* @brief find upstream protection from the given link
279 * @param[out] flank: the stored flank lanes
280 */
281 void findFlankProtection(MSLink* link, MSLink* origLink, std::vector<const MSLane*>& flank);
282
284 void addFoes(const MSLink* link);
285
287 void addSidings(MSDriveWay* foe, bool addToFoe = false);
288
290 void addBidiFoes(const MSRailSignal* ownSignal, bool extended);
291
293 void addParallelFoes(const MSLink* link, const MSEdge* first);
294
296 void addReversalFoes();
297
298 /* @brief build shortened driveway that ends where the foe train leaves the conflict zone of this driveway
299 * @return whether the foe has received a new entry in myFoes
300 */
301 bool buildSubFoe(MSDriveWay* foe, bool movingBlock);
302
304 void addConflictLink(const MSLink* link);
305
307 std::pair<bool, const MSDriveWay*> canUseSiding(const SUMOVehicle* ego, const MSDriveWay* foe, bool recurse = true) const;
308
309 bool isFoeOrSubFoe(const MSDriveWay* foe) const;
310
311 bool forwardEndOnRoute(const MSDriveWay* foe) const;
312
313 void addSwitchFoes(MSLink* link);
314
315 bool haveSubTrains() const;
316
317 /* @brief whether the train would have matched this driveway in it's past
318 * @return If matching, returns the number of edges the vehicle has gone past the start of the driveway,
319 * Indicate no-match by returning a negative value */
320 int matchesPastRoute(SUMOVehicle& sveh) const;
321
323 void enterDriveWay(SUMOVehicle& sveh, Notification reason);
324
325 static bool hasJoin(const SUMOVehicle* ego, const SUMOVehicle* foe);
326
327 static bool isSwitch(const MSLink* link);
328
329 void _saveState(OutputDevice& out) const;
330
332 static std::string getTLLinkID(const MSLink* link);
333
335 static std::string getJunctionLinkID(const MSLink* link);
336
338 static std::string formatVisitedMap(const LaneVisitedMap& visited);
339
341 static void appendMapIndex(LaneVisitedMap& map, const MSLane* lane);
342
343private:
344
345 struct Siding {
346 Siding(int s, int e, double l) : start(s), end(e), length(l) {}
347 // indices along route
348 int start;
349 int end;
350 double length;
351 };
352
353 std::set<SUMOVehicle*> myTrains;
354
355 std::vector<VehicleEvent> myVehicleEvents;
356 std::vector<MSDriveWay*> myFoes;
357 std::map<const MSDriveWay*, std::vector<Siding>, ComparatorIdLess> mySidings;
358 std::vector<std::set <const MSDriveWay*> > myDeadlocks;
359
360 /* @brief shortened versions of this driveway to be used as foes instead of the long original
361 * (ends as soon as the train has left a particular conflict section)
362 * they are never attached to a LinkInfo and thus never the target of the match() function */
363 std::vector<MSDriveWay*> mySubDriveWays;
364
366 std::vector<const MSEdge*> myReversals;
367
369 std::string myFirstVehicle;
370
372 static bool myWriteVehicles;
373 static std::set<const MSEdge*> myBlockLengthWarnings;
374
376 static std::map<const MSLink*, std::vector<MSDriveWay*> > mySwitchDriveWays;
377
379 static std::map<const MSEdge*, std::vector<MSDriveWay*> > myReversalDriveWays;
380
382 static std::map<const MSEdge*, std::vector<MSDriveWay*>, ComparatorNumericalIdLess > myDepartureDriveways;
383 static std::map<const MSJunction*, int> myDepartDrivewayIndex;
385 static std::map<const MSEdge*, std::vector<MSDriveWay*> > myDepartureDrivewaysEnds;
386
388 static std::map<const MSEdge*, std::vector<MSDriveWay*>, ComparatorNumericalIdLess> myEndingDriveways;
389
391 static std::map<ConstMSEdgeVector, MSDriveWay*> myDriveWayRouteLookup;
392 static std::map<std::string, MSDriveWay*> myDriveWayLookup;
393
394};
long long int SUMOTime
Definition GUI.h:36
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:73
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition MSRoute.h:57
void addFoes(const MSLink *link)
add all driveWays that start at the given link as foes
std::vector< MSLink * > myConflictLinks
Definition MSDriveWay.h:248
const SUMOVehicle * myActive
whether the current signal is switched green for a train approaching this block
Definition MSDriveWay.h:204
bool crossingConflict(const MSDriveWay &other) const
Wether there is a crossing conflict with the given driveway.
static std::string getJunctionLinkID(const MSLink *link)
return junctionID_junctionLinkIndex
static void clearState()
bool haveSubTrains() const
bool myIsSubDriveway
Definition MSDriveWay.h:223
std::vector< MSDriveWay * > mySubDriveWays
Definition MSDriveWay.h:363
std::vector< std::set< const MSDriveWay * > > myDeadlocks
Definition MSDriveWay.h:358
void checkFlanks(const MSLink *originLink, const std::vector< const MSLane * > &lanes, const LaneVisitedMap &visited, bool allFoes, std::set< MSLink * > &flankSwitches) const
bool myAbortedBuild
whether driveway building was aborted due to MAX_BLOCK_LENGTH
Definition MSDriveWay.h:220
bool buildSubFoe(MSDriveWay *foe, bool movingBlock)
static std::map< const MSJunction *, int > myDepartDrivewayIndex
Definition MSDriveWay.h:383
static bool hasJoin(const SUMOVehicle *ego, const SUMOVehicle *foe)
bool isDepartDriveway() const
Definition MSDriveWay.h:159
static std::string getClickableTLLinkID(const MSLink *link)
return logicID_linkIndex in a way that allows clicking in sumo-gui
const MSLink * myOrigin
the link that enters this driveway or nullptr for a departure driveWay
Definition MSDriveWay.h:201
bool myTerminateRoute
Definition MSDriveWay.h:218
std::vector< const MSLane * > myBidi
Definition MSDriveWay.h:232
static bool myWriteVehicles
Definition MSDriveWay.h:372
void checkCrossingFlanks(MSLink *dwLink, const LaneVisitedMap &visited, std::set< MSLink * > &flankSwitches) const
bool notifyReroute(SUMOTrafficObject &veh)
Called if the vehicle change it's route.
bool hasLinkConflict(const Approaching &closest, const MSLink *foeLink) const
Whether the approaching vehicle is prevent from driving by another vehicle approaching the given link...
void findFlankProtection(MSLink *link, MSLink *origLink, std::vector< const MSLane * > &flank)
std::vector< const MSLane * > myBidiExtended
Definition MSDriveWay.h:236
void addReversalFoes()
derive foe driveways that enter the bidi section by reversing
static bool hasRS(const MSEdge *cur, const MSEdge *next)
void addBidiFoes(const MSRailSignal *ownSignal, bool extended)
derive foe driveways based on myBidi or myBidiExtended
static const MSDriveWay * retrieveDepartDriveWay(const MSEdge *edge, const std::string &id)
static bool haveDriveWays()
Definition MSDriveWay.h:72
void writeBlocks(OutputDevice &od) const
Write block items for this driveway.
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, Notification reason, const MSLane *enteredLane=0)
Called if the vehicle leaves the reminder's lane.
std::vector< const MSLane * > myForward
Definition MSDriveWay.h:227
const std::vector< const MSLane * > & getBidi() const
Definition MSDriveWay.h:122
std::vector< const MSEdge * > myReversals
track own occurences in myReversalDriveWays for cleanup in destructor
Definition MSDriveWay.h:366
std::map< const MSDriveWay *, std::vector< Siding >, ComparatorIdLess > mySidings
Definition MSDriveWay.h:357
const std::vector< MSDriveWay * > & getSubDriveWays() const
Definition MSDriveWay.h:170
void writeBlockVehicles(OutputDevice &od) const
virtual ~MSDriveWay()
Destructor.
bool match(MSRouteIterator firstIt, MSRouteIterator endIt) const
whether the give route matches this driveway
static void appendMapIndex(LaneVisitedMap &map, const MSLane *lane)
append to map by map index and avoid undefined behavior
bool overlap(const MSDriveWay &other) const
Wether this driveway (route) overlaps with the given one.
void setEvents(const std::vector< VehicleEvent > &events)
Definition MSDriveWay.h:138
void buildRoute(const MSLink *origin, MSRouteIterator next, MSRouteIterator end, LaneVisitedMap &visited, std::set< MSLink * > &)
std::vector< const MSLane * > myFlank
Definition MSDriveWay.h:240
static std::string getTLLinkID(const MSLink *link)
return logicID_linkIndex
const std::vector< const MSLane * > & getForward() const
Definition MSDriveWay.h:150
std::vector< const MSEdge * > myRoute
list of edges for matching against train routes
Definition MSDriveWay.h:207
std::map< const MSLane *, int, ComparatorNumericalIdLess > LaneVisitedMap
Definition MSDriveWay.h:45
static void writeDepatureBlocks(OutputDevice &od, bool writeVehicles)
static std::map< ConstMSEdgeVector, MSDriveWay * > myDriveWayRouteLookup
lookup table for state loading
Definition MSDriveWay.h:391
int getNumericalID() const
Definition MSDriveWay.h:130
static std::set< const MSEdge * > myBlockLengthWarnings
Definition MSDriveWay.h:373
static std::map< const MSEdge *, std::vector< MSDriveWay * > > myReversalDriveWays
all driveways reversing on the given switch (used to look up flank foes)
Definition MSDriveWay.h:379
static void init()
void _saveState(OutputDevice &out) const
static std::string formatVisitedMap(const LaneVisitedMap &visited)
print link descriptions
static std::map< std::string, MSDriveWay * > myDriveWayLookup
Definition MSDriveWay.h:392
int matchesPastRoute(SUMOVehicle &sveh) const
const std::vector< MSLink * > & getConflictLinks() const
Definition MSDriveWay.h:126
const std::vector< MSDriveWay * > & getFoes() const
Definition MSDriveWay.h:146
const MSLink * getOrigin() const
Definition MSDriveWay.h:163
bool flankConflict(const MSDriveWay &other) const
Wether there is a flank conflict with the given driveway.
bool conflictLaneOccupied(bool store=true, const SUMOVehicle *ego=nullptr) const
whether any of myConflictLanes is occupied (vehicles that are the target of a join must be ignored)
void addSwitchFoes(MSLink *link)
bool hasTrain(SUMOVehicle *veh) const
whether the given train is on this driveway
static std::map< const MSEdge *, std::vector< MSDriveWay * > > myDepartureDrivewaysEnds
all driveways that do not start at a rail signal (and are only used at departure) by end edge
Definition MSDriveWay.h:385
int myCoreSize
number of edges in myRoute where overlap with other driveways is forbidden
Definition MSDriveWay.h:210
std::pair< const SUMOVehicle *const, const MSLink::ApproachingVehicleInformation > Approaching
Definition MSDriveWay.h:43
void addConflictLink(const MSLink *link)
add symmetical conflict link for foes when building a new driveway
static void cleanup()
bool notifyLeaveBack(SUMOTrafficObject &veh, Notification reason, const MSLane *leftLane)
Called if the vehicle's back leaves the reminder's lane.
std::string myFirstVehicle
the first vehicle using this driveway
Definition MSDriveWay.h:369
int myNumericalID
global driveway index
Definition MSDriveWay.h:198
bool forwardEndOnRoute(const MSDriveWay *foe) const
bool myFoundJump
Definition MSDriveWay.h:217
static void saveState(OutputDevice &out)
Save driveway occupancy into the given stream.
static std::map< const MSEdge *, std::vector< MSDriveWay * >, ComparatorNumericalIdLess > myDepartureDriveways
all driveways that do not start at a rail signal (and are only used at departure)
Definition MSDriveWay.h:382
void setVehicle(const std::string &vehID)
Definition MSDriveWay.h:142
bool myBidiEnded
whether driveway building was aborted when no further bidi edge was found
Definition MSDriveWay.h:222
static bool mustYield(const Approaching &veh, const Approaching &foe)
Whether veh must yield to the foe train.
const std::vector< const MSEdge * > & getRoute() const
Definition MSDriveWay.h:114
void addSidings(MSDriveWay *foe, bool addToFoe=false)
add sidings for the given foe
void enterDriveWay(SUMOVehicle &sveh, Notification reason)
helper method for notifyEnter
bool bidiBlockedByEnd(const MSDriveWay &other) const
Wether there is a bidi conflict with the end of the given driveway.
static int myGlobalDriveWayIndex
Definition MSDriveWay.h:371
static MSDriveWay * buildDriveWay(const std::string &id, const MSLink *link, MSRouteIterator first, MSRouteIterator end)
construct a new driveway by searching along the given route until all block structures are found
bool myFoundSignal
whether this driveway ends its forward section with a rail signal (and thus comprises a full block)
Definition MSDriveWay.h:216
static std::map< const MSLink *, std::vector< MSDriveWay * > > mySwitchDriveWays
all driveways passing the given switch (used to look up flank foes)
Definition MSDriveWay.h:376
bool isFoeOrSubFoe(const MSDriveWay *foe) const
const std::vector< const MSLane * > & getFlank() const
Definition MSDriveWay.h:118
const std::vector< VehicleEvent > & getEvents() const
Definition MSDriveWay.h:134
int myForwardEdgeCount
number of normal edges in myForward
Definition MSDriveWay.h:213
void addDWDeadlock(const std::vector< const MSDriveWay * > &deadlockFoes)
static std::map< const MSEdge *, std::vector< MSDriveWay * >, ComparatorNumericalIdLess > myEndingDriveways
all driveways that end on the given edge
Definition MSDriveWay.h:388
bool foeDriveWayApproached() const
whether any of my Foes is being approached
static void loadState(const SUMOSAXAttributes &attrs, int tag)
bool forwardRouteConflict(std::set< const MSEdge * > forward, const MSDriveWay &other, bool secondCheck=false)
Wether the route of other passes into the forward section of this driveway.
std::pair< bool, const MSDriveWay * > canUseSiding(const SUMOVehicle *ego, const MSDriveWay *foe, bool recurse=true) const
return whether a siding can be used. If a siding exist but is occupied, also return the occupied driv...
std::vector< const MSLane * > myConflictLanes
the lanes that must be clear of trains before this signal can switch to green
Definition MSDriveWay.h:243
static const MSDriveWay * getDepartureDriveway(const SUMOVehicle *veh, bool init=false)
std::vector< MSDriveWay * > myFoes
Definition MSDriveWay.h:356
std::vector< VehicleEvent > myVehicleEvents
Definition MSDriveWay.h:355
std::set< const MSLane *, ComparatorNumericalIdLess > LaneSet
Definition MSDriveWay.h:44
static bool isSwitch(const MSLink *link)
bool notifyEnter(SUMOTrafficObject &veh, Notification reason, const MSLane *enteredLane)
Checks whether the reminder is activated by a vehicle entering the lane.
bool bidiBlockedBy(const MSDriveWay &other) const
Wether there is a bidi conflict with the given driveway.
bool reserve(const Approaching &closest, MSEdgeVector &occupied)
attempt reserve this driveway for the given vehicle
std::set< SUMOVehicle * > myTrains
Definition MSDriveWay.h:353
void addParallelFoes(const MSLink *link, const MSEdge *first)
derive foe driveways that start at the same signal
bool foeDriveWayOccupied(bool store, const SUMOVehicle *ego, MSEdgeVector &occupied) const
whether any of myFoes is occupied (vehicles that are the target of a join must be ignored)
A road/street connecting two junctions.
Definition MSEdge.h:77
Representation of a lane in the micro simulation.
Definition MSLane.h:84
Something on a lane to be noticed about vehicle movement.
Notification
Definition of a vehicle state.
A signal for rails.
Base class for objects which have an id.
Definition Named.h:54
Static storage of an output device and its base (abstract) implementation.
Encapsulated SAX-Attributes.
Representation of a vehicle, person, or container.
Representation of a vehicle.
Definition SUMOVehicle.h:62
Function-object for stable sorting of objects acting like Named without being derived (SUMOVehicle)
Definition Named.h:30
Function-object for stable sorting of objects with numerical ids.
Definition Named.h:39
Siding(int s, int e, double l)
Definition MSDriveWay.h:346
VehicleEvent(SUMOTime _time, bool _isEntry, const std::string &_id, Notification _reason)
Definition MSDriveWay.h:48