Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-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 : /****************************************************************************/
14 : /// @file MSLane.h
15 : /// @author Christian Roessel
16 : /// @author Daniel Krajzewicz
17 : /// @author Jakob Erdmann
18 : /// @author Christoph Sommer
19 : /// @author Tino Morenz
20 : /// @author Michael Behrisch
21 : /// @author Mario Krumnow
22 : /// @author Leonhard Luecken
23 : /// @date Mon, 12 Mar 2001
24 : ///
25 : // Representation of a lane in the micro simulation
26 : /****************************************************************************/
27 : #pragma once
28 : #include <config.h>
29 :
30 : #include <memory>
31 : #include <vector>
32 : #include <map>
33 : #include <deque>
34 : #include <cassert>
35 : #include <utils/common/Named.h>
36 : #include <utils/common/Parameterised.h>
37 : #include <utils/common/SUMOVehicleClass.h>
38 : #include <utils/vehicle/SUMOVehicle.h>
39 : #include <utils/common/NamedRTree.h>
40 : #include <utils/emissions/PollutantsInterface.h>
41 : #include <utils/geom/PositionVector.h>
42 : #include "MSGlobals.h"
43 : #include "MSLeaderInfo.h"
44 : #include "MSMoveReminder.h"
45 : #include "MSVehicle.h"
46 :
47 : #include <utils/foxtools/MFXSynchQue.h>
48 : #ifdef HAVE_FOX
49 : #include <utils/foxtools/MFXWorkerThread.h>
50 : #endif
51 : #include <utils/common/StopWatch.h>
52 :
53 :
54 : // ===========================================================================
55 : // class declarations
56 : // ===========================================================================
57 : class MSEdge;
58 : class MSBaseVehicle;
59 : class MSLaneChanger;
60 : class MSLink;
61 : class MSVehicleTransfer;
62 : class MSVehicleControl;
63 : class OutputDevice;
64 : class MSLeaderInfo;
65 : class MSJunction;
66 :
67 :
68 : // ===========================================================================
69 : // type definitions
70 : // ===========================================================================
71 : /// Coverage info
72 : typedef std::map<const MSLane*, std::pair<double, double> > LaneCoverageInfo;
73 :
74 : // ===========================================================================
75 : // class definitions
76 : // ===========================================================================
77 : /**
78 : * @class MSLane
79 : * @brief Representation of a lane in the micro simulation
80 : *
81 : * Class which represents a single lane. Somekind of the main class of the
82 : * simulation. Allows moving vehicles.
83 : */
84 : class MSLane : public Named, public Parameterised {
85 : public:
86 : class StoringVisitor {
87 : public:
88 : /// @brief Constructor
89 : StoringVisitor(std::set<const Named*>& objects, const PositionVector& shape,
90 : const double range, const int domain)
91 2094869 : : myObjects(objects), myShape(shape), myRange(range), myDomain(domain) {}
92 :
93 : /// @brief Adds the given object to the container
94 : void add(const MSLane* const l) const;
95 :
96 : private:
97 : /// @brief The container
98 : std::set<const Named*>& myObjects;
99 : const PositionVector& myShape;
100 : const double myRange;
101 : const int myDomain;
102 :
103 : private:
104 : /// @brief invalidated copy constructor
105 : StoringVisitor(const StoringVisitor& src);
106 :
107 : /// @brief invalidated assignment operator
108 : StoringVisitor& operator=(const StoringVisitor& src);
109 : };
110 :
111 : /// needs access to myTmpVehicles (this maybe should be done via double-buffering!!!)
112 : friend class MSLaneChanger;
113 : friend class MSLaneChangerSublane;
114 :
115 : friend class MSQueueExport;
116 : friend class AnyVehicleIterator;
117 :
118 : /// Container for vehicles.
119 : typedef std::vector<MSVehicle*> VehCont;
120 :
121 : // TODO: Better documentation
122 : /// @brief AnyVehicleIterator is a structure, which manages the iteration through all vehicles on the lane,
123 : /// that may be of importance for the car-following dynamics along that lane. The relevant types of vehicles are:
124 : /// 1) vehicles with their front on the lane (myVehicles),
125 : /// 2) vehicles intersecting the lane but with front on another lane (myPartialVehicles)
126 : ///
127 : /// In the context of retrieving linkLeaders during lane changing a third group of vehicles is checked:
128 : /// 3) vehicles processed during lane changing (myTmpVehicles)
129 : class AnyVehicleIterator {
130 : public:
131 : AnyVehicleIterator(
132 : const MSLane* lane,
133 : int i1,
134 : int i2,
135 : int i3,
136 : const int i1End,
137 : const int i2End,
138 : const int i3End,
139 1572636153 : bool downstream = true) :
140 1572636153 : myLane(lane),
141 1572636153 : myI1(i1),
142 1572636153 : myI2(i2),
143 1572636153 : myI3(i3),
144 1572636153 : myI1End(i1End),
145 1572636153 : myI2End(i2End),
146 1572636153 : myI3End(i3End),
147 1572636153 : myDownstream(downstream),
148 1572636153 : myDirection(downstream ? 1 : -1) {
149 : }
150 :
151 : bool operator== (AnyVehicleIterator const& other) const {
152 : return (myI1 == other.myI1
153 11450173009 : && myI2 == other.myI2
154 : && myI3 == other.myI3
155 3297032264 : && myI1End == other.myI1End
156 : && myI2End == other.myI2End
157 1410865619 : && myI3End == other.myI3End);
158 : }
159 :
160 : bool operator!= (AnyVehicleIterator const& other) const {
161 : return !(*this == other);
162 : }
163 :
164 : const MSVehicle* operator->() {
165 : return **this;
166 : }
167 :
168 : const MSVehicle* operator*();
169 :
170 : AnyVehicleIterator& operator++();
171 :
172 : private:
173 : bool nextIsMyVehicles() const;
174 :
175 : /// @brief the lane that is being iterated
176 : const MSLane* myLane;
177 : /// @brief index for myVehicles
178 : int myI1;
179 : /// @brief index for myPartialVehicles
180 : int myI2;
181 : /// @brief index for myTmpVehicles
182 : int myI3;
183 : /// @brief end index for myVehicles
184 : int myI1End;
185 : /// @brief end index for myPartialVehicles
186 : int myI2End;
187 : /// @brief end index for myTmpVehicles
188 : int myI3End;
189 : /// @brief iteration direction
190 : bool myDownstream;
191 : /// @brief index delta
192 : int myDirection;
193 :
194 : };
195 :
196 :
197 : public:
198 : /** @enum ChangeRequest
199 : * @brief Requests set via TraCI
200 : */
201 : enum CollisionAction {
202 : COLLISION_ACTION_NONE,
203 : COLLISION_ACTION_WARN,
204 : COLLISION_ACTION_TELEPORT,
205 : COLLISION_ACTION_REMOVE
206 : };
207 :
208 : /** @brief Constructor
209 : *
210 : * @param[in] id The lane's id
211 : * @param[in] maxSpeed The speed allowed on this lane
212 : * @param[in] friction The friction of this lane
213 : * @param[in] length The lane's length
214 : * @param[in] edge The edge this lane belongs to
215 : * @param[in] numericalID The numerical id of the lane
216 : * @param[in] shape The shape of the lane
217 : * @param[in] width The width of the lane
218 : * @param[in] permissions Encoding of the Vehicle classes that may drive on this lane
219 : * @param[in] index The index of this lane within its parent edge
220 : * @param[in] isRampAccel Whether this lane is an acceleration lane
221 : * @see SUMOVehicleClass
222 : */
223 : MSLane(const std::string& id, double maxSpeed, double friction, double length, MSEdge* const edge,
224 : int numericalID, const PositionVector& shape, double width,
225 : SVCPermissions permissions,
226 : SVCPermissions changeLeft, SVCPermissions changeRight,
227 : int index, bool isRampAccel,
228 : const std::string& type,
229 : const PositionVector& outlineShape);
230 :
231 :
232 : /// @brief Destructor
233 : virtual ~MSLane();
234 :
235 : /// @brief returns the associated thread index
236 : inline int getThreadIndex() const {
237 : return myRNGIndex % MSGlobals::gNumSimThreads;
238 : }
239 :
240 : /// @brief returns the associated RNG index
241 : inline int getRNGIndex() const {
242 32569376 : return myRNGIndex;
243 : }
244 :
245 : /// @brief return the associated RNG
246 : SumoRNG* getRNG() const {
247 748801090 : return &myRNGs[myRNGIndex];
248 : }
249 :
250 : /// @brief return the number of RNGs
251 : static int getNumRNGs() {
252 5934 : return (int)myRNGs.size();
253 : }
254 :
255 : /// @brief save random number generator states to the given output device
256 : static void saveRNGStates(OutputDevice& out);
257 :
258 : /// @brief load random number generator state for the given rng index
259 : static void loadRNGState(int index, const std::string& state);
260 :
261 : /// @name Additional initialisation
262 : /// @{
263 :
264 : /** @brief Delayed initialization
265 : *
266 : * Not all lane-members are known at the time the lane is born, above all the pointers
267 : * to other lanes, so we have to add them later.
268 : *
269 : * @param[in] link An outgoing link
270 : */
271 : void addLink(MSLink* link);
272 :
273 : /** @brief Adds a neighbor to this lane
274 : *
275 : * @param[in] id The lane's id
276 : */
277 : void setOpposite(MSLane* oppositeLane);
278 :
279 : /** @brief Adds the (overlapping) reverse direction lane to this lane
280 : *
281 : * @param[in] id The lane's id
282 : */
283 : void setBidiLane(MSLane* bidyLane);
284 : ///@}
285 :
286 : /// @name Used by the GUI for secondary shape visualization
287 : /// @{
288 0 : virtual void addSecondaryShape(const PositionVector& /*shape*/) {}
289 :
290 1856 : virtual double getLengthGeometryFactor(bool /*secondaryShape*/) const {
291 1856 : return myLengthGeometryFactor;
292 : }
293 :
294 1632 : virtual const PositionVector& getShape(bool /*secondaryShape*/) const {
295 1632 : return myShape;
296 : }
297 : ///@}
298 :
299 238356 : virtual void updateMesoGUISegments() {}
300 :
301 : /// @name interaction with MSMoveReminder
302 : /// @{
303 :
304 : /** @brief Add a move-reminder to move-reminder container
305 : *
306 : * The move reminder will not be deleted by the lane.
307 : *
308 : * @param[in] rem The move reminder to add
309 : */
310 : virtual void addMoveReminder(MSMoveReminder* rem, bool addToVehicles = true);
311 :
312 :
313 : /** @brief Remove a move-reminder from move-reminder container
314 : *
315 : * The move reminder will not be deleted by the lane.
316 : * @param[in] rem The move reminder to remvoe
317 : */
318 : virtual void removeMoveReminder(MSMoveReminder* rem);
319 :
320 :
321 : /** @brief Return the list of this lane's move reminders
322 : * @return Previously added move reminder
323 : */
324 : inline const std::vector< MSMoveReminder* >& getMoveReminders() const {
325 : return myMoveReminders;
326 : }
327 : ///@}
328 :
329 :
330 :
331 : /// @name Vehicle insertion
332 : ///@{
333 :
334 : /** @brief Tries to insert the given vehicle
335 : *
336 : * The insertion position and speed are determined in dependence
337 : * to the vehicle's departure definition, first.
338 : *
339 : * Then, the vehicle is tried to be inserted into the lane
340 : * using these values by a call to "isInsertionSuccess". The result of
341 : * "isInsertionSuccess" is returned.
342 : *
343 : * @param[in] v The vehicle to insert
344 : * @return Whether the vehicle could be inserted
345 : * @see isInsertionSuccess
346 : * @see MSVehicle::getDepartureDefinition
347 : * @see MSVehicle::DepartArrivalDefinition
348 : */
349 : bool insertVehicle(MSVehicle& v);
350 :
351 :
352 : /** @brief Tries to insert the given vehicle with the given state (speed and pos)
353 : *
354 : * Checks whether the vehicle can be inserted at the given position with the
355 : * given speed so that no collisions with leader/follower occur and the speed
356 : * does not cause unexpected behaviour on consecutive lanes. Returns false
357 : * if the vehicle can not be inserted.
358 : *
359 : * If the insertion can take place, incorporateVehicle() is called and true is returned.
360 : *
361 : * @param[in] vehicle The vehicle to insert
362 : * @param[in] speed The speed with which it shall be inserted
363 : * @param[in] pos The position at which it shall be inserted
364 : * @param[in] posLat The lateral position at which it shall be inserted
365 : * @param[in] recheckNextLanes Forces patching the speed for not being too fast on next lanes
366 : * @param[in] notification The cause of insertion (i.e. departure, teleport, parking) defaults to departure
367 : * @return Whether the vehicle could be inserted
368 : * @see MSVehicle::enterLaneAtInsertion
369 : */
370 : bool isInsertionSuccess(MSVehicle* vehicle, double speed, double pos, double posLat,
371 : bool recheckNextLanes,
372 : MSMoveReminder::Notification notification);
373 :
374 : // XXX: Documentation?
375 : bool checkFailure(const MSVehicle* aVehicle, double& speed, double& dist, const double nspeed, const bool patchSpeed, const std::string errorMsg, InsertionCheck check) const;
376 :
377 : /** @brief inserts vehicle as close as possible to the last vehicle on this
378 : * lane (or at the end of the lane if there is no leader)
379 : */
380 : bool lastInsertion(MSVehicle& veh, double mspeed, double posLat, bool patchSpeed);
381 :
382 : /** @brief Tries to insert the given vehicle on any place
383 : *
384 : * @param[in] veh The vehicle to insert
385 : * @param[in] speed The maximum insertion speed
386 : * @param[in] notification The cause of insertion (i.e. departure, teleport, parking) defaults to departure
387 : * @return Whether the vehicle could be inserted
388 : */
389 : bool freeInsertion(MSVehicle& veh, double speed, double posLat,
390 : MSMoveReminder::Notification notification = MSMoveReminder::NOTIFICATION_DEPARTED);
391 :
392 :
393 : /** @brief Inserts the given vehicle at the given position
394 : *
395 : * No checks are done, vehicle insertion using this method may
396 : * generate collisions (possibly delayed).
397 : * @param[in] veh The vehicle to insert
398 : * @param[in] pos The position at which the vehicle shall be inserted
399 : * @param[in] notification The cause of insertion (i.e. departure, teleport, parking) defaults to departure
400 : * @param[in] posLat The lateral position at which the vehicle shall be inserted
401 : */
402 : void forceVehicleInsertion(MSVehicle* veh, double pos, MSMoveReminder::Notification notification, double posLat = 0);
403 : /// @}
404 :
405 :
406 :
407 : /// @name Handling vehicles lapping into several lanes (-> partial occupation)
408 : /// or which committed a maneuver that will lead them into another (sublane case -> maneuver reservations)
409 : /// @{
410 : /** @brief Sets the information about a vehicle lapping into this lane
411 : *
412 : * This vehicle is added to myVehicles and may be distinguished from regular
413 : * vehicles by the disparity between this lane and v->getLane()
414 : * @param[in] v The vehicle which laps into this lane
415 : * @return This lane's length
416 : */
417 : virtual double setPartialOccupation(MSVehicle* v);
418 :
419 : /** @brief Removes the information about a vehicle lapping into this lane
420 : * @param[in] v The vehicle which laps into this lane
421 : */
422 : virtual void resetPartialOccupation(MSVehicle* v);
423 :
424 : /** @brief Registers the lane change intentions (towards this lane) for the given vehicle
425 : */
426 : virtual void setManeuverReservation(MSVehicle* v);
427 :
428 : /** @brief Unregisters a vehicle, which previously registered for maneuvering into this lane
429 : * @param[in] v The vehicle
430 : */
431 : virtual void resetManeuverReservation(MSVehicle* v);
432 :
433 : /** @brief Returns the last vehicles on the lane
434 : *
435 : * The information about the last vehicles in this lanes in all sublanes
436 : * occupied by ego are
437 : * returned. Partial occupators are included
438 : * @param[in] ego The vehicle for which to restrict the returned leaderInfo
439 : * @param[in] minPos The minimum position from which to start search for leaders
440 : * @param[in] allowCached Whether the cached value may be used
441 : * @return Information about the last vehicles
442 : */
443 : const MSLeaderInfo getLastVehicleInformation(const MSVehicle* ego, double latOffset, double minPos = 0, bool allowCached = true) const;
444 :
445 : /// @brief analogue to getLastVehicleInformation but in the upstream direction
446 : const MSLeaderInfo getFirstVehicleInformation(const MSVehicle* ego, double latOffset, bool onlyFrontOnLane, double maxPos = std::numeric_limits<double>::max(), bool allowCached = true) const;
447 :
448 : /// @}
449 :
450 : /// @name Access to vehicles
451 : /// @{
452 :
453 : /** @brief Returns the number of vehicles on this lane (for which this lane
454 : * is responsible)
455 : * @return The number of vehicles with their front on this lane
456 : */
457 : int getVehicleNumber() const {
458 565203248 : return (int)myVehicles.size();
459 : }
460 :
461 : /** @brief Returns the number of vehicles on this lane (including partial
462 : * occupators)
463 : * @return The number of vehicles with intersecting this lane
464 : */
465 : int getVehicleNumberWithPartials() const {
466 54846031 : return (int)myVehicles.size() + (int)myPartialVehicles.size();
467 : }
468 :
469 : /** @brief Returns the number of vehicles partially on this lane (for which this lane
470 : * is not responsible)
471 : * @return The number of vehicles touching this lane but with their front on another lane
472 : */
473 : int getPartialVehicleNumber() const {
474 : return (int)myPartialVehicles.size();
475 : }
476 :
477 :
478 : /** @brief Returns the vehicles container; locks it for microsimulation
479 : *
480 : * Please note that it is necessary to release the vehicles container
481 : * afterwards using "releaseVehicles".
482 : * @return The vehicles on this lane
483 : */
484 2297489710 : virtual const VehCont& getVehiclesSecure() const {
485 2297489710 : return myVehicles;
486 : }
487 :
488 :
489 : /// @brief begin iterator for iterating over all vehicles touching this lane in downstream direction
490 : AnyVehicleIterator anyVehiclesBegin() const {
491 : return AnyVehicleIterator(this, 0, 0, 0,
492 1135387241 : (int)myVehicles.size(), (int)myPartialVehicles.size(), (int)myTmpVehicles.size(), true);
493 : }
494 :
495 : /// @brief end iterator for iterating over all vehicles touching this lane in downstream direction
496 : AnyVehicleIterator anyVehiclesEnd() const {
497 : return AnyVehicleIterator(this, (int)myVehicles.size(), (int)myPartialVehicles.size(), (int)myTmpVehicles.size(),
498 11364409986 : (int)myVehicles.size(), (int)myPartialVehicles.size(), (int)myTmpVehicles.size(), true);
499 : }
500 :
501 : /// @brief begin iterator for iterating over all vehicles touching this lane in upstream direction
502 : AnyVehicleIterator anyVehiclesUpstreamBegin() const {
503 : return AnyVehicleIterator(this, (int)myVehicles.size() - 1, (int)myPartialVehicles.size() - 1, (int)myTmpVehicles.size() - 1,
504 403530630 : -1, -1, -1, false);
505 : }
506 :
507 : /// @brief end iterator for iterating over all vehicles touching this lane in upstream direction
508 : AnyVehicleIterator anyVehiclesUpstreamEnd() const {
509 : return AnyVehicleIterator(this, -1, -1, -1, -1, -1, -1, false);
510 : }
511 :
512 : /** @brief Allows to use the container for microsimulation again
513 : */
514 2297489708 : virtual void releaseVehicles() const { }
515 : /// @}
516 :
517 :
518 :
519 : /// @name Atomar value getter
520 : /// @{
521 :
522 :
523 : /** @brief Returns this lane's numerical id
524 : * @return This lane's numerical id
525 : */
526 : inline int getNumericalID() const {
527 1931385137 : return myNumericalID;
528 : }
529 :
530 :
531 : /** @brief Returns this lane's shape
532 : * @return This lane's shape
533 : */
534 : inline const PositionVector& getShape() const {
535 1036648280 : return myShape;
536 : }
537 :
538 : /// @brief return shape.length() / myLength
539 : inline double getLengthGeometryFactor() const {
540 2749832 : return myLengthGeometryFactor;
541 : }
542 :
543 : /// @brief return whether this lane is an acceleration lane
544 : inline bool isAccelLane() const {
545 614781 : return myIsRampAccel;
546 : }
547 :
548 : /// @brief return the type of this lane
549 : const std::string& getLaneType() const {
550 : return myLaneType;
551 : }
552 :
553 : /* @brief fit the given lane position to a visibly suitable geometry position
554 : * (lane length might differ from geometry length) */
555 : inline double interpolateLanePosToGeometryPos(double lanePos) const {
556 15973535 : return lanePos * myLengthGeometryFactor;
557 : }
558 :
559 : /* @brief fit the given lane position to a visibly suitable geometry position
560 : * and return the coordinates */
561 : inline const Position geometryPositionAtOffset(double offset, double lateralOffset = 0) const {
562 1594068067 : return myShape.positionAtOffset(interpolateLanePosToGeometryPos(offset), lateralOffset);
563 : }
564 :
565 : /* @brief fit the given geometry position to a valid lane position
566 : * (lane length might differ from geometry length) */
567 : inline double interpolateGeometryPosToLanePos(double geometryPos) const {
568 9897040 : return geometryPos / myLengthGeometryFactor;
569 : }
570 :
571 : /** @brief Returns the lane's maximum speed, given a vehicle's speed limit adaptation
572 : * @param[in] The vehicle to return the adapted speed limit for
573 : * @return This lane's resulting max. speed
574 : */
575 5560945822 : inline double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const {
576 5560945822 : return getVehicleMaxSpeed(veh, veh->getMaxSpeed());
577 : }
578 :
579 :
580 7577004376 : inline double getVehicleMaxSpeed(const SUMOTrafficObject* const veh, double vehMaxSpeed) const {
581 7577004376 : if (myRestrictions != nullptr) {
582 5055316 : std::map<SUMOVehicleClass, double>::const_iterator r = myRestrictions->find(veh->getVClass());
583 5055316 : if (r != myRestrictions->end()) {
584 4841917 : if (mySpeedModified) {
585 32590 : return MIN2(myMaxSpeed, MIN2(vehMaxSpeed, r->second * veh->getChosenSpeedFactor()));
586 : } else {
587 4825622 : return MIN2(vehMaxSpeed, r->second * veh->getChosenSpeedFactor());
588 : }
589 : }
590 : }
591 7572162459 : return MIN2(vehMaxSpeed, myMaxSpeed * veh->getChosenSpeedFactor());
592 : }
593 :
594 : inline bool isSpeedModified() const {
595 1680 : return mySpeedModified;
596 : }
597 :
598 :
599 : /** @brief Returns the lane's maximum allowed speed
600 : * @return This lane's maximum allowed speed
601 : */
602 : inline double getSpeedLimit() const {
603 580219347 : return myMaxSpeed;
604 : }
605 :
606 :
607 848 : inline double getSpeedLimit(SUMOVehicleClass svc) const {
608 848 : if (myRestrictions != nullptr) {
609 : std::map<SUMOVehicleClass, double>::const_iterator r = myRestrictions->find(svc);
610 0 : if (r != myRestrictions->end()) {
611 0 : if (mySpeedModified) {
612 0 : return MIN2(myMaxSpeed, r->second);
613 : } else {
614 0 : return r->second;
615 : }
616 : }
617 : }
618 848 : return myMaxSpeed;
619 : }
620 :
621 :
622 : /** @brief Returns the lane's friction coefficient
623 : * @return This lane's friction coefficient
624 : */
625 0 : inline double getFrictionCoefficient() const {
626 4088 : return myFrictionCoefficient;
627 : }
628 :
629 : /** @brief Returns the lane's length
630 : * @return This lane's length
631 : */
632 : inline double getLength() const {
633 38845517462 : return myLength;
634 : }
635 :
636 :
637 : /** @brief Returns the vehicle class permissions for this lane
638 : * @return This lane's allowed vehicle classes
639 : */
640 : inline SVCPermissions getPermissions() const {
641 86958995 : return myPermissions;
642 : }
643 :
644 : /** @brief Returns the vehicle class permissions for changing to the left neighbour lane
645 : * @return The vehicle classes allowed to change to the left neighbour lane
646 : */
647 : inline SVCPermissions getChangeLeft() const {
648 26 : return myChangeLeft;
649 : }
650 :
651 : /** @brief Returns the vehicle class permissions for changing to the right neighbour lane
652 : * @return The vehicle classes allowed to change to the right neighbour lane
653 : */
654 : inline SVCPermissions getChangeRight() const {
655 18 : return myChangeRight;
656 : }
657 :
658 : /** @brief Returns the lane's width
659 : * @return This lane's width
660 : */
661 : double getWidth() const {
662 5065485847 : return myWidth;
663 : }
664 :
665 : /** @brief Returns the lane's index
666 : * @return This lane's index
667 : */
668 : int getIndex() const {
669 2950360059 : return myIndex;
670 : }
671 : /// @}
672 :
673 : /// @brief return the index of the link to the next crossing if this is walkingArea, else -1
674 : int getCrossingIndex() const;
675 :
676 :
677 : /// @name Vehicle movement (longitudinal)
678 : /// @{
679 :
680 : /** @brief Compute safe velocities for all vehicles based on positions and
681 : * speeds from the last time step. Also registers
682 : * ApproachingVehicleInformation for all links
683 : *
684 : * This method goes through all vehicles calling their "planMove" method.
685 : * @see MSVehicle::planMove
686 : */
687 : virtual void planMovements(const SUMOTime t);
688 :
689 : /** @brief Register junction approaches for all vehicles after velocities
690 : * have been planned.
691 : *
692 : * This method goes through all vehicles calling their * "setApproachingForAllLinks" method.
693 : */
694 : virtual void setJunctionApproaches() const;
695 :
696 : /** @brief This updates the MSLeaderInfo argument with respect to the given MSVehicle.
697 : * All leader-vehicles on the same edge, which are relevant for the vehicle
698 : * (i.e. with position > vehicle's position) and not already integrated into
699 : * the LeaderInfo, are integrated.
700 : * The given iterators vehPart and vehRes give access to these vehicles which are
701 : * either partial occupators or have issued a maneuver reservation for the lane
702 : * (the latter occurs only for the sublane model).
703 : */
704 : void updateLeaderInfo(const MSVehicle* veh, VehCont::reverse_iterator& vehPart, VehCont::reverse_iterator& vehRes, MSLeaderInfo& ahead) const;
705 :
706 : /** @brief Executes planned vehicle movements with regards to right-of-way
707 : *
708 : * This method goes through all vehicles calling their executeMove method
709 : * which causes vehicles to update their positions and speeds.
710 : * Vehicles wich move to the next lane are stored in the targets lane buffer
711 : *
712 : * @return Returns true, if all vehicles left the lane.
713 : *
714 : * @see MSVehicle::executeMove
715 : */
716 : virtual void executeMovements(const SUMOTime t);
717 :
718 : /// Insert buffered vehicle into the real lane.
719 : virtual void integrateNewVehicles();
720 :
721 : /** @brief Set a flag to recalculate the brutto (including minGaps) occupancy of this lane (used if mingap is changed)
722 : */
723 : void markRecalculateBruttoSum();
724 :
725 : /// @brief updated current vehicle length sum (delayed to avoid lane-order-dependency)
726 : void updateLengthSum();
727 : ///@}
728 :
729 :
730 : /// @brief short-circut collision check if nothing changed since the last check
731 : inline bool needsCollisionCheck() const {
732 380296307 : return myNeedsCollisionCheck;
733 : }
734 :
735 : /// @brief require another collision check due to relevant changes in the simulation
736 : inline void requireCollisionCheck() {
737 4715366 : myNeedsCollisionCheck = true;
738 1029278 : }
739 :
740 : /// Check if vehicles are too close.
741 : virtual void detectCollisions(SUMOTime timestep, const std::string& stage);
742 :
743 :
744 : /** Returns the information whether this lane may be used to continue
745 : the current route */
746 : virtual bool appropriate(const MSVehicle* veh) const;
747 :
748 :
749 : /// returns the container with all links !!!
750 : const std::vector<MSLink*>& getLinkCont() const {
751 1730 : return myLinks;
752 : }
753 :
754 : /// returns the link to the given lane or nullptr, if it is not connected
755 : const MSLink* getLinkTo(const MSLane* const) const;
756 :
757 : /// returns the internal lane leading to the given lane or nullptr, if there is none
758 : const MSLane* getInternalFollowingLane(const MSLane* const) const;
759 :
760 : /// Returns the entry link if this is an internal lane, else nullptr
761 : const MSLink* getEntryLink() const;
762 :
763 :
764 : /// Returns true if there is not a single vehicle on the lane.
765 : bool empty() const {
766 : assert(myVehBuffer.size() == 0);
767 : return myVehicles.empty();
768 : }
769 :
770 : /** @brief Sets a new maximum speed for the lane (used by TraCI, MSLaneSpeedTrigger (VSS) and MSCalibrator)
771 : * @param[in] val the new speed in m/s
772 : * @param[in] modified whether this modifies the original speed
773 : * @param[in] jamThreshold also set a new jamThreshold
774 : */
775 : void setMaxSpeed(const double val, const bool modified = true, const double jamThreshold = -1);
776 :
777 : /** @brief Sets a new friction coefficient for the lane [*to be later (used by TraCI and MSCalibrator)*]
778 : * @param[in] val the new friction coefficient [0..1]
779 : */
780 : void setFrictionCoefficient(double val);
781 :
782 : /** @brief Sets a new length for the lane (used by TraCI only)
783 : * @param[in] val the new length in m
784 : */
785 : void setLength(double val);
786 :
787 : /** @brief Returns the lane's edge
788 : * @return This lane's edge
789 : */
790 : MSEdge& getEdge() const {
791 51769339513 : return *myEdge;
792 : }
793 :
794 : const MSJunction* getFromJunction() const;
795 : const MSJunction* getToJunction() const;
796 :
797 : /** @brief Returns the lane's follower if it is an internal lane, the edge of the lane otherwise
798 : * @return This lane's follower
799 : */
800 : const MSEdge* getNextNormal() const;
801 :
802 :
803 : /** @brief Returns 0 if the lane is not internal. Otherwise the first part of the
804 : * connection (sequence of internal lanes along junction) corresponding to the lane
805 : * is returned and the offset is set to the distance of the begin of this lane
806 : * to the begin of the returned.
807 : */
808 : const MSLane* getFirstInternalInConnection(double& offset) const;
809 :
810 :
811 : /// @brief Static (sic!) container methods
812 : /// {
813 :
814 : /** @brief Inserts a MSLane into the static dictionary
815 : *
816 : * Returns true if the key id isn't already in the dictionary.
817 : * Otherwise returns false.
818 : * @param[in] id The id of the lane
819 : * @param[in] lane The lane itself
820 : * @return Whether the lane was added
821 : * @todo make non-static
822 : * @todo why is the id given? The lane is named
823 : */
824 : static bool dictionary(const std::string& id, MSLane* lane);
825 :
826 :
827 : /** @brief Returns the MSLane associated to the key id
828 : *
829 : * The lane is returned if exists, otherwise 0 is returned.
830 : * @param[in] id The id of the lane
831 : * @return The lane
832 : */
833 : static MSLane* dictionary(const std::string& id);
834 :
835 :
836 : /** @brief Clears the dictionary */
837 : static void clear();
838 :
839 :
840 : /** @brief Returns the number of stored lanes
841 : * @return The number of stored lanes
842 : */
843 : static int dictSize() {
844 42422 : return (int)myDict.size();
845 : }
846 :
847 :
848 : /** @brief Adds the ids of all stored lanes into the given vector
849 : * @param[in, filled] into The vector to add the IDs into
850 : */
851 : static void insertIDs(std::vector<std::string>& into);
852 :
853 :
854 : /** @brief Fills the given RTree with lane instances
855 : * @param[in, filled] into The RTree to fill
856 : * @see TraCILaneRTree
857 : */
858 : template<class RTREE>
859 : static void fill(RTREE& into);
860 :
861 :
862 : /// @brief initialize rngs
863 : static void initRNGs(const OptionsCont& oc);
864 : /// @}
865 :
866 :
867 :
868 : // XXX: succLink does not exist... Documentation?
869 : /** Same as succLink, but does not throw any assertions when
870 : the succeeding link could not be found;
871 : Returns the myLinks.end() instead; Further, the number of edges to
872 : look forward may be given */
873 : static std::vector<MSLink*>::const_iterator succLinkSec(const SUMOVehicle& veh,
874 : int nRouteSuccs,
875 : const MSLane& succLinkSource,
876 : const std::vector<MSLane*>& conts);
877 :
878 :
879 : /** Returns the information whether the given link shows at the end
880 : of the list of links (is not valid) */
881 : inline bool isLinkEnd(std::vector<MSLink*>::const_iterator& i) const {
882 : return i == myLinks.end();
883 : }
884 :
885 : /** Returns the information whether the given link shows at the end
886 : of the list of links (is not valid) */
887 : inline bool isLinkEnd(std::vector<MSLink*>::iterator& i) {
888 : return i == myLinks.end();
889 : }
890 :
891 : /** Returns the information whether the lane is has no vehicle and no
892 : partial occupation*/
893 : inline bool isEmpty() const {
894 229944 : return myVehicles.empty() && myPartialVehicles.empty();
895 : }
896 :
897 : /** Returns whether the lane pertains to an internal edge*/
898 : bool isInternal() const;
899 :
900 : /** Returns whether the lane pertains to a normal edge*/
901 : bool isNormal() const;
902 :
903 : /** Returns whether the lane pertains to a crossing edge*/
904 : bool isCrossing() const;
905 :
906 : /** Returns whether the lane pertains to a crossing edge*/
907 : bool isPriorityCrossing() const;
908 :
909 : /** Returns whether the lane pertains to a walkingarea*/
910 : bool isWalkingArea() const;
911 :
912 : /// @brief returns the last vehicle for which this lane is responsible or 0
913 : MSVehicle* getLastFullVehicle() const;
914 :
915 : /// @brief returns the first vehicle for which this lane is responsible or 0
916 : MSVehicle* getFirstFullVehicle() const;
917 :
918 : /// @brief returns the last vehicle that is fully or partially on this lane
919 : MSVehicle* getLastAnyVehicle() const;
920 :
921 : /// @brief returns the first vehicle that is fully or partially on this lane
922 : MSVehicle* getFirstAnyVehicle() const;
923 :
924 : /* @brief remove the vehicle from this lane
925 : * @param[notify] whether moveReminders of the vehicle shall be triggered
926 : */
927 : virtual MSVehicle* removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify = true);
928 :
929 : void leftByLaneChange(MSVehicle* v);
930 : void enteredByLaneChange(MSVehicle* v);
931 :
932 : /** @brief Returns the lane with the given offset parallel to this one or 0 if it does not exist
933 : * @param[in] offset The offset of the result lane
934 : */
935 : MSLane* getParallelLane(int offset, bool includeOpposite = true) const;
936 :
937 :
938 : /** @brief Sets the permissions to the given value. If a transientID is given, the permissions are recored as temporary
939 : * @param[in] permissions The new permissions
940 : * @param[in] transientID The id of the permission-modification or the special value PERMANENT
941 : */
942 : void setPermissions(SVCPermissions permissions, long long transientID);
943 : void resetPermissions(long long transientID);
944 : bool hadPermissionChanges() const;
945 :
946 : /** @brief Sets the permissions for changing to the left neighbour lane
947 : * @param[in] permissions The new permissions
948 : */
949 : void setChangeLeft(SVCPermissions permissions);
950 :
951 : /** @brief Sets the permissions for changing to the right neighbour lane
952 : * @param[in] permissions The new permissions
953 : */
954 : void setChangeRight(SVCPermissions permissions);
955 :
956 : inline bool allowsVehicleClass(SUMOVehicleClass vclass) const {
957 4592971504 : return (myPermissions & vclass) == vclass;
958 : }
959 :
960 : bool allowsVehicleClass(SUMOVehicleClass vclass, int routingMode) const;
961 :
962 : /** @brief Returns whether the given vehicle class may change left from this lane */
963 : inline bool allowsChangingLeft(SUMOVehicleClass vclass) const {
964 298597416 : return (myChangeLeft & vclass) == vclass;
965 : }
966 :
967 : /** @brief Returns whether the given vehicle class may change left from this lane */
968 : inline bool allowsChangingRight(SUMOVehicleClass vclass) const {
969 270791919 : return (myChangeRight & vclass) == vclass;
970 : }
971 :
972 : void addIncomingLane(MSLane* lane, MSLink* viaLink);
973 :
974 :
975 : struct IncomingLaneInfo {
976 : MSLane* lane;
977 : double length;
978 : MSLink* viaLink;
979 : };
980 :
981 : const std::vector<IncomingLaneInfo>& getIncomingLanes() const {
982 1460693 : return myIncomingLanes;
983 : }
984 :
985 :
986 : void addApproachingLane(MSLane* lane, bool warnMultiCon);
987 : inline bool isApproachedFrom(MSEdge* const edge) {
988 : return myApproachingLanes.find(edge) != myApproachingLanes.end();
989 : }
990 : bool isApproachedFrom(MSLane* const lane, SUMOVehicleClass svc);
991 :
992 : /// @brief Returns vehicle class specific stopOffset for the vehicle
993 : double getVehicleStopOffset(const MSVehicle* veh) const;
994 :
995 : /// @brief Returns vehicle class specific stopOffsets
996 : const StopOffset& getLaneStopOffsets() const;
997 :
998 : /// @brief Set vehicle class specific stopOffsets
999 : void setLaneStopOffset(const StopOffset& stopOffset);
1000 :
1001 : /** @enum MinorLinkMode
1002 : * @brief determine whether/how getFollowers looks upstream beyond minor links
1003 : */
1004 : enum MinorLinkMode {
1005 : FOLLOW_NEVER = 0,
1006 : FOLLOW_ALWAYS = 1,
1007 : FOLLOW_ONCOMING = 2,
1008 : };
1009 :
1010 : /// @brief return the sublane followers with the largest missing rear gap among all predecessor lanes (within dist)
1011 : MSLeaderDistanceInfo getFollowersOnConsecutive(const MSVehicle* ego, double backOffset,
1012 : bool allSublanes, double searchDist = -1, MinorLinkMode mLinkMode = FOLLOW_ALWAYS, bool maxSearchDist = false) const;
1013 :
1014 : /// @brief return by how much further the leader must be inserted to avoid rear end collisions
1015 : double getMissingRearGap(const MSVehicle* leader, double backOffset, double leaderSpeed) const;
1016 :
1017 : /** @brief Returns the immediate leader of veh and the distance to veh
1018 : * starting on this lane
1019 : *
1020 : * Iterates over the current lane to find a leader and then uses
1021 : * getLeaderOnConsecutive()
1022 : * @param[in] veh The vehicle for which the information shall be computed
1023 : * @param[in] vehPos The vehicle position relative to this lane (may be negative)
1024 : * @param[in] bestLaneConts The succeding lanes that shall be checked (if any)
1025 : * @param[in] dist Optional distance to override default (ego stopDist)
1026 : * @param[in] checkTmpVehicles Whether myTmpVehicles should be used instead of myVehicles
1027 : * @return
1028 : */
1029 : std::pair<MSVehicle* const, double> getLeader(const MSVehicle* veh, const double vehPos, const std::vector<MSLane*>& bestLaneConts, double dist = -1, bool checkTmpVehicles = false) const;
1030 :
1031 : /** @brief Returns the immediate leader and the distance to him
1032 : *
1033 : * Goes along the vehicle's estimated used lanes (bestLaneConts). For each link,
1034 : * it is determined whether the vehicle will pass it. If so, the subsequent lane
1035 : * is investigated. If a vehicle (leader) is found, it is returned, together with the length
1036 : * of the investigated lanes until this vehicle's end, including the already seen
1037 : * place (seen).
1038 : *
1039 : * If no leading vehicle was found, <0, -1> is returned.
1040 : *
1041 : * Pretty slow, as it has to go along lanes.
1042 : *
1043 : * @todo: There are some oddities:
1044 : * - what about crossing a link at red, or if a link is closed? Has a following vehicle to be regarded or not?
1045 : *
1046 : * @param[in] dist The distance to investigate
1047 : * @param[in] seen The already seen place (normally the place in front on own lane)
1048 : * @param[in] speed The speed of the vehicle used for determining whether a subsequent link will be opened at arrival time
1049 : * @param[in] veh The vehicle for which the information shall be computed
1050 : * @param[in] bestLaneConts The lanes the vehicle will use in future
1051 : * @param[in] considerCrossingFoes Whether vehicles on crossing foe links should be considered
1052 : * @return
1053 : */
1054 : std::pair<MSVehicle* const, double> getLeaderOnConsecutive(double dist, double seen,
1055 : double speed, const MSVehicle& veh, const std::vector<MSLane*>& bestLaneConts, bool considerCrossingFoes = true) const;
1056 :
1057 : /// @brief Returns the immediate leaders and the distance to them (as getLeaderOnConsecutive but for the sublane case)
1058 : void getLeadersOnConsecutive(double dist, double seen, double speed, const MSVehicle* ego,
1059 : const std::vector<MSLane*>& bestLaneConts, MSLeaderDistanceInfo& result, bool oppositeDirection = false) const;
1060 :
1061 :
1062 : /// @brief get leaders for ego on the given lane
1063 : void addLeaders(const MSVehicle* vehicle, double vehPos, MSLeaderDistanceInfo& result, bool oppositeDirection = false);
1064 :
1065 :
1066 : /** @brief Returns the most dangerous leader and the distance to him
1067 : *
1068 : * Goes along the vehicle's estimated used lanes (bestLaneConts). For each link,
1069 : * it is determined whether the ego vehicle will pass it. If so, the subsequent lane
1070 : * is investigated. Check all lanes up to the stopping distance of ego.
1071 : * Return the leader vehicle (and the gap) which puts the biggest speed constraint on ego.
1072 : *
1073 : * If no leading vehicle was found, <0, -1> is returned.
1074 : *
1075 : * Pretty slow, as it has to go along lanes.
1076 : *
1077 : * @param[in] dist The distance to investigate
1078 : * @param[in] seen The already seen place (normally the place in front on own lane)
1079 : * @param[in] speed The speed of the vehicle used for determining whether a subsequent link will be opened at arrival time
1080 : * @param[in] veh The (ego) vehicle for which the information shall be computed
1081 : * @return
1082 : */
1083 : std::pair<MSVehicle* const, double> getCriticalLeader(double dist, double seen, double speed, const MSVehicle& veh) const;
1084 :
1085 : /* @brief return the partial vehicle closest behind ego or 0
1086 : * if no such vehicle exists */
1087 : MSVehicle* getPartialBehind(const MSVehicle* ego) const;
1088 :
1089 : /// @brief get all vehicles that are inlapping from consecutive edges
1090 : MSLeaderInfo getPartialBeyond() const;
1091 :
1092 : /// @brief Returns all vehicles closer than downstreamDist along the road network starting on the given
1093 : /// position. Predecessor lanes are searched upstream for the given upstreamDistance.
1094 : /// @note Re-implementation of the corresponding method in MSDevice_SSM, which cannot be easily adapted, as it gathers
1095 : /// additional information for conflict lanes, etc.
1096 : /// @param[in] startPos - start position of the search on the first lane
1097 : /// @param[in] downstreamDist - distance to search downstream
1098 : /// @param[in] upstreamDist - distance to search upstream
1099 : /// @param[in/out] checkedLanes - lanes, which were already scanned (current lane is added, if not present,
1100 : /// otherwise the scan is aborted; TODO: this may disregard unscanned parts of the lane in specific circular set ups.)
1101 : /// @return vehs - List of vehicles found
1102 : std::set<MSVehicle*> getSurroundingVehicles(double startPos, double downstreamDist, double upstreamDist, std::shared_ptr<LaneCoverageInfo> checkedLanes) const;
1103 :
1104 : /// @brief Returns all vehicles on the lane overlapping with the interval [a,b]
1105 : /// @note Does not consider vehs with front on subsequent lanes
1106 : std::set<MSVehicle*> getVehiclesInRange(const double a, const double b) const;
1107 :
1108 : /// @brief Returns all upcoming junctions within given range along the given (non-internal) continuation lanes measured from given position
1109 : std::vector<const MSJunction*> getUpcomingJunctions(double pos, double range, const std::vector<MSLane*>& contLanes) const;
1110 :
1111 : /// @brief Returns all upcoming links within given range along the given (non-internal) continuation lanes measured from given position
1112 : std::vector<const MSLink*> getUpcomingLinks(double pos, double range, const std::vector<MSLane*>& contLanes) const;
1113 :
1114 : /** @brief get the most likely precedecessor lane (sorted using by_connections_to_sorter).
1115 : * The result is cached in myLogicalPredecessorLane
1116 : */
1117 : MSLane* getLogicalPredecessorLane() const;
1118 :
1119 : /** @brief get normal lane leading to this internal lane, for normal lanes,
1120 : * the lane itself is returned
1121 : */
1122 : const MSLane* getNormalPredecessorLane() const;
1123 :
1124 : /** @brief get normal lane following this internal lane, for normal lanes,
1125 : * the lane itself is returned
1126 : */
1127 : const MSLane* getNormalSuccessorLane() const;
1128 :
1129 : /** @brief return the (first) predecessor lane from the given edge
1130 : */
1131 : MSLane* getLogicalPredecessorLane(const MSEdge& fromEdge) const;
1132 :
1133 :
1134 : /** Return the main predecessor lane for the current.
1135 : * If there are several incoming lanes, the first attempt is to return the priorized.
1136 : * If this does not yield an unambiguous lane, the one with the least angle difference
1137 : * to the current is selected.
1138 : */
1139 : MSLane* getCanonicalPredecessorLane() const;
1140 :
1141 :
1142 : /** Return the main successor lane for the current.
1143 : * If there are several outgoing lanes, the first attempt is to return the priorized.
1144 : * If this does not yield an unambiguous lane, the one with the least angle difference
1145 : * to the current is selected.
1146 : */
1147 : MSLane* getCanonicalSuccessorLane() const;
1148 :
1149 : /// @brief get the state of the link from the logical predecessor to this lane
1150 : LinkState getIncomingLinkState() const;
1151 :
1152 : /// @brief get the list of outgoing lanes
1153 : const std::vector<std::pair<const MSLane*, const MSEdge*> > getOutgoingViaLanes() const;
1154 :
1155 : /// @brief get the list of all direct (disregarding internal predecessors) non-internal predecessor lanes of this lane
1156 : std::vector<const MSLane*> getNormalIncomingLanes() const;
1157 :
1158 : /// @name Current state retrieval
1159 : //@{
1160 :
1161 : /** @brief Returns the mean speed on this lane
1162 : * @return The average speed of vehicles during the last step; default speed if no vehicle was on this lane
1163 : */
1164 : double getMeanSpeed() const;
1165 :
1166 : /// @brief get the mean speed of all bicycles on this lane
1167 : double getMeanSpeedBike() const;
1168 :
1169 : /** @brief Returns the overall waiting time on this lane
1170 : * @return The sum of the waiting time of all vehicles during the last step;
1171 : */
1172 : double getWaitingSeconds() const;
1173 :
1174 :
1175 : /** @brief Returns the brutto (including minGaps) occupancy of this lane during the last step
1176 : * @return The occupancy during the last step
1177 : */
1178 : double getBruttoOccupancy() const;
1179 :
1180 :
1181 : /** @brief Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)
1182 : * @return The occupancy during the last step
1183 : */
1184 : double getNettoOccupancy() const;
1185 :
1186 :
1187 : /** @brief Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the last step
1188 : * @return The sum of vehicle lengths of vehicles in the last step
1189 : */
1190 : inline double getBruttoVehLenSum() const {
1191 4468217266 : return myBruttoVehicleLengthSum;
1192 : }
1193 :
1194 :
1195 : /** @brief Returns the sum of last step emissions
1196 : * The value is always per 1s, so multiply by step length if necessary.
1197 : * @return emissions of vehicles on this lane during the last step
1198 : */
1199 : template<PollutantsInterface::EmissionType ET>
1200 397053 : double getEmissions() const {
1201 : double ret = 0;
1202 402061 : for (MSVehicle* const v : getVehiclesSecure()) {
1203 5008 : ret += v->getEmissions<ET>();
1204 : }
1205 397053 : releaseVehicles();
1206 397053 : return ret;
1207 : }
1208 :
1209 :
1210 : /** @brief Returns the sum of last step noise emissions
1211 : * @return noise emissions of vehicles on this lane during the last step
1212 : */
1213 : double getHarmonoise_NoiseEmissions() const;
1214 : /// @}
1215 :
1216 : void setRightSideOnEdge(double value, int rightmostSublane) {
1217 2153915 : myRightSideOnEdge = value;
1218 2153915 : myRightmostSublane = rightmostSublane;
1219 : }
1220 :
1221 : /// @brief initialized vClass-specific speed limits
1222 : void initRestrictions();
1223 :
1224 : void checkBufferType();
1225 :
1226 : double getRightSideOnEdge() const {
1227 5242434079 : return myRightSideOnEdge;
1228 : }
1229 :
1230 : int getRightmostSublane() const {
1231 102879505 : return myRightmostSublane;
1232 : }
1233 :
1234 : double getCenterOnEdge() const {
1235 26403 : return myRightSideOnEdge + 0.5 * myWidth;
1236 : }
1237 :
1238 : /// @brief sorts myPartialVehicles
1239 : void sortPartialVehicles();
1240 :
1241 : /// @brief sorts myManeuverReservations
1242 : void sortManeuverReservations();
1243 :
1244 : /// @brief return the neighboring opposite direction lane for lane changing or nullptr
1245 : MSLane* getOpposite() const;
1246 :
1247 : /// @brief return the opposite direction lane of this lanes edge or nullptr
1248 : MSLane* getParallelOpposite() const;
1249 :
1250 : /// @brief return the corresponding position on the opposite lane
1251 : double getOppositePos(double pos) const;
1252 :
1253 : /* @brief find leader for a vehicle depending on the relative driving direction
1254 : * @param[in] ego The ego vehicle
1255 : * @param[in] dist The look-ahead distance when looking at consecutive lanes
1256 : * @param[in] oppositeDir Whether the lane has the opposite driving direction of ego
1257 : * @return the leader vehicle and its gap to ego
1258 : */
1259 : std::pair<MSVehicle* const, double> getOppositeLeader(const MSVehicle* ego, double dist, bool oppositeDir, MinorLinkMode mLinkMode = MinorLinkMode::FOLLOW_NEVER) const;
1260 :
1261 : /* @brief find follower for a vehicle that is located on the opposite of this lane
1262 : * @param[in] ego The ego vehicle
1263 : * @return the follower vehicle and its gap to ego
1264 : */
1265 : std::pair<MSVehicle* const, double> getOppositeFollower(const MSVehicle* ego) const;
1266 :
1267 :
1268 : /** @brief Find follower vehicle for the given ego vehicle (which may be on the opposite direction lane)
1269 : * @param[in] ego The ego vehicle
1270 : * @param[in] egoPos The ego position mapped to the current lane
1271 : * @param[in] dist The look-back distance when looking at consecutive lanes
1272 : * @param[in] ignoreMinorLinks Whether backward search should stop at minor links
1273 : * @return the follower vehicle and its gap to ego
1274 : */
1275 : std::pair<MSVehicle* const, double> getFollower(const MSVehicle* ego, double egoPos, double dist, MinorLinkMode mLinkMode, bool maxSearchDist = false) const;
1276 :
1277 :
1278 : ///@brief add parking vehicle. This should only used during state loading
1279 : void addParking(MSBaseVehicle* veh);
1280 :
1281 : ///@brief remove parking vehicle. This must be syncrhonized when running with GUI
1282 : virtual void removeParking(MSBaseVehicle* veh);
1283 :
1284 : /// @brief retrieve the parking vehicles (see GUIParkingArea)
1285 : const std::set<const MSBaseVehicle*>& getParkingVehicles() const {
1286 : return myParkingVehicles;
1287 : }
1288 :
1289 : /// @brief whether this lane is selected in the GUI
1290 1091441 : virtual bool isSelected() const {
1291 1091441 : return false;
1292 : }
1293 :
1294 : /// @brief retrieve bidirectional lane or nullptr
1295 : MSLane* getBidiLane() const;
1296 :
1297 : /// @brief whether this lane must check for junction collisions
1298 : bool mustCheckJunctionCollisions() const;
1299 :
1300 : #ifdef HAVE_FOX
1301 : MFXWorkerThread::Task* getPlanMoveTask(const SUMOTime time) {
1302 : mySimulationTask.init(&MSLane::planMovements, time);
1303 15918434 : return &mySimulationTask;
1304 : }
1305 :
1306 : MFXWorkerThread::Task* getExecuteMoveTask(const SUMOTime time) {
1307 : mySimulationTask.init(&MSLane::executeMovements, time);
1308 15918434 : return &mySimulationTask;
1309 : }
1310 :
1311 : MFXWorkerThread::Task* getLaneChangeTask(const SUMOTime time) {
1312 : mySimulationTask.init(&MSLane::changeLanes, time);
1313 : return &mySimulationTask;
1314 : }
1315 : #endif
1316 :
1317 : std::vector<StopWatch<std::chrono::nanoseconds> >& getStopWatch() {
1318 : return myStopWatch;
1319 : }
1320 :
1321 : void changeLanes(const SUMOTime time);
1322 :
1323 : /// @name State saving/loading
1324 : /// @{
1325 :
1326 : /** @brief Saves the state of this lane into the given stream
1327 : *
1328 : * Basically, a list of vehicle ids
1329 : *
1330 : * @param[in, filled] out The (possibly binary) device to write the state into
1331 : * @todo What about throwing an IOError?
1332 : */
1333 : void saveState(OutputDevice& out);
1334 :
1335 : /** @brief Remove all vehicles before quick-loading state */
1336 : void clearState();
1337 :
1338 : /** @brief Loads the state of this segment with the given parameters
1339 : *
1340 : * This method is called for every internal que the segment has.
1341 : * Every vehicle is retrieved from the given MSVehicleControl and added to this
1342 : * lane.
1343 : *
1344 : * @param[in] vehs The vehicles for the current lane
1345 : * @todo What about throwing an IOError?
1346 : * @todo What about throwing an error if something else fails (a vehicle can not be referenced)?
1347 : */
1348 : void loadState(const std::vector<SUMOVehicle*>& vehs);
1349 :
1350 :
1351 : /* @brief helper function for state saving: checks whether any outgoing
1352 : * links are being approached */
1353 : bool hasApproaching() const;
1354 :
1355 : /// @}
1356 :
1357 :
1358 : /** @brief Callback for visiting the lane when traversing an RTree
1359 : *
1360 : * This is used in the TraCIServerAPI_Lane for context subscriptions.
1361 : *
1362 : * @param[in] cont The context doing all the work
1363 : * @see libsumo::Helper::LaneStoringVisitor::add
1364 : */
1365 172976833 : void visit(const MSLane::StoringVisitor& cont) const {
1366 172976833 : cont.add(this);
1367 172976833 : }
1368 :
1369 : /// @brief whether the lane has pedestrians on it
1370 : bool hasPedestrians() const;
1371 :
1372 : /// This is just a wrapper around MSPModel::nextBlocking. You should always check using hasPedestrians before calling this method.
1373 : std::pair<const MSPerson*, double> nextBlocking(double minPos, double minRight, double maxLeft, double stopTime = 0, bool bidi = false) const;
1374 :
1375 : /// @brief return the empty space up to the last standing vehicle or the empty space on the whole lane if no vehicle is standing
1376 : double getSpaceTillLastStanding(const MSVehicle* ego, bool& foundStopped) const;
1377 :
1378 : /// @brief compute maximum braking distance on this lane
1379 : double getMaximumBrakeDist() const;
1380 :
1381 : inline const PositionVector* getOutlineShape() const {
1382 : return myOutlineShape;
1383 : }
1384 :
1385 : static void initCollisionOptions(const OptionsCont& oc);
1386 : static void initCollisionAction(const OptionsCont& oc, const std::string& option, CollisionAction& myAction);
1387 :
1388 : static CollisionAction getCollisionAction() {
1389 6436 : return myCollisionAction;
1390 : }
1391 :
1392 : static CollisionAction getIntermodalCollisionAction() {
1393 : return myIntermodalCollisionAction;
1394 : }
1395 :
1396 : static DepartSpeedDefinition& getDefaultDepartSpeedDefinition() {
1397 : return myDefaultDepartSpeedDefinition;
1398 : }
1399 :
1400 : static double& getDefaultDepartSpeed() {
1401 : return myDefaultDepartSpeed;
1402 : }
1403 :
1404 :
1405 : static const long CHANGE_PERMISSIONS_PERMANENT = 0;
1406 : static const long CHANGE_PERMISSIONS_GUI = 1;
1407 :
1408 : protected:
1409 : /// moves myTmpVehicles int myVehicles after a lane change procedure
1410 : virtual void swapAfterLaneChange(SUMOTime t);
1411 :
1412 : /** @brief Inserts the vehicle into this lane, and informs it about entering the network
1413 : *
1414 : * Calls the vehicles enterLaneAtInsertion function,
1415 : * updates statistics and modifies the active state as needed
1416 : * @param[in] veh The vehicle to be incorporated
1417 : * @param[in] pos The position of the vehicle
1418 : * @param[in] speed The speed of the vehicle
1419 : * @param[in] posLat The lateral position of the vehicle
1420 : * @param[in] at
1421 : * @param[in] notification The cause of insertion (i.e. departure, teleport, parking) defaults to departure
1422 : */
1423 : virtual void incorporateVehicle(MSVehicle* veh, double pos, double speed, double posLat,
1424 : const MSLane::VehCont::iterator& at,
1425 : MSMoveReminder::Notification notification = MSMoveReminder::NOTIFICATION_DEPARTED);
1426 :
1427 : /// @brief detect whether a vehicle collids with pedestrians on the junction
1428 : void detectPedestrianJunctionCollision(const MSVehicle* collider, const PositionVector& colliderBoundary, const MSLane* foeLane,
1429 : SUMOTime timestep, const std::string& stage,
1430 : std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove,
1431 : std::set<const MSVehicle*, ComparatorNumericalIdLess>& toTeleport);
1432 :
1433 : /// @brief detect whether there is a collision between the two vehicles
1434 : bool detectCollisionBetween(SUMOTime timestep, const std::string& stage, MSVehicle* collider, MSVehicle* victim,
1435 : std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove,
1436 : std::set<const MSVehicle*, ComparatorNumericalIdLess>& toTeleport) const;
1437 :
1438 : /// @brief take action upon collision
1439 : void handleCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSVehicle* victim,
1440 : double gap, double latGap,
1441 : std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove,
1442 : std::set<const MSVehicle*, ComparatorNumericalIdLess>& toTeleport) const;
1443 :
1444 : void handleIntermodalCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSTransportable* victim,
1445 : double gap, const std::string& collisionType,
1446 : std::set<const MSVehicle*, ComparatorNumericalIdLess>& toRemove,
1447 : std::set<const MSVehicle*, ComparatorNumericalIdLess>& toTeleport) const;
1448 :
1449 : /* @brief determine depart speed and whether it may be patched
1450 : * @param[in] veh The departing vehicle
1451 : * @param[out] whether the speed may be patched to account for safety
1452 : * @return the depart speed
1453 : */
1454 : double getDepartSpeed(const MSVehicle& veh, bool& patchSpeed);
1455 :
1456 : /* @brief determine the lateral depart position
1457 : * @param[in] veh The departing vehicle
1458 : * @return the lateral depart position
1459 : */
1460 : double getDepartPosLat(const MSVehicle& veh);
1461 :
1462 : /** @brief return the maximum safe speed for insertion behind leaders
1463 : * (a negative value indicates that safe insertion is impossible) */
1464 : double safeInsertionSpeed(const MSVehicle* veh, double seen, const MSLeaderInfo& leaders, double speed);
1465 :
1466 : /// @brief check whether pedestrians on this lane interfere with vehicle insertion
1467 : bool checkForPedestrians(const MSVehicle* aVehicle, double& speed, double& dist, double pos, bool patchSpeed) const;
1468 :
1469 : /// @brief check whether any of the outgoing links are being approached
1470 : bool hasApproaching(const std::vector<MSLink*>& links) const;
1471 :
1472 : /// @brief return length of fractional vehicles on this lane
1473 : double getFractionalVehicleLength(bool brutto) const;
1474 :
1475 : /// @brief whether the route of the give vehicle might be extended on insertion
1476 : bool mayContinue(const MSVehicle* veh) const;
1477 :
1478 : /// @brief whether any link from this lane is unsafe
1479 : bool hasUnsafeLink() const;
1480 :
1481 : /// @brief detect frontal collisions
1482 : static bool isFrontalCollision(const MSVehicle* collider, const MSVehicle* victim);
1483 :
1484 : /// Unique numerical ID (set on reading by netload)
1485 : int myNumericalID;
1486 :
1487 : /// The shape of the lane
1488 : PositionVector myShape;
1489 :
1490 : /// @brief the outline of the lane (optional)
1491 : PositionVector* myOutlineShape = nullptr;
1492 :
1493 : /// The lane index
1494 : int myIndex;
1495 :
1496 : /** @brief The lane's vehicles.
1497 : This container holds all vehicles that have their front (longitudinally)
1498 : and their center (laterally) on this lane.
1499 : These are the vehicles that this lane is 'responsibly' for (i.e. when executing movements)
1500 :
1501 : The entering vehicles are inserted at the front
1502 : of this container and the leaving ones leave from the back, e.g. the
1503 : vehicle in front of the junction (often called first) is
1504 : myVehicles.back() (if it exists). And if it is an iterator at a
1505 : vehicle, ++it points to the vehicle in front. This is the interaction
1506 : vehicle. */
1507 : VehCont myVehicles;
1508 :
1509 : /** @brief The lane's partial vehicles.
1510 : This container holds all vehicles that are partially on this lane but which are
1511 : in myVehicles of another lane.
1512 : Reasons for partial occupancies include the following
1513 : - the back is still on this lane during regular movement
1514 : - the vehicle is performing a continuous lane-change maneuver
1515 : - sub-lane simulation where vehicles can freely move laterally among the lanes of an edge
1516 :
1517 : The entering vehicles are inserted at the front
1518 : of this container and the leaving ones leave from the back. */
1519 : VehCont myPartialVehicles;
1520 :
1521 : /** @brief Container for lane-changing vehicles. After completion of lane-change-
1522 : process, the containers will be swapped with myVehicles. */
1523 : VehCont myTmpVehicles;
1524 :
1525 : /** @brief Buffer for vehicles that moved from their previous lane onto this one.
1526 : * Integrated after all vehicles executed their moves*/
1527 : MFXSynchQue<MSVehicle*, std::vector<MSVehicle*> > myVehBuffer;
1528 :
1529 : /** @brief The vehicles which registered maneuvering into the lane within their current action step.
1530 : * This is currently only relevant for sublane simulation, since continuous lanechanging
1531 : * uses the partial vehicle mechanism.
1532 : *
1533 : * The entering vehicles are inserted at the front
1534 : * of this container and the leaving ones leave from the back. */
1535 : VehCont myManeuverReservations;
1536 :
1537 : /* @brief list of vehicles that are parking near this lane
1538 : * (not necessarily on the road but having reached their stop on this lane)
1539 : * */
1540 : std::set<const MSBaseVehicle*> myParkingVehicles;
1541 :
1542 : /// Lane length [m]
1543 : double myLength;
1544 :
1545 : /// Lane width [m]
1546 : const double myWidth;
1547 :
1548 : /// Lane's vClass specific stop offset [m]. The map is either of length 0, which means no
1549 : /// special stopOffset was set, or of length 1, where the key is a bitset representing a subset
1550 : /// of the SUMOVehicleClass Enum and the value is the offset in meters.
1551 : StopOffset myLaneStopOffset;
1552 :
1553 : /// The lane's edge, for routing only.
1554 : MSEdge* const myEdge;
1555 :
1556 : /// Lane-wide speed limit [m/s]
1557 : double myMaxSpeed;
1558 : /// Lane-wide friction coefficient [0..1]
1559 : double myFrictionCoefficient;
1560 :
1561 : /// @brief Whether the current speed limit is set by a variable speed sign (VSS), TraCI or a MSCalibrator
1562 : bool mySpeedModified;
1563 :
1564 : /// The vClass permissions for this lane
1565 : SVCPermissions myPermissions;
1566 :
1567 : /// The vClass permissions for changing from this lane
1568 : SVCPermissions myChangeLeft;
1569 : SVCPermissions myChangeRight;
1570 :
1571 : /// The original vClass permissions for this lane (before temporary modifications)
1572 : SVCPermissions myOriginalPermissions;
1573 :
1574 : /// The vClass speed restrictions for this lane
1575 : const std::map<SUMOVehicleClass, double>* myRestrictions;
1576 :
1577 : /// All direct predecessor lanes
1578 : std::vector<IncomingLaneInfo> myIncomingLanes;
1579 :
1580 : ///
1581 : mutable MSLane* myLogicalPredecessorLane;
1582 :
1583 : /// Similar to LogicalPredecessorLane, @see getCanonicalPredecessorLane()
1584 : mutable MSLane* myCanonicalPredecessorLane;
1585 :
1586 : /// Main successor lane, @see getCanonicalSuccessorLane()
1587 : mutable MSLane* myCanonicalSuccessorLane;
1588 :
1589 : /// @brief The current length of all vehicles on this lane, including their minGaps
1590 : double myBruttoVehicleLengthSum;
1591 :
1592 : /// @brief The current length of all vehicles on this lane, excluding their minGaps
1593 : double myNettoVehicleLengthSum;
1594 :
1595 : /// @brief The length of all vehicles that have left this lane in the current step (this lane, including their minGaps)
1596 : double myBruttoVehicleLengthSumToRemove;
1597 :
1598 : /// @brief The length of all vehicles that have left this lane in the current step (this lane, excluding their minGaps)
1599 : double myNettoVehicleLengthSumToRemove;
1600 :
1601 : /// @brief Flag to recalculate the occupancy (including minGaps) after a change in minGap
1602 : bool myRecalculateBruttoSum;
1603 :
1604 : /** The lane's Links to its succeeding lanes and the default
1605 : right-of-way rule, i.e. blocked or not blocked. */
1606 : std::vector<MSLink*> myLinks;
1607 :
1608 : /// All direct internal and direct (disregarding internal predecessors) non-internal predecessor lanes of this lane
1609 : std::map<MSEdge*, std::vector<MSLane*> > myApproachingLanes;
1610 :
1611 : /// @brief leaders on all sublanes as seen by approaching vehicles (cached)
1612 : mutable MSLeaderInfo myLeaderInfo;
1613 : /// @brief followers on all sublanes as seen by vehicles on consecutive lanes (cached)
1614 : mutable MSLeaderInfo myFollowerInfo;
1615 :
1616 : /// @brief time step for which myLeaderInfo was last updated
1617 : mutable SUMOTime myLeaderInfoTime;
1618 : /// @brief time step for which myFollowerInfo was last updated
1619 : mutable SUMOTime myFollowerInfoTime;
1620 :
1621 : /// @brief precomputed myShape.length / myLength
1622 : const double myLengthGeometryFactor;
1623 :
1624 : /// @brief whether this lane is an acceleration lane
1625 : const bool myIsRampAccel;
1626 :
1627 : /// @brief the type of this lane
1628 : const std::string myLaneType;
1629 :
1630 : /// @brief the combined width of all lanes with lower index on myEdge
1631 : double myRightSideOnEdge;
1632 : /// @brief the index of the rightmost sublane of this lane on myEdge
1633 : int myRightmostSublane;
1634 :
1635 : /// @brief whether a collision check is currently needed
1636 : bool myNeedsCollisionCheck;
1637 :
1638 : // @brief the neighboring opposite direction or nullptr
1639 : MSLane* myOpposite;
1640 :
1641 : // @brief bidi lane or nullptr
1642 : MSLane* myBidiLane;
1643 :
1644 : // @brief transient changes in permissions
1645 : std::map<long long, SVCPermissions> myPermissionChanges;
1646 :
1647 : // @brief index of the associated thread-rng
1648 : int myRNGIndex;
1649 :
1650 : /// definition of the static dictionary type
1651 : typedef std::map< std::string, MSLane* > DictType;
1652 :
1653 : /// Static dictionary to associate string-ids with objects.
1654 : static DictType myDict;
1655 :
1656 : static std::vector<SumoRNG> myRNGs;
1657 :
1658 : private:
1659 : /// @brief This lane's move reminder
1660 : std::vector< MSMoveReminder* > myMoveReminders;
1661 :
1662 : /// @brief the action to take on collisions
1663 : static CollisionAction myCollisionAction;
1664 : static CollisionAction myIntermodalCollisionAction;
1665 : static bool myCheckJunctionCollisions;
1666 : static double myCheckJunctionCollisionMinGap;
1667 : static SUMOTime myCollisionStopTime;
1668 : static SUMOTime myIntermodalCollisionStopTime;
1669 : static double myCollisionMinGapFactor;
1670 : static bool myExtrapolateSubstepDepart;
1671 : static DepartSpeedDefinition myDefaultDepartSpeedDefinition;
1672 : static double myDefaultDepartSpeed;
1673 : /**
1674 : * @class vehicle_position_sorter
1675 : * @brief Sorts vehicles by their position (descending)
1676 : */
1677 : class vehicle_position_sorter {
1678 : public:
1679 : /// @brief Constructor
1680 : explicit vehicle_position_sorter(const MSLane* lane) :
1681 : myLane(lane) {
1682 : }
1683 :
1684 :
1685 : /** @brief Comparing operator
1686 : * @param[in] v1 First vehicle to compare
1687 : * @param[in] v2 Second vehicle to compare
1688 : * @return Whether the first vehicle is further on the lane than the second
1689 : */
1690 : int operator()(MSVehicle* v1, MSVehicle* v2) const;
1691 :
1692 : const MSLane* myLane;
1693 :
1694 : };
1695 :
1696 : /**
1697 : * @class vehicle_reverse_position_sorter
1698 : * @brief Sorts vehicles by their position (ascending)
1699 : */
1700 : class vehicle_natural_position_sorter {
1701 : public:
1702 : /// @brief Constructor
1703 : explicit vehicle_natural_position_sorter(const MSLane* lane) :
1704 : myLane(lane) {
1705 : }
1706 :
1707 :
1708 : /** @brief Comparing operator
1709 : * @param[in] v1 First vehicle to compare
1710 : * @param[in] v2 Second vehicle to compare
1711 : * @return Whether the first vehicle is further on the lane than the second
1712 : */
1713 : int operator()(MSVehicle* v1, MSVehicle* v2) const;
1714 :
1715 : const MSLane* myLane;
1716 :
1717 : };
1718 :
1719 : /** @class by_connections_to_sorter
1720 : * @brief Sorts edges by their angle relative to the given edge (straight comes first)
1721 : *
1722 : */
1723 : class by_connections_to_sorter {
1724 : public:
1725 : /// @brief constructor
1726 : explicit by_connections_to_sorter(const MSEdge* const e);
1727 :
1728 : /// @brief comparing operator
1729 : int operator()(const MSEdge* const e1, const MSEdge* const e2) const;
1730 :
1731 : private:
1732 : const MSEdge* const myEdge;
1733 : double myLaneDir;
1734 : };
1735 :
1736 :
1737 :
1738 : /** @class incoming_lane_priority_sorter
1739 : * @brief Sorts lanes (IncomingLaneInfos) by their priority or, if this doesn't apply,
1740 : * wrt. the angle difference magnitude relative to the target lane's angle (straight comes first)
1741 : */
1742 : class incoming_lane_priority_sorter {
1743 : public:
1744 : /// @brief constructor
1745 : explicit incoming_lane_priority_sorter(const MSLane* targetLane);
1746 :
1747 : /// @brief comparing operator
1748 : int operator()(const IncomingLaneInfo& lane1, const IncomingLaneInfo& lane2) const;
1749 :
1750 : private:
1751 : const MSLane* const myLane;
1752 : double myLaneDir;
1753 : };
1754 :
1755 :
1756 : /** @class outgoing_lane_priority_sorter
1757 : * @brief Sorts lanes (their origin link) by the priority of their noninternal target edges or, if this doesn't yield an unambiguous result,
1758 : * wrt. the angle difference magnitude relative to the target lane's angle (straight comes first)
1759 : */
1760 : class outgoing_lane_priority_sorter {
1761 : public:
1762 : /// @brief constructor
1763 : explicit outgoing_lane_priority_sorter(const MSLane* sourceLane);
1764 :
1765 : /// @brief comparing operator
1766 : int operator()(const MSLink* link1, const MSLink* link2) const;
1767 :
1768 : private:
1769 : double myLaneDir;
1770 : };
1771 :
1772 : /**
1773 : * @class edge_finder
1774 : */
1775 : class edge_finder {
1776 : public:
1777 6527668 : edge_finder(MSEdge* e) : myEdge(e) {}
1778 : bool operator()(const IncomingLaneInfo& ili) const {
1779 2223820 : return &(ili.lane->getEdge()) == myEdge;
1780 : }
1781 : private:
1782 : const MSEdge* const myEdge;
1783 : };
1784 :
1785 : #ifdef HAVE_FOX
1786 : /// Type of the function that is called for the simulation stage (e.g. planMovements).
1787 : typedef void(MSLane::*Operation)(const SUMOTime);
1788 :
1789 : /**
1790 : * @class SimulationTask
1791 : * @brief the routing task which mainly calls reroute of the vehicle
1792 : */
1793 2135643 : class SimulationTask : public MFXWorkerThread::Task {
1794 : public:
1795 : SimulationTask(MSLane& l, const SUMOTime time)
1796 2153995 : : myLane(l), myTime(time) {}
1797 : void init(Operation operation, const SUMOTime time) {
1798 31836868 : myOperation = operation;
1799 31836868 : myTime = time;
1800 : }
1801 31836868 : void run(MFXWorkerThread* /*context*/) {
1802 : try {
1803 31836868 : (myLane.*(myOperation))(myTime);
1804 2423579 : } catch (ProcessError& e) {
1805 2423579 : WRITE_ERROR(e.what());
1806 2423579 : }
1807 31836868 : }
1808 : private:
1809 : Operation myOperation = nullptr;
1810 : MSLane& myLane;
1811 : SUMOTime myTime;
1812 : private:
1813 : /// @brief Invalidated assignment operator.
1814 : SimulationTask& operator=(const SimulationTask&) = delete;
1815 : };
1816 :
1817 : SimulationTask mySimulationTask;
1818 : /// @brief Mutex for access to the cached leader info value
1819 : mutable FXMutex myLeaderInfoMutex;
1820 : /// @brief Mutex for access to the cached follower info value
1821 : mutable FXMutex myFollowerInfoMutex;
1822 : /// @brief Mutex for access to the cached follower info value
1823 : mutable FXMutex myPartialOccupatorMutex;
1824 : #endif
1825 : std::vector<StopWatch<std::chrono::nanoseconds> > myStopWatch;
1826 :
1827 : private:
1828 : /// @brief invalidated copy constructor
1829 : MSLane(const MSLane&) = delete;
1830 :
1831 : /// @brief invalidated assignment operator
1832 : MSLane& operator=(const MSLane&) = delete;
1833 :
1834 :
1835 : };
1836 :
1837 : // specialized implementation for speedup and avoiding warnings
1838 : #define LANE_RTREE_QUAL RTree<MSLane*, MSLane, float, 2, MSLane::StoringVisitor>
1839 :
1840 : template<>
1841 : inline float LANE_RTREE_QUAL::RectSphericalVolume(Rect* a_rect) {
1842 : ASSERT(a_rect);
1843 627489 : const float extent0 = a_rect->m_max[0] - a_rect->m_min[0];
1844 627489 : const float extent1 = a_rect->m_max[1] - a_rect->m_min[1];
1845 447908 : return .78539816f * (extent0 * extent0 + extent1 * extent1);
1846 : }
1847 :
1848 : template<>
1849 : inline LANE_RTREE_QUAL::Rect LANE_RTREE_QUAL::CombineRect(Rect* a_rectA, Rect* a_rectB) {
1850 : ASSERT(a_rectA && a_rectB);
1851 : Rect newRect;
1852 642009 : newRect.m_min[0] = rtree_min(a_rectA->m_min[0], a_rectB->m_min[0]);
1853 642009 : newRect.m_max[0] = rtree_max(a_rectA->m_max[0], a_rectB->m_max[0]);
1854 642009 : newRect.m_min[1] = rtree_min(a_rectA->m_min[1], a_rectB->m_min[1]);
1855 642009 : newRect.m_max[1] = rtree_max(a_rectA->m_max[1], a_rectB->m_max[1]);
1856 : return newRect;
1857 : }
|