Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/microsim/MSEdge.h
193741 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 MSEdge.h
15
/// @author Christian Roessel
16
/// @author Daniel Krajzewicz
17
/// @author Jakob Erdmann
18
/// @author Sascha Krieg
19
/// @author Michael Behrisch
20
/// @date Mon, 12 Mar 2001
21
///
22
// A road/street connecting two junctions
23
/****************************************************************************/
24
#pragma once
25
#include <config.h>
26
27
#include <vector>
28
#include <map>
29
#include <string>
30
#include <iostream>
31
#ifdef HAVE_FOX
32
#include <utils/foxtools/fxheader.h>
33
#endif
34
#include <utils/common/Named.h>
35
#include <utils/common/Parameterised.h>
36
#include <utils/common/SUMOTime.h>
37
#include <utils/common/SUMOVehicleClass.h>
38
#include <utils/geom/Boundary.h>
39
#include <utils/router/ReversedEdge.h>
40
#include <utils/router/RailEdge.h>
41
#include <utils/vehicle/SUMOVehicle.h>
42
#include <utils/vehicle/SUMOTrafficObject.h>
43
#include "MSNet.h"
44
45
46
// ===========================================================================
47
// class declarations
48
// ===========================================================================
49
class Boundary;
50
class OutputDevice;
51
class SUMOVehicle;
52
class SUMOVehicleParameter;
53
class MSVehicle;
54
class MSLane;
55
class MSLaneChanger;
56
class MSPerson;
57
class MSJunction;
58
class MSEdge;
59
class MSTransportable;
60
61
62
// ===========================================================================
63
// class definitions
64
// ===========================================================================
65
/**
66
* @class MSEdge
67
* @brief A road/street connecting two junctions
68
*
69
* A single connection between two junctions.
70
* Holds lanes which are reponsible for vehicle movements.
71
*/
72
73
typedef std::vector<MSEdge*> MSEdgeVector;
74
typedef std::vector<const MSEdge*> ConstMSEdgeVector;
75
typedef std::vector<std::pair<const MSEdge*, const MSEdge*> > MSConstEdgePairVector;
76
77
class MSEdge : public Named, public Parameterised {
78
private:
79
/** @brief "Map" from vehicle class to allowed lanes */
80
typedef std::vector<std::pair<SVCPermissions, std::shared_ptr<const std::vector<MSLane*> > > > AllowedLanesCont;
81
82
/** @brief Succeeding edges (keys) and allowed lanes to reach these edges (values). */
83
typedef std::map<const MSEdge*, AllowedLanesCont> AllowedLanesByTarget;
84
85
86
public:
87
friend class MSLaneChangerSublane; // needs access to myLaneChanger
88
89
/** @brief Constructor.
90
*
91
* After calling this constructor, the edge is not yet initialised
92
* completely. A call to "initialize" with proper values is needed
93
* for this.
94
*
95
* @param[in] id The id of the edge
96
* @param[in] numericalID The numerical id (index) of the edge
97
* @param[in] function A basic type of the edge
98
* @param[in] streetName The street name for that edge
99
*/
100
MSEdge(const std::string& id, int numericalID, const SumoXMLEdgeFunc function,
101
const std::string& streetName, const std::string& edgeType,
102
const std::string& routingType, int priority, double distance);
103
104
105
/// @brief Destructor.
106
virtual ~MSEdge();
107
108
109
/** @brief Initialize the edge.
110
*
111
* @param[in] allowed Information which edges may be reached from which lanes
112
* @param[in] lanes List of this edge's lanes
113
*/
114
void initialize(const std::vector<MSLane*>* lanes);
115
116
117
/** @brief Recalculates the cached values
118
*/
119
void recalcCache();
120
121
122
/// @todo Has to be called after all edges were built and all connections were set...; Still, is not very nice
123
virtual void closeBuilding();
124
125
/// Has to be called after all sucessors and predecessors have been set (after closeBuilding())
126
void buildLaneChanger();
127
128
/* @brief returns whether initizliaing a lane change is permitted on this edge
129
* @note Has to be called after all sucessors and predecessors have been set (after closeBuilding())
130
*/
131
bool allowsLaneChanging() const;
132
133
/// @name Access to the edge's lanes
134
/// @{
135
136
/** @brief Returns the lane left to the one given, 0 if the given lane is leftmost
137
*
138
* @param[in] lane The lane right to the one to be returned
139
* @return The lane left to the given, 0 if no such lane exists
140
* @todo This method searches for the given in the container; probably, this could be done faster
141
*/
142
MSLane* leftLane(const MSLane* const lane) const;
143
144
145
/** @brief Returns the lane right to the one given, 0 if the given lane is rightmost
146
*
147
* @param[in] lane The lane left to the one to be returned
148
* @return The lane right to the given, 0 if no such lane exists
149
* @todo This method searches for the given in the container; probably, this could be done faster
150
*/
151
MSLane* rightLane(const MSLane* const lane) const;
152
153
154
/** @brief Returns the lane with the given offset parallel to the given lane one or 0 if it does not exist
155
*
156
* @param[in] lane The base lane
157
* @param[in] offset The offset of the result lane
158
* @param[in] includeOpposte Whether an opposite direction lane may be returned
159
* @todo This method searches for the given in the container; probably, this could be done faster
160
*/
161
MSLane* parallelLane(const MSLane* const lane, int offset, bool includeOpposite = true) const;
162
163
164
/** @brief Returns this edge's lanes
165
*
166
* @return This edge's lanes
167
*/
168
inline const std::vector<MSLane*>& getLanes() const {
169
return *myLanes;
170
}
171
172
inline int getNumLanes() const {
173
return (int)myLanes->size();
174
}
175
176
/// @brief return the number of lanes that permit non-weak modes if the edge allows non weak modes and the number of lanes otherwise
177
int getNumDrivingLanes() const;
178
179
/// @brief return total number of vehicles on this edges lanes or segments
180
int getVehicleNumber() const;
181
182
/// @brief whether this edge has no vehicles
183
bool isEmpty() const;
184
185
/// @brief return vehicles on this edges lanes or segments
186
std::vector<const SUMOVehicle*> getVehicles() const;
187
188
double getBruttoOccupancy() const;
189
190
/// @brief return flow based on meanSpead @note: may produced incorrect results when jammed
191
double getFlow() const;
192
193
/// @brief return accumated waiting time for all vehicles on this edges lanes or segments
194
double getWaitingSeconds() const;
195
196
/// @brief return mean occupancy on this edges lanes or segments
197
double getOccupancy() const;
198
199
/** @brief Returns this edge's persons set.
200
* @brief Avoids the creation of new vector as in getSortedPersons
201
*
202
* @return This edge's persons.
203
*/
204
inline const std::set<MSTransportable*, ComparatorNumericalIdLess>& getPersons() const {
205
return myPersons;
206
}
207
208
/** @brief Returns this edge's persons sorted by pos
209
*
210
* @return This edge's persons sorted by pos
211
*/
212
std::vector<MSTransportable*> getSortedPersons(SUMOTime timestep, bool includeRiding = false) const;
213
214
215
/** @brief Returns this edge's containers sorted by pos
216
*
217
* @return This edge's containers sorted by pos
218
*/
219
std::vector<MSTransportable*> getSortedContainers(SUMOTime timestep, bool includeRiding = false) const;
220
221
/** @brief Get the allowed lanes to reach the destination-edge.
222
*
223
* If there is no such edge, return nullptr. Then you are on the wrong edge.
224
*
225
* @param[in] destination The edge to reach
226
* @param[in] vclass The vehicle class for which this information shall be returned
227
* @return The lanes that may be used to reach the given edge, nullptr if no such lanes exist
228
*/
229
const std::vector<MSLane*>* allowedLanes(const MSEdge& destination,
230
SUMOVehicleClass vclass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;
231
232
233
234
/** @brief Get the allowed lanes for the given vehicle class.
235
*
236
* If there is no such edge, return nullptr. Then you are on the wrong edge.
237
*
238
* @param[in] vclass The vehicle class for which this information shall be returned
239
* @return The lanes that may be used by the given vclass
240
*/
241
const std::vector<MSLane*>* allowedLanes(SUMOVehicleClass vclass = SVC_IGNORING) const;
242
const std::vector<MSLane*>* allowedLanes(SUMOVehicleClass vclass, bool ignoreTransientPermissions) const;
243
244
inline bool isConnectedTo(const MSEdge& destination, SUMOVehicleClass vclass, bool ignoreTransientPermissions = false) const {
245
const std::vector<MSLane*>* const lanes = allowedLanes(destination, vclass, ignoreTransientPermissions);
246
return lanes != nullptr && !lanes->empty();
247
}
248
/// @}
249
250
251
252
/// @name Access to other edge attributes
253
/// @{
254
255
/** @brief Returns the edge type (SumoXMLEdgeFunc)
256
* @return This edge's SumoXMLEdgeFunc
257
* @see SumoXMLEdgeFunc
258
*/
259
inline SumoXMLEdgeFunc getFunction() const {
260
return myFunction;
261
}
262
263
/// @brief return whether this edge is an internal edge
264
inline bool isNormal() const {
265
return myFunction == SumoXMLEdgeFunc::NORMAL;
266
}
267
268
/// @brief return whether this edge is an internal edge
269
inline bool isInternal() const {
270
return myFunction == SumoXMLEdgeFunc::INTERNAL;
271
}
272
273
/// @brief return whether this edge is a pedestrian crossing
274
inline bool isCrossing() const {
275
return myFunction == SumoXMLEdgeFunc::CROSSING;
276
}
277
278
279
/// @brief check and register the opposite superposable edge if any
280
void checkAndRegisterBiDirEdge(const std::string& bidiID = "");
281
282
/// @brief return opposite superposable/congruent edge, if it exist and 0 else
283
inline const MSEdge* getBidiEdge() const {
284
return myBidiEdge;
285
}
286
287
/// @brief return whether this edge is walking area
288
inline bool isWalkingArea() const {
289
return myFunction == SumoXMLEdgeFunc::WALKINGAREA;
290
}
291
292
inline bool isTazConnector() const {
293
return myFunction == SumoXMLEdgeFunc::CONNECTOR;
294
}
295
296
void setOtherTazConnector(const MSEdge* edge) {
297
myOtherTazConnector = edge;
298
}
299
300
const MSEdge* getOtherTazConnector() const {
301
return myOtherTazConnector;
302
}
303
304
/** @brief Returns the numerical id of the edge
305
* @return This edge's numerical id
306
*/
307
inline int getNumericalID() const {
308
return myNumericalID;
309
}
310
311
312
/** @brief Returns the street name of the edge
313
*/
314
const std::string& getStreetName() const {
315
return myStreetName;
316
}
317
318
/** @brief Returns the type of the edge
319
*/
320
const std::string& getEdgeType() const {
321
return myEdgeType;
322
}
323
324
/** @brief Returns the type of the edge
325
*/
326
const std::string& getRoutingType() const {
327
return myRoutingType.empty() ? myEdgeType : myRoutingType;
328
}
329
330
double getPreference(const SUMOVTypeParameter& pars) const;
331
332
// @brief try to infer edge type for internal edges
333
void inferEdgeType();
334
335
/** @brief Returns the priority of the edge
336
*/
337
int getPriority() const {
338
return myPriority;
339
}
340
341
/** @brief Returns the kilometrage/mileage encoding at the start of the edge
342
* (negative values encode descending direction)
343
*/
344
double getDistance() const {
345
return myDistance;
346
}
347
348
/** @brief Returns the kilometrage/mileage at the given offset along the edge
349
*/
350
double getDistanceAt(double pos) const;
351
352
bool hasDistance() const {
353
return myDistance != 0;
354
}
355
/// @}
356
357
/**@brief Sets the crossed edge ids for a crossing edge
358
*
359
*/
360
void setCrossingEdges(const std::vector<std::string>& crossingEdges) {
361
myCrossingEdges.clear();
362
myCrossingEdges.insert(myCrossingEdges.begin(), crossingEdges.begin(), crossingEdges.end());
363
}
364
365
/**@brief Gets the crossed edge ids
366
*@return The list of crossed edge ids in a crossing edge or an empty vector
367
*/
368
const std::vector<std::string>& getCrossingEdges() const {
369
return myCrossingEdges;
370
}
371
372
373
/// @name Access to succeeding/predecessing edges
374
/// @{
375
376
/** @brief Adds an edge to the list of edges which may be reached from this edge and to the incoming of the other edge
377
*
378
* This is mainly used by the taz (district) parsing
379
* @param[in] edge The edge to add
380
*/
381
void addSuccessor(MSEdge* edge, const MSEdge* via = nullptr);
382
383
void resetTAZ(MSJunction* junction);
384
385
/** @brief Returns the number of edges that may be reached from this edge
386
* @return The number of following edges
387
*/
388
int getNumSuccessors() const {
389
return (int) mySuccessors.size();
390
}
391
392
393
/** @brief Returns the following edges, restricted by vClass
394
* @param[in] vClass The vClass for which to restrict the successors
395
* @return The eligible following edges
396
*/
397
const MSEdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;
398
399
/** @brief Returns the following edges with internal vias, restricted by vClass
400
* @param[in] vClass The vClass for which to restrict the successors
401
* @return The eligible following edges
402
*/
403
const MSConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;
404
405
406
/** @brief Returns the number of edges this edge is connected to
407
*
408
* @return The number of edges following this edge
409
*/
410
int getNumPredecessors() const {
411
return (int) myPredecessors.size();
412
}
413
414
415
/** @brief
416
* @return
417
*/
418
const MSEdgeVector& getPredecessors() const {
419
return myPredecessors;
420
}
421
422
423
const MSJunction* getFromJunction() const {
424
return myFromJunction;
425
}
426
427
const MSJunction* getToJunction() const {
428
return myToJunction;
429
}
430
431
432
void setJunctions(MSJunction* from, MSJunction* to);
433
/// @}
434
435
436
437
/// @name Access to vaporizing interface
438
/// @{
439
440
/** @brief Returns whether vehicles on this edge shall be vaporized
441
* @return Whether no vehicle shall be on this edge
442
*/
443
bool isVaporizing() const {
444
return myVaporizationRequests > 0;
445
}
446
447
448
/** @brief Enables vaporization
449
*
450
* The internal vaporization counter is increased enabling the
451
* vaporization.
452
* Called from the event handler.
453
* @param[in] t The current time (unused)
454
* @return Time to next call (always 0)
455
* @exception ProcessError not thrown by this method, just derived
456
*/
457
SUMOTime incVaporization(SUMOTime t);
458
459
460
/** @brief Disables vaporization
461
*
462
* The internal vaporization counter is decreased what disables
463
* the vaporization if it was only once enabled.
464
* Called from the event handler.
465
* @param[in] t The current time (unused)
466
* @return Time to next call (always 0)
467
* @exception ProcessError not thrown by this method, just derived
468
*/
469
SUMOTime decVaporization(SUMOTime t);
470
/// @}
471
472
473
/** @brief Computes and returns the current travel time for this edge
474
*
475
* The mean speed of all lanes is used to compute the travel time.
476
* To avoid infinite travel times, the given minimum speed is used.
477
*
478
* @param[in] minSpeed The minimumSpeed to assume if traffic on this edge is stopped
479
* @return The current effort (travel time) to pass the edge
480
*/
481
double getCurrentTravelTime(const double minSpeed = NUMERICAL_EPS) const;
482
483
484
/// @brief returns the minimum travel time for the given vehicle
485
inline double getMinimumTravelTime(const SUMOVehicle* const veh) const {
486
if (myFunction == SumoXMLEdgeFunc::CONNECTOR) {
487
return 0;
488
} else if (veh != 0) {
489
return getLength() / getVehicleMaxSpeed(veh) + myTimePenalty;
490
} else {
491
return myEmptyTraveltime;
492
}
493
}
494
495
double getTimePenalty() const {
496
return myTimePenalty;
497
}
498
499
/** @brief Returns the travel time for the given edge
500
*
501
* @param[in] edge The edge for which the travel time shall be retrieved
502
* @param[in] veh The vehicle for which the travel time on this edge shall be retrieved
503
* @param[in] time The time for which the travel time shall be returned [s]
504
* @return The traveltime needed by the given vehicle to pass the edge at the given time
505
*/
506
static inline double getTravelTimeStatic(const MSEdge* const edge, const SUMOVehicle* const veh, double time) {
507
return MSNet::getInstance()->getTravelTime(edge, veh, time);
508
}
509
510
static double getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double time);
511
512
/** @brief Returns the averaged speed used by the routing device
513
*/
514
double getRoutingSpeed() const;
515
516
517
/// @name Methods releated to vehicle insertion
518
/// @{
519
520
/** @brief Tries to insert the given vehicle into the network
521
*
522
* The procedure for choosing the proper lane is determined, first.
523
* In dependence to this, the proper lane is chosen.
524
*
525
* Insertion itself is done by calling the chose lane's "insertVehicle"
526
* method but only if the checkOnly argument is false. The check needs
527
* to be certain only in the negative case (if false is returned, there
528
* is no way this vehicle would be inserted).
529
*
530
* @param[in] v The vehicle to insert
531
* @param[in] time The current simulation time
532
* @param[in] checkOnly Whether we perform only the check without actually inserting
533
* @param[in] forceCheck Whether the full insertion check should be run for each pending vehicle
534
* or whether insertion on lanes for which an insertion has already a failed should be ignored
535
* in the current time step.
536
* @return Whether the vehicle could be inserted
537
* @see MSLane::insertVehicle
538
*/
539
bool insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly = false, const bool forceCheck = false) const;
540
541
/// @brief check whether the given departSpeed is valid for this edge
542
bool validateDepartSpeed(SUMOVehicle& v) const;
543
544
/** @brief Finds the emptiest lane allowing the vehicle class
545
*
546
* The emptiest lane is the one which vehicle insertion is most likely to succeed.
547
*
548
* If there are no vehicles before departPos, then the lane with the largest
549
* gap between departPos and the last vehicle is
550
* Otheriwise the lane with lowes occupancy is selected
551
* If there is more than one, the first according to its
552
* index in the lane container is chosen.
553
*
554
* If allowed==0, the lanes allowed for the given vehicle class
555
* will be used.
556
*
557
* @param[in] allowed The lanes to choose from
558
* @param[in] vclass The vehicle class to look for
559
* @param[in] departPos An upper bound on vehicle depart position
560
* @return the least occupied lane
561
* @see allowedLanes
562
*/
563
MSLane* getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const;
564
565
/** @brief Finds the most probable lane allowing the vehicle class
566
*
567
* The most probable lane is the one which best corresponds to the desired speed of the vehicle
568
* Vehicles with lower speeds will use lanes to the right while
569
* vehicles with higher speeds will use lanes to the left
570
*
571
* @param[in] allowed The lanes to choose from
572
* @param[in] vclass The vehicle class to look for
573
* @param[in] departPos An upper bound on vehicle depart position
574
* @param[in] maxSpeed The vehicles maxSpeed (including speedFactor)
575
* @return the least occupied lane
576
* @see allowedLanes
577
*/
578
MSLane* getProbableLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos, double maxSpeed) const;
579
580
581
/** @brief Finds a depart lane for the given vehicle parameters
582
*
583
* Depending on the depart lane procedure a depart lane is chosen.
584
* Repeated calls with the same vehicle may return different results
585
* if the procedure is "random" or "free". In case no appropriate
586
* lane was found, 0 is returned.
587
*
588
* @param[in] veh The vehicle to get the depart lane for
589
* @return a possible/chosen depart lane, 0 if no lane can be used
590
*/
591
MSLane* getDepartLane(MSVehicle& veh) const;
592
593
/* @brief get the rightmost lane that allows the given vClass or nullptr
594
* @param[in] defaultFirst Whether the first lane should be returned if all lanes are forbidden
595
*/
596
MSLane* getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst = false, int routingMode = 0) const;
597
598
/// @brief consider given departLane parameter (only for validating speeds)
599
MSLane* getDepartLaneMeso(SUMOVehicle& veh) const;
600
601
/** @brief Returns the last time a vehicle could not be inserted
602
* @return The current value
603
*/
604
inline SUMOTime getLastFailedInsertionTime() const {
605
return myLastFailedInsertionTime;
606
}
607
608
609
/** @brief Sets the last time a vehicle could not be inserted
610
* @param[in] time the new value
611
*/
612
inline void setLastFailedInsertionTime(SUMOTime time) const {
613
myLastFailedInsertionTime = time;
614
}
615
/// @}
616
617
618
/** @brief Performs lane changing on this edge */
619
void changeLanes(SUMOTime t) const;
620
621
622
/// @todo extension: inner junctions are not filled
623
const MSEdge* getInternalFollowingEdge(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;
624
625
626
/// @brief returns the length of all internal edges on the junction until reaching the non-internal edge followerAfterInternal.
627
double getInternalFollowingLengthTo(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;
628
629
/// @brief if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
630
const MSEdge* getNormalBefore() const;
631
632
/// @brief if this edge is an internal edge, return its first normal successor, otherwise the edge itself
633
const MSEdge* getNormalSuccessor() const;
634
635
/// @brief Returns whether the vehicle (class) is not allowed on the edge
636
inline bool prohibits(const SUMOVehicle* const vehicle) const {
637
if (vehicle == nullptr) {
638
return false;
639
}
640
const SUMOVehicleClass svc = vehicle->getVClass();
641
return (vehicle->ignoreTransientPermissions()
642
? (myOriginalCombinedPermissions & svc) != svc
643
: (myCombinedPermissions & svc) != svc);
644
}
645
646
bool hasTransientPermissions() const;
647
648
/** @brief Returns whether this edge has restriction parameters forbidding the given vehicle to pass it
649
* The restriction mechanism is not implemented yet for the microsim, so it always returns false.
650
* @param[in] vehicle The vehicle for which the information has to be returned
651
* @return Whether the vehicle must not enter this edge
652
*/
653
inline bool restricts(const SUMOVehicle* const /* vehicle */) const {
654
return false;
655
}
656
657
/// @brief Returns the combined permissions of all lanes of this edge
658
inline SVCPermissions getPermissions() const {
659
return myCombinedPermissions;
660
}
661
662
/** @brief Returns the edges's width (sum over all lanes)
663
* @return This edges's width
664
*/
665
double getWidth() const {
666
return myWidth;
667
}
668
669
/// @brief Returns the right side offsets of this edge's sublanes
670
const std::vector<double> getSubLaneSides() const {
671
return mySublaneSides;
672
}
673
674
void rebuildAllowedLanes(const bool onInit = false, bool updateVehicles = false);
675
676
void rebuildAllowedTargets(const bool updateVehicles = true);
677
678
679
/** @brief optimistic air distance heuristic for use in routing
680
* @param[in] other The edge to which the distance shall be returned
681
* @param[in] doBoundaryEstimate whether the distance should be estimated by looking at the distance of the bounding boxes
682
* @return The distance to the other edge
683
*/
684
double getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate = false) const;
685
686
687
/// @brief return the coordinates of the center of the given stop
688
static const Position getStopPosition(const SUMOVehicleParameter::Stop& stop);
689
690
691
/** @brief return the length of the edge
692
* @return The edge's length
693
*/
694
inline double getLength() const {
695
return myLength;
696
}
697
698
699
/** @brief Returns the speed limit of the edge
700
* @caution The speed limit of the first lane is retured; should probably be the fastest edge
701
* @return The maximum speed allowed on this edge
702
*/
703
double getSpeedLimit() const;
704
705
/// @brief return shape.length() / myLength
706
double getLengthGeometryFactor() const;
707
708
/** @brief Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
709
* @param[in] val the new speed in m/s
710
*/
711
void setMaxSpeed(double val, double jamThreshold = -1);
712
713
/** @brief Sets a new friction coefficient COF for all lanes [*later to be (used by TraCI and MSCalibrator)*]
714
* @param[in] val the new coefficient in [0..1]
715
*/
716
void setFrictionCoefficient(double val) const;
717
718
/** @brief Returns the maximum speed the vehicle may use on this edge
719
*
720
* @caution Only the first lane is considered
721
* @return The maximum velocity on this edge for the given vehicle
722
*/
723
double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const;
724
725
726
virtual void addTransportable(MSTransportable* t) const;
727
728
virtual void removeTransportable(MSTransportable* t) const;
729
730
inline bool isRoundabout() const {
731
return myAmRoundabout;
732
}
733
734
void markAsRoundabout() {
735
myAmRoundabout = true;
736
}
737
738
void markDelayed() const {
739
myAmDelayed = true;
740
}
741
742
// return whether there have been vehicles on this or the bidi edge (if there is any) at least once
743
inline bool isDelayed() const {
744
return myAmDelayed || (myBidiEdge != nullptr && myBidiEdge->myAmDelayed);
745
}
746
747
bool hasLaneChanger() const {
748
return myLaneChanger != nullptr;
749
}
750
751
/// @brief retrieve properties of a blocked vehicle that wants to chane to the lane with the given index
752
std::pair<double, SUMOTime> getLastBlocked(int index) const;
753
754
/// @brief whether this edge allows changing to the opposite direction edge
755
bool canChangeToOpposite() const;
756
757
/// @brief Returns the opposite direction edge if on exists else a nullptr
758
const MSEdge* getOppositeEdge() const;
759
760
/// @brief get the mean speed
761
double getMeanSpeed() const;
762
763
/// @brief get the mean friction over the lanes
764
double getMeanFriction() const;
765
766
/// @brief get the mean speed of all bicycles on this edge
767
double getMeanSpeedBike() const;
768
769
/// @brief whether any lane has a minor link
770
bool hasMinorLink() const;
771
772
/// @brief return whether this edge is at the fringe of the network
773
bool isFringe() const {
774
return myAmFringe;
775
}
776
777
/// @brief return whether this edge prohibits changing for the given vClass when starting on the given lane index
778
bool hasChangeProhibitions(SUMOVehicleClass svc, int index) const;
779
780
/// @brief whether this lane is selected in the GUI
781
virtual bool isSelected() const {
782
return false;
783
}
784
785
/// @brief grant exclusive access to the mesoscopic state
786
virtual void lock() const {}
787
788
/// @brief release exclusive access to the mesoscopic state
789
virtual void unlock() const {};
790
791
/// @brief Adds a vehicle to the list of waiting vehicles
792
void addWaiting(SUMOVehicle* vehicle) const;
793
794
/// @brief Removes a vehicle from the list of waiting vehicles
795
void removeWaiting(const SUMOVehicle* vehicle) const;
796
797
/* @brief returns a vehicle that is waiting for a for a person or a container at this edge at the given position
798
* @param[in] transportable The person or container that wants to ride
799
* @param[in] position The vehicle shall be positioned in the interval [position - t, position + t], where t is some tolerance
800
*/
801
SUMOVehicle* getWaitingVehicle(MSTransportable* transportable, const double position) const;
802
803
/** @brief Remove all transportables before quick-loading state */
804
void clearState();
805
806
void postLoadInitLaneChanger();
807
808
static DepartLaneDefinition& getDefaultDepartLaneDefinition() {
809
return myDefaultDepartLaneDefinition;
810
}
811
812
static int& getDefaultDepartLane() {
813
return myDefaultDepartLane;
814
}
815
816
/** @brief Inserts edge into the static dictionary
817
Returns true if the key id isn't already in the dictionary. Otherwise
818
returns false. */
819
static bool dictionary(const std::string& id, MSEdge* edge);
820
821
/** @brief Returns the MSEdge associated to the key id if it exists, otherwise returns nullptr. */
822
static MSEdge* dictionary(const std::string& id);
823
824
/** @brief Returns the MSEdge associated to the key id giving a hint with a numerical id. */
825
static MSEdge* dictionaryHint(const std::string& id, const int startIdx);
826
827
/// @brief Returns all edges with a numerical id
828
static const MSEdgeVector& getAllEdges();
829
830
/** @brief Clears the dictionary */
831
static void clear();
832
833
/** @brief Inserts IDs of all known edges into the given vector */
834
static void insertIDs(std::vector<std::string>& into);
835
836
static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored = 0);
837
838
static void setMesoIgnoredVClasses(SVCPermissions ignored) {
839
myMesoIgnoredVClasses = ignored;
840
}
841
842
public:
843
/// @name Static parser helper
844
/// @{
845
846
/** @brief Parses the given string assuming it contains a list of edge ids divided by spaces
847
*
848
* Splits the string at spaces, uses polymorph method to generate edge vector.
849
* @param[in] desc The string containing space-separated edge ids
850
* @param[out] into The vector to fill
851
* @param[in] rid The id of the route these description belongs to; used for error message generation
852
* @exception ProcessError If one of the strings contained is not a known edge id
853
*/
854
static void parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
855
const std::string& rid);
856
857
858
/** @brief Parses the given string vector assuming it edge ids
859
* @param[in] desc The string vector containing edge ids
860
* @param[out] into The vector to fill
861
* @param[in] rid The id of the route these description belongs to; used for error message generation
862
* @exception ProcessError If one of the strings contained is not a known edge id
863
*/
864
static void parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
865
const std::string& rid);
866
/// @}
867
868
869
ReversedEdge<MSEdge, SUMOVehicle>* getReversedRoutingEdge() const {
870
if (myReversedRoutingEdge == nullptr) {
871
myReversedRoutingEdge = new ReversedEdge<MSEdge, SUMOVehicle>(this);
872
}
873
return myReversedRoutingEdge;
874
}
875
876
RailEdge<MSEdge, SUMOVehicle>* getRailwayRoutingEdge() const {
877
if (myRailwayRoutingEdge == nullptr) {
878
myRailwayRoutingEdge = new RailEdge<MSEdge, SUMOVehicle>(this);
879
}
880
return myRailwayRoutingEdge;
881
}
882
883
protected:
884
/** @class by_id_sorter
885
* @brief Sorts edges by their ids
886
*/
887
class by_id_sorter {
888
public:
889
/// @brief constructor
890
explicit by_id_sorter() { }
891
892
/// @brief comparing operator
893
int operator()(const MSEdge* const e1, const MSEdge* const e2) const {
894
return e1->getNumericalID() < e2->getNumericalID();
895
}
896
897
};
898
899
/** @class transportable_by_position_sorter
900
* @brief Sorts transportables by their positions
901
*/
902
class transportable_by_position_sorter {
903
public:
904
/// @brief constructor
905
explicit transportable_by_position_sorter(SUMOTime timestep): myTime(timestep) { }
906
907
/// @brief comparing operator
908
int operator()(const MSTransportable* const c1, const MSTransportable* const c2) const;
909
private:
910
SUMOTime myTime;
911
};
912
913
914
/// @brief return upper bound for the depart position on this edge
915
double getDepartPosBound(const MSVehicle& veh, bool upper = true) const;
916
917
protected:
918
/// @brief This edge's numerical id
919
const int myNumericalID;
920
921
/// @brief Container for the edge's lane; should be sorted: (right-hand-traffic) the more left the lane, the higher the container-index
922
std::shared_ptr<const std::vector<MSLane*> > myLanes;
923
924
/// @brief This member will do the lane-change
925
MSLaneChanger* myLaneChanger;
926
927
/// @brief the purpose of the edge
928
const SumoXMLEdgeFunc myFunction;
929
930
/// @brief Vaporizer counter
931
int myVaporizationRequests;
932
933
/// @brief The time of last insertion failure
934
mutable SUMOTime myLastFailedInsertionTime;
935
936
/// @brief A cache for the rejected insertion attempts. Used to assure that no
937
/// further insertion attempts are made on a lane where an attempt has
938
/// already failed in the current time step if MSInsertionControl::myEagerInsertionCheck is off.
939
mutable std::set<int> myFailedInsertionMemory;
940
941
/// @brief The crossed edges id for a crossing edge. On not crossing edges it is empty
942
std::vector<std::string> myCrossingEdges;
943
944
/// @brief The succeeding edges
945
MSEdgeVector mySuccessors;
946
947
MSConstEdgePairVector myViaSuccessors;
948
949
/// @brief The preceeding edges
950
MSEdgeVector myPredecessors;
951
952
/// @brief the junctions for this edge
953
MSJunction* myFromJunction;
954
MSJunction* myToJunction;
955
956
/// @brief Persons on the edge for drawing and pushbutton
957
mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myPersons;
958
959
/// @brief Containers on the edge
960
mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myContainers;
961
962
/// @name Storages for allowed lanes (depending on vehicle classes)
963
/// @{
964
965
/// @brief Associative container from vehicle class to allowed-lanes.
966
AllowedLanesCont myAllowed;
967
AllowedLanesCont myOrigAllowed;
968
969
/// @brief From target edge to lanes allowed to be used to reach it
970
AllowedLanesByTarget myAllowedTargets;
971
AllowedLanesByTarget myOrigAllowedTargets;
972
973
/// @brief The intersection of lane permissions for this edge
974
SVCPermissions myMinimumPermissions = SVCAll;
975
/// @brief The union of lane permissions for this edge
976
SVCPermissions myCombinedPermissions = 0;
977
978
/// @brief The original intersection of lane permissions for this edge (before temporary modifications)
979
SVCPermissions myOriginalMinimumPermissions = SVCAll;
980
/// @brief The original union of lane permissions for this edge (before temporary modifications)
981
SVCPermissions myOriginalCombinedPermissions = SVCAll;
982
983
/// @brief whether transient permission changes were applied to this edge or a predecessor
984
bool myHaveTransientPermissions;
985
/// @}
986
987
/// @brief the other taz-connector if this edge isTazConnector, otherwise nullptr
988
const MSEdge* myOtherTazConnector;
989
990
/// @brief the real-world name of this edge (need not be unique)
991
std::string myStreetName;
992
993
/// @brief the type of the edge (optionally used during network creation)
994
std::string myEdgeType;
995
996
/// @brief the routing type of the edge (used to look up vType and vClass specific routing preferences)
997
std::string myRoutingType;
998
999
/// @brief the priority of the edge (used during network creation)
1000
const int myPriority;
1001
1002
/// @brief the kilometrage/mileage at the start of the edge
1003
const double myDistance;
1004
1005
/// Edge width [m]
1006
double myWidth;
1007
1008
/// @brief the length of the edge (cached value for speedup)
1009
double myLength;
1010
1011
/// @brief the traveltime on the empty edge (cached value for speedup)
1012
double myEmptyTraveltime;
1013
1014
/// @brief flat penalty when computing traveltime
1015
double myTimePenalty;
1016
1017
/// @brief whether this edge had a vehicle with less than max speed on it
1018
mutable bool myAmDelayed;
1019
1020
/// @brief whether this edge belongs to a roundabout
1021
bool myAmRoundabout;
1022
1023
/// @brief whether this edge is at the network fringe
1024
bool myAmFringe;
1025
1026
/// @brief the right side for each sublane on this edge
1027
std::vector<double> mySublaneSides;
1028
1029
/// @name Static edge container
1030
/// @{
1031
1032
/// @brief definition of the static dictionary type
1033
typedef std::map< std::string, MSEdge* > DictType;
1034
1035
/** @brief Static dictionary to associate string-ids with objects.
1036
* @deprecated Move to MSEdgeControl, make non-static
1037
*/
1038
static DictType myDict;
1039
1040
/** @brief Static list of edges
1041
* @deprecated Move to MSEdgeControl, make non-static
1042
*/
1043
static MSEdgeVector myEdges;
1044
1045
static SVCPermissions myMesoIgnoredVClasses;
1046
1047
static DepartLaneDefinition myDefaultDepartLaneDefinition;
1048
static int myDefaultDepartLane;
1049
/// @}
1050
1051
1052
/// @brief The successors available for a given vClass
1053
mutable std::map<SUMOVehicleClass, MSEdgeVector> myClassesSuccessorMap;
1054
1055
/// @brief The successors available for a given vClass
1056
mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myClassesViaSuccessorMap;
1057
mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myOrigClassesViaSuccessorMap;
1058
1059
/// @brief The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start and end node for normal edges
1060
Boundary myBoundary;
1061
1062
/// @brief List of waiting vehicles
1063
mutable std::vector<SUMOVehicle*> myWaiting;
1064
1065
#ifdef HAVE_FOX
1066
/// @brief Mutex for accessing waiting vehicles
1067
mutable FXMutex myWaitingMutex;
1068
1069
/// @brief Mutex for accessing successor edges
1070
mutable FXMutex mySuccessorMutex;
1071
#endif
1072
1073
private:
1074
1075
/// @brief the oppositing superposable edge
1076
const MSEdge* myBidiEdge;
1077
1078
/// @brief a reversed version for backward routing
1079
mutable ReversedEdge<MSEdge, SUMOVehicle>* myReversedRoutingEdge = nullptr;
1080
mutable RailEdge<MSEdge, SUMOVehicle>* myRailwayRoutingEdge = nullptr;
1081
1082
/// @brief Invalidated copy constructor.
1083
MSEdge(const MSEdge&);
1084
1085
/// @brief assignment operator.
1086
MSEdge& operator=(const MSEdge&) = delete;
1087
1088
void setBidiLanes();
1089
1090
bool isSuperposable(const MSEdge* other);
1091
1092
void addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const;
1093
};
1094
1095