Eclipse SUMO - Simulation of Urban MObility
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-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 /****************************************************************************/
20 // A connection between lanes
21 /****************************************************************************/
22 #pragma once
23 #include <config.h>
24 
25 #include <vector>
26 #include <set>
27 #include <utils/common/SUMOTime.h>
31 
32 
33 // ===========================================================================
34 // class declarations
35 // ===========================================================================
36 class MSLane;
37 class MSJunction;
38 class MSVehicle;
39 class MSPerson;
40 class OutputDevice;
42 
43 
44 // ===========================================================================
45 // class definitions
46 // ===========================================================================
67 class MSLink {
68 public:
69 
75  LL_IN_THE_WAY = 1 << 0,
77  LL_FROM_LEFT = 1 << 1,
79  LL_SAME_SOURCE = 1 << 2,
81  LL_SAME_TARGET = 1 << 3
82  };
83 
84  struct LinkLeader {
85  LinkLeader(MSVehicle* _veh, double _gap, double _distToCrossing, int _llFlags = LL_FROM_LEFT, double _latOffst = 0) :
86  vehAndGap(std::make_pair(_veh, _gap)),
87  distToCrossing(_distToCrossing),
88  llFlags(_llFlags),
89  latOffset(_latOffst)
90  { }
91 
92  inline bool fromLeft() const {
93  return (llFlags & LL_FROM_LEFT) != 0;
94  }
95  inline bool inTheWay() const {
96  return (llFlags & LL_IN_THE_WAY) != 0;
97  }
98  inline bool sameTarget() const {
99  return (llFlags & LL_SAME_TARGET) != 0;
100  }
101  inline bool sameSource() const {
102  return (llFlags & LL_SAME_SOURCE) != 0;
103  }
104 
105  std::pair<MSVehicle*, double> vehAndGap;
107  int llFlags;
108  double latOffset;
109 
110  };
111 
112  typedef std::vector<LinkLeader> LinkLeaders;
113 
123  ApproachingVehicleInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime,
124  const double _arrivalSpeed, const double _leaveSpeed,
125  const bool _willPass,
126  const double _arrivalSpeedBraking,
127  const SUMOTime _waitingTime,
128  const double _dist,
129  const double _speed,
130  const double _latOffset
131  ) :
132  arrivalTime(_arrivalTime), leavingTime(_leavingTime),
133  arrivalSpeed(_arrivalSpeed), leaveSpeed(_leaveSpeed),
134  willPass(_willPass),
135  arrivalSpeedBraking(_arrivalSpeedBraking),
136  waitingTime(_waitingTime),
137  dist(_dist),
138  speed(_speed),
139  latOffset(_latOffset) {
140  }
141 
147  const double arrivalSpeed;
149  const double leaveSpeed;
151  const bool willPass;
153  const double arrivalSpeedBraking;
157  const double dist;
159  const double speed;
161  const double latOffset;
162 
163  };
164 
174  ApproachingPersonInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime) :
175  arrivalTime(_arrivalTime), leavingTime(_leavingTime) {}
180  };
181 
182  typedef std::map<const SUMOVehicle*, const ApproachingVehicleInformation, ComparatorNumericalIdLess> ApproachInfos;
183  typedef std::vector<const SUMOTrafficObject*> BlockingFoes;
184  typedef std::map<const MSPerson*, ApproachingPersonInformation> PersonApproachInfos;
185 
191  };
192 
194  struct ConflictInfo {
195 
196  ConflictInfo(double lbc, double cs, ConflictFlag fl = CONFLICT_DEFAULT) :
197  foeConflictIndex(-1),
199  conflictSize(cs),
200  flag(fl)
201  {}
207  double conflictSize;
208 
210 
211  double getFoeLengthBehindCrossing(const MSLink* foeExitLink) const;
212  double getFoeConflictSize(const MSLink* foeExitLink) const;
213  double getLengthBehindCrossing(const MSLink* exitLink) const;
214  };
215 
217  struct CustomConflict {
218  CustomConflict(const MSLane* f, const MSLane* t, double s, double e) :
219  from(f), to(t), startPos(s), endPos(e) {}
220  const MSLane* from;
221  const MSLane* to;
222  double startPos;
223  double endPos;
224  };
225 
234  MSLink(MSLane* predLane,
235  MSLane* succLane,
236  MSLane* via,
237  LinkDirection dir,
238  LinkState state,
239  double length,
240  double foeVisibilityDistance,
241  bool keepClear,
242  MSTrafficLightLogic* logic,
243  int tlLinkIdx,
244  bool indirect);
245 
246 
248  ~MSLink();
249 
250  void addCustomConflict(const MSLane* from, const MSLane* to, double startPos, double endPos);
251 
259  void setRequestInformation(int index, bool hasFoes, bool isCont,
260  const std::vector<MSLink*>& foeLinks, const std::vector<MSLane*>& foeLanes,
261  MSLane* internalLaneBefore = 0);
262 
264  void addWalkingAreaFoe(const MSLane* lane) {
265  myWalkingAreaFoe = lane;
266  }
267 
269  void addWalkingAreaFoeExit(const MSLane* lane) {
270  myWalkingAreaFoeExit = lane;
271  }
272 
275  return myWalkingAreaFoe;
276  }
278  return myWalkingAreaFoeExit;
279  }
280 
285  void setApproaching(const SUMOVehicle* approaching, const SUMOTime arrivalTime,
286  const double arrivalSpeed, const double leaveSpeed, const bool setRequest,
287  const double arrivalSpeedBraking,
288  const SUMOTime waitingTime, double dist, double latOffset);
289 
291  void setApproaching(const SUMOVehicle* approaching, ApproachingVehicleInformation ai);
292 
294  void setApproachingPerson(const MSPerson* approaching, const SUMOTime arrivalTime, const SUMOTime leaveTime);
295 
297  void removeApproaching(const SUMOVehicle* veh);
298 
300  void removeApproachingPerson(const MSPerson* person);
301 
302  /* @brief return information about this vehicle if it is registered as
303  * approaching (dummy values otherwise)
304  * @note used for visualisation of link items */
305  ApproachingVehicleInformation getApproaching(const SUMOVehicle* veh) const;
306 
308  const ApproachInfos& getApproaching() const {
309  return myApproachingVehicles;
310  }
311 
313  void clearState();
314 
322  bool opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength,
323  double impatience, double decel, SUMOTime waitingTime,
324  double posLat = 0,
325  BlockingFoes* collectFoes = nullptr,
326  bool ignoreRed = false,
327  const SUMOTrafficObject* ego = nullptr,
328  double dist = -1) const;
329 
345  bool blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
346  bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
347  BlockingFoes* collectFoes = nullptr, const SUMOTrafficObject* ego = nullptr, bool lastWasContRed = false, double dist = -1) const;
348 
349 
359  bool hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, double speed, double decel) const;
360 
365  std::pair<const SUMOVehicle*, const MSLink*> getFirstApproachingFoe(const MSLink* wrapAround) const;
366 
368  return myJunction;
369  }
370 
371 
376  LinkState getState() const {
377  return myState;
378  }
379 
380 
386  return myOffState;
387  }
388 
394  return myLastGreenState;
395  }
396 
397 
398  //@brief Returns the time of the last state change
399  inline SUMOTime getLastStateChange() const {
400  return myLastStateChange;
401  }
402 
403 
408  inline LinkDirection getDirection() const {
409  return myDirection;
410  }
411 
412 
413 
419  void setTLState(LinkState state, SUMOTime t);
420 
424  void setTLLogic(const MSTrafficLightLogic* logic);
425 
430  inline MSLane* getLane() const {
431  return myLane;
432  }
433 
434 
439  inline int getIndex() const {
440  return myIndex;
441  }
442 
444  inline int getTLIndex() const {
445  return myTLIndex;
446  }
447 
449  inline const MSTrafficLightLogic* getTLLogic() const {
450  return myLogic;
451  }
452 
456  inline bool havePriority() const {
457  return myState >= 'A' && myState <= 'Z';
458  }
459 
460  inline bool haveOffPriority() const {
461  return myOffState >= 'A' && myOffState <= 'Z';
462  }
463 
467  inline bool haveRed() const {
469  }
470 
471  inline bool haveYellow() const {
473  }
474 
475  inline bool haveGreen() const {
477  }
478 
479  inline bool isTLSControlled() const {
480  return myLogic != 0;
481  }
482 
483  inline bool isTurnaround() const {
485  }
486 
491  double getLength() const {
492  return myLength;
493  }
494 
495 
502  double getFoeVisibilityDistance() const {
504  }
505 
506  double getDistToFoePedCrossing() const {
507  return myDistToFoePedCrossing;
508  }
509 
514  bool hasFoes() const {
515  return myHasFoes;
516  }
517 
518  // @brief return whether the vehicle may continute past this link to wait within the intersection
519  bool isCont() const;
520 
521 
523  bool keepClear() const {
524  return myKeepClear;
525  }
526 
528  bool isIndirect() const {
529  return myAmIndirect;
530  }
531 
533  bool lastWasContMajor() const;
534 
536  bool lastWasContState(LinkState linkState) const;
537 
541  double getInternalLengthsAfter() const;
542 
546  double getInternalLengthsBefore() const;
547 
553  double getLengthsBeforeCrossing(const MSLane* foeLane) const;
554 
555 
561  double getLengthBeforeCrossing(const MSLane* foeLane) const;
562 
563 
568  inline MSLane* getViaLane() const {
569  return myInternalLane;
570  }
571 
580  const LinkLeaders getLeaderInfo(const MSVehicle* ego, double dist, std::vector<const MSPerson*>* collectBlockers = 0, bool isShadowLink = false) const;
581 
583  double getZipperSpeed(const MSVehicle* ego, const double dist, double vSafe,
584  SUMOTime arrivalTime,
585  const BlockingFoes* foes) const;
586 
588  inline MSLane* getViaLaneOrLane() const {
589  return myInternalLane != nullptr ? myInternalLane : myLane;
590  }
591 
592 
594  inline const MSLane* getLaneBefore() const {
595  assert(myInternalLaneBefore == nullptr || myLaneBefore == myInternalLaneBefore); // lane before mismatch!
596  return myLaneBefore;
597  }
598 
600  inline const MSLane* getInternalLaneBefore() const {
601  return myInternalLaneBefore;
602  }
603 
605  SUMOTime getLeaveTime(const SUMOTime arrivalTime, const double arrivalSpeed, const double leaveSpeed, const double vehicleLength) const;
606 
608  void writeApproaching(OutputDevice& od, const std::string fromLaneID) const;
609 
611  MSLink* getParallelLink(int direction) const;
612 
615 
617  inline bool fromInternalLane() const {
618  return myInternalLaneBefore != nullptr;
619  }
620 
622  bool isEntryLink() const;
623 
625  bool isConflictEntryLink() const;
626 
628  bool isExitLink() const;
629 
631  bool isExitLinkAfterInternalJunction() const;
632 
634  const MSLink* getCorrespondingExitLink() const;
635 
637  const MSLink* getCorrespondingEntryLink() const;
638 
640  bool isInternalJunctionLink() const;
641 
644  return myMesoTLSPenalty;
645  }
646 
648  double getGreenFraction() const {
649  return myGreenFraction;
650  }
651 
653  void setMesoTLSPenalty(const SUMOTime penalty) {
654  myMesoTLSPenalty = penalty;
655  }
656 
658  void setGreenFraction(const double fraction) {
659  myGreenFraction = fraction;
660  }
661 
662  const std::vector<const MSLane*>& getFoeLanes() const {
663  return myFoeLanes;
664  }
665 
666  const std::vector<ConflictInfo>& getConflicts() const {
667  return myConflicts;
668  }
669 
670  const std::vector<MSLink*>& getFoeLinks() const {
671  return myFoeLinks;
672  }
673 
676  return myPermissions;
677  }
678 
680  void initParallelLinks();
681 
683  inline double getLateralShift() const {
684  return myLateralShift;
685  }
686 
688  std::string getDescription() const;
689 
691  static void recheckSetRequestInformation();
692 
693  static bool ignoreFoe(const SUMOTrafficObject* ego, const SUMOTrafficObject* foe);
694 
695  static const double NO_INTERSECTION;
696 
697 private:
699  static inline bool unsafeMergeSpeeds(double leaderSpeed, double followerSpeed, double leaderDecel, double followerDecel) {
700  // XXX mismatch between continuous an discrete deceleration
701  return (leaderSpeed * leaderSpeed / leaderDecel) <= (followerSpeed * followerSpeed / followerDecel);
702  }
703 
705  static bool couldBrakeForLeader(double followDist, double leaderDist, const MSVehicle* follow, const MSVehicle* leader);
706 
707  MSLink* computeParallelLink(int direction);
708 
710  void checkWalkingAreaFoe(const MSVehicle* ego, const MSLane* foeLane, std::vector<const MSPerson*>* collectBlockers, LinkLeaders& result) const;
711 
713  bool isInFront(const MSVehicle* ego, const PositionVector& egoPath, const Position& pPos) const;
714 
716  double isOnComingPed(const MSVehicle* ego, const MSPerson* p) const;
717 
719  Position getFuturePosition(const MSPerson* p, double timeHorizon = 1) const;
720 
721  bool blockedByFoe(const SUMOVehicle* veh, const ApproachingVehicleInformation& avi,
722  SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
723  bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
724  const SUMOTrafficObject* ego) const;
725 
727  bool checkContOff() const;
728 
730  bool contIntersect(const MSLane* lane, const MSLane* foe);
731 
733  double computeDistToDivergence(const MSLane* lane, const MSLane* sibling, double minDist, bool sameSource) const;
734 
736  static SUMOTime computeFoeArrivalTimeBraking(SUMOTime arrivalTime, const SUMOVehicle* foe, SUMOTime foeArrivalTime, double impatience, double dist, double& fasb);
737 
739  static bool lateralOverlap(double posLat, double width, double posLat2, double width2);
740 
742  const CustomConflict* getCustomConflict(const MSLane* foeLane) const;
743 
745  void updateDistToFoePedCrossing(double dist);
746 
747 private:
750 
753 
756 
758  int myIndex;
759 
761  const int myTLIndex;
762 
765 
772 
775 
778 
781  double myLength;
782 
788 
791 
793  bool myHasFoes;
794 
795  // @brief whether vehicles may continue past this link to wait within the intersection
796  bool myAmCont;
797  // @brief whether vehicles may continue past this link to wait within the intersection after switching of the traffic light at this intersection
799 
800  // @brief whether vehicles must keep the intersection clear if there is a downstream jam
802 
805 
806  /* @brief The preceding junction-internal lane, only used at
807  * - exit links (from internal lane to normal lane)
808  * - internal junction links (from internal lane to internal lane)
809  */
811 
816 
819 
820  /* @brief lengths after the crossing point with foeLane
821  * (index corresponds to myFoeLanes)
822  * empty vector for entry links
823  * */
824  std::vector<ConflictInfo> myConflicts;
825 
826  std::vector<CustomConflict> myCustomConflicts;
827 
828  // TODO: documentation
829  std::vector<MSLink*> myFoeLinks;
830  std::vector<const MSLane*> myFoeLanes;
831 
832  /* prioritized links when the traffic light is switched off (only needed for RightOfWay::ALLWAYSTOP)
833  * @note stored as a pointer to save space since it won't be used in most cases
834  */
835  std::vector<MSLink*>* myOffFoeLinks;
836 
841 
844 
845  /* @brief Links with the same origin lane and the same destination edge that may
846  be in conflict for sublane simulation */
847  std::vector<MSLink*> mySublaneFoeLinks;
848  /* @brief Links with the same origin lane and different destination edge that may
849  be in conflict for sublane simulation */
850  std::vector<MSLink*> mySublaneFoeLinks2;
851 
852  /* @brief Internal Lanes with the same origin lane and the same destination edge that may
853  be in conflict for sublane simulation */
854  std::vector<MSLane*> mySublaneFoeLanes;
855 
856  static const SUMOTime myLookaheadTime;
858 
860  static std::set<std::pair<MSLink*, MSLink*> > myRecheck;
861 
864 
866  const bool myAmIndirect;
867 
869  double myRadius;
870 
873 
876 
878  MSLink(const MSLink& s);
879 
881  MSLink& operator=(const MSLink& s);
882 
883 };
long long int SUMOTime
Definition: GUI.h:35
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_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
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.
Definition: OutputDevice.h:61
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:62
Definition: json.hpp:4471