Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/microsim/MSEdge.h
185785 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file 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
243
inline bool isConnectedTo(const MSEdge& destination, SUMOVehicleClass vclass, bool ignoreTransientPermissions = false) const {
244
const std::vector<MSLane*>* const lanes = allowedLanes(destination, vclass, ignoreTransientPermissions);
245
return lanes != nullptr && !lanes->empty();
246
}
247
/// @}
248
249
250
251
/// @name Access to other edge attributes
252
/// @{
253
254
/** @brief Returns the edge type (SumoXMLEdgeFunc)
255
* @return This edge's SumoXMLEdgeFunc
256
* @see SumoXMLEdgeFunc
257
*/
258
inline SumoXMLEdgeFunc getFunction() const {
259
return myFunction;
260
}
261
262
/// @brief return whether this edge is an internal edge
263
inline bool isNormal() const {
264
return myFunction == SumoXMLEdgeFunc::NORMAL;
265
}
266
267
/// @brief return whether this edge is an internal edge
268
inline bool isInternal() const {
269
return myFunction == SumoXMLEdgeFunc::INTERNAL;
270
}
271
272
/// @brief return whether this edge is a pedestrian crossing
273
inline bool isCrossing() const {
274
return myFunction == SumoXMLEdgeFunc::CROSSING;
275
}
276
277
278
/// @brief check and register the opposite superposable edge if any
279
void checkAndRegisterBiDirEdge(const std::string& bidiID = "");
280
281
/// @brief return opposite superposable/congruent edge, if it exist and 0 else
282
inline const MSEdge* getBidiEdge() const {
283
return myBidiEdge;
284
}
285
286
/// @brief return whether this edge is walking area
287
inline bool isWalkingArea() const {
288
return myFunction == SumoXMLEdgeFunc::WALKINGAREA;
289
}
290
291
inline bool isTazConnector() const {
292
return myFunction == SumoXMLEdgeFunc::CONNECTOR;
293
}
294
295
void setOtherTazConnector(const MSEdge* edge) {
296
myOtherTazConnector = edge;
297
}
298
299
const MSEdge* getOtherTazConnector() const {
300
return myOtherTazConnector;
301
}
302
303
/** @brief Returns the numerical id of the edge
304
* @return This edge's numerical id
305
*/
306
inline int getNumericalID() const {
307
return myNumericalID;
308
}
309
310
311
/** @brief Returns the street name of the edge
312
*/
313
const std::string& getStreetName() const {
314
return myStreetName;
315
}
316
317
/** @brief Returns the type of the edge
318
*/
319
const std::string& getEdgeType() const {
320
return myEdgeType;
321
}
322
323
/** @brief Returns the type of the edge
324
*/
325
const std::string& getRoutingType() const {
326
return myRoutingType.empty() ? myEdgeType : myRoutingType;
327
}
328
329
double getPreference(const SUMOVTypeParameter& pars) const;
330
331
// @brief try to infer edge type for internal edges
332
void inferEdgeType();
333
334
/** @brief Returns the priority of the edge
335
*/
336
int getPriority() const {
337
return myPriority;
338
}
339
340
/** @brief Returns the kilometrage/mileage encoding at the start of the edge
341
* (negative values encode descending direction)
342
*/
343
double getDistance() const {
344
return myDistance;
345
}
346
347
/** @brief Returns the kilometrage/mileage at the given offset along the edge
348
*/
349
double getDistanceAt(double pos) const;
350
351
bool hasDistance() const {
352
return myDistance != 0;
353
}
354
/// @}
355
356
/**@brief Sets the crossed edge ids for a crossing edge
357
*
358
*/
359
void setCrossingEdges(const std::vector<std::string>& crossingEdges) {
360
myCrossingEdges.clear();
361
myCrossingEdges.insert(myCrossingEdges.begin(), crossingEdges.begin(), crossingEdges.end());
362
}
363
364
/**@brief Gets the crossed edge ids
365
*@return The list of crossed edge ids in a crossing edge or an empty vector
366
*/
367
const std::vector<std::string>& getCrossingEdges() const {
368
return myCrossingEdges;
369
}
370
371
372
/// @name Access to succeeding/predecessing edges
373
/// @{
374
375
/** @brief Adds an edge to the list of edges which may be reached from this edge and to the incoming of the other edge
376
*
377
* This is mainly used by the taz (district) parsing
378
* @param[in] edge The edge to add
379
*/
380
void addSuccessor(MSEdge* edge, const MSEdge* via = nullptr);
381
382
void resetTAZ(MSJunction* junction);
383
384
/** @brief Returns the number of edges that may be reached from this edge
385
* @return The number of following edges
386
*/
387
int getNumSuccessors() const {
388
return (int) mySuccessors.size();
389
}
390
391
392
/** @brief Returns the following edges, restricted by vClass
393
* @param[in] vClass The vClass for which to restrict the successors
394
* @return The eligible following edges
395
*/
396
const MSEdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;
397
398
/** @brief Returns the following edges with internal vias, restricted by vClass
399
* @param[in] vClass The vClass for which to restrict the successors
400
* @return The eligible following edges
401
*/
402
const MSConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;
403
404
405
/** @brief Returns the number of edges this edge is connected to
406
*
407
* @return The number of edges following this edge
408
*/
409
int getNumPredecessors() const {
410
return (int) myPredecessors.size();
411
}
412
413
414
/** @brief
415
* @return
416
*/
417
const MSEdgeVector& getPredecessors() const {
418
return myPredecessors;
419
}
420
421
422
const MSJunction* getFromJunction() const {
423
return myFromJunction;
424
}
425
426
const MSJunction* getToJunction() const {
427
return myToJunction;
428
}
429
430
431
void setJunctions(MSJunction* from, MSJunction* to);
432
/// @}
433
434
435
436
/// @name Access to vaporizing interface
437
/// @{
438
439
/** @brief Returns whether vehicles on this edge shall be vaporized
440
* @return Whether no vehicle shall be on this edge
441
*/
442
bool isVaporizing() const {
443
return myVaporizationRequests > 0;
444
}
445
446
447
/** @brief Enables vaporization
448
*
449
* The internal vaporization counter is increased enabling the
450
* vaporization.
451
* Called from the event handler.
452
* @param[in] t The current time (unused)
453
* @return Time to next call (always 0)
454
* @exception ProcessError not thrown by this method, just derived
455
*/
456
SUMOTime incVaporization(SUMOTime t);
457
458
459
/** @brief Disables vaporization
460
*
461
* The internal vaporization counter is decreased what disables
462
* the vaporization if it was only once enabled.
463
* Called from the event handler.
464
* @param[in] t The current time (unused)
465
* @return Time to next call (always 0)
466
* @exception ProcessError not thrown by this method, just derived
467
*/
468
SUMOTime decVaporization(SUMOTime t);
469
/// @}
470
471
472
/** @brief Computes and returns the current travel time for this edge
473
*
474
* The mean speed of all lanes is used to compute the travel time.
475
* To avoid infinite travel times, the given minimum speed is used.
476
*
477
* @param[in] minSpeed The minimumSpeed to assume if traffic on this edge is stopped
478
* @return The current effort (travel time) to pass the edge
479
*/
480
double getCurrentTravelTime(const double minSpeed = NUMERICAL_EPS) const;
481
482
483
/// @brief returns the minimum travel time for the given vehicle
484
inline double getMinimumTravelTime(const SUMOVehicle* const veh) const {
485
if (myFunction == SumoXMLEdgeFunc::CONNECTOR) {
486
return 0;
487
} else if (veh != 0) {
488
return getLength() / getVehicleMaxSpeed(veh) + myTimePenalty;
489
} else {
490
return myEmptyTraveltime;
491
}
492
}
493
494
double getTimePenalty() const {
495
return myTimePenalty;
496
}
497
498
/** @brief Returns the travel time for the given edge
499
*
500
* @param[in] edge The edge for which the travel time shall be retrieved
501
* @param[in] veh The vehicle for which the travel time on this edge shall be retrieved
502
* @param[in] time The time for which the travel time shall be returned [s]
503
* @return The traveltime needed by the given vehicle to pass the edge at the given time
504
*/
505
static inline double getTravelTimeStatic(const MSEdge* const edge, const SUMOVehicle* const veh, double time) {
506
return MSNet::getInstance()->getTravelTime(edge, veh, time);
507
}
508
509
static double getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double time);
510
511
/** @brief Returns the averaged speed used by the routing device
512
*/
513
double getRoutingSpeed() const;
514
515
516
/// @name Methods releated to vehicle insertion
517
/// @{
518
519
/** @brief Tries to insert the given vehicle into the network
520
*
521
* The procedure for choosing the proper lane is determined, first.
522
* In dependence to this, the proper lane is chosen.
523
*
524
* Insertion itself is done by calling the chose lane's "insertVehicle"
525
* method but only if the checkOnly argument is false. The check needs
526
* to be certain only in the negative case (if false is returned, there
527
* is no way this vehicle would be inserted).
528
*
529
* @param[in] v The vehicle to insert
530
* @param[in] time The current simulation time
531
* @param[in] checkOnly Whether we perform only the check without actually inserting
532
* @param[in] forceCheck Whether the full insertion check should be run for each pending vehicle
533
* or whether insertion on lanes for which an insertion has already a failed should be ignored
534
* in the current time step.
535
* @return Whether the vehicle could be inserted
536
* @see MSLane::insertVehicle
537
*/
538
bool insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly = false, const bool forceCheck = false) const;
539
540
/// @brief check whether the given departSpeed is valid for this edge
541
bool validateDepartSpeed(SUMOVehicle& v) const;
542
543
/** @brief Finds the emptiest lane allowing the vehicle class
544
*
545
* The emptiest lane is the one which vehicle insertion is most likely to succeed.
546
*
547
* If there are no vehicles before departPos, then the lane with the largest
548
* gap between departPos and the last vehicle is
549
* Otheriwise the lane with lowes occupancy is selected
550
* If there is more than one, the first according to its
551
* index in the lane container is chosen.
552
*
553
* If allowed==0, the lanes allowed for the given vehicle class
554
* will be used.
555
*
556
* @param[in] allowed The lanes to choose from
557
* @param[in] vclass The vehicle class to look for
558
* @param[in] departPos An upper bound on vehicle depart position
559
* @return the least occupied lane
560
* @see allowedLanes
561
*/
562
MSLane* getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const;
563
564
/** @brief Finds the most probable lane allowing the vehicle class
565
*
566
* The most probable lane is the one which best corresponds to the desired speed of the vehicle
567
* Vehicles with lower speeds will use lanes to the right while
568
* vehicles with higher speeds will use lanes to the left
569
*
570
* @param[in] allowed The lanes to choose from
571
* @param[in] vclass The vehicle class to look for
572
* @param[in] departPos An upper bound on vehicle depart position
573
* @param[in] maxSpeed The vehicles maxSpeed (including speedFactor)
574
* @return the least occupied lane
575
* @see allowedLanes
576
*/
577
MSLane* getProbableLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos, double maxSpeed) const;
578
579
580
/** @brief Finds a depart lane for the given vehicle parameters
581
*
582
* Depending on the depart lane procedure a depart lane is chosen.
583
* Repeated calls with the same vehicle may return different results
584
* if the procedure is "random" or "free". In case no appropriate
585
* lane was found, 0 is returned.
586
*
587
* @param[in] veh The vehicle to get the depart lane for
588
* @return a possible/chosen depart lane, 0 if no lane can be used
589
*/
590
MSLane* getDepartLane(MSVehicle& veh) const;
591
592
/* @brief get the rightmost lane that allows the given vClass or nullptr
593
* @param[in] defaultFirst Whether the first lane should be returned if all lanes are forbidden
594
*/
595
MSLane* getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst = false, int routingMode = 0) const;
596
597
/// @brief consider given departLane parameter (only for validating speeds)
598
MSLane* getDepartLaneMeso(SUMOVehicle& veh) const;
599
600
/** @brief Returns the last time a vehicle could not be inserted
601
* @return The current value
602
*/
603
inline SUMOTime getLastFailedInsertionTime() const {
604
return myLastFailedInsertionTime;
605
}
606
607
608
/** @brief Sets the last time a vehicle could not be inserted
609
* @param[in] time the new value
610
*/
611
inline void setLastFailedInsertionTime(SUMOTime time) const {
612
myLastFailedInsertionTime = time;
613
}
614
/// @}
615
616
617
/** @brief Performs lane changing on this edge */
618
void changeLanes(SUMOTime t) const;
619
620
621
/// @todo extension: inner junctions are not filled
622
const MSEdge* getInternalFollowingEdge(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;
623
624
625
/// @brief returns the length of all internal edges on the junction until reaching the non-internal edge followerAfterInternal.
626
double getInternalFollowingLengthTo(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;
627
628
/// @brief if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
629
const MSEdge* getNormalBefore() const;
630
631
/// @brief if this edge is an internal edge, return its first normal successor, otherwise the edge itself
632
const MSEdge* getNormalSuccessor() const;
633
634
/// @brief Returns whether the vehicle (class) is not allowed on the edge
635
inline bool prohibits(const SUMOVehicle* const vehicle) const {
636
if (vehicle == nullptr) {
637
return false;
638
}
639
const SUMOVehicleClass svc = vehicle->getVClass();
640
return (vehicle->ignoreTransientPermissions()
641
? (myOriginalCombinedPermissions & svc) != svc
642
: (myCombinedPermissions & svc) != svc);
643
}
644
645
bool hasTransientPermissions() const;
646
647
/** @brief Returns whether this edge has restriction parameters forbidding the given vehicle to pass it
648
* The restriction mechanism is not implemented yet for the microsim, so it always returns false.
649
* @param[in] vehicle The vehicle for which the information has to be returned
650
* @return Whether the vehicle must not enter this edge
651
*/
652
inline bool restricts(const SUMOVehicle* const /* vehicle */) const {
653
return false;
654
}
655
656
/// @brief Returns the combined permissions of all lanes of this edge
657
inline SVCPermissions getPermissions() const {
658
return myCombinedPermissions;
659
}
660
661
/** @brief Returns the edges's width (sum over all lanes)
662
* @return This edges's width
663
*/
664
double getWidth() const {
665
return myWidth;
666
}
667
668
/// @brief Returns the right side offsets of this edge's sublanes
669
const std::vector<double> getSubLaneSides() const {
670
return mySublaneSides;
671
}
672
673
void rebuildAllowedLanes(const bool onInit = false, bool updateVehicles = false);
674
675
void rebuildAllowedTargets(const bool updateVehicles = true);
676
677
678
/** @brief optimistic air distance heuristic for use in routing
679
* @param[in] other The edge to which the distance shall be returned
680
* @param[in] doBoundaryEstimate whether the distance should be estimated by looking at the distance of the bounding boxes
681
* @return The distance to the other edge
682
*/
683
double getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate = false) const;
684
685
686
/// @brief return the coordinates of the center of the given stop
687
static const Position getStopPosition(const SUMOVehicleParameter::Stop& stop);
688
689
690
/** @brief return the length of the edge
691
* @return The edge's length
692
*/
693
inline double getLength() const {
694
return myLength;
695
}
696
697
698
/** @brief Returns the speed limit of the edge
699
* @caution The speed limit of the first lane is retured; should probably be the fastest edge
700
* @return The maximum speed allowed on this edge
701
*/
702
double getSpeedLimit() const;
703
704
/// @brief return shape.length() / myLength
705
double getLengthGeometryFactor() const;
706
707
/** @brief Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
708
* @param[in] val the new speed in m/s
709
*/
710
void setMaxSpeed(double val, double jamThreshold = -1);
711
712
/** @brief Sets a new friction coefficient COF for all lanes [*later to be (used by TraCI and MSCalibrator)*]
713
* @param[in] val the new coefficient in [0..1]
714
*/
715
void setFrictionCoefficient(double val) const;
716
717
/** @brief Returns the maximum speed the vehicle may use on this edge
718
*
719
* @caution Only the first lane is considered
720
* @return The maximum velocity on this edge for the given vehicle
721
*/
722
double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const;
723
724
725
virtual void addTransportable(MSTransportable* t) const;
726
727
virtual void removeTransportable(MSTransportable* t) const;
728
729
inline bool isRoundabout() const {
730
return myAmRoundabout;
731
}
732
733
void markAsRoundabout() {
734
myAmRoundabout = true;
735
}
736
737
void markDelayed() const {
738
myAmDelayed = true;
739
}
740
741
// return whether there have been vehicles on this or the bidi edge (if there is any) at least once
742
inline bool isDelayed() const {
743
return myAmDelayed || (myBidiEdge != nullptr && myBidiEdge->myAmDelayed);
744
}
745
746
bool hasLaneChanger() const {
747
return myLaneChanger != nullptr;
748
}
749
750
/// @brief retrieve properties of a blocked vehicle that wants to chane to the lane with the given index
751
std::pair<double, SUMOTime> getLastBlocked(int index) const;
752
753
/// @brief whether this edge allows changing to the opposite direction edge
754
bool canChangeToOpposite() const;
755
756
/// @brief Returns the opposite direction edge if on exists else a nullptr
757
const MSEdge* getOppositeEdge() const;
758
759
/// @brief get the mean speed
760
double getMeanSpeed() const;
761
762
/// @brief get the mean friction over the lanes
763
double getMeanFriction() const;
764
765
/// @brief get the mean speed of all bicycles on this edge
766
double getMeanSpeedBike() const;
767
768
/// @brief whether any lane has a minor link
769
bool hasMinorLink() const;
770
771
/// @brief return whether this edge is at the fringe of the network
772
bool isFringe() const {
773
return myAmFringe;
774
}
775
776
/// @brief return whether this edge prohibits changing for the given vClass when starting on the given lane index
777
bool hasChangeProhibitions(SUMOVehicleClass svc, int index) const;
778
779
/// @brief whether this lane is selected in the GUI
780
virtual bool isSelected() const {
781
return false;
782
}
783
784
/// @brief grant exclusive access to the mesoscopic state
785
virtual void lock() const {}
786
787
/// @brief release exclusive access to the mesoscopic state
788
virtual void unlock() const {};
789
790
/// @brief Adds a vehicle to the list of waiting vehicles
791
void addWaiting(SUMOVehicle* vehicle) const;
792
793
/// @brief Removes a vehicle from the list of waiting vehicles
794
void removeWaiting(const SUMOVehicle* vehicle) const;
795
796
/* @brief returns a vehicle that is waiting for a for a person or a container at this edge at the given position
797
* @param[in] transportable The person or container that wants to ride
798
* @param[in] position The vehicle shall be positioned in the interval [position - t, position + t], where t is some tolerance
799
*/
800
SUMOVehicle* getWaitingVehicle(MSTransportable* transportable, const double position) const;
801
802
/** @brief Remove all transportables before quick-loading state */
803
void clearState();
804
805
/// @brief update meso segment parameters
806
void updateMesoType();
807
808
void postLoadInitLaneChanger();
809
810
static DepartLaneDefinition& getDefaultDepartLaneDefinition() {
811
return myDefaultDepartLaneDefinition;
812
}
813
814
static int& getDefaultDepartLane() {
815
return myDefaultDepartLane;
816
}
817
818
/** @brief Inserts edge into the static dictionary
819
Returns true if the key id isn't already in the dictionary. Otherwise
820
returns false. */
821
static bool dictionary(const std::string& id, MSEdge* edge);
822
823
/** @brief Returns the MSEdge associated to the key id if it exists, otherwise returns nullptr. */
824
static MSEdge* dictionary(const std::string& id);
825
826
/** @brief Returns the MSEdge associated to the key id giving a hint with a numerical id. */
827
static MSEdge* dictionaryHint(const std::string& id, const int startIdx);
828
829
/// @brief Returns all edges with a numerical id
830
static const MSEdgeVector& getAllEdges();
831
832
/** @brief Clears the dictionary */
833
static void clear();
834
835
/** @brief Inserts IDs of all known edges into the given vector */
836
static void insertIDs(std::vector<std::string>& into);
837
838
static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored = 0);
839
840
static void setMesoIgnoredVClasses(SVCPermissions ignored) {
841
myMesoIgnoredVClasses = ignored;
842
}
843
844
public:
845
/// @name Static parser helper
846
/// @{
847
848
/** @brief Parses the given string assuming it contains a list of edge ids divided by spaces
849
*
850
* Splits the string at spaces, uses polymorph method to generate edge vector.
851
* @param[in] desc The string containing space-separated edge ids
852
* @param[out] into The vector to fill
853
* @param[in] rid The id of the route these description belongs to; used for error message generation
854
* @exception ProcessError If one of the strings contained is not a known edge id
855
*/
856
static void parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
857
const std::string& rid);
858
859
860
/** @brief Parses the given string vector assuming it edge ids
861
* @param[in] desc The string vector containing edge ids
862
* @param[out] into The vector to fill
863
* @param[in] rid The id of the route these description belongs to; used for error message generation
864
* @exception ProcessError If one of the strings contained is not a known edge id
865
*/
866
static void parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
867
const std::string& rid);
868
/// @}
869
870
871
ReversedEdge<MSEdge, SUMOVehicle>* getReversedRoutingEdge() const {
872
if (myReversedRoutingEdge == nullptr) {
873
myReversedRoutingEdge = new ReversedEdge<MSEdge, SUMOVehicle>(this);
874
}
875
return myReversedRoutingEdge;
876
}
877
878
RailEdge<MSEdge, SUMOVehicle>* getRailwayRoutingEdge() const {
879
if (myRailwayRoutingEdge == nullptr) {
880
myRailwayRoutingEdge = new RailEdge<MSEdge, SUMOVehicle>(this);
881
}
882
return myRailwayRoutingEdge;
883
}
884
885
protected:
886
/** @class by_id_sorter
887
* @brief Sorts edges by their ids
888
*/
889
class by_id_sorter {
890
public:
891
/// @brief constructor
892
explicit by_id_sorter() { }
893
894
/// @brief comparing operator
895
int operator()(const MSEdge* const e1, const MSEdge* const e2) const {
896
return e1->getNumericalID() < e2->getNumericalID();
897
}
898
899
};
900
901
/** @class transportable_by_position_sorter
902
* @brief Sorts transportables by their positions
903
*/
904
class transportable_by_position_sorter {
905
public:
906
/// @brief constructor
907
explicit transportable_by_position_sorter(SUMOTime timestep): myTime(timestep) { }
908
909
/// @brief comparing operator
910
int operator()(const MSTransportable* const c1, const MSTransportable* const c2) const;
911
private:
912
SUMOTime myTime;
913
};
914
915
916
/// @brief return upper bound for the depart position on this edge
917
double getDepartPosBound(const MSVehicle& veh, bool upper = true) const;
918
919
protected:
920
/// @brief This edge's numerical id
921
const int myNumericalID;
922
923
/// @brief Container for the edge's lane; should be sorted: (right-hand-traffic) the more left the lane, the higher the container-index
924
std::shared_ptr<const std::vector<MSLane*> > myLanes;
925
926
/// @brief This member will do the lane-change
927
MSLaneChanger* myLaneChanger;
928
929
/// @brief the purpose of the edge
930
const SumoXMLEdgeFunc myFunction;
931
932
/// @brief Vaporizer counter
933
int myVaporizationRequests;
934
935
/// @brief The time of last insertion failure
936
mutable SUMOTime myLastFailedInsertionTime;
937
938
/// @brief A cache for the rejected insertion attempts. Used to assure that no
939
/// further insertion attempts are made on a lane where an attempt has
940
/// already failed in the current time step if MSInsertionControl::myEagerInsertionCheck is off.
941
mutable std::set<int> myFailedInsertionMemory;
942
943
/// @brief The crossed edges id for a crossing edge. On not crossing edges it is empty
944
std::vector<std::string> myCrossingEdges;
945
946
/// @brief The succeeding edges
947
MSEdgeVector mySuccessors;
948
949
MSConstEdgePairVector myViaSuccessors;
950
951
/// @brief The preceeding edges
952
MSEdgeVector myPredecessors;
953
954
/// @brief the junctions for this edge
955
MSJunction* myFromJunction;
956
MSJunction* myToJunction;
957
958
/// @brief Persons on the edge for drawing and pushbutton
959
mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myPersons;
960
961
/// @brief Containers on the edge
962
mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myContainers;
963
964
/// @name Storages for allowed lanes (depending on vehicle classes)
965
/// @{
966
967
/// @brief Associative container from vehicle class to allowed-lanes.
968
AllowedLanesCont myAllowed;
969
AllowedLanesCont myOrigAllowed;
970
971
/// @brief From target edge to lanes allowed to be used to reach it
972
AllowedLanesByTarget myAllowedTargets;
973
AllowedLanesByTarget myOrigAllowedTargets;
974
975
/// @brief The intersection of lane permissions for this edge
976
SVCPermissions myMinimumPermissions = SVCAll;
977
/// @brief The union of lane permissions for this edge
978
SVCPermissions myCombinedPermissions = 0;
979
980
/// @brief The original intersection of lane permissions for this edge (before temporary modifications)
981
SVCPermissions myOriginalMinimumPermissions = SVCAll;
982
/// @brief The original union of lane permissions for this edge (before temporary modifications)
983
SVCPermissions myOriginalCombinedPermissions;
984
985
/// @brief whether transient permission changes were applied to this edge or a predecessor
986
bool myHaveTransientPermissions;
987
/// @}
988
989
/// @brief the other taz-connector if this edge isTazConnector, otherwise nullptr
990
const MSEdge* myOtherTazConnector;
991
992
/// @brief the real-world name of this edge (need not be unique)
993
std::string myStreetName;
994
995
/// @brief the type of the edge (optionally used during network creation)
996
std::string myEdgeType;
997
998
/// @brief the routing type of the edge (used to look up vType and vClass specific routing preferences)
999
std::string myRoutingType;
1000
1001
/// @brief the priority of the edge (used during network creation)
1002
const int myPriority;
1003
1004
/// @brief the kilometrage/mileage at the start of the edge
1005
const double myDistance;
1006
1007
/// Edge width [m]
1008
double myWidth;
1009
1010
/// @brief the length of the edge (cached value for speedup)
1011
double myLength;
1012
1013
/// @brief the traveltime on the empty edge (cached value for speedup)
1014
double myEmptyTraveltime;
1015
1016
/// @brief flat penalty when computing traveltime
1017
double myTimePenalty;
1018
1019
/// @brief whether this edge had a vehicle with less than max speed on it
1020
mutable bool myAmDelayed;
1021
1022
/// @brief whether this edge belongs to a roundabout
1023
bool myAmRoundabout;
1024
1025
/// @brief whether this edge is at the network fringe
1026
bool myAmFringe;
1027
1028
/// @brief the right side for each sublane on this edge
1029
std::vector<double> mySublaneSides;
1030
1031
/// @name Static edge container
1032
/// @{
1033
1034
/// @brief definition of the static dictionary type
1035
typedef std::map< std::string, MSEdge* > DictType;
1036
1037
/** @brief Static dictionary to associate string-ids with objects.
1038
* @deprecated Move to MSEdgeControl, make non-static
1039
*/
1040
static DictType myDict;
1041
1042
/** @brief Static list of edges
1043
* @deprecated Move to MSEdgeControl, make non-static
1044
*/
1045
static MSEdgeVector myEdges;
1046
1047
static SVCPermissions myMesoIgnoredVClasses;
1048
1049
static DepartLaneDefinition myDefaultDepartLaneDefinition;
1050
static int myDefaultDepartLane;
1051
/// @}
1052
1053
1054
/// @brief The successors available for a given vClass
1055
mutable std::map<SUMOVehicleClass, MSEdgeVector> myClassesSuccessorMap;
1056
1057
/// @brief The successors available for a given vClass
1058
mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myClassesViaSuccessorMap;
1059
mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myOrigClassesViaSuccessorMap;
1060
1061
/// @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
1062
Boundary myBoundary;
1063
1064
/// @brief List of waiting vehicles
1065
mutable std::vector<SUMOVehicle*> myWaiting;
1066
1067
#ifdef HAVE_FOX
1068
/// @brief Mutex for accessing waiting vehicles
1069
mutable FXMutex myWaitingMutex;
1070
1071
/// @brief Mutex for accessing successor edges
1072
mutable FXMutex mySuccessorMutex;
1073
#endif
1074
1075
private:
1076
1077
/// @brief the oppositing superposable edge
1078
const MSEdge* myBidiEdge;
1079
1080
/// @brief a reversed version for backward routing
1081
mutable ReversedEdge<MSEdge, SUMOVehicle>* myReversedRoutingEdge = nullptr;
1082
mutable RailEdge<MSEdge, SUMOVehicle>* myRailwayRoutingEdge = nullptr;
1083
1084
/// @brief Invalidated copy constructor.
1085
MSEdge(const MSEdge&);
1086
1087
/// @brief assignment operator.
1088
MSEdge& operator=(const MSEdge&) = delete;
1089
1090
void setBidiLanes();
1091
1092
bool isSuperposable(const MSEdge* other);
1093
1094
void addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const;
1095
};
1096
1097