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