Line data Source code
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 : /****************************************************************************/
14 : /// @file MSLink.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Sept 2002
19 : ///
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>
28 : #include <utils/common/SUMOVehicleClass.h>
29 : #include <utils/vehicle/SUMOVehicle.h>
30 : #include <utils/xml/SUMOXMLDefinitions.h>
31 :
32 :
33 : // ===========================================================================
34 : // class declarations
35 : // ===========================================================================
36 : class MSLane;
37 : class MSJunction;
38 : class MSVehicle;
39 : class MSPerson;
40 : class OutputDevice;
41 : class MSTrafficLightLogic;
42 :
43 :
44 : // ===========================================================================
45 : // class definitions
46 : // ===========================================================================
47 : /**
48 : * @class MSLinks
49 : * @brief A connection between lanes
50 : *
51 : * A link is basically a connection between two lanes, stored within the
52 : * originating (the one that is being left) lane and pointing to the
53 : * approached lane. When using inner-junction simulation, additionally
54 : * a "via-lane" is stored, the one that is used to cross the junction
55 : * and which represents the links shape.
56 : *
57 : * Because right-of-way rules are controlled by the junctions, the link
58 : * stores the information about where to write information about approaching
59 : * vehicles (the "request") and where to get the information whether the
60 : * vehicle really may drive (the "respond").
61 : *
62 : * Because a link is a connection over a junction, it basically also has a
63 : * length. This length is needed to assure that vehicles have the correct halting
64 : * distance before approaching the link. In the case of using internal lanes,
65 : * the link's length is 0.
66 : */
67 : class MSLink {
68 : public:
69 :
70 : /** @enum LinkLeaderFlag
71 : * @brief additional information for link leaders
72 : */
73 : enum LinkLeaderFlag {
74 : /// @brief vehicle is in the way
75 : LL_IN_THE_WAY = 1 << 0,
76 : /// @brief link leader is passing from left to right
77 : LL_FROM_LEFT = 1 << 1,
78 : /// @brief link leader is coming from the same (normal) lane
79 : LL_SAME_SOURCE = 1 << 2,
80 : /// @brief link leader is targeting the same outgoing lane
81 : LL_SAME_TARGET = 1 << 3
82 : };
83 :
84 : struct LinkLeader {
85 21227511 : LinkLeader(MSVehicle* _veh, double _gap, double _distToCrossing, int _llFlags = LL_FROM_LEFT, double _latOffst = 0) :
86 21227511 : vehAndGap(std::make_pair(_veh, _gap)),
87 21227511 : distToCrossing(_distToCrossing),
88 21227511 : llFlags(_llFlags),
89 21227511 : latOffset(_latOffst)
90 : { }
91 :
92 : inline bool fromLeft() const {
93 107400 : return (llFlags & LL_FROM_LEFT) != 0;
94 : }
95 : inline bool inTheWay() const {
96 70688 : return (llFlags & LL_IN_THE_WAY) != 0;
97 : }
98 : inline bool sameTarget() const {
99 837970 : return (llFlags & LL_SAME_TARGET) != 0;
100 : }
101 : inline bool sameSource() const {
102 481429 : return (llFlags & LL_SAME_SOURCE) != 0;
103 : }
104 :
105 : std::pair<MSVehicle*, double> vehAndGap;
106 : double distToCrossing;
107 : int llFlags;
108 : double latOffset;
109 :
110 : };
111 :
112 : typedef std::vector<LinkLeader> LinkLeaders;
113 :
114 : /** @struct ApproachingVehicleInformation
115 : * @brief A structure holding the information about vehicles approaching a link
116 : */
117 : struct ApproachingVehicleInformation {
118 : /** @brief Constructor
119 : * @param[in] waitingTime The time during which the vehicle is waiting at this link
120 : * this needs to be placed here because MSVehicle::myWaitingTime is updated in between
121 : * calls to opened() causing order dependencies
122 : **/
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 816702683 : ) :
132 816702683 : arrivalTime(_arrivalTime), leavingTime(_leavingTime),
133 816702683 : arrivalSpeed(_arrivalSpeed), leaveSpeed(_leaveSpeed),
134 816702683 : willPass(_willPass),
135 816702683 : arrivalSpeedBraking(_arrivalSpeedBraking),
136 816702683 : waitingTime(_waitingTime),
137 816702683 : dist(_dist),
138 816702683 : speed(_speed),
139 814029195 : latOffset(_latOffset) {
140 2673488 : }
141 :
142 : /// @brief The time the vehicle's front arrives at the link
143 : const SUMOTime arrivalTime;
144 : /// @brief The estimated time at which the vehicle leaves the link
145 : const SUMOTime leavingTime;
146 : /// @brief The estimated speed with which the vehicle arrives at the link (for headway computation)
147 : const double arrivalSpeed;
148 : /// @brief The estimated speed with which the vehicle leaves the link (for headway computation)
149 : const double leaveSpeed;
150 : /// @brief Whether the vehicle wants to pass the link (@todo: check semantics)
151 : const bool willPass;
152 : /// @brief The estimated speed with which the vehicle arrives at the link if it starts braking(for headway computation)
153 : const double arrivalSpeedBraking;
154 : /// @brief The waiting duration at the current link
155 : const SUMOTime waitingTime;
156 : /// @brief The distance up to the current link
157 : const double dist;
158 : /// @brief The current speed
159 : const double speed;
160 : /// @brief The lateral offset from the center of the entering lane
161 : const double latOffset;
162 :
163 : };
164 :
165 : /** @struct ApproachingPersonInformation
166 : * @brief A structure holding the information about persons approaching a pedestrian crossing link
167 : */
168 : struct ApproachingPersonInformation {
169 : /** @brief Constructor
170 : * @param[in] waitingTime The time during which the vehicle is waiting at this link
171 : * this needs to be placed here because MSVehicle::myWaitingTime is updated in between
172 : * calls to opened() causing order dependencies
173 : **/
174 575759 : ApproachingPersonInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime) :
175 575759 : arrivalTime(_arrivalTime), leavingTime(_leavingTime) {}
176 : /// @brief The time the vehicle's front arrives at the link
177 : const SUMOTime arrivalTime;
178 : /// @brief The estimated time at which the vehicle leaves the link
179 : const SUMOTime 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 :
186 : enum ConflictFlag {
187 : CONFLICT_DEFAULT,
188 : CONFLICT_DUMMY_MERGE,
189 : CONFLICT_NO_INTERSECTION,
190 : CONFLICT_STOP_AT_INTERNAL_JUNCTION,
191 : CONFLICT_SIBLING_CONTINUATION
192 : };
193 :
194 : /// @brief pre-computed information for conflict points
195 : struct ConflictInfo {
196 :
197 4510930 : ConflictInfo(double lbc, double cs, ConflictFlag fl = CONFLICT_DEFAULT) :
198 4300044 : foeConflictIndex(-1),
199 4510930 : lengthBehindCrossing(lbc),
200 4510930 : conflictSize(cs),
201 4510930 : flag(fl)
202 : {}
203 : /// @brief the conflict from the perspective of the foe
204 : int foeConflictIndex;
205 : /// @brief length of internal lane after the crossing point
206 : double lengthBehindCrossing;
207 : /// @brief the length of the conflict space
208 : double conflictSize;
209 :
210 : ConflictFlag flag;
211 :
212 : double getFoeLengthBehindCrossing(const MSLink* foeExitLink) const;
213 : double getFoeConflictSize(const MSLink* foeExitLink) const;
214 : double getLengthBehindCrossing(const MSLink* exitLink) const;
215 : };
216 :
217 : /// @brief holds user defined conflict positions (must be interpreted for the correct exitLink)
218 : struct CustomConflict {
219 4 : CustomConflict(const MSLane* f, const MSLane* t, double s, double e) :
220 4 : from(f), to(t), startPos(s), endPos(e) {}
221 : const MSLane* from;
222 : const MSLane* to;
223 : double startPos;
224 : double endPos;
225 : };
226 :
227 : /** @brief Constructor for simulation which uses internal lanes
228 : *
229 : * @param[in] succLane The lane approached by this link
230 : * @param[in] via The lane to use within the junction
231 : * @param[in] dir The direction of this link
232 : * @param[in] state The state of this link
233 : * @param[in] length The length of this link
234 : */
235 : MSLink(MSLane* predLane,
236 : MSLane* succLane,
237 : MSLane* via,
238 : LinkDirection dir,
239 : LinkState state,
240 : double length,
241 : double foeVisibilityDistance,
242 : bool keepClear,
243 : MSTrafficLightLogic* logic,
244 : int tlLinkIdx,
245 : bool indirect);
246 :
247 :
248 : /// @brief Destructor
249 : ~MSLink();
250 :
251 : void addCustomConflict(const MSLane* from, const MSLane* to, double startPos, double endPos);
252 :
253 : /** @brief Sets the request information
254 : *
255 : * Because traffic lights and junction logics are loaded after links,
256 : * we have to assign the information about the right-of-way
257 : * requests and responses after the initialisation.
258 : * @todo Unsecure!
259 : */
260 : void setRequestInformation(int index, bool hasFoes, bool isCont,
261 : const std::vector<MSLink*>& foeLinks, const std::vector<MSLane*>& foeLanes,
262 : MSLane* internalLaneBefore = 0);
263 :
264 : /// @brief add walkingarea as foe (when entering the junction)
265 : void addWalkingAreaFoe(const MSLane* lane) {
266 6769 : myWalkingAreaFoe = lane;
267 6769 : }
268 :
269 : /// @brief add walkingarea as foe (when leaving the junction)
270 : void addWalkingAreaFoeExit(const MSLane* lane) {
271 6839 : myWalkingAreaFoeExit = lane;
272 6839 : }
273 :
274 : /// @brief get walkingarea as foes
275 : const MSLane* getWalkingAreaFoe() {
276 2882849 : return myWalkingAreaFoe;
277 : }
278 : const MSLane* getWalkingAreaFoeExit() {
279 2881941 : return myWalkingAreaFoeExit;
280 : }
281 :
282 : /** @brief Sets the information about an approaching vehicle
283 : *
284 : * The information is stored in myApproachingVehicles.
285 : */
286 : void setApproaching(const SUMOVehicle* approaching, const SUMOTime arrivalTime,
287 : const double arrivalSpeed, const double leaveSpeed, const bool setRequest,
288 : const double arrivalSpeedBraking,
289 : const SUMOTime waitingTime, double dist, double latOffset);
290 :
291 : /** @brief Sets the information about an approaching vehicle */
292 : void setApproaching(const SUMOVehicle* approaching, ApproachingVehicleInformation ai);
293 :
294 : /** @brief Sets the information about an approaching person (only for a pedestrian crossing) */
295 : void setApproachingPerson(const MSPerson* approaching, const SUMOTime arrivalTime, const SUMOTime leaveTime);
296 :
297 : /// @brief removes the vehicle from myApproachingVehicles
298 : void removeApproaching(const SUMOVehicle* veh);
299 :
300 : /// @brief removes the person from myApproachingPersons
301 : void removeApproachingPerson(const MSPerson* person);
302 :
303 : /* @brief return information about this vehicle if it is registered as
304 : * approaching (dummy values otherwise)
305 : * @note used for visualisation of link items */
306 : ApproachingVehicleInformation getApproaching(const SUMOVehicle* veh) const;
307 : const ApproachingVehicleInformation* getApproachingPtr(const SUMOVehicle* veh) const;
308 :
309 : /// @brief return all approaching vehicles
310 : const ApproachInfos& getApproaching() const {
311 : return myApproachingVehicles;
312 : }
313 :
314 : /// @brief return all approaching vehicles
315 : const PersonApproachInfos* getApproachingPersons() const {
316 65489 : return myApproachingPersons;
317 : }
318 :
319 : /** @brief Remove all approaching vehicles before quick-loading state */
320 : void clearState();
321 :
322 : /** @brief Returns the information whether the link may be passed
323 : *
324 : * Valid after the junctions have set their reponds
325 : *
326 : * @param[in] collectFoes If a vector is passed, all blocking foes are collected and inserted into this vector
327 : * @return Whether this link may be passed.
328 : */
329 : bool opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength,
330 : double impatience, double decel, SUMOTime waitingTime,
331 : double posLat = 0,
332 : BlockingFoes* collectFoes = nullptr,
333 : bool ignoreRed = false,
334 : const SUMOTrafficObject* ego = nullptr,
335 : double dist = -1) const;
336 :
337 : /** @brief Returns the information whether this link is blocked
338 : * Valid after the vehicles have set their requests
339 : * @param[in] arrivalTime The arrivalTime of the vehicle who checks for an approaching foe
340 : * @param[in] leaveTime The leaveTime of the vehicle who checks for an approaching foe
341 : * @param[in] arrivalSpeed The speed with which the checking vehicle plans to arrive at the link
342 : * @param[in] leaveSpeed The speed with which the checking vehicle plans to leave the link
343 : * @param[in] sameTargetLane Whether the link that calls this method has the same target lane as this link
344 : * @param[in] impatience The impatience of the checking vehicle
345 : * @param[in] decel The maximum deceleration of the checking vehicle
346 : * @param[in] waitingTime The waiting time of the checking vehicle
347 : * @param[in] collectFoes If a vector is passed the return value is always False, instead all blocking foes are collected and inserted into this vector
348 : * @param[in] lastWasContRed Whether the link which is checked, is an internal junction link where the entry has red
349 : * @return Whether this link is blocked
350 : * @note Since this needs to be called without a SUMOVehicle (TraCI), we cannot simply pass the checking vehicle itself
351 : **/
352 : bool blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
353 : bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
354 : BlockingFoes* collectFoes = nullptr, const SUMOTrafficObject* ego = nullptr, bool lastWasContRed = false, double dist = -1) const;
355 :
356 :
357 : /** @brief Returns the information whether a vehicle is approaching on one of the link's foe streams
358 : *
359 : * Valid after the vehicles have set their requests
360 : * @param[in] arrivalTime The arrivalTime of the vehicle who checks for an approaching foe
361 : * @param[in] leaveTime The leaveTime of the vehicle who checks for an approaching foe
362 : * @param[in] speed The speed with which the checking vehicle plans to leave the link
363 : * @param[in] decel The maximum deceleration of the checking vehicle
364 : * @return Whether a foe of this link is approaching
365 : */
366 : bool hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, double speed, double decel) const;
367 :
368 : /** @brief get the foe vehicle that is closest to the intersection or nullptr along with the foe link
369 : * This function is used for finding circular deadlock at right_before_left junctions
370 : * @param[in] wrapAround The link on which the ego vehicle wants to enter the junction
371 : */
372 : std::pair<const SUMOVehicle*, const MSLink*> getFirstApproachingFoe(const MSLink* wrapAround) const;
373 :
374 : MSJunction* getJunction() const {
375 4818776 : return myJunction;
376 : }
377 :
378 :
379 : /** @brief Returns the current state of the link
380 : *
381 : * @return The current state of this link
382 : */
383 : LinkState getState() const {
384 1592049132 : return myState;
385 : }
386 :
387 :
388 : /** @brief Returns the off-state for the link
389 : *
390 : * @return The current state of this link
391 : */
392 : LinkState getOffState() const {
393 2556819 : return myOffState;
394 : }
395 :
396 : /** @brief Returns the last green state of the link
397 : *
398 : * @return The last green state of this link
399 : */
400 : LinkState getLastGreenState() const {
401 942131 : return myLastGreenState;
402 : }
403 :
404 :
405 : //@brief Returns the time of the last state change
406 : inline SUMOTime getLastStateChange() const {
407 105600 : return myLastStateChange;
408 : }
409 :
410 :
411 : /** @brief Returns the direction the vehicle passing this link take
412 : *
413 : * @return The direction of this link
414 : */
415 : inline LinkDirection getDirection() const {
416 181516287 : return myDirection;
417 : }
418 :
419 :
420 :
421 : /** @brief Sets the current tl-state
422 : *
423 : * @param[in] state The current state of the link
424 : * @param[in] t The time of the state change
425 : */
426 : void setTLState(LinkState state, SUMOTime t);
427 :
428 : /** @brief Sets the currently active tlLogic
429 : * @param[in] logic The currently active logic
430 : */
431 : void setTLLogic(const MSTrafficLightLogic* logic);
432 :
433 : /** @brief Returns the connected lane
434 : *
435 : * @return The lane approached by this link
436 : */
437 : inline MSLane* getLane() const {
438 3636315999 : return myLane;
439 : }
440 :
441 :
442 : /** @brief Returns the respond index (for visualization)
443 : *
444 : * @return The respond index for this link
445 : */
446 : inline int getIndex() const {
447 2274538 : return myIndex;
448 : }
449 :
450 : /** @brief Returns the TLS index */
451 : inline int getTLIndex() const {
452 15241917 : return myTLIndex;
453 : }
454 :
455 : /** @brief Returns the TLS index */
456 : inline const MSTrafficLightLogic* getTLLogic() const {
457 14367542 : return myLogic;
458 : }
459 :
460 : /** @brief Returns whether this link is a major link
461 : * @return Whether the link has a large priority
462 : */
463 : inline bool havePriority() const {
464 4326852504 : return myState >= 'A' && myState <= 'Z';
465 : }
466 :
467 : inline bool haveOffPriority() const {
468 40 : return myOffState >= 'A' && myOffState <= 'Z';
469 : }
470 :
471 : /** @brief Returns whether this link is blocked by a red (or redyellow) traffic light
472 : * @return Whether the link has a red light
473 : */
474 : inline bool haveRed() const {
475 1453286326 : return myState == LINKSTATE_TL_RED || myState == LINKSTATE_TL_REDYELLOW;
476 : }
477 :
478 : inline bool haveYellow() const {
479 1392160837 : return myState == LINKSTATE_TL_YELLOW_MINOR || myState == LINKSTATE_TL_YELLOW_MAJOR;
480 : }
481 :
482 : inline bool haveGreen() const {
483 79492242 : return myState == LINKSTATE_TL_GREEN_MAJOR || myState == LINKSTATE_TL_GREEN_MINOR;
484 : }
485 :
486 : inline bool mustStop() const {
487 597735312 : return myState == LINKSTATE_STOP || myState == LINKSTATE_ALLWAY_STOP;
488 : }
489 :
490 : inline bool isTLSControlled() const {
491 1893420 : return myLogic != 0;
492 : }
493 :
494 : inline bool isTurnaround() const {
495 196562393 : return myDirection == LinkDirection::TURN || myDirection == LinkDirection::TURN_LEFTHAND;
496 : }
497 :
498 : /** @brief Returns the length of this link
499 : *
500 : * @return The length of this link
501 : */
502 : double getLength() const {
503 2202551789 : return myLength;
504 : }
505 :
506 :
507 : /** @brief Returns the distance on the approaching lane from which an
508 : * approaching vehicle is able to see all relevant foes and
509 : * may accelerate if the link is minor and no foe is approaching.
510 : *
511 : * @return The foe-visibility-distance
512 : */
513 : double getFoeVisibilityDistance() const {
514 2188446920 : return myFoeVisibilityDistance;
515 : }
516 :
517 : double getDistToFoePedCrossing() const {
518 38795431 : return myDistToFoePedCrossing;
519 : }
520 :
521 : /** @brief Returns whether this link belongs to a junction where more than one edge is incoming
522 : *
523 : * @return Whether any foe links exist
524 : */
525 : bool hasFoes() const {
526 485255017 : return myHasFoes;
527 : }
528 :
529 : // @brief return whether the vehicle may continute past this link to wait within the intersection
530 : bool isCont() const;
531 :
532 :
533 : /// @brief whether the junction after this link must be kept clear
534 : bool keepClear() const {
535 154001007 : return myKeepClear;
536 : }
537 :
538 : /// @brief whether this link is the start of an indirect turn
539 : bool isIndirect() const {
540 1231573 : return myAmIndirect;
541 : }
542 :
543 : /// @brief whether this is a link past an internal junction which currently has priority
544 : bool lastWasContMajor() const;
545 :
546 : /// @brief whether this is a link past an internal junction where the entry to the junction currently has the given state
547 : bool lastWasContState(LinkState linkState) const;
548 :
549 : /** @brief Returns the cumulative length of all internal lanes after this link
550 : * @return sum of the lengths of all internal lanes following this link
551 : */
552 : double getInternalLengthsAfter() const;
553 :
554 : /** @brief Returns the cumulative length of all internal lanes before this link
555 : * @return sum of the lengths of all internal lanes before this link
556 : */
557 : double getInternalLengthsBefore() const;
558 :
559 : /** @brief Returns the sum of the lengths along internal lanes following this link
560 : * to the crossing with the given foe lane, if the lane is no foe
561 : * lane to any of the internal lanes, INVALID_DOUBLE is returned.
562 : * @see getLengthBeforeCrossing()
563 : */
564 : double getLengthsBeforeCrossing(const MSLane* foeLane) const;
565 :
566 :
567 : /** @brief Returns the internal length from the beginning of the link's internal lane before
568 : * to the crossing with the given foe lane if applicable, if the lane is no foe
569 : * lane to the link, INVALID_DOUBLE is returned.
570 : * @see getLengthsBeforeCrossing()
571 : */
572 : double getLengthBeforeCrossing(const MSLane* foeLane) const;
573 :
574 :
575 : /** @brief Returns the following inner lane
576 : *
577 : * @return The inner lane to use to cross the junction
578 : */
579 : inline MSLane* getViaLane() const {
580 3415794071 : return myInternalLane;
581 : }
582 :
583 : /** @brief Returns all potential link leaders (vehicles on foeLanes)
584 : * Valid during the planMove() phase
585 : * @param[in] ego The ego vehicle that is looking for leaders
586 : * @param[in] dist The distance of the vehicle who is asking about the leader to this link
587 : * @param[out] blocking Return blocking pedestrians if a vector is given
588 : * @param[in] isShadowLink whether this link is a shadowLink for ego
589 : * @return The all vehicles on foeLanes and their (virtual) distances to the asking vehicle
590 : */
591 : const LinkLeaders getLeaderInfo(const MSVehicle* ego, double dist, std::vector<const MSPerson*>* collectBlockers = 0, bool isShadowLink = false) const;
592 :
593 : /// @brief return the speed at which ego vehicle must approach the zipper link
594 : double getZipperSpeed(const MSVehicle* ego, const double dist, double vSafe,
595 : SUMOTime arrivalTime,
596 : const BlockingFoes* foes) const;
597 :
598 : /// @brief return the via lane if it exists and the lane otherwise
599 : inline MSLane* getViaLaneOrLane() const {
600 1775499404 : return myInternalLane != nullptr ? myInternalLane : myLane;
601 : }
602 :
603 :
604 : /// @brief return the internalLaneBefore if it exists and the laneBefore otherwise
605 : inline const MSLane* getLaneBefore() const {
606 : assert(myInternalLaneBefore == nullptr || myLaneBefore == myInternalLaneBefore); // lane before mismatch!
607 720184604 : return myLaneBefore;
608 : }
609 :
610 : /// @brief return myInternalLaneBefore (always 0 when compiled without internal lanes)
611 : inline const MSLane* getInternalLaneBefore() const {
612 694901753 : return myInternalLaneBefore;
613 : }
614 :
615 : /// @brief return the expected time at which the given vehicle will clear the link
616 : SUMOTime getLeaveTime(const SUMOTime arrivalTime, const double arrivalSpeed, const double leaveSpeed, const double vehicleLength) const;
617 :
618 : /// @brief write information about all approaching vehicles to the given output device
619 : void writeApproaching(OutputDevice& od, const std::string fromLaneID) const;
620 :
621 : /// @brief return the link that is parallel to this lane or 0
622 : MSLink* getParallelLink(int direction) const;
623 :
624 : /// @brief return the link that is the opposite entry link to this one
625 : MSLink* getOppositeDirectionLink() const;
626 :
627 : /// @brief return whether the fromLane of this link is an internal lane
628 : inline bool fromInternalLane() const {
629 824194116 : return myInternalLaneBefore != nullptr;
630 : }
631 :
632 : /// @brief return whether the toLane of this link is an internal lane and fromLane is a normal lane
633 : bool isEntryLink() const;
634 :
635 : /// @brief return whether this link enters the conflict area (not a continuation link)
636 : bool isConflictEntryLink() const;
637 :
638 : /// @brief return whether the fromLane of this link is an internal lane and toLane is a normal lane
639 : bool isExitLink() const;
640 :
641 : /// @brief return whether the fromLane of this link is an internal lane and its incoming lane is also an internal lane
642 : bool isExitLinkAfterInternalJunction() const;
643 :
644 : /// @brief returns the corresponding exit link for entryLinks to a junction.
645 : const MSLink* getCorrespondingExitLink() const;
646 :
647 : /// @brief returns the corresponding entry link for exitLinks to a junction.
648 : const MSLink* getCorrespondingEntryLink() const;
649 :
650 : /// @brief return whether the fromLane and the toLane of this link are internal lanes
651 : bool isInternalJunctionLink() const;
652 :
653 : /** @brief Returns the time penalty for passing a tls-controlled link (meso) */
654 : SUMOTime getMesoTLSPenalty() const {
655 52022 : return myMesoTLSPenalty;
656 : }
657 :
658 : /** @brief Returns the average proportion of green time to cycle time */
659 : double getGreenFraction() const {
660 49540 : return myGreenFraction;
661 : }
662 :
663 : /** @brief Sets the time penalty for passing a tls-controlled link (meso) */
664 : void setMesoTLSPenalty(const SUMOTime penalty) {
665 177711 : myMesoTLSPenalty = penalty;
666 : }
667 :
668 : /** @brief Sets the green fraction for passing a tls-controlled link (meso) */
669 : void setGreenFraction(const double fraction) {
670 177551 : myGreenFraction = fraction;
671 : }
672 :
673 : const std::vector<const MSLane*>& getFoeLanes() const {
674 : return myFoeLanes;
675 : }
676 :
677 : const std::vector<ConflictInfo>& getConflicts() const {
678 : return myConflicts;
679 : }
680 :
681 : const std::vector<MSLink*>& getFoeLinks() const {
682 : return myFoeLinks;
683 : }
684 :
685 : /// @brief who may use this link
686 : SVCPermissions getPermissions() const {
687 6968 : return myPermissions;
688 : }
689 :
690 : /// @brief initialize parallel links (to be called after all links are loaded)
691 : void initParallelLinks();
692 :
693 : /// @brief return lateral shift that must be applied when passing this link
694 : inline double getLateralShift() const {
695 859428891 : return myLateralShift;
696 : }
697 :
698 : /// @brief get string description for this link
699 : std::string getDescription() const;
700 :
701 : /// @brief get the closest vehicle approaching this link
702 : std::pair<const SUMOVehicle* const, const ApproachingVehicleInformation> getClosest() const;
703 :
704 : inline bool hasFoeCrossing() const {
705 89631 : return myHavePedestrianCrossingFoe;
706 : }
707 :
708 : /// @brief whether this link is for a railsignal that was passed in this step
709 : bool railSignalWasPassed() const;
710 :
711 : /// @brief post-processing for legacy networks
712 : static void recheckSetRequestInformation();
713 :
714 : static bool ignoreFoe(const SUMOTrafficObject* ego, const SUMOTrafficObject* foe);
715 :
716 : static const double NO_INTERSECTION;
717 :
718 : private:
719 : /// @brief return whether the given vehicles may NOT merge safely
720 : static inline bool unsafeMergeSpeeds(double leaderSpeed, double followerSpeed, double leaderDecel, double followerDecel) {
721 : // XXX mismatch between continuous an discrete deceleration
722 21872372 : return (leaderSpeed * leaderSpeed / leaderDecel) <= (followerSpeed * followerSpeed / followerDecel);
723 : }
724 :
725 : /// @brief whether follower could stay behind leader (possibly by braking)
726 : static bool couldBrakeForLeader(double followDist, double leaderDist, const MSVehicle* follow, const MSVehicle* leader);
727 :
728 : MSLink* computeParallelLink(int direction);
729 :
730 : /// @brief check for persons on walkingarea in the path of ego vehicle
731 : void checkWalkingAreaFoe(const MSVehicle* ego, const MSLane* foeLane, std::vector<const MSPerson*>* collectBlockers, LinkLeaders& result) const;
732 :
733 : /// @brief whether the given person is in front of the car
734 : bool isInFront(const MSVehicle* ego, const PositionVector& egoPath, const Position& pPos) const;
735 :
736 : /// @brief whether the given person is walking towards the car returned as a factor in [0, 1]
737 : double isOnComingPed(const MSVehicle* ego, const MSPerson* p) const;
738 :
739 : /// @brief return extrapolated position of the given person after the given time
740 : Position getFuturePosition(const MSPerson* p, double timeHorizon = 1) const;
741 :
742 : bool blockedByFoe(const SUMOVehicle* veh, const ApproachingVehicleInformation& avi,
743 : SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
744 : bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
745 : const SUMOTrafficObject* ego) const;
746 :
747 : /// @brief figure out whether the cont status remains in effect when switching off the tls
748 : bool checkContOff() const;
749 :
750 : /// @brief check if the lane intersects with a foe cont-lane
751 : bool contIntersect(const MSLane* lane, const MSLane* foe);
752 :
753 : /// @brief compute point of divergence for geomatries with a common start or end
754 : double computeDistToDivergence(const MSLane* lane, const MSLane* sibling, double minDist, bool sameSource, double siblingPredLength = 0) const;
755 :
756 : /// @brief compute arrival time if foe vehicle is braking for ego
757 : static SUMOTime computeFoeArrivalTimeBraking(SUMOTime arrivalTime, const SUMOVehicle* foe, SUMOTime foeArrivalTime, double impatience, double dist, double& fasb);
758 :
759 : /// @brief check whether the given vehicle positions overlap laterally
760 : static bool lateralOverlap(double posLat, double width, double posLat2, double width2);
761 :
762 : /// @brief return CustomConflict with foeLane if it is defined
763 : const CustomConflict* getCustomConflict(const MSLane* foeLane) const;
764 :
765 : /// @brief add information about another pedestrian crossing
766 : void updateDistToFoePedCrossing(double dist);
767 :
768 : private:
769 : /// @brief The lane behind the junction approached by this link
770 : MSLane* myLane;
771 :
772 : /// @brief The lane approaching this link
773 : MSLane* myLaneBefore;
774 :
775 : ApproachInfos myApproachingVehicles;
776 : PersonApproachInfos* myApproachingPersons;
777 :
778 : /// @brief The position within this respond
779 : int myIndex;
780 :
781 : /// @brief the traffic light index
782 : const int myTLIndex;
783 :
784 : /// @brief the controlling logic or 0
785 : const MSTrafficLightLogic* myLogic;
786 :
787 : /// @brief The state of the link
788 : LinkState myState;
789 : /// @brief The last green state of the link (minor or major)
790 : LinkState myLastGreenState;
791 : /// @brief The state of the link when switching of traffic light control
792 : const LinkState myOffState;
793 :
794 : /// @brief The time of the last state change
795 : SUMOTime myLastStateChange;
796 :
797 : /// @brief An abstract (hopefully human readable) definition of the link's direction
798 : LinkDirection myDirection;
799 :
800 : /// @brief The length of the link
801 : /// @note This is not equal to the result of getInternalLengthsAfter for links with more than one internal lane.
802 : double myLength;
803 :
804 : /// @brief distance from which an approaching vehicle is able to
805 : /// see all relevant foes and may accelerate if the link is minor
806 : /// and no foe is approaching. Defaults to 4.5m.
807 : /// For zipper links (major) this is the distance at which zipper merging starts (and foes become "visible")
808 : double myFoeVisibilityDistance;
809 :
810 : /// @brief distance from the stop line to the first pedestrian crossing or maxdouble
811 : double myDistToFoePedCrossing;
812 :
813 : /// @brief Whether any foe links exist
814 : bool myHasFoes;
815 :
816 : // @brief whether vehicles may continue past this link to wait within the intersection
817 : bool myAmCont;
818 : // @brief whether vehicles may continue past this link to wait within the intersection after switching of the traffic light at this intersection
819 : bool myAmContOff;
820 :
821 : // @brief whether vehicles must keep the intersection clear if there is a downstream jam
822 : bool myKeepClear;
823 :
824 : /// @brief The following junction-internal lane if used
825 : MSLane* const myInternalLane;
826 :
827 : /* @brief The preceding junction-internal lane, only used at
828 : * - exit links (from internal lane to normal lane)
829 : * - internal junction links (from internal lane to internal lane)
830 : */
831 : const MSLane* myInternalLaneBefore;
832 :
833 : /// @brief penalty time at tls for mesoscopic simulation
834 : SUMOTime myMesoTLSPenalty;
835 : /// @brief green fraction at tls for mesoscopic simulation
836 : double myGreenFraction;
837 :
838 : /// @brief lateral shift to be applied when passing this link
839 : double myLateralShift;
840 :
841 : /* @brief lengths after the crossing point with foeLane
842 : * (index corresponds to myFoeLanes)
843 : * empty vector for entry links
844 : * */
845 : std::vector<ConflictInfo> myConflicts;
846 :
847 : std::vector<CustomConflict> myCustomConflicts;
848 :
849 : // TODO: documentation
850 : std::vector<MSLink*> myFoeLinks;
851 : std::vector<const MSLane*> myFoeLanes;
852 :
853 : /* prioritized links when the traffic light is switched off (only needed for RightOfWay::ALLWAYSTOP)
854 : * @note stored as a pointer to save space since it won't be used in most cases
855 : */
856 : std::vector<MSLink*>* myOffFoeLinks;
857 :
858 : /// @brief walkingArea that must be checked when entering the intersection
859 : const MSLane* myWalkingAreaFoe;
860 : /// @brief walkingArea that must be checked when leaving the intersection
861 : const MSLane* myWalkingAreaFoeExit;
862 :
863 : /// @brief whether on of myFoeLanes is a crossing
864 : bool myHavePedestrianCrossingFoe;
865 :
866 : /* @brief Links with the same origin lane and the same destination edge that may
867 : be in conflict for sublane simulation */
868 : std::vector<MSLink*> mySublaneFoeLinks;
869 : /* @brief Links with the same origin lane and different destination edge that may
870 : be in conflict for sublane simulation */
871 : std::vector<MSLink*> mySublaneFoeLinks2;
872 :
873 : /* @brief Internal Lanes with the same origin lane and the same destination edge that may
874 : be in conflict for sublane simulation */
875 : std::vector<MSLane*> mySublaneFoeLanes;
876 :
877 : static const SUMOTime myLookaheadTime;
878 : static const SUMOTime myLookaheadTimeZipper;
879 :
880 : /// @brief links that need post processing after initialization (to deal with legacy networks)
881 : static std::set<std::pair<MSLink*, MSLink*> > myRecheck;
882 :
883 : MSLink* myParallelRight;
884 : MSLink* myParallelLeft;
885 :
886 : /// @brief whether this connection is an indirect turning movement
887 : const bool myAmIndirect;
888 :
889 : /// @brief the turning radius for this link or doublemax for straight links
890 : double myRadius;
891 :
892 : /// @brief who may drive on this link
893 : SVCPermissions myPermissions;
894 :
895 : /// @brief the junction to which this link belongs
896 : MSJunction* myJunction;
897 :
898 : /// invalidated copy constructor
899 : MSLink(const MSLink& s);
900 :
901 : /// invalidated assignment operator
902 : MSLink& operator=(const MSLink& s);
903 :
904 : };
|