Line data Source code
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 : /****************************************************************************/
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 19470017 : LinkLeader(MSVehicle* _veh, double _gap, double _distToCrossing, int _llFlags = LL_FROM_LEFT, double _latOffst = 0) :
86 19470017 : vehAndGap(std::make_pair(_veh, _gap)),
87 19470017 : distToCrossing(_distToCrossing),
88 19470017 : llFlags(_llFlags),
89 19470017 : latOffset(_latOffst)
90 : { }
91 :
92 : inline bool fromLeft() const {
93 89358 : return (llFlags & LL_FROM_LEFT) != 0;
94 : }
95 : inline bool inTheWay() const {
96 66742 : return (llFlags & LL_IN_THE_WAY) != 0;
97 : }
98 : inline bool sameTarget() const {
99 847419 : return (llFlags & LL_SAME_TARGET) != 0;
100 : }
101 : inline bool sameSource() const {
102 479317 : 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 782870316 : ) :
132 782870316 : arrivalTime(_arrivalTime), leavingTime(_leavingTime),
133 782870316 : arrivalSpeed(_arrivalSpeed), leaveSpeed(_leaveSpeed),
134 782870316 : willPass(_willPass),
135 782870316 : arrivalSpeedBraking(_arrivalSpeedBraking),
136 782870316 : waitingTime(_waitingTime),
137 782870316 : dist(_dist),
138 782870316 : speed(_speed),
139 780205398 : latOffset(_latOffset) {
140 2664918 : }
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 537031 : ApproachingPersonInformation(const SUMOTime _arrivalTime, const SUMOTime _leavingTime) :
175 537031 : 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 : };
192 :
193 : /// @brief pre-computed information for conflict points
194 : struct ConflictInfo {
195 :
196 4491131 : ConflictInfo(double lbc, double cs, ConflictFlag fl = CONFLICT_DEFAULT) :
197 4491131 : foeConflictIndex(-1),
198 4491131 : lengthBehindCrossing(lbc),
199 4491131 : conflictSize(cs),
200 4491131 : flag(fl)
201 : {}
202 : /// @brief the conflict from the perspective of the foe
203 : int foeConflictIndex;
204 : /// @brief length of internal lane after the crossing point
205 : double lengthBehindCrossing;
206 : /// @brief the length of the conflict space
207 : double conflictSize;
208 :
209 : ConflictFlag flag;
210 :
211 : double getFoeLengthBehindCrossing(const MSLink* foeExitLink) const;
212 : double getFoeConflictSize(const MSLink* foeExitLink) const;
213 : double getLengthBehindCrossing(const MSLink* exitLink) const;
214 : };
215 :
216 : /// @brief holds user defined conflict positions (must be interpreted for the correct exitLink)
217 : struct CustomConflict {
218 4 : CustomConflict(const MSLane* f, const MSLane* t, double s, double e) :
219 4 : from(f), to(t), startPos(s), endPos(e) {}
220 : const MSLane* from;
221 : const MSLane* to;
222 : double startPos;
223 : double endPos;
224 : };
225 :
226 : /** @brief Constructor for simulation which uses internal lanes
227 : *
228 : * @param[in] succLane The lane approached by this link
229 : * @param[in] via The lane to use within the junction
230 : * @param[in] dir The direction of this link
231 : * @param[in] state The state of this link
232 : * @param[in] length The length of this link
233 : */
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 :
247 : /// @brief Destructor
248 : ~MSLink();
249 :
250 : void addCustomConflict(const MSLane* from, const MSLane* to, double startPos, double endPos);
251 :
252 : /** @brief Sets the request information
253 : *
254 : * Because traffic lights and junction logics are loaded after links,
255 : * we have to assign the information about the right-of-way
256 : * requests and responses after the initialisation.
257 : * @todo Unsecure!
258 : */
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 :
263 : /// @brief add walkingarea as foe (when entering the junction)
264 : void addWalkingAreaFoe(const MSLane* lane) {
265 6594 : myWalkingAreaFoe = lane;
266 6594 : }
267 :
268 : /// @brief add walkingarea as foe (when leaving the junction)
269 : void addWalkingAreaFoeExit(const MSLane* lane) {
270 6667 : myWalkingAreaFoeExit = lane;
271 6667 : }
272 :
273 : /// @brief get walkingarea as foes
274 : const MSLane* getWalkingAreaFoe() {
275 2601267 : return myWalkingAreaFoe;
276 : }
277 : const MSLane* getWalkingAreaFoeExit() {
278 2600359 : return myWalkingAreaFoeExit;
279 : }
280 :
281 : /** @brief Sets the information about an approaching vehicle
282 : *
283 : * The information is stored in myApproachingVehicles.
284 : */
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 :
290 : /** @brief Sets the information about an approaching vehicle */
291 : void setApproaching(const SUMOVehicle* approaching, ApproachingVehicleInformation ai);
292 :
293 : /** @brief Sets the information about an approaching person (only for a pedestrian crossing) */
294 : void setApproachingPerson(const MSPerson* approaching, const SUMOTime arrivalTime, const SUMOTime leaveTime);
295 :
296 : /// @brief removes the vehicle from myApproachingVehicles
297 : void removeApproaching(const SUMOVehicle* veh);
298 :
299 : /// @brief removes the person from myApproachingPersons
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 :
307 : /// @brief return all approaching vehicles
308 : const ApproachInfos& getApproaching() const {
309 : return myApproachingVehicles;
310 : }
311 :
312 : /// @brief return all approaching vehicles
313 : const PersonApproachInfos* getApproachingPersons() const {
314 64446 : return myApproachingPersons;
315 : }
316 :
317 : /** @brief Remove all approaching vehicles before quick-loading state */
318 : void clearState();
319 :
320 : /** @brief Returns the information whether the link may be passed
321 : *
322 : * Valid after the junctions have set their reponds
323 : *
324 : * @param[in] collectFoes If a vector is passed, all blocking foes are collected and inserted into this vector
325 : * @return Whether this link may be passed.
326 : */
327 : bool opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength,
328 : double impatience, double decel, SUMOTime waitingTime,
329 : double posLat = 0,
330 : BlockingFoes* collectFoes = nullptr,
331 : bool ignoreRed = false,
332 : const SUMOTrafficObject* ego = nullptr,
333 : double dist = -1) const;
334 :
335 : /** @brief Returns the information whether this link is blocked
336 : * Valid after the vehicles have set their requests
337 : * @param[in] arrivalTime The arrivalTime of the vehicle who checks for an approaching foe
338 : * @param[in] leaveTime The leaveTime of the vehicle who checks for an approaching foe
339 : * @param[in] arrivalSpeed The speed with which the checking vehicle plans to arrive at the link
340 : * @param[in] leaveSpeed The speed with which the checking vehicle plans to leave the link
341 : * @param[in] sameTargetLane Whether the link that calls this method has the same target lane as this link
342 : * @param[in] impatience The impatience of the checking vehicle
343 : * @param[in] decel The maximum deceleration of the checking vehicle
344 : * @param[in] waitingTime The waiting time of the checking vehicle
345 : * @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
346 : * @param[in] lastWasContRed Whether the link which is checked, is an internal junction link where the entry has red
347 : * @return Whether this link is blocked
348 : * @note Since this needs to be called without a SUMOVehicle (TraCI), we cannot simply pass the checking vehicle itself
349 : **/
350 : bool blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
351 : bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
352 : BlockingFoes* collectFoes = nullptr, const SUMOTrafficObject* ego = nullptr, bool lastWasContRed = false, double dist = -1) const;
353 :
354 :
355 : /** @brief Returns the information whether a vehicle is approaching on one of the link's foe streams
356 : *
357 : * Valid after the vehicles have set their requests
358 : * @param[in] arrivalTime The arrivalTime of the vehicle who checks for an approaching foe
359 : * @param[in] leaveTime The leaveTime of the vehicle who checks for an approaching foe
360 : * @param[in] speed The speed with which the checking vehicle plans to leave the link
361 : * @param[in] decel The maximum deceleration of the checking vehicle
362 : * @return Whether a foe of this link is approaching
363 : */
364 : bool hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, double speed, double decel) const;
365 :
366 : /** @brief get the foe vehicle that is closest to the intersection or nullptr along with the foe link
367 : * This function is used for finding circular deadlock at right_before_left junctions
368 : * @param[in] wrapAround The link on which the ego vehicle wants to enter the junction
369 : */
370 : std::pair<const SUMOVehicle*, const MSLink*> getFirstApproachingFoe(const MSLink* wrapAround) const;
371 :
372 : MSJunction* getJunction() const {
373 4423923 : return myJunction;
374 : }
375 :
376 :
377 : /** @brief Returns the current state of the link
378 : *
379 : * @return The current state of this link
380 : */
381 : LinkState getState() const {
382 1518784917 : return myState;
383 : }
384 :
385 :
386 : /** @brief Returns the off-state for the link
387 : *
388 : * @return The current state of this link
389 : */
390 : LinkState getOffState() const {
391 2801335 : return myOffState;
392 : }
393 :
394 : /** @brief Returns the last green state of the link
395 : *
396 : * @return The last green state of this link
397 : */
398 : LinkState getLastGreenState() const {
399 562100 : return myLastGreenState;
400 : }
401 :
402 :
403 : //@brief Returns the time of the last state change
404 : inline SUMOTime getLastStateChange() const {
405 51899 : return myLastStateChange;
406 : }
407 :
408 :
409 : /** @brief Returns the direction the vehicle passing this link take
410 : *
411 : * @return The direction of this link
412 : */
413 : inline LinkDirection getDirection() const {
414 171999275 : return myDirection;
415 : }
416 :
417 :
418 :
419 : /** @brief Sets the current tl-state
420 : *
421 : * @param[in] state The current state of the link
422 : * @param[in] t The time of the state change
423 : */
424 : void setTLState(LinkState state, SUMOTime t);
425 :
426 : /** @brief Sets the currently active tlLogic
427 : * @param[in] logic The currently active logic
428 : */
429 : void setTLLogic(const MSTrafficLightLogic* logic);
430 :
431 : /** @brief Returns the connected lane
432 : *
433 : * @return The lane approached by this link
434 : */
435 : inline MSLane* getLane() const {
436 3479215515 : return myLane;
437 : }
438 :
439 :
440 : /** @brief Returns the respond index (for visualization)
441 : *
442 : * @return The respond index for this link
443 : */
444 : inline int getIndex() const {
445 1903010 : return myIndex;
446 : }
447 :
448 : /** @brief Returns the TLS index */
449 : inline int getTLIndex() const {
450 31936065 : return myTLIndex;
451 : }
452 :
453 : /** @brief Returns the TLS index */
454 : inline const MSTrafficLightLogic* getTLLogic() const {
455 14249479 : return myLogic;
456 : }
457 :
458 : /** @brief Returns whether this link is a major link
459 : * @return Whether the link has a large priority
460 : */
461 : inline bool havePriority() const {
462 3954226363 : return myState >= 'A' && myState <= 'Z';
463 : }
464 :
465 : inline bool haveOffPriority() const {
466 40 : return myOffState >= 'A' && myOffState <= 'Z';
467 : }
468 :
469 : /** @brief Returns whether this link is blocked by a red (or redyellow) traffic light
470 : * @return Whether the link has a red light
471 : */
472 : inline bool haveRed() const {
473 1381960364 : return myState == LINKSTATE_TL_RED || myState == LINKSTATE_TL_REDYELLOW;
474 : }
475 :
476 : inline bool haveYellow() const {
477 1313810317 : return myState == LINKSTATE_TL_YELLOW_MINOR || myState == LINKSTATE_TL_YELLOW_MAJOR;
478 : }
479 :
480 : inline bool haveGreen() const {
481 140319682 : return myState == LINKSTATE_TL_GREEN_MAJOR || myState == LINKSTATE_TL_GREEN_MINOR;
482 : }
483 :
484 : inline bool mustStop() const {
485 567285991 : return myState == LINKSTATE_STOP || myState == LINKSTATE_ALLWAY_STOP;
486 : }
487 :
488 : inline bool isTLSControlled() const {
489 1982586 : return myLogic != 0;
490 : }
491 :
492 : inline bool isTurnaround() const {
493 62680006 : return myDirection == LinkDirection::TURN || myDirection == LinkDirection::TURN_LEFTHAND;
494 : }
495 :
496 : /** @brief Returns the length of this link
497 : *
498 : * @return The length of this link
499 : */
500 : double getLength() const {
501 2105749638 : return myLength;
502 : }
503 :
504 :
505 : /** @brief Returns the distance on the approaching lane from which an
506 : * approaching vehicle is able to see all relevant foes and
507 : * may accelerate if the link is minor and no foe is approaching.
508 : *
509 : * @return The foe-visibility-distance
510 : */
511 : double getFoeVisibilityDistance() const {
512 2083079796 : return myFoeVisibilityDistance;
513 : }
514 :
515 : double getDistToFoePedCrossing() const {
516 37066368 : return myDistToFoePedCrossing;
517 : }
518 :
519 : /** @brief Returns whether this link belongs to a junction where more than one edge is incoming
520 : *
521 : * @return Whether any foe links exist
522 : */
523 : bool hasFoes() const {
524 456822713 : return myHasFoes;
525 : }
526 :
527 : // @brief return whether the vehicle may continute past this link to wait within the intersection
528 : bool isCont() const;
529 :
530 :
531 : /// @brief whether the junction after this link must be kept clear
532 : bool keepClear() const {
533 147549181 : return myKeepClear;
534 : }
535 :
536 : /// @brief whether this link is the start of an indirect turn
537 : bool isIndirect() const {
538 1327692 : return myAmIndirect;
539 : }
540 :
541 : /// @brief whether this is a link past an internal junction which currently has priority
542 : bool lastWasContMajor() const;
543 :
544 : /// @brief whether this is a link past an internal junction where the entry to the junction currently has the given state
545 : bool lastWasContState(LinkState linkState) const;
546 :
547 : /** @brief Returns the cumulative length of all internal lanes after this link
548 : * @return sum of the lengths of all internal lanes following this link
549 : */
550 : double getInternalLengthsAfter() const;
551 :
552 : /** @brief Returns the cumulative length of all internal lanes before this link
553 : * @return sum of the lengths of all internal lanes before this link
554 : */
555 : double getInternalLengthsBefore() const;
556 :
557 : /** @brief Returns the sum of the lengths along internal lanes following this link
558 : * to the crossing with the given foe lane, if the lane is no foe
559 : * lane to any of the internal lanes, INVALID_DOUBLE is returned.
560 : * @see getLengthBeforeCrossing()
561 : */
562 : double getLengthsBeforeCrossing(const MSLane* foeLane) const;
563 :
564 :
565 : /** @brief Returns the internal length from the beginning of the link's internal lane before
566 : * to the crossing with the given foe lane if applicable, if the lane is no foe
567 : * lane to the link, INVALID_DOUBLE is returned.
568 : * @see getLengthsBeforeCrossing()
569 : */
570 : double getLengthBeforeCrossing(const MSLane* foeLane) const;
571 :
572 :
573 : /** @brief Returns the following inner lane
574 : *
575 : * @return The inner lane to use to cross the junction
576 : */
577 : inline MSLane* getViaLane() const {
578 2250603238 : return myInternalLane;
579 : }
580 :
581 : /** @brief Returns all potential link leaders (vehicles on foeLanes)
582 : * Valid during the planMove() phase
583 : * @param[in] ego The ego vehicle that is looking for leaders
584 : * @param[in] dist The distance of the vehicle who is asking about the leader to this link
585 : * @param[out] blocking Return blocking pedestrians if a vector is given
586 : * @param[in] isShadowLink whether this link is a shadowLink for ego
587 : * @return The all vehicles on foeLanes and their (virtual) distances to the asking vehicle
588 : */
589 : const LinkLeaders getLeaderInfo(const MSVehicle* ego, double dist, std::vector<const MSPerson*>* collectBlockers = 0, bool isShadowLink = false) const;
590 :
591 : /// @brief return the speed at which ego vehicle must approach the zipper link
592 : double getZipperSpeed(const MSVehicle* ego, const double dist, double vSafe,
593 : SUMOTime arrivalTime,
594 : const BlockingFoes* foes) const;
595 :
596 : /// @brief return the via lane if it exists and the lane otherwise
597 : inline MSLane* getViaLaneOrLane() const {
598 1659415771 : return myInternalLane != nullptr ? myInternalLane : myLane;
599 : }
600 :
601 :
602 : /// @brief return the internalLaneBefore if it exists and the laneBefore otherwise
603 : inline const MSLane* getLaneBefore() const {
604 : assert(myInternalLaneBefore == nullptr || myLaneBefore == myInternalLaneBefore); // lane before mismatch!
605 678400830 : return myLaneBefore;
606 : }
607 :
608 : /// @brief return myInternalLaneBefore (always 0 when compiled without internal lanes)
609 : inline const MSLane* getInternalLaneBefore() const {
610 538344509 : return myInternalLaneBefore;
611 : }
612 :
613 : /// @brief return the expected time at which the given vehicle will clear the link
614 : SUMOTime getLeaveTime(const SUMOTime arrivalTime, const double arrivalSpeed, const double leaveSpeed, const double vehicleLength) const;
615 :
616 : /// @brief write information about all approaching vehicles to the given output device
617 : void writeApproaching(OutputDevice& od, const std::string fromLaneID) const;
618 :
619 : /// @brief return the link that is parallel to this lane or 0
620 : MSLink* getParallelLink(int direction) const;
621 :
622 : /// @brief return the link that is the opposite entry link to this one
623 : MSLink* getOppositeDirectionLink() const;
624 :
625 : /// @brief return whether the fromLane of this link is an internal lane
626 : inline bool fromInternalLane() const {
627 780518572 : return myInternalLaneBefore != nullptr;
628 : }
629 :
630 : /// @brief return whether the toLane of this link is an internal lane and fromLane is a normal lane
631 : bool isEntryLink() const;
632 :
633 : /// @brief return whether this link enters the conflict area (not a continuation link)
634 : bool isConflictEntryLink() const;
635 :
636 : /// @brief return whether the fromLane of this link is an internal lane and toLane is a normal lane
637 : bool isExitLink() const;
638 :
639 : /// @brief return whether the fromLane of this link is an internal lane and its incoming lane is also an internal lane
640 : bool isExitLinkAfterInternalJunction() const;
641 :
642 : /// @brief returns the corresponding exit link for entryLinks to a junction.
643 : const MSLink* getCorrespondingExitLink() const;
644 :
645 : /// @brief returns the corresponding entry link for exitLinks to a junction.
646 : const MSLink* getCorrespondingEntryLink() const;
647 :
648 : /// @brief return whether the fromLane and the toLane of this link are internal lanes
649 : bool isInternalJunctionLink() const;
650 :
651 : /** @brief Returns the time penalty for passing a tls-controlled link (meso) */
652 : SUMOTime getMesoTLSPenalty() const {
653 192679 : return myMesoTLSPenalty;
654 : }
655 :
656 : /** @brief Returns the average proportion of green time to cycle time */
657 : double getGreenFraction() const {
658 48820 : return myGreenFraction;
659 : }
660 :
661 : /** @brief Sets the time penalty for passing a tls-controlled link (meso) */
662 : void setMesoTLSPenalty(const SUMOTime penalty) {
663 180557 : myMesoTLSPenalty = penalty;
664 : }
665 :
666 : /** @brief Sets the green fraction for passing a tls-controlled link (meso) */
667 : void setGreenFraction(const double fraction) {
668 180397 : myGreenFraction = fraction;
669 180397 : }
670 :
671 : const std::vector<const MSLane*>& getFoeLanes() const {
672 : return myFoeLanes;
673 : }
674 :
675 : const std::vector<ConflictInfo>& getConflicts() const {
676 : return myConflicts;
677 : }
678 :
679 : const std::vector<MSLink*>& getFoeLinks() const {
680 : return myFoeLinks;
681 : }
682 :
683 : /// @brief who may use this link
684 : SVCPermissions getPermissions() const {
685 1102 : return myPermissions;
686 : }
687 :
688 : /// @brief initialize parallel links (to be called after all links are loaded)
689 : void initParallelLinks();
690 :
691 : /// @brief return lateral shift that must be applied when passing this link
692 : inline double getLateralShift() const {
693 817828071 : return myLateralShift;
694 : }
695 :
696 : /// @brief get string description for this link
697 : std::string getDescription() const;
698 :
699 : /// @brief get the closest vehicle approaching this link
700 : std::pair<const SUMOVehicle* const, const ApproachingVehicleInformation> getClosest() const;
701 :
702 :
703 : /// @brief post-processing for legacy networks
704 : static void recheckSetRequestInformation();
705 :
706 : static bool ignoreFoe(const SUMOTrafficObject* ego, const SUMOTrafficObject* foe);
707 :
708 : static const double NO_INTERSECTION;
709 :
710 : private:
711 : /// @brief return whether the given vehicles may NOT merge safely
712 : static inline bool unsafeMergeSpeeds(double leaderSpeed, double followerSpeed, double leaderDecel, double followerDecel) {
713 : // XXX mismatch between continuous an discrete deceleration
714 20373614 : return (leaderSpeed * leaderSpeed / leaderDecel) <= (followerSpeed * followerSpeed / followerDecel);
715 : }
716 :
717 : /// @brief whether follower could stay behind leader (possibly by braking)
718 : static bool couldBrakeForLeader(double followDist, double leaderDist, const MSVehicle* follow, const MSVehicle* leader);
719 :
720 : MSLink* computeParallelLink(int direction);
721 :
722 : /// @brief check for persons on walkingarea in the path of ego vehicle
723 : void checkWalkingAreaFoe(const MSVehicle* ego, const MSLane* foeLane, std::vector<const MSPerson*>* collectBlockers, LinkLeaders& result) const;
724 :
725 : /// @brief whether the given person is in front of the car
726 : bool isInFront(const MSVehicle* ego, const PositionVector& egoPath, const Position& pPos) const;
727 :
728 : /// @brief whether the given person is walking towards the car returned as a factor in [0, 1]
729 : double isOnComingPed(const MSVehicle* ego, const MSPerson* p) const;
730 :
731 : /// @brief return extrapolated position of the given person after the given time
732 : Position getFuturePosition(const MSPerson* p, double timeHorizon = 1) const;
733 :
734 : bool blockedByFoe(const SUMOVehicle* veh, const ApproachingVehicleInformation& avi,
735 : SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
736 : bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
737 : const SUMOTrafficObject* ego) const;
738 :
739 : /// @brief figure out whether the cont status remains in effect when switching off the tls
740 : bool checkContOff() const;
741 :
742 : /// @brief check if the lane intersects with a foe cont-lane
743 : bool contIntersect(const MSLane* lane, const MSLane* foe);
744 :
745 : /// @brief compute point of divergence for geomatries with a common start or end
746 : double computeDistToDivergence(const MSLane* lane, const MSLane* sibling, double minDist, bool sameSource) const;
747 :
748 : /// @brief compute arrival time if foe vehicle is braking for ego
749 : static SUMOTime computeFoeArrivalTimeBraking(SUMOTime arrivalTime, const SUMOVehicle* foe, SUMOTime foeArrivalTime, double impatience, double dist, double& fasb);
750 :
751 : /// @brief check whether the given vehicle positions overlap laterally
752 : static bool lateralOverlap(double posLat, double width, double posLat2, double width2);
753 :
754 : /// @brief return CustomConflict with foeLane if it is defined
755 : const CustomConflict* getCustomConflict(const MSLane* foeLane) const;
756 :
757 : /// @brief add information about another pedestrian crossing
758 : void updateDistToFoePedCrossing(double dist);
759 :
760 : private:
761 : /// @brief The lane behind the junction approached by this link
762 : MSLane* myLane;
763 :
764 : /// @brief The lane approaching this link
765 : MSLane* myLaneBefore;
766 :
767 : ApproachInfos myApproachingVehicles;
768 : PersonApproachInfos* myApproachingPersons;
769 :
770 : /// @brief The position within this respond
771 : int myIndex;
772 :
773 : /// @brief the traffic light index
774 : const int myTLIndex;
775 :
776 : /// @brief the controlling logic or 0
777 : const MSTrafficLightLogic* myLogic;
778 :
779 : /// @brief The state of the link
780 : LinkState myState;
781 : /// @brief The last green state of the link (minor or major)
782 : LinkState myLastGreenState;
783 : /// @brief The state of the link when switching of traffic light control
784 : const LinkState myOffState;
785 :
786 : /// @brief The time of the last state change
787 : SUMOTime myLastStateChange;
788 :
789 : /// @brief An abstract (hopefully human readable) definition of the link's direction
790 : LinkDirection myDirection;
791 :
792 : /// @brief The length of the link
793 : /// @note This is not equal to the result of getInternalLengthsAfter for links with more than one internal lane.
794 : double myLength;
795 :
796 : /// @brief distance from which an approaching vehicle is able to
797 : /// see all relevant foes and may accelerate if the link is minor
798 : /// and no foe is approaching. Defaults to 4.5m.
799 : /// For zipper links (major) this is the distance at which zipper merging starts (and foes become "visible")
800 : double myFoeVisibilityDistance;
801 :
802 : /// @brief distance from the stop line to the first pedestrian crossing or maxdouble
803 : double myDistToFoePedCrossing;
804 :
805 : /// @brief Whether any foe links exist
806 : bool myHasFoes;
807 :
808 : // @brief whether vehicles may continue past this link to wait within the intersection
809 : bool myAmCont;
810 : // @brief whether vehicles may continue past this link to wait within the intersection after switching of the traffic light at this intersection
811 : bool myAmContOff;
812 :
813 : // @brief whether vehicles must keep the intersection clear if there is a downstream jam
814 : bool myKeepClear;
815 :
816 : /// @brief The following junction-internal lane if used
817 : MSLane* const myInternalLane;
818 :
819 : /* @brief The preceding junction-internal lane, only used at
820 : * - exit links (from internal lane to normal lane)
821 : * - internal junction links (from internal lane to internal lane)
822 : */
823 : const MSLane* myInternalLaneBefore;
824 :
825 : /// @brief penalty time at tls for mesoscopic simulation
826 : SUMOTime myMesoTLSPenalty;
827 : /// @brief green fraction at tls for mesoscopic simulation
828 : double myGreenFraction;
829 :
830 : /// @brief lateral shift to be applied when passing this link
831 : double myLateralShift;
832 :
833 : /* @brief lengths after the crossing point with foeLane
834 : * (index corresponds to myFoeLanes)
835 : * empty vector for entry links
836 : * */
837 : std::vector<ConflictInfo> myConflicts;
838 :
839 : std::vector<CustomConflict> myCustomConflicts;
840 :
841 : // TODO: documentation
842 : std::vector<MSLink*> myFoeLinks;
843 : std::vector<const MSLane*> myFoeLanes;
844 :
845 : /* prioritized links when the traffic light is switched off (only needed for RightOfWay::ALLWAYSTOP)
846 : * @note stored as a pointer to save space since it won't be used in most cases
847 : */
848 : std::vector<MSLink*>* myOffFoeLinks;
849 :
850 : /// @brief walkingArea that must be checked when entering the intersection
851 : const MSLane* myWalkingAreaFoe;
852 : /// @brief walkingArea that must be checked when leaving the intersection
853 : const MSLane* myWalkingAreaFoeExit;
854 :
855 : /// @brief whether on of myFoeLanes is a crossing
856 : bool myHavePedestrianCrossingFoe;
857 :
858 : /* @brief Links with the same origin lane and the same destination edge that may
859 : be in conflict for sublane simulation */
860 : std::vector<MSLink*> mySublaneFoeLinks;
861 : /* @brief Links with the same origin lane and different destination edge that may
862 : be in conflict for sublane simulation */
863 : std::vector<MSLink*> mySublaneFoeLinks2;
864 :
865 : /* @brief Internal Lanes with the same origin lane and the same destination edge that may
866 : be in conflict for sublane simulation */
867 : std::vector<MSLane*> mySublaneFoeLanes;
868 :
869 : static const SUMOTime myLookaheadTime;
870 : static const SUMOTime myLookaheadTimeZipper;
871 :
872 : /// @brief links that need post processing after initialization (to deal with legacy networks)
873 : static std::set<std::pair<MSLink*, MSLink*> > myRecheck;
874 :
875 : MSLink* myParallelRight;
876 : MSLink* myParallelLeft;
877 :
878 : /// @brief whether this connection is an indirect turning movement
879 : const bool myAmIndirect;
880 :
881 : /// @brief the turning radius for this link or doublemax for straight links
882 : double myRadius;
883 :
884 : /// @brief who may drive on this link
885 : SVCPermissions myPermissions;
886 :
887 : /// @brief the junction to which this link belongs
888 : MSJunction* myJunction;
889 :
890 : /// invalidated copy constructor
891 : MSLink(const MSLink& s);
892 :
893 : /// invalidated assignment operator
894 : MSLink& operator=(const MSLink& s);
895 :
896 : };
|