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