Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSLink.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-2026 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/****************************************************************************/
20// A connection between lanes
21/****************************************************************************/
22#pragma once
23#include <config.h>
24
25#include <vector>
26#include <set>
31#include "MSLane.h"
32
33
34// ===========================================================================
35// class declarations
36// ===========================================================================
37class MSLane;
38class MSJunction;
39class MSVehicle;
40class MSPerson;
41class OutputDevice;
43
44
45// ===========================================================================
46// class definitions
47// ===========================================================================
68class MSLink {
69public:
70
76 LL_IN_THE_WAY = 1 << 0,
78 LL_FROM_LEFT = 1 << 1,
82 LL_SAME_TARGET = 1 << 3
83 };
84
85 struct LinkLeader {
86 LinkLeader(MSVehicle* _veh, double _gap, double _distToCrossing, int _llFlags = LL_FROM_LEFT, double _latOffst = 0) :
87 vehAndGap(std::make_pair(_veh, _gap)),
88 distToCrossing(_distToCrossing),
89 llFlags(_llFlags),
90 latOffset(_latOffst)
91 { }
92
93 inline bool fromLeft() const {
94 return (llFlags & LL_FROM_LEFT) != 0;
95 }
96 inline bool inTheWay() const {
97 return (llFlags & LL_IN_THE_WAY) != 0;
98 }
99 inline bool sameTarget() const {
100 return (llFlags & LL_SAME_TARGET) != 0;
101 }
102 inline bool sameSource() const {
103 return (llFlags & LL_SAME_SOURCE) != 0;
104 }
105
106 std::pair<MSVehicle*, double> vehAndGap;
109 double latOffset;
110
111 };
112
113 typedef std::vector<LinkLeader> LinkLeaders;
114
124 ApproachingVehicleInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime,
125 const double _arrivalSpeed, const double _leaveSpeed,
126 const bool _willPass,
127 const double _arrivalSpeedBraking,
128 const SUMOTime _waitingTime,
129 const double _dist,
130 const double _speed,
131 const double _latOffset
132 ) :
133 arrivalTime(_arrivalTime), leavingTime(_leavingTime),
134 arrivalSpeed(_arrivalSpeed), leaveSpeed(_leaveSpeed),
135 willPass(_willPass),
136 arrivalSpeedBraking(_arrivalSpeedBraking),
137 waitingTime(_waitingTime),
138 dist(_dist),
139 speed(_speed),
140 latOffset(_latOffset) {
141 }
142
148 const double arrivalSpeed;
150 const double leaveSpeed;
152 const bool willPass;
158 const double dist;
160 const double speed;
162 const double latOffset;
163
164 };
165
175 ApproachingPersonInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime) :
176 arrivalTime(_arrivalTime), leavingTime(_leavingTime) {}
181 };
182
183 typedef std::map<const SUMOVehicle*, const ApproachingVehicleInformation, ComparatorNumericalIdLess> ApproachInfos;
184 typedef std::vector<const SUMOTrafficObject*> BlockingFoes;
185 typedef std::map<const MSPerson*, ApproachingPersonInformation> PersonApproachInfos;
186
194
197
198 ConflictInfo(double lbc, double cs, ConflictFlag fl = CONFLICT_DEFAULT) :
201 conflictSize(cs),
202 flag(fl)
203 {}
210
212
213 double getFoeLengthBehindCrossing(const MSLink* foeExitLink) const;
214 double getFoeConflictSize(const MSLink* foeExitLink) const;
215 double getLengthBehindCrossing(const MSLink* exitLink) const;
216 };
217
220 CustomConflict(const MSLane* f, const MSLane* t, double s, double e) :
221 from(f), to(t), startPos(s), endPos(e) {}
222 const MSLane* from;
223 const MSLane* to;
224 double startPos;
225 double endPos;
226 };
227
230 bool operator()(const MSLink* const a, const MSLink* const b) const {
231 return (a->getLane()->getNumericalID() < b->getLane()->getNumericalID())
232 || (a->getLane()->getNumericalID() == b->getLane()->getNumericalID() && a->getIndex() < b->getIndex());
233 }
234 };
235
236
245 MSLink(MSLane* predLane,
246 MSLane* succLane,
247 MSLane* via,
248 LinkDirection dir,
249 LinkState state,
250 double length,
251 double foeVisibilityDistance,
252 bool keepClear,
253 MSTrafficLightLogic* logic,
254 int tlLinkIdx,
255 bool indirect);
256
257
259 ~MSLink();
260
261 void addCustomConflict(const MSLane* from, const MSLane* to, double startPos, double endPos);
262
270 void setRequestInformation(int index, bool hasFoes, bool isCont,
271 const std::vector<MSLink*>& foeLinks, const std::vector<MSLane*>& foeLanes,
272 MSLane* internalLaneBefore = 0);
273
275 void addWalkingAreaFoe(const MSLane* lane) {
276 myWalkingAreaFoe = lane;
277 }
278
280 void addWalkingAreaFoeExit(const MSLane* lane) {
282 }
283
286 return myWalkingAreaFoe;
287 }
291
296 void setApproaching(const SUMOVehicle* approaching, const SUMOTime arrivalTime,
297 const double arrivalSpeed, const double leaveSpeed, const bool setRequest,
298 const double arrivalSpeedBraking,
299 const SUMOTime waitingTime, double dist, double latOffset);
300
302 void setApproaching(const SUMOVehicle* approaching, ApproachingVehicleInformation ai);
303
305 void setApproachingPerson(const MSPerson* approaching, const SUMOTime arrivalTime, const SUMOTime leaveTime);
306
308 void removeApproaching(const SUMOVehicle* veh);
309
311 void removeApproachingPerson(const MSPerson* person);
312
313 /* @brief return information about this vehicle if it is registered as
314 * approaching (dummy values otherwise)
315 * @note used for visualisation of link items */
316 ApproachingVehicleInformation getApproaching(const SUMOVehicle* veh) const;
317 const ApproachingVehicleInformation* getApproachingPtr(const SUMOVehicle* veh) const;
318
322 }
323
328
330 void clearState();
331
339 bool opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength,
340 double impatience, double decel, SUMOTime waitingTime,
341 double posLat = 0,
342 BlockingFoes* collectFoes = nullptr,
343 bool ignoreRed = false,
344 const SUMOTrafficObject* ego = nullptr,
345 double dist = -1) const;
346
362 bool blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
363 bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
364 BlockingFoes* collectFoes = nullptr, const SUMOTrafficObject* ego = nullptr, bool lastWasContRed = false, double dist = -1) const;
365
366
376 bool hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, double speed, double decel) const;
377
382 std::pair<const SUMOVehicle*, const MSLink*> getFirstApproachingFoe(const MSLink* wrapAround) const;
383
385 return myJunction;
386 }
387
388
394 return myState;
395 }
396
397
403 return myOffState;
404 }
405
411 return myLastGreenState;
412 }
413
414
415 //@brief Returns the time of the last state change
417 return myLastStateChange;
418 }
419
420
426 return myDirection;
427 }
428
429
430
436 void setTLState(LinkState state, SUMOTime t);
437
441 void setTLLogic(const MSTrafficLightLogic* logic);
442
447 inline MSLane* getLane() const {
448 return myLane;
449 }
450
451
456 inline int getIndex() const {
457 return myIndex;
458 }
459
461 inline int getTLIndex() const {
462 return myTLIndex;
463 }
464
466 inline const MSTrafficLightLogic* getTLLogic() const {
467 return myLogic;
468 }
469
473 inline bool havePriority() const {
474 return myState >= 'A' && myState <= 'Z';
475 }
476
477 inline bool haveOffPriority() const {
478 return myOffState >= 'A' && myOffState <= 'Z';
479 }
480
484 inline bool haveRed() const {
486 }
487
488 inline bool haveYellow() const {
490 }
491
492 inline bool haveGreen() const {
494 }
495
496 inline bool mustStop() const {
498 }
499
500 inline bool isTLSControlled() const {
501 return myLogic != 0;
502 }
503
507
512 double getLength() const {
513 return myLength;
514 }
515
516
525 }
526
527 double getDistToFoePedCrossing() const {
529 }
530
535 bool hasFoes() const {
536 return myHasFoes;
537 }
538
539 // @brief return whether the vehicle may continute past this link to wait within the intersection
540 bool isCont() const;
541
542
544 bool keepClear() const {
545 return myKeepClear;
546 }
547
549 bool isIndirect() const {
550 return myAmIndirect;
551 }
552
554 bool lastWasContMajor() const;
555
557 bool lastWasContState(LinkState linkState) const;
558
562 double getInternalLengthsAfter() const;
563
567 double getInternalLengthsBefore() const;
568
574 double getLengthsBeforeCrossing(const MSLane* foeLane) const;
575
576
582 double getLengthBeforeCrossing(const MSLane* foeLane) const;
583
584
589 inline MSLane* getViaLane() const {
590 return myInternalLane;
591 }
592
601 const LinkLeaders getLeaderInfo(const MSVehicle* ego, double dist, std::vector<const MSPerson*>* collectBlockers = 0, bool isShadowLink = false) const;
602
604 double getZipperSpeed(const MSVehicle* ego, const double dist, double vSafe,
605 SUMOTime arrivalTime,
606 const BlockingFoes* foes) const;
607
609 inline MSLane* getViaLaneOrLane() const {
610 return myInternalLane != nullptr ? myInternalLane : myLane;
611 }
612
613
615 inline const MSLane* getLaneBefore() const {
616 assert(myInternalLaneBefore == nullptr || myLaneBefore == myInternalLaneBefore); // lane before mismatch!
617 return myLaneBefore;
618 }
619
621 inline const MSLane* getInternalLaneBefore() const {
623 }
624
626 SUMOTime getLeaveTime(const SUMOTime arrivalTime, const double arrivalSpeed, const double leaveSpeed, const double vehicleLength) const;
627
629 void writeApproaching(OutputDevice& od, const std::string fromLaneID) const;
630
632 MSLink* getParallelLink(int direction) const;
633
636
638 inline bool fromInternalLane() const {
639 return myInternalLaneBefore != nullptr;
640 }
641
643 bool isEntryLink() const;
644
646 bool isConflictEntryLink() const;
647
649 bool isExitLink() const;
650
653
655 const MSLink* getCorrespondingExitLink() const;
656
658 const MSLink* getCorrespondingEntryLink() const;
659
661 bool isInternalJunctionLink() const;
662
665 return myMesoTLSPenalty;
666 }
667
669 double getGreenFraction() const {
670 return myGreenFraction;
671 }
672
674 void setMesoTLSPenalty(const SUMOTime penalty) {
675 myMesoTLSPenalty = penalty;
676 }
677
679 void setGreenFraction(const double fraction) {
680 myGreenFraction = fraction;
681 }
682
683 const std::vector<const MSLane*>& getFoeLanes() const {
684 return myFoeLanes;
685 }
686
687 const std::vector<ConflictInfo>& getConflicts() const {
688 return myConflicts;
689 }
690
691 const std::vector<MSLink*>& getFoeLinks() const {
692 return myFoeLinks;
693 }
694
697 return myPermissions;
698 }
699
701 void initParallelLinks();
702
704 inline double getLateralShift() const {
705 return myLateralShift;
706 }
707
709 std::string getDescription() const;
710
712 std::pair<const SUMOVehicle* const, const ApproachingVehicleInformation> getClosest() const;
713
714 inline bool hasFoeCrossing() const {
716 }
717
719 bool railSignalWasPassed() const;
720
722 static void recheckSetRequestInformation();
723
724 static bool ignoreFoe(const SUMOTrafficObject* ego, const SUMOTrafficObject* foe);
725
726 static const double NO_INTERSECTION;
727
728private:
730 static inline bool unsafeMergeSpeeds(double leaderSpeed, double followerSpeed, double leaderDecel, double followerDecel) {
731 // XXX mismatch between continuous an discrete deceleration
732 return (leaderSpeed * leaderSpeed / leaderDecel) <= (followerSpeed * followerSpeed / followerDecel);
733 }
734
736 static bool couldBrakeForLeader(double followDist, double leaderDist, const MSVehicle* follow, const MSVehicle* leader);
737
738 MSLink* computeParallelLink(int direction);
739
741 void checkWalkingAreaFoe(const MSVehicle* ego, const MSLane* foeLane, std::vector<const MSPerson*>* collectBlockers, LinkLeaders& result) const;
742
744 bool isInFront(const MSVehicle* ego, const PositionVector& egoPath, const Position& pPos) const;
745
747 double isOnComingPed(const MSVehicle* ego, const MSPerson* p) const;
748
750 Position getFuturePosition(const MSPerson* p, double timeHorizon = 1) const;
751
752 bool blockedByFoe(const SUMOVehicle* veh, const ApproachingVehicleInformation& avi,
753 SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
754 bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
755 const SUMOTrafficObject* ego) const;
756
758 bool checkContOff() const;
759
761 bool contIntersect(const MSLane* lane, const MSLane* foe);
762
764 double computeDistToDivergence(const MSLane* lane, const MSLane* sibling, double minDist, bool sameSource, double siblingPredLength = 0) const;
765
767 static SUMOTime computeFoeArrivalTimeBraking(SUMOTime arrivalTime, const SUMOVehicle* foe, SUMOTime foeArrivalTime, double impatience, double dist, double& fasb);
768
770 static bool lateralOverlap(double posLat, double width, double posLat2, double width2);
771
773 const CustomConflict* getCustomConflict(const MSLane* foeLane) const;
774
776 void updateDistToFoePedCrossing(double dist);
777
778private:
781
784
787
790
792 const int myTLIndex;
793
796
803
806
809
812 double myLength;
813
819
822
825
826 // @brief whether vehicles may continue past this link to wait within the intersection
828 // @brief whether vehicles may continue past this link to wait within the intersection after switching of the traffic light at this intersection
830
831 // @brief whether vehicles must keep the intersection clear if there is a downstream jam
833
836
837 /* @brief The preceding junction-internal lane, only used at
838 * - exit links (from internal lane to normal lane)
839 * - internal junction links (from internal lane to internal lane)
840 */
842
847
850
851 /* @brief lengths after the crossing point with foeLane
852 * (index corresponds to myFoeLanes)
853 * empty vector for entry links
854 * */
855 std::vector<ConflictInfo> myConflicts;
856
857 std::vector<CustomConflict> myCustomConflicts;
858
859 // TODO: documentation
860 std::vector<MSLink*> myFoeLinks;
861 std::vector<const MSLane*> myFoeLanes;
862
863 /* prioritized links when the traffic light is switched off (only needed for RightOfWay::ALLWAYSTOP)
864 * @note stored as a pointer to save space since it won't be used in most cases
865 */
866 std::vector<MSLink*>* myOffFoeLinks;
867
872
875
876 /* @brief Links with the same origin lane and the same destination edge that may
877 be in conflict for sublane simulation */
878 std::vector<MSLink*> mySublaneFoeLinks;
879 /* @brief Links with the same origin lane and different destination edge that may
880 be in conflict for sublane simulation */
881 std::vector<MSLink*> mySublaneFoeLinks2;
882
883 /* @brief Internal Lanes with the same origin lane and the same destination edge that may
884 be in conflict for sublane simulation */
885 std::vector<MSLane*> mySublaneFoeLanes;
886
889
891 static std::set<std::pair<MSLink*, MSLink*> > myRecheck;
892
895
897 const bool myAmIndirect;
898
900 double myRadius;
901
904
907
909 MSLink(const MSLink& s);
910
913
914};
long long int SUMOTime
Definition GUI.h:36
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
@ TURN
The link is a 180 degree turn.
@ TURN_LEFTHAND
The link is a 180 degree turn (left-hand network)
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_TL_REDYELLOW
The link has red light (must brake) but indicates upcoming green.
@ LINKSTATE_ALLWAY_STOP
This is an uncontrolled, all-way stop link.
@ LINKSTATE_STOP
This is an uncontrolled, minor link, has to stop.
@ LINKSTATE_TL_YELLOW_MAJOR
The link has yellow light, may pass.
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_TL_YELLOW_MINOR
The link has yellow light, has to brake anyway.
@ LINKSTATE_TL_RED
The link has red light (must brake)
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
The base class for an intersection.
Definition MSJunction.h:58
Representation of a lane in the micro simulation.
Definition MSLane.h:84
int getNumericalID() const
Returns this lane's numerical id.
Definition MSLane.h:526
The parent class for traffic light logics.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
Static storage of an output device and its base (abstract) implementation.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
A list of positions.
Representation of a vehicle, person, or container.
Representation of a vehicle.
Definition SUMOVehicle.h:63
Definition json.hpp:4471