Eclipse SUMO - Simulation of Urban MObility
MSEdge.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2023 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/****************************************************************************/
24// A road/street connecting two junctions
25/****************************************************************************/
26#include <config.h>
27
28#include <algorithm>
29#include <iostream>
30#include <cassert>
31#ifdef HAVE_FOX
33#endif
37#include <mesosim/MELoop.h>
38#include <mesosim/MESegment.h>
39#include <mesosim/MEVehicle.h>
40#include "MSInsertionControl.h"
41#include "MSJunction.h"
42#include "MSLane.h"
43#include "MSLaneChanger.h"
45#include "MSLink.h"
46#include "MSGlobals.h"
47#include "MSNet.h"
48#include "MSVehicle.h"
49#include "MSLeaderInfo.h"
52#include "MSEdge.h"
53
54#define BEST_LANE_LOOKAHEAD 3000.0
55
56// ===========================================================================
57// static member definitions
58// ===========================================================================
62
63
64// ===========================================================================
65// member method definitions
66// ===========================================================================
67MSEdge::MSEdge(const std::string& id, int numericalID,
68 const SumoXMLEdgeFunc function,
69 const std::string& streetName,
70 const std::string& edgeType,
71 int priority,
72 double distance) :
73 Named(id), myNumericalID(numericalID), myLanes(nullptr),
74 myLaneChanger(nullptr), myFunction(function), myVaporizationRequests(0),
75 myLastFailedInsertionTime(-1),
76 myFromJunction(nullptr), myToJunction(nullptr),
77 myOtherTazConnector(nullptr),
78 myStreetName(streetName),
79 myEdgeType(edgeType),
80 myPriority(priority),
81 myDistance(distance),
82 myWidth(0.),
83 myLength(0.),
84 myEmptyTraveltime(0.),
85 myTimePenalty(0.),
86 myAmDelayed(false),
87 myAmRoundabout(false),
88 myAmFringe(true),
89 myBidiEdge(nullptr)
90{ }
91
92
94 delete myLaneChanger;
97}
98
99
100void
101MSEdge::initialize(const std::vector<MSLane*>* lanes) {
102 assert(lanes != 0);
103 myLanes = std::shared_ptr<const std::vector<MSLane*> >(lanes);
106 }
107 for (MSLane* const lane : *lanes) {
108 lane->setRightSideOnEdge(myWidth, (int)mySublaneSides.size());
109 MSLeaderInfo ahead(lane->getWidth());
110 for (int j = 0; j < ahead.numSublanes(); ++j) {
112 }
113 myWidth += lane->getWidth();
114 }
115}
116
117
119 if (myLanes->empty()) {
120 return;
121 }
122 myLength = myLanes->front()->getLength();
123 myEmptyTraveltime = myLength / MAX2(getSpeedLimit(), NUMERICAL_EPS);
125 SUMOTime minorPenalty = 0;
126 bool haveTLSPenalty = MSGlobals::gTLSPenalty > 0;
129 minorPenalty = edgeType.minorPenalty;
130 haveTLSPenalty = edgeType.tlsPenalty > 0;
131 }
132 if (haveTLSPenalty || minorPenalty > 0) {
133 // add tls penalties to the minimum travel time
134 SUMOTime minPenalty = -1;
135 for (const MSLane* const l : *myLanes) {
136 for (const MSLink* const link : l->getLinkCont()) {
137 SUMOTime linkPenalty = link->isTLSControlled() ? link->getMesoTLSPenalty() : (link->havePriority() ? 0 : minorPenalty);
138 if (minPenalty == -1) {
139 minPenalty = linkPenalty;
140 } else {
141 minPenalty = MIN2(minPenalty, linkPenalty);
142 }
143 }
144 }
145 if (minPenalty > 0) {
146 myEmptyTraveltime += STEPS2TIME(minPenalty);
147 myTimePenalty = STEPS2TIME(minPenalty);
148 }
149 }
150 }
152 const MSLink* link = myLanes->front()->getIncomingLanes()[0].viaLink;
153 if (!link->isTLSControlled() && !link->havePriority()) {
156 }
157 }
158}
159
160
161void
163 mySuccessors.clear();
164 myPredecessors.clear();
165 for (const MSEdge* edge : junction->getIncoming()) {
166 if (!edge->isInternal()) {
167 MSEdgeVector& succ = const_cast<MSEdgeVector&>(edge->mySuccessors);
168 MSConstEdgePairVector& succVia = const_cast<MSConstEdgePairVector&>(edge->myViaSuccessors);
169 MSEdgeVector& pred = const_cast<MSEdgeVector&>(edge->myPredecessors);
170 auto it = std::find(succ.begin(), succ.end(), this);
171 auto it2 = std::find(succVia.begin(), succVia.end(), std::make_pair(const_cast<const MSEdge*>(this), (const MSEdge*)nullptr));
172 auto it3 = std::find(pred.begin(), pred.end(), this);
173 if (it != succ.end()) {
174 succ.erase(it);
175 succVia.erase(it2);
176 }
177 if (it3 != pred.end()) {
178 pred.erase(it3);
179 }
180 }
181 }
182}
183
184void
186 for (MSLane* const lane : *myLanes) {
187 for (MSLink* const link : lane->getLinkCont()) {
188 link->initParallelLinks();
189 MSLane* const toL = link->getLane();
190 MSLane* const viaL = link->getViaLane();
191 if (toL != nullptr) {
192 MSEdge& to = toL->getEdge();
193 if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
194 mySuccessors.push_back(&to);
195 myViaSuccessors.push_back(std::make_pair(&to, (viaL == nullptr ? nullptr : &viaL->getEdge())));
196 }
197 if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
198 to.myPredecessors.push_back(this);
199 }
200 if (link->getDirection() != LinkDirection::TURN) {
201 myAmFringe = false;
202 }
203 }
204 if (viaL != nullptr) {
205 MSEdge& to = viaL->getEdge();
206 if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
207 to.myPredecessors.push_back(this);
208 }
209 }
210 }
211 lane->checkBufferType();
212 }
213 std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
215 recalcCache();
216
217 // extend lookup table for sublane model after all edges are read
218 if (myLanes->back()->getOpposite() != nullptr) {
219 MSLane* opposite = myLanes->back()->getOpposite();
220 MSLeaderInfo ahead(opposite->getWidth());
221 for (int j = 0; j < ahead.numSublanes(); ++j) {
223 }
224 }
225}
226
227
228void
231 if (!myLanes->empty()) {
233 }
234}
235
236
237void
239 if (!myLanes->empty()) {
240 const bool allowChanging = allowsLaneChanging();
242 // may always initiate sublane-change
243 myLaneChanger = new MSLaneChangerSublane(myLanes.get(), allowChanging);
244 } else {
246 myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
247 } else if (myLanes->size() > 1 || canChangeToOpposite()) {
248 myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
249 }
250 }
251 }
252}
253
254
255bool
258 // allow changing only if all links leading to this internal lane have priority
259 // or they are controlled by a traffic light
260 for (const MSLane* const lane : *myLanes) {
261 const MSLink* const link = lane->getLogicalPredecessorLane()->getLinkTo(lane);
262 assert(link != nullptr);
263 const LinkState state = link->getState();
264 if (state == LINKSTATE_MINOR
265 || state == LINKSTATE_EQUAL
266 || state == LINKSTATE_STOP
267 || state == LINKSTATE_ALLWAY_STOP
268 || state == LINKSTATE_DEADEND) {
269 return false;
270 }
271 }
272 }
273 return true;
274}
275
276
277void
278MSEdge::addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const {
279 if (!allowedLanes->empty()) {
280 // recheck whether we had this list to save memory
281 for (auto& allowed : laneCont) {
282 if (*allowed.second == *allowedLanes) {
283 allowed.first |= permissions;
284 return;
285 }
286 }
287 laneCont.push_back(std::make_pair(permissions, allowedLanes));
288 }
289}
290
291
294 SVCPermissions ignored = myMesoIgnoredVClasses & ~ignoreIgnored;
295 return (p | ignored) == ignored ? 0 : p;
296}
297
298
299void
300MSEdge::rebuildAllowedLanes(const bool onInit) {
301 // rebuild myMinimumPermissions and myCombinedPermissions
304 for (MSLane* const lane : *myLanes) {
305 // same dedicated lanes are ignored in meso to avoid capacity errors.
306 // Here we have to make sure that vehicles which are set to depart on
307 // such lanes trigger an error.
308 SVCPermissions allow = getMesoPermissions(lane->getPermissions(), SVC_PEDESTRIAN);
309 myMinimumPermissions &= allow;
310 myCombinedPermissions |= allow;
311 }
312 // rebuild myAllowed
313 myAllowed.clear();
315 myAllowed.push_back(std::make_pair(SVC_IGNORING, myLanes));
316 for (int vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
317 if ((myCombinedPermissions & vclass) == vclass) {
318 std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
319 for (MSLane* const lane : *myLanes) {
320 if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
321 allowedLanes->push_back(lane);
322 }
323 }
325 }
326 }
327 }
328 if (!onInit) {
330 for (MSEdge* pred : myPredecessors) {
331 pred->rebuildAllowedTargets(false);
332 }
334 for (MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(*this); s != nullptr; s = s->getNextSegment()) {
335 s->updatePermissions();
336 }
337 }
338 }
339}
340
341
342void
343MSEdge::rebuildAllowedTargets(const bool updateVehicles) {
344 myAllowedTargets.clear();
345 for (const MSEdge* target : mySuccessors) {
346 bool universalMap = true; // whether the mapping for SVC_IGNORING is also valid for all vehicle classes
347 std::shared_ptr<std::vector<MSLane*> > allLanes = std::make_shared<std::vector<MSLane*> >();
348 // compute the mapping for SVC_IGNORING
349 for (MSLane* const lane : *myLanes) {
350 SVCPermissions combinedTargetPermissions = 0;
351 for (const MSLink* const link : lane->getLinkCont()) {
352 if (&link->getLane()->getEdge() == target) {
353 allLanes->push_back(lane);
354 combinedTargetPermissions |= link->getLane()->getPermissions();
355 if (link->getViaLane() != nullptr &&
356 ((lane->getPermissions() & link->getLane()->getPermissions()) != link->getViaLane()->getPermissions())) {
357 // custom connection permissions
358 universalMap = false;
359 }
360 }
361 }
362 if (combinedTargetPermissions == 0 || (lane->getPermissions() & combinedTargetPermissions) != lane->getPermissions()) {
363 universalMap = false;
364 }
365 }
366 if (universalMap) {
367 if (myAllowed.empty()) {
368 // we have no lane specific permissions
369 myAllowedTargets[target].push_back(std::make_pair(myMinimumPermissions, myLanes));
370 } else {
371 for (const auto& i : myAllowed) {
372 addToAllowed(i.first, i.second, myAllowedTargets[target]);
373 }
374 }
375 } else {
376 addToAllowed(SVC_IGNORING, allLanes, myAllowedTargets[target]);
377 // compute the vclass specific mapping
378 for (int vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
379 if ((myCombinedPermissions & vclass) == vclass) {
380 std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
381 for (MSLane* const lane : *myLanes) {
382 if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
383 for (const MSLink* const link : lane->getLinkCont()) {
384 if (link->getLane()->allowsVehicleClass((SUMOVehicleClass)vclass) && &link->getLane()->getEdge() == target && (link->getViaLane() == nullptr || link->getViaLane()->allowsVehicleClass((SUMOVehicleClass)vclass))) {
385 allowedLanes->push_back(lane);
386 }
387 }
388 }
389 }
391 }
392 }
393 }
394 }
395 if (updateVehicles) {
396 for (const MSLane* const lane : *myLanes) {
397 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
398 for (MSVehicle* veh : vehs) {
399 veh->updateBestLanes(true);
400 }
401 lane->releaseVehicles();
402 }
403 }
404 myClassesSuccessorMap.clear();
405}
406
407
408// ------------ Access to the edge's lanes
409MSLane*
410MSEdge::leftLane(const MSLane* const lane) const {
411 return parallelLane(lane, 1);
412}
413
414
415MSLane*
416MSEdge::rightLane(const MSLane* const lane) const {
417 return parallelLane(lane, -1);
418}
419
420
421MSLane*
422MSEdge::parallelLane(const MSLane* const lane, int offset, bool includeOpposite) const {
423 const int resultIndex = lane->getIndex() + offset;
424 if (resultIndex >= getNumLanes() && includeOpposite) {
425 const MSEdge* opposite = getOppositeEdge();
426 if (opposite != nullptr && resultIndex < getNumLanes() + opposite->getNumLanes()) {
427 return opposite->getLanes()[opposite->getNumLanes() + getNumLanes() - resultIndex - 1];
428 }
429 return nullptr;
430 } else if (resultIndex >= (int)myLanes->size() || resultIndex < 0) {
431 return nullptr;
432 } else {
433 return (*myLanes)[resultIndex];
434 }
435}
436
437
438const std::vector<MSLane*>*
439MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
440 AllowedLanesByTarget::const_iterator i = myAllowedTargets.find(&destination);
441 if (i != myAllowedTargets.end()) {
442 for (const auto& allowed : i->second) {
443 if ((allowed.first & vclass) == vclass) {
444 return allowed.second.get();
445 }
446 }
447 }
448 return nullptr;
449}
450
451
452const std::vector<MSLane*>*
454 if ((myMinimumPermissions & vclass) == vclass) {
455 return myLanes.get();
456 } else {
457 if ((myCombinedPermissions & vclass) == vclass) {
458 for (const auto& allowed : myAllowed) {
459 if ((allowed.first & vclass) == vclass) {
460 return allowed.second.get();
461 }
462 }
463 }
464 return nullptr;
465 }
466}
467
468
469// ------------
473 return 0;
474}
475
476
480 return 0;
481}
482
483
484MSLane*
485MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const {
486 if (allowed == nullptr) {
487 allowed = allowedLanes(vclass);
488 }
489 MSLane* res = nullptr;
490 if (allowed != nullptr) {
491 double largestGap = 0;
492 MSLane* resByGap = nullptr;
493 double leastOccupancy = std::numeric_limits<double>::max();
494 for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
495 const double occupancy = (*i)->getBruttoOccupancy();
496 if (occupancy < leastOccupancy) {
497 res = (*i);
498 leastOccupancy = occupancy;
499 }
500 const MSVehicle* last = (*i)->getLastFullVehicle();
501 const double lastGap = (last != nullptr ? last->getPositionOnLane() : myLength) - departPos;
502 if (lastGap > largestGap) {
503 largestGap = lastGap;
504 resByGap = (*i);
505 }
506 }
507 if (resByGap != nullptr) {
508 //if (res != resByGap) std::cout << SIMTIME << " edge=" << getID() << " departPos=" << departPos << " res=" << Named::getIDSecure(res) << " resByGap=" << Named::getIDSecure(resByGap) << " largestGap=" << largestGap << "\n";
509 res = resByGap;
510 }
511 }
512 return res;
513}
514
515
516double
517MSEdge::getDepartPosBound(const MSVehicle& veh, bool upper) const {
518 const SUMOVehicleParameter& pars = veh.getParameter();
519 double pos = getLength();
520 // determine the position
521 switch (pars.departPosProcedure) {
523 pos = pars.departPos;
524 if (pos < 0.) {
525 pos += myLength;
526 }
527 break;
529 // could be any position on the edge
530 break;
532 // could be any position on the edge due to multiple random attempts
533 break;
535 // many candidate positions, upper bound could be computed exactly
536 // with much effort
537 break;
539 if (upper) {
540 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
541 MSVehicle* last = (*i)->getLastFullVehicle();
542 if (last != nullptr) {
543 pos = MIN2(pos, last->getPositionOnLane());
544 }
545 }
546 } else {
547 pos = 0;
548 }
549 break;
552 if (!upper) {
553 pos = 0;
554 }
555 break;
556 default:
557 pos = MIN2(pos, veh.getVehicleType().getLength());
558 break;
559 }
560 return pos;
561}
562
563MSLane*
566 if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
567 return nullptr;
568 }
569 return (*myLanes)[veh.getParameter().departLane];
570 }
571 return (*myLanes)[0];
572}
573
574MSLane*
576 switch (veh.getParameter().departLaneProcedure) {
578 if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
579 return nullptr;
580 }
581 return (*myLanes)[veh.getParameter().departLane];
585 return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
587 if (veh.getRoute().size() == 1) {
588 return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
589 } else {
591 }
593 veh.updateBestLanes(false, myLanes->front());
594 const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes();
595 double bestLength = -1;
596 for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
597 if ((*i).length > bestLength) {
598 bestLength = (*i).length;
599 }
600 }
601 // beyond a certain length, all lanes are suitable
602 // however, we still need to check departPos to avoid unsuitable insertion
603 // (this is only possible in some cases)
604 double departPos = 0;
605 if (bestLength > BEST_LANE_LOOKAHEAD) {
606 departPos = getDepartPosBound(veh);
607 bestLength = MIN2(bestLength - departPos, BEST_LANE_LOOKAHEAD);
608 }
609 std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
610 for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
611 if (((*i).length - departPos) >= bestLength) {
612 bestLanes->push_back((*i).lane);
613 }
614 }
615 MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
616 delete bestLanes;
617 return ret;
618 }
621 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
622 if ((*i)->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
623 return *i;
624 }
625 }
626 return nullptr;
627 default:
628 break;
629 }
630 if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
631 return nullptr;
632 }
633 return (*myLanes)[0];
634}
635
636bool
638 const SUMOVehicleParameter& pars = v.getParameter();
639 const MSVehicleType& type = v.getVehicleType();
641 // departSpeed could have been rounded down in the output
642 double vMax = getVehicleMaxSpeed(&v) + SPEED_EPS;
643 if (pars.departSpeed > vMax) {
644 // check departLane (getVehicleMaxSpeed checks lane 0)
645 MSLane* departLane = MSGlobals::gMesoNet ? getDepartLaneMeso(v) : getDepartLane(dynamic_cast<MSVehicle&>(v));
646 if (departLane != nullptr) {
647 vMax = departLane->getVehicleMaxSpeed(&v);
649 // speedFactor could have been rounded down in the output
650 vMax *= (1 + SPEED_EPS);
651 }
652 // additive term must come after multiplication!
653 vMax += SPEED_EPS;
654 if (pars.departSpeed > vMax) {
655 const std::vector<double>& speedFactorParams = type.getSpeedFactor().getParameter();
656 if (speedFactorParams[1] > 0.) {
658 if (v.getChosenSpeedFactor() > speedFactorParams[0] + 2 * speedFactorParams[1]) {
659 // only warn for significant deviation
660 WRITE_WARNINGF(TL("Choosing new speed factor % for vehicle '%' to match departure speed % (max %)."),
661 toString(v.getChosenSpeedFactor()), pars.id, pars.departSpeed, vMax);
662 }
663 } else {
664 return false;
665 }
666 }
667 }
668 }
669 }
670 return true;
671}
672
673
674bool
675MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly, const bool forceCheck) const {
676 // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal
678 || v.getRouteValidity(true, checkOnly) != MSBaseVehicle::ROUTE_VALID) {
679 return checkOnly;
680 }
681 const SUMOVehicleParameter& pars = v.getParameter();
682 if (!validateDepartSpeed(v)) {
683 const std::string errorMsg = "Departure speed for vehicle '" + pars.id + "' is too high for the departure edge '" + getID() + "'.";
685 throw ProcessError(errorMsg);
686 } else {
687 WRITE_WARNING(errorMsg);
688 }
689 }
691 if (!forceCheck && myLastFailedInsertionTime == time) {
692 return false;
693 }
694 double pos = 0.0;
695 switch (pars.departPosProcedure) {
697 if (pars.departPos >= 0.) {
698 pos = pars.departPos;
699 } else {
700 pos = pars.departPos + getLength();
701 }
702 if (pos < 0 || pos > getLength()) {
703 WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
704 v.getID() + "'. Inserting at lane end instead.");
705 pos = getLength();
706 }
707 break;
711 break;
712 default:
713 break;
714 }
715 bool result = false;
716 MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
717 MEVehicle* veh = static_cast<MEVehicle*>(&v);
718 int qIdx;
720 while (segment != nullptr && !result) {
721 if (checkOnly) {
722 result = segment->hasSpaceFor(veh, time, qIdx, true) == time;
723 } else {
724 result = segment->initialise(veh, time);
725 }
726 segment = segment->getNextSegment();
727 }
728 } else {
729 if (checkOnly) {
730 result = segment->hasSpaceFor(veh, time, qIdx, true) == time;
731 } else {
732 result = segment->initialise(veh, time);
733 }
734 }
735 return result;
736 }
737 if (checkOnly) {
738 switch (v.getParameter().departLaneProcedure) {
742 MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
743 if (insertionLane == nullptr) {
744 WRITE_WARNING("could not insert vehicle '" + v.getID() + "' on any lane of edge '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()));
745 return false;
746 }
747 const double occupancy = insertionLane->getBruttoOccupancy();
748 return occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength;
749 }
750 default:
751 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
752 const double occupancy = (*i)->getBruttoOccupancy();
753 if (occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength) {
754 return true;
755 }
756 }
757 }
758 return false;
759 }
760 MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
761 if (insertionLane == nullptr) {
762 return false;
763 }
764
765 if (!forceCheck) {
766 if (myLastFailedInsertionTime == time) {
767 if (myFailedInsertionMemory.count(insertionLane->getIndex())) {
768 // A vehicle was already rejected for the proposed insertionLane in this timestep
769 return false;
770 }
771 } else {
772 // last rejection occurred in a previous timestep, clear cache
774 }
775 }
776
777 bool success = insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
778
779 if (!success) {
780 // constraints may enforce explicit re-ordering so we need to try other vehicles after failure
781 if (!insertionLane->knowsParameter("insertionOrder" + v.getID())) {
782 myFailedInsertionMemory.insert(insertionLane->getIndex());
783 }
784 }
785 return success;
786}
787
788
789void
791 if (myLaneChanger != nullptr) {
793 }
794}
795
796
797const MSEdge*
798MSEdge::getInternalFollowingEdge(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const {
799 //@todo to be optimized
800 for (const MSLane* const l : *myLanes) {
801 for (const MSLink* const link : l->getLinkCont()) {
802 if (&link->getLane()->getEdge() == followerAfterInternal) {
803 if (link->getViaLane() != nullptr) {
804 if (link->getViaLane()->allowsVehicleClass(vClass)) {
805 return &link->getViaLane()->getEdge();
806 } else {
807 continue;
808 }
809 } else {
810 return nullptr; // network without internal links
811 }
812 }
813 }
814 }
815 return nullptr;
816}
817
818
819double
820MSEdge::getInternalFollowingLengthTo(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const {
821 assert(followerAfterInternal != 0);
822 assert(!followerAfterInternal->isInternal());
823 double dist = 0.;
824 const MSEdge* edge = getInternalFollowingEdge(followerAfterInternal, vClass);
825 // Take into account non-internal lengths until next non-internal edge
826 while (edge != nullptr && edge->isInternal()) {
827 dist += edge->getLength();
828 edge = edge->getInternalFollowingEdge(followerAfterInternal, vClass);
829 }
830 return dist;
831}
832
833
834const MSEdge*
836 const MSEdge* result = this;
837 while (result->isInternal() && MSGlobals::gUsingInternalLanes) {
838 assert(result->getPredecessors().size() == 1);
839 result = result->getPredecessors().front();
840 }
841 return result;
842}
843
844const MSEdge*
846 const MSEdge* result = this;
847 while (result->isInternal()) {
848 assert(result->getSuccessors().size() == 1);
849 result = result->getSuccessors().front();
850 }
851 return result;
852}
853
854double
856 double v = 0;
857 double totalNumVehs = 0;
859 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
860 const int numVehs = segment->getCarNumber();
861 if (numVehs > 0) {
862 v += numVehs * segment->getMeanSpeed();
863 totalNumVehs += numVehs;
864 }
865 }
866 if (totalNumVehs == 0) {
867 return getLength() / myEmptyTraveltime; // may include tls-penalty
868 }
869 } else {
870 for (const MSLane* const lane : *myLanes) {
871 int numVehs = lane->getVehicleNumber();
872 if (numVehs == 0) {
873 // take speed limit but with lowest possible weight
874 numVehs = 1;
875 }
876 v += numVehs * lane->getMeanSpeed();
877 totalNumVehs += numVehs;
878 }
879 if (myBidiEdge != nullptr) {
880 for (const MSLane* const lane : myBidiEdge->getLanes()) {
881 if (lane->getVehicleNumber() > 0) {
882 // do not route across edges which are already occupied in reverse direction
883 return 0;
884 }
885 }
886 }
887 if (totalNumVehs == 0) {
888 return getSpeedLimit();
889 }
890 }
891 return v / totalNumVehs;
892}
893
894
895double
897 double f = 0.;
898 for (const MSLane* const lane : *myLanes) {
899 f += lane->getFrictionCoefficient();
900 }
901 if (!myLanes->empty()) {
902 return f / (double)myLanes->size();
903 }
904 return 1.;
905}
906
907
908double
911 // no separate bicycle speeds in meso
912 return getMeanSpeed();
913 }
914 double v = 0;
915 double totalNumVehs = 0;
916 for (const MSLane* const lane : *myLanes) {
917 const int numVehs = lane->getVehicleNumber();
918 v += numVehs * lane->getMeanSpeedBike();
919 totalNumVehs += numVehs;
920 }
921 if (totalNumVehs == 0) {
922 return getSpeedLimit();
923 }
924 return v / totalNumVehs;
925}
926
927
928double
929MSEdge::getCurrentTravelTime(double minSpeed) const {
930 assert(minSpeed > 0);
931 if (!myAmDelayed) {
932 return myEmptyTraveltime;
933 }
934 return getLength() / MAX2(minSpeed, getMeanSpeed());
935}
936
937
938double
940 return MSRoutingEngine::getAssumedSpeed(this, nullptr);
941}
942
943
944bool
945MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
946 const DictType::iterator it = myDict.lower_bound(id);
947 if (it == myDict.end() || it->first != id) {
948 // id not in myDict
949 myDict.emplace_hint(it, id, ptr);
950 while (ptr->getNumericalID() >= (int)myEdges.size()) {
951 myEdges.push_back(nullptr);
952 }
953 myEdges[ptr->getNumericalID()] = ptr;
954 return true;
955 }
956 return false;
957}
958
959
960MSEdge*
961MSEdge::dictionary(const std::string& id) {
962 const DictType::iterator it = myDict.find(id);
963 if (it == myDict.end()) {
964 return nullptr;
965 }
966 return it->second;
967}
968
969
970MSEdge*
971MSEdge::dictionaryHint(const std::string& id, const int startIdx) {
972 // this method is mainly useful when parsing connections from the net.xml which are sorted by "from" id
973 if (myEdges[startIdx] != nullptr && myEdges[startIdx]->getID() == id) {
974 return myEdges[startIdx];
975 }
976 if (startIdx + 1 < (int)myEdges.size() && myEdges[startIdx + 1] != nullptr && myEdges[startIdx + 1]->getID() == id) {
977 return myEdges[startIdx + 1];
978 }
979 return dictionary(id);
980}
981
982
983const MSEdgeVector&
985 return myEdges;
986}
987
988
989void
991 for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
992 delete (*i).second;
993 }
994 myDict.clear();
995 myEdges.clear();
996}
997
998
999void
1000MSEdge::insertIDs(std::vector<std::string>& into) {
1001 for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1002 into.push_back((*i).first);
1003 }
1004}
1005
1006
1007void
1008MSEdge::parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
1009 const std::string& rid) {
1010 StringTokenizer st(desc);
1011 parseEdgesList(st.getVector(), into, rid);
1012}
1013
1014
1015void
1016MSEdge::parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
1017 const std::string& rid) {
1018 for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
1019 const MSEdge* edge = MSEdge::dictionary(*i);
1020 // check whether the edge exists
1021 if (edge == nullptr) {
1022 throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
1023 + "\n The route can not be build.");
1024 }
1025 into.push_back(edge);
1026 }
1027}
1028
1029
1030double
1031MSEdge::getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate) const {
1032 assert(this != other);
1033 if (doBoundaryEstimate) {
1034 return myBoundary.distanceTo2D(other->myBoundary);
1035 }
1036 if (isTazConnector()) {
1037 if (other->isTazConnector()) {
1038 return myBoundary.distanceTo2D(other->myBoundary);
1039 }
1040 return myBoundary.distanceTo2D(other->getLanes()[0]->getShape()[0]);
1041 }
1042 if (other->isTazConnector()) {
1043 return other->myBoundary.distanceTo2D(getLanes()[0]->getShape()[-1]);
1044 }
1045 return getLanes()[0]->getShape()[-1].distanceTo2D(other->getLanes()[0]->getShape()[0]);
1046}
1047
1048
1049const Position
1051 return MSLane::dictionary(stop.lane)->geometryPositionAtOffset((stop.endPos + stop.startPos) / 2.);
1052}
1053
1054
1055double
1057 // @note lanes might have different maximum speeds in theory
1058 return myLanes->empty() ? 1 : getLanes()[0]->getSpeedLimit();
1059}
1060
1061
1062double
1064 return myLanes->empty() ? 1 : getLanes()[0]->getLengthGeometryFactor();
1065}
1066
1067double
1069 // @note lanes might have different maximum speeds in theory
1070 return myLanes->empty() ? 1 : getLanes()[0]->getVehicleMaxSpeed(veh);
1071}
1072
1073
1074void
1075MSEdge::setMaxSpeed(double val) const {
1076 assert(val >= 0);
1077 if (myLanes != nullptr) {
1078 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
1079 (*i)->setMaxSpeed(val);
1080 }
1081 }
1082}
1083
1084
1085void
1087 if (t->isPerson()) {
1088 myPersons.insert(t);
1089 } else {
1090 myContainers.insert(t);
1091 }
1092}
1093
1094void
1096 std::set<MSTransportable*, ComparatorNumericalIdLess>& tc = t->isPerson() ? myPersons : myContainers;
1097 auto it = tc.find(t);
1098 if (it != tc.end()) {
1099 tc.erase(it);
1100 }
1101}
1102
1103std::vector<MSTransportable*>
1104MSEdge::getSortedPersons(SUMOTime timestep, bool includeRiding) const {
1105 std::vector<MSTransportable*> result(myPersons.begin(), myPersons.end());
1106 if (includeRiding) {
1107 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
1108 const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
1109 for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
1110 const std::vector<MSTransportable*>& persons = (*j)->getPersons();
1111 result.insert(result.end(), persons.begin(), persons.end());
1112 }
1113 (*i)->releaseVehicles();
1114 }
1115 }
1116 sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
1117 return result;
1118}
1119
1120
1121std::vector<MSTransportable*>
1122MSEdge::getSortedContainers(SUMOTime timestep, bool /* includeRiding */) const {
1123 std::vector<MSTransportable*> result(myContainers.begin(), myContainers.end());
1124 sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
1125 return result;
1126}
1127
1128
1129int
1131 const double pos1 = c1->getCurrentStage()->getEdgePos(myTime);
1132 const double pos2 = c2->getCurrentStage()->getEdgePos(myTime);
1133 if (pos1 != pos2) {
1134 return pos1 < pos2;
1135 }
1136 return c1->getID() < c2->getID();
1137}
1138
1139
1140void
1142 mySuccessors.push_back(edge);
1143 myViaSuccessors.push_back(std::make_pair(edge, via));
1144 if (isTazConnector() && edge->getFromJunction() != nullptr) {
1146 }
1147
1148 edge->myPredecessors.push_back(this);
1149 if (edge->isTazConnector() && getToJunction() != nullptr) {
1150 edge->myBoundary.add(getToJunction()->getPosition());
1151 }
1152}
1153
1154
1155const MSEdgeVector&
1157 if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == SumoXMLEdgeFunc::CONNECTOR) {
1158 return mySuccessors;
1159 }
1160#ifdef HAVE_FOX
1161 ScopedLocker<> lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
1162#endif
1163 std::map<SUMOVehicleClass, MSEdgeVector>::iterator i = myClassesSuccessorMap.find(vClass);
1164 if (i == myClassesSuccessorMap.end()) {
1165 // instantiate vector
1166 myClassesSuccessorMap[vClass];
1167 i = myClassesSuccessorMap.find(vClass);
1168 // this vClass is requested for the first time. rebuild all successors
1169 for (MSEdgeVector::const_iterator it = mySuccessors.begin(); it != mySuccessors.end(); ++it) {
1170 if ((*it)->isTazConnector()) {
1171 i->second.push_back(*it);
1172 } else {
1173 const std::vector<MSLane*>* allowed = allowedLanes(**it, vClass);
1174 if (allowed != nullptr && allowed->size() > 0) {
1175 i->second.push_back(*it);
1176 }
1177 }
1178 }
1179 }
1180 // can use cached value
1181 return i->second;
1182}
1183
1184
1187 if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == SumoXMLEdgeFunc::CONNECTOR) {
1188 return myViaSuccessors;
1189 }
1190#ifdef HAVE_FOX
1191 ScopedLocker<> lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
1192#endif
1193 auto i = myClassesViaSuccessorMap.find(vClass);
1194 if (i != myClassesViaSuccessorMap.end()) {
1195 // can use cached value
1196 return i->second;
1197 }
1198 // instantiate vector
1200 // this vClass is requested for the first time. rebuild all successors
1201 for (const auto& viaPair : myViaSuccessors) {
1202 if (viaPair.first->isTazConnector()) {
1203 result.push_back(viaPair);
1204 } else {
1205 const std::vector<MSLane*>* allowed = allowedLanes(*viaPair.first, vClass);
1206 if (allowed != nullptr && allowed->size() > 0) {
1207 result.push_back(viaPair);
1208 }
1209 }
1210 }
1211 return result;
1212}
1213
1214
1215void
1217 myFromJunction = from;
1218 myToJunction = to;
1219 if (!isTazConnector()) {
1220 myBoundary.add(from->getPosition());
1221 myBoundary.add(to->getPosition());
1222 }
1223}
1224
1225
1226bool
1228 return (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr &&
1229 // do not change on curved internal lanes
1230 (!isInternal()
1232 && myLanes->back()->getIncomingLanes()[0].viaLink->getDirection() == LinkDirection::STRAIGHT)));
1233}
1234
1235
1236const MSEdge*
1238 if (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr) {
1239 return &(myLanes->back()->getOpposite()->getEdge());
1240 } else {
1241 return nullptr;
1242 }
1243}
1244
1245
1246bool
1248 for (const MSLane* const l : *myLanes) {
1249 for (const MSLink* const link : l->getLinkCont()) {
1250 if (!link->havePriority()) {
1251 return true;
1252 }
1253 }
1254 }
1255 return false;
1256}
1257
1258
1259void
1260MSEdge::checkAndRegisterBiDirEdge(const std::string& bidiID) {
1261 if (bidiID != "") {
1262 myBidiEdge = dictionary(bidiID);
1263 if (myBidiEdge == nullptr) {
1264 WRITE_ERRORF(TL("Bidi-edge '%' does not exist"), bidiID);
1265 }
1266 setBidiLanes();
1267 return;
1268 }
1270 return;
1271 }
1272 // legacy networks (no bidi attribute)
1274 for (ConstMSEdgeVector::const_iterator it = candidates.begin(); it != candidates.end(); it++) {
1275 if ((*it)->getToJunction() == myFromJunction) { //reverse edge
1276 if (myBidiEdge != nullptr && isSuperposable(*it)) {
1277 WRITE_WARNINGF(TL("Ambiguous superposable edges between junction '%' and '%'."), myToJunction->getID(), myFromJunction->getID());
1278 break;
1279 }
1280 if (isSuperposable(*it)) {
1281 myBidiEdge = *it;
1282 setBidiLanes();
1283 }
1284 }
1285 }
1286}
1287
1288
1289void
1291 assert(myBidiEdge != nullptr);
1292 if (getNumLanes() == 1 && myBidiEdge->getNumLanes() == 1) {
1293 // the other way round is set when this method runs for the bidiEdge
1294 getLanes()[0]->setBidiLane(myBidiEdge->getLanes()[0]);
1295 } else {
1296 // find lanes with matching reversed shapes
1297 int numBidiLanes = 0;
1298 for (MSLane* l1 : *myLanes) {
1299 for (MSLane* l2 : *myBidiEdge->myLanes) {
1300 if (l1->getShape().reverse().almostSame(l2->getShape(), POSITION_EPS)) {
1301 l1->setBidiLane(l2);
1302 numBidiLanes++;
1303 }
1304 }
1305 }
1306 // warn only once for each pair
1307 if (numBidiLanes == 0 && getID() < myBidiEdge->getID()) {
1308 WRITE_WARNINGF(TL("Edge '%s' and bidi edge '%s' have no matching bidi lanes"), getID(), myBidiEdge->getID());
1309 }
1310 }
1311}
1312
1313
1314bool
1316 if (other == nullptr || other->getLanes().size() != myLanes->size()) {
1317 return false;
1318 }
1319 std::vector<MSLane*>::const_iterator it1 = myLanes->begin();
1320 std::vector<MSLane*>::const_reverse_iterator it2 = other->getLanes().rbegin();
1321 do {
1322 if ((*it1)->getShape().reverse() != (*it2)->getShape()) {
1323 return false;
1324 }
1325 it1++;
1326 it2++;
1327 } while (it1 != myLanes->end());
1328
1329 return true;
1330}
1331
1332
1333void
1335#ifdef HAVE_FOX
1336 ScopedLocker<> lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1337#endif
1338 myWaiting.push_back(vehicle);
1339}
1340
1341
1342void
1343MSEdge::removeWaiting(const SUMOVehicle* vehicle) const {
1344#ifdef HAVE_FOX
1345 ScopedLocker<> lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1346#endif
1347 std::vector<SUMOVehicle*>::iterator it = std::find(myWaiting.begin(), myWaiting.end(), vehicle);
1348 if (it != myWaiting.end()) {
1349 myWaiting.erase(it);
1350 }
1351}
1352
1353
1355MSEdge::getWaitingVehicle(MSTransportable* transportable, const double position) const {
1356#ifdef HAVE_FOX
1357 ScopedLocker<> lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1358#endif
1359 for (SUMOVehicle* const vehicle : myWaiting) {
1360 if (transportable->isWaitingFor(vehicle)) {
1361 if (vehicle->isStoppedInRange(position, MSGlobals::gStopTolerance) ||
1362 (!vehicle->hasDeparted() &&
1363 (vehicle->getParameter().departProcedure == DepartDefinition::TRIGGERED ||
1364 vehicle->getParameter().departProcedure == DepartDefinition::CONTAINER_TRIGGERED))) {
1365 return vehicle;
1366 }
1367 if (!vehicle->isLineStop(position) && vehicle->allowsBoarding(transportable)) {
1368 WRITE_WARNING((transportable->isPerson() ? "Person '" : "Container '")
1369 + transportable->getID() + "' at edge '" + getID() + "' position " + toString(position) + " cannot use waiting vehicle '"
1370 + vehicle->getID() + "' at position " + toString(vehicle->getPositionOnLane()) + " because it is too far away.");
1371 }
1372 }
1373 }
1374 return nullptr;
1375}
1376
1377std::vector<const SUMOVehicle*>
1379 std::vector<const SUMOVehicle*> result;
1381 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1382 std::vector<const MEVehicle*> segmentVehs = segment->getVehicles();
1383 result.insert(result.end(), segmentVehs.begin(), segmentVehs.end());
1384 }
1385 } else {
1386 for (MSLane* lane : getLanes()) {
1387 for (auto veh : lane->getVehiclesSecure()) {
1388 result.push_back(veh);
1389 }
1390 lane->releaseVehicles();
1391 }
1392 }
1393 return result;
1394}
1395
1396
1397int
1399 return (int)getVehicles().size();
1400}
1401
1402
1403bool
1407 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1408 if (segment->getCarNumber() > 0) {
1409 return false;
1410 }
1411 }
1412 } else {
1413 for (MSLane* lane : getLanes()) {
1414 if (lane->getVehicleNumber() > 0) {
1415 return false;
1416 }
1417 }
1418 }
1419 return true;
1420}
1421
1422
1423double
1425 double wtime = 0;
1427 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1428 wtime += segment->getWaitingSeconds();
1429 }
1430 } else {
1431 for (MSLane* lane : getLanes()) {
1432 wtime += lane->getWaitingSeconds();
1433 }
1434 }
1435 return wtime;
1436}
1437
1438
1439double
1441 if (myLanes->size() == 0) {
1442 return 0;
1443 }
1446 double sum = 0;
1447 for (const SUMOVehicle* veh : getVehicles()) {
1448 sum += dynamic_cast<const MEVehicle*>(veh)->getVehicleType().getLength();
1449 }
1450 return sum / (myLength * (double)myLanes->size());
1451 } else {
1452 double sum = 0;
1453 for (auto lane : getLanes()) {
1454 sum += lane->getNettoOccupancy();
1455 }
1456 return sum / (double)myLanes->size();
1457 }
1458}
1459
1460
1461double
1463 if (myLanes->size() == 0) {
1464 return 0;
1465 }
1466 double flow = 0;
1467 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1468 flow += (double) segment->getCarNumber() * segment->getMeanSpeed();
1469 }
1470 return 3600 * flow / (*myLanes)[0]->getLength();
1471}
1472
1473
1474double
1476 if (myLanes->size() == 0) {
1477 return 0;
1478 }
1479 double occ = 0;
1480 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1481 occ += segment->getBruttoOccupancy();
1482 }
1483 return occ / (*myLanes)[0]->getLength() / (double)(myLanes->size());
1484}
1485
1486double
1487MSEdge::getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double /*time*/) {
1488 return edge->getLength() / MIN2(MSRoutingEngine::getAssumedSpeed(edge, veh), veh->getMaxSpeed());
1489}
1490
1491
1492void
1494 // @note must be called after closeBuilding() to ensure successors and
1495 // predecessors are set
1496 if (isInternal() && myEdgeType == "") {
1497 const std::string typeBefore = getNormalBefore()->getEdgeType();
1498 if (typeBefore != "") {
1499 const std::string typeAfter = getNormalSuccessor()->getEdgeType();
1500 if (typeBefore == typeAfter) {
1501 myEdgeType = typeBefore;
1502 } else if (typeAfter != "") {
1503 MSNet* net = MSNet::getInstance();
1504 auto resBefore = net->getRestrictions(typeBefore);
1505 auto resAfter = net->getRestrictions(typeAfter);
1506 if (resBefore != nullptr && resAfter != nullptr) {
1507 // create new restrictions for this type-combination
1508 myEdgeType = typeBefore + "|" + typeAfter;
1509 if (net->getRestrictions(myEdgeType) == nullptr) {
1510 for (const auto& item : *resBefore) {
1511 const SUMOVehicleClass svc = item.first;
1512 const double speed = item.second;
1513 const auto it = (*resAfter).find(svc);
1514 if (it != (*resAfter).end()) {
1515 const double speed2 = it->second;
1516 const double newSpeed = (MSNet::getInstance()->hasJunctionHigherSpeeds()
1517 ? MAX2(speed, speed2) : (speed + speed2) / 2);
1518 net->addRestriction(myEdgeType, svc, newSpeed);
1519 }
1520 }
1521 }
1522 }
1523 }
1524 }
1525 }
1526}
1527
1528
1529double
1530MSEdge::getDistanceAt(double pos) const {
1531 // negative values of myDistances indicate descending kilometrage
1532 return fabs(myDistance + pos);
1533}
1534
1535void
1537 myPersons.clear();
1538 myContainers.clear();
1539 myWaiting.clear();
1540}
1541
1542/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
#define BEST_LANE_LOOKAHEAD
Definition: MSEdge.cpp:54
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
std::vector< std::pair< const MSEdge *, const MSEdge * > > MSConstEdgePairVector
Definition: MSEdge.h:75
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:73
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:271
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:280
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:270
#define TL(string)
Definition: MsgHandler.h:287
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition: SUMOTime.cpp:69
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
const SVCPermissions SVCAll
all VClasses are allowed
const SUMOVehicleClass SUMOVehicleClass_MAX
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PRIVATE
private vehicles
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ RANDOM
The lane is chosen randomly.
@ BEST_FREE
The least occupied lane from best lanes.
@ GIVEN
The lane is given.
@ ALLOWED_FREE
The least occupied lane from lanes which allow the continuation.
@ DEFAULT
No information given; use default.
@ FIRST_ALLOWED
The rightmost lane the vehicle may use.
@ FREE
The least occupied lane is used.
@ RANDOM
The position is set by the vehroute device.
@ GIVEN
The position is given.
@ DEFAULT
No information given; use default.
@ FREE
A free position is chosen.
@ BASE
Back-at-zero position.
@ LAST
Insert behind the last vehicle as close as possible to still allow the specified departSpeed....
@ RANDOM_FREE
If a fixed number of random choices fails, a free position is chosen.
const int VEHPARS_SPEEDFACTOR_SET
@ GIVEN
The speed is given.
@ CONTAINER_TRIGGERED
The departure is container triggered.
@ TRIGGERED
The departure is person triggered.
@ TURN
The link is a 180 degree turn.
@ STRAIGHT
The link is a straight direction.
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_ALLWAY_STOP
This is an uncontrolled, all-way stop link.
@ LINKSTATE_STOP
This is an uncontrolled, minor link, has to stop.
@ LINKSTATE_EQUAL
This is an uncontrolled, right-before-left link.
@ LINKSTATE_DEADEND
This is a dead end link.
@ LINKSTATE_MINOR
This is an uncontrolled, minor link, has to brake.
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
double distanceTo2D(const Position &p) const
returns the euclidean distance in the x-y-plane
Definition: Boundary.cpp:222
std::vector< double > & getParameter()
Returns the parameters of this distribution.
void updateSegmentsForEdge(const MSEdge &e)
Update segments after loading meso edge type parameters from additional file.
Definition: MELoop.cpp:312
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:325
A single mesoscopic segment (cell)
Definition: MESegment.h:49
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:356
SUMOTime hasSpaceFor(const MEVehicle *const veh, const SUMOTime entryTime, int &qIdx, const bool init=false) const
Returns whether the given vehicle would still fit into the segment.
Definition: MESegment.cpp:302
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:234
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:42
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
double getLength() const
Returns the vehicle's length.
const MSRoute & getRoute() const
Returns the current route.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Sorts edges by their ids.
Definition: MSEdge.h:838
Sorts transportables by their positions.
Definition: MSEdge.h:853
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition: MSEdge.cpp:1130
A road/street connecting two junctions.
Definition: MSEdge.h:77
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:984
SUMOVehicle * getWaitingVehicle(MSTransportable *transportable, const double position) const
Definition: MSEdge.cpp:1355
void addToAllowed(const SVCPermissions permissions, std::shared_ptr< const std::vector< MSLane * > > allowedLanes, AllowedLanesCont &laneCont) const
Definition: MSEdge.cpp:278
void changeLanes(SUMOTime t) const
Performs lane changing on this edge.
Definition: MSEdge.cpp:790
double getBruttoOccupancy() const
Definition: MSEdge.cpp:1475
SVCPermissions myCombinedPermissions
The union of lane permissions for this edge.
Definition: MSEdge.h:925
double getFlow() const
return flow based on meanSpead
Definition: MSEdge.cpp:1462
Boundary myBoundary
The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start ...
Definition: MSEdge.h:994
double myWidth
Edge width [m].
Definition: MSEdge.h:944
AllowedLanesByTarget myAllowedTargets
From target edge to lanes allowed to be used to reach it.
Definition: MSEdge.h:920
MSLane * getDepartLane(MSVehicle &veh) const
Finds a depart lane for the given vehicle parameters.
Definition: MSEdge.cpp:575
SUMOTime myLastFailedInsertionTime
The time of last insertion failure.
Definition: MSEdge.h:885
std::set< MSTransportable *, ComparatorNumericalIdLess > myContainers
Containers on the edge.
Definition: MSEdge.h:911
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:990
void inferEdgeType()
Definition: MSEdge.cpp:1493
void setJunctions(MSJunction *from, MSJunction *to)
Definition: MSEdge.cpp:1216
double getMeanSpeedBike() const
get the mean speed of all bicycles on this edge
Definition: MSEdge.cpp:909
static MSEdgeVector myEdges
Static list of edges.
Definition: MSEdge.h:981
AllowedLanesCont myAllowed
Associative container from vehicle class to allowed-lanes.
Definition: MSEdge.h:917
double myEmptyTraveltime
the traveltime on the empty edge (cached value for speedup)
Definition: MSEdge.h:950
void updateMesoType()
update meso segment parameters
Definition: MSEdge.cpp:229
bool myAmFringe
whether this edge is at the network fringe
Definition: MSEdge.h:962
static double getTravelTimeAggregated(const MSEdge *const edge, const SUMOVehicle *const veh, double time)
Definition: MSEdge.cpp:1487
MSJunction * myToJunction
Definition: MSEdge.h:905
void checkAndRegisterBiDirEdge(const std::string &bidiID="")
check and register the opposite superposable edge if any
Definition: MSEdge.cpp:1260
virtual ~MSEdge()
Destructor.
Definition: MSEdge.cpp:93
double getDepartPosBound(const MSVehicle &veh, bool upper=true) const
return upper bound for the depart position on this edge
Definition: MSEdge.cpp:517
const double myDistance
the kilometrage/mileage at the start of the edge
Definition: MSEdge.h:941
void clearState()
Remove all transportables before quick-loading state.
Definition: MSEdge.cpp:1536
MSLane * getDepartLaneMeso(SUMOVehicle &veh) const
consider given departLane parameter (only for validating speeds)
Definition: MSEdge.cpp:564
const MSEdge * myBidiEdge
the oppositing superposable edge
Definition: MSEdge.h:1010
MSLane * leftLane(const MSLane *const lane) const
Returns the lane left to the one given, 0 if the given lane is leftmost.
Definition: MSEdge.cpp:410
std::string myEdgeType
the type of the edge (optionally used during network creation)
Definition: MSEdge.h:935
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
Definition: MSEdge.cpp:1237
static void parseEdgesList(const std::string &desc, ConstMSEdgeVector &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition: MSEdge.cpp:1008
double getLengthGeometryFactor() const
return shape.length() / myLength
Definition: MSEdge.cpp:1063
void addSuccessor(MSEdge *edge, const MSEdge *via=nullptr)
Adds an edge to the list of edges which may be reached from this edge and to the incoming of the othe...
Definition: MSEdge.cpp:1141
friend class MSLaneChangerSublane
Definition: MSEdge.h:87
std::vector< SUMOVehicle * > myWaiting
List of waiting vehicles.
Definition: MSEdge.h:997
const MSEdge * getNormalSuccessor() const
if this edge is an internal edge, return its first normal successor, otherwise the edge itself
Definition: MSEdge.cpp:845
void rebuildAllowedLanes(const bool onInit=false)
Definition: MSEdge.cpp:300
double getInternalFollowingLengthTo(const MSEdge *followerAfterInternal, SUMOVehicleClass vClass) const
returns the length of all internal edges on the junction until reaching the non-internal edge followe...
Definition: MSEdge.cpp:820
bool isNormal() const
return whether this edge is an internal edge
Definition: MSEdge.h:260
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's persons sorted by pos.
Definition: MSEdge.cpp:1104
bool isSuperposable(const MSEdge *other)
Definition: MSEdge.cpp:1315
bool validateDepartSpeed(SUMOVehicle &v) const
check whether the given departSpeed is valid for this edge
Definition: MSEdge.cpp:637
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:439
double getDistanceTo(const MSEdge *other, const bool doBoundaryEstimate=false) const
optimistic air distance heuristic for use in routing
Definition: MSEdge.cpp:1031
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges with internal vias, restricted by vClass.
Definition: MSEdge.cpp:1186
static MSEdge * dictionaryHint(const std::string &id, const int startIdx)
Returns the MSEdge associated to the key id giving a hint with a numerical id.
Definition: MSEdge.cpp:971
MSLaneChanger * myLaneChanger
This member will do the lane-change.
Definition: MSEdge.h:876
double getOccupancy() const
return mean occupancy on this edges lanes or segments
Definition: MSEdge.cpp:1440
std::vector< MSTransportable * > getSortedContainers(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's containers sorted by pos.
Definition: MSEdge.cpp:1122
const SumoXMLEdgeFunc myFunction
the purpose of the edge
Definition: MSEdge.h:879
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:118
double getSpeedLimit() const
Returns the speed limit of the edge @caution The speed limit of the first lane is retured; should pro...
Definition: MSEdge.cpp:1056
bool myAmDelayed
whether this edge had a vehicle with less than max speed on it
Definition: MSEdge.h:956
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:988
SUMOTime decVaporization(SUMOTime t)
Disables vaporization.
Definition: MSEdge.cpp:478
MSEdgeVector myPredecessors
The preceeding edges.
Definition: MSEdge.h:901
void rebuildAllowedTargets(const bool updateVehicles=true)
Definition: MSEdge.cpp:343
static SVCPermissions myMesoIgnoredVClasses
Definition: MSEdge.h:983
std::vector< std::pair< SVCPermissions, std::shared_ptr< const std::vector< MSLane * > > > > AllowedLanesCont
"Map" from vehicle class to allowed lanes
Definition: MSEdge.h:80
const MSJunction * getToJunction() const
Definition: MSEdge.h:415
double getLength() const
return the length of the edge
Definition: MSEdge.h:658
void initialize(const std::vector< MSLane * > *lanes)
Initialize the edge.
Definition: MSEdge.cpp:101
virtual void closeBuilding()
Definition: MSEdge.cpp:185
static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored=0)
Definition: MSEdge.cpp:293
bool canChangeToOpposite() const
whether this edge allows changing to the opposite direction edge
Definition: MSEdge.cpp:1227
std::set< int > myFailedInsertionMemory
A cache for the rejected insertion attempts. Used to assure that no further insertion attempts are ma...
Definition: MSEdge.h:890
const MSJunction * getFromJunction() const
Definition: MSEdge.h:411
double getMeanSpeed() const
get the mean speed
Definition: MSEdge.cpp:855
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSEdge.h:976
std::set< MSTransportable *, ComparatorNumericalIdLess > myPersons
Persons on the edge for drawing and pushbutton.
Definition: MSEdge.h:908
bool isTazConnector() const
Definition: MSEdge.h:288
int getNumLanes() const
Definition: MSEdge.h:172
double getDistanceAt(double pos) const
Returns the kilometrage/mileage at the given offset along the edge.
Definition: MSEdge.cpp:1530
MSConstEdgePairVector myViaSuccessors
Definition: MSEdge.h:898
void setBidiLanes()
Definition: MSEdge.cpp:1290
MSEdgeVector mySuccessors
The succeeding edges.
Definition: MSEdge.h:896
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:265
MSLane * rightLane(const MSLane *const lane) const
Returns the lane right to the one given, 0 if the given lane is rightmost.
Definition: MSEdge.cpp:416
double getCurrentTravelTime(const double minSpeed=NUMERICAL_EPS) const
Computes and returns the current travel time for this edge.
Definition: MSEdge.cpp:929
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:303
void resetTAZ(MSJunction *junction)
Definition: MSEdge.cpp:162
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:431
bool insertVehicle(SUMOVehicle &v, SUMOTime time, const bool checkOnly=false, const bool forceCheck=false) const
Tries to insert the given vehicle into the network.
Definition: MSEdge.cpp:675
static const Position getStopPosition(const SUMOVehicleParameter::Stop &stop)
return the coordinates of the center of the given stop
Definition: MSEdge.cpp:1050
void addWaiting(SUMOVehicle *vehicle) const
Adds a vehicle to the list of waiting vehicles.
Definition: MSEdge.cpp:1334
MSLane * parallelLane(const MSLane *const lane, int offset, bool includeOpposite=true) const
Returns the lane with the given offset parallel to the given lane one or 0 if it does not exist.
Definition: MSEdge.cpp:422
ReversedEdge< MSEdge, SUMOVehicle > * myReversedRoutingEdge
a reversed version for backward routing
Definition: MSEdge.h:1013
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:316
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition: MSEdge.cpp:945
std::vector< const SUMOVehicle * > getVehicles() const
return vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1378
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:1000
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:1068
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition: MSEdge.cpp:471
MSJunction * myFromJunction
the junctions for this edge
Definition: MSEdge.h:904
double getMeanFriction() const
get the mean friction over the lanes
Definition: MSEdge.cpp:896
std::map< std::string, MSEdge * > DictType
definition of the static dictionary type
Definition: MSEdge.h:971
bool hasMinorLink() const
whether any lane has a minor link
Definition: MSEdge.cpp:1247
std::map< SUMOVehicleClass, MSConstEdgePairVector > myClassesViaSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:991
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition: MSEdge.cpp:835
int getVehicleNumber() const
return total number of vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1398
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:406
virtual void removeTransportable(MSTransportable *t) const
Definition: MSEdge.cpp:1095
SumoXMLEdgeFunc getFunction() const
Returns the edge type (SumoXMLEdgeFunc)
Definition: MSEdge.h:255
bool allowsLaneChanging() const
Definition: MSEdge.cpp:256
void setMaxSpeed(double val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:1075
bool isEmpty() const
whether this edge has no vehicles
Definition: MSEdge.cpp:1404
MSEdge(const std::string &id, int numericalID, const SumoXMLEdgeFunc function, const std::string &streetName, const std::string &edgeType, int priority, double distance)
Constructor.
Definition: MSEdge.cpp:67
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal, SUMOVehicleClass vClass) const
Definition: MSEdge.cpp:798
void buildLaneChanger()
Has to be called after all sucessors and predecessors have been set (after closeBuilding())
Definition: MSEdge.cpp:238
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:939
virtual void lock() const
grant exclusive access to the mesoscopic state
Definition: MSEdge.h:744
void removeWaiting(const SUMOVehicle *vehicle) const
Removes a vehicle from the list of waiting vehicles.
Definition: MSEdge.cpp:1343
std::vector< double > mySublaneSides
the right side for each sublane on this edge
Definition: MSEdge.h:965
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1156
std::shared_ptr< const std::vector< MSLane * > > myLanes
Container for the edge's lane; should be sorted: (right-hand-traffic) the more left the lane,...
Definition: MSEdge.h:873
double getWaitingSeconds() const
return accumated waiting time for all vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1424
int myVaporizationRequests
Vaporizer counter.
Definition: MSEdge.h:882
double myTimePenalty
flat penalty when computing traveltime
Definition: MSEdge.h:953
SVCPermissions myMinimumPermissions
The intersection of lane permissions for this edge.
Definition: MSEdge.h:923
MSLane * getFreeLane(const std::vector< MSLane * > *allowed, const SUMOVehicleClass vclass, double departPos) const
Finds the emptiest lane allowing the vehicle class.
Definition: MSEdge.cpp:485
virtual void addTransportable(MSTransportable *t) const
Definition: MSEdge.cpp:1086
RailEdge< MSEdge, SUMOVehicle > * myRailwayRoutingEdge
Definition: MSEdge.h:1014
double myLength
the length of the edge (cached value for speedup)
Definition: MSEdge.h:947
static double gStopTolerance
The tolerance to apply when matching waiting persons and vehicles.
Definition: MSGlobals.h:163
static bool gUseMesoSim
Definition: MSGlobals.h:103
static double gMinorPenalty
(minimum) time penalty for passing a minor link when routing
Definition: MSGlobals.h:152
static bool gCheckRoutes
Definition: MSGlobals.h:88
static double gTLSPenalty
scaled (minimum) time penalty for passing a tls link when routing
Definition: MSGlobals.h:154
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:109
static double gLateralResolution
Definition: MSGlobals.h:97
static int gNumSimThreads
how many threads to use for simulation
Definition: MSGlobals.h:143
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:94
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:78
static int gNumThreads
how many threads to use
Definition: MSGlobals.h:146
The base class for an intersection.
Definition: MSJunction.h:58
const ConstMSEdgeVector & getOutgoing() const
Definition: MSJunction.h:116
const Position & getPosition(bool secondaryShape=false) const
Definition: MSJunction.cpp:68
const ConstMSEdgeVector & getIncoming() const
Definition: MSJunction.h:110
Performs lane changing of vehicles.
Definition: MSLaneChanger.h:45
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge'e lanes.
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:636
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:119
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
Definition: MSLane.h:565
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:629
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:3179
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:2325
virtual const PositionVector & getShape(bool) const
Definition: MSLane.h:293
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:745
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:622
int numSublanes() const
Definition: MSLeaderInfo.h:86
The simulated network and simulation perfomer.
Definition: MSNet.h:88
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
bool hasJunctionHigherSpeeds() const
return whether the network was built with higher junction speeds
Definition: MSNet.h:783
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition: MSNet.cpp:352
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition: MSNet.cpp:346
const MESegment::MesoEdgeType & getMesoType(const std::string &typeID)
Returns edge type specific meso parameters if no type specific parameters have been loaded,...
Definition: MSNet.cpp:366
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:85
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:73
static double getAssumedSpeed(const MSEdge *edge, const SUMOVehicle *veh)
return current travel speed assumption
virtual double getEdgePos(SUMOTime now) const
Definition: MSStage.cpp:79
MSStage * getCurrentStage() const
Return the current stage.
bool isPerson() const
Whether it is a person.
bool isWaitingFor(const SUMOVehicle *vehicle) const
Whether the transportable waits for the given vehicle in the current step.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:5644
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:5638
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:377
The car-following model and parameter.
Definition: MSVehicleType.h:63
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
const Distribution_Parameterized & getSpeedFactor() const
Returns this type's speed factor.
double getLength() const
Get vehicle's length [m].
double computeChosenSpeedDeviation(SumoRNG *rng, const double minDev=-1.) const
Computes and returns the speed deviation.
Base class for objects which have an id.
Definition: Named.h:54
const std::string & getID() const
Returns the id.
Definition: Named.h:74
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
static const T & getRandomFrom(const std::vector< T > &v, SumoRNG *rng=nullptr)
Returns a random element from the given vector.
Definition: RandHelper.h:204
Representation of a vehicle, person, or container.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual double getChosenSpeedFactor() const =0
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual double getMaxSpeed() const =0
Returns the object's maximum speed (minimum of technical and desired maximum speed)
Representation of a vehicle.
Definition: SUMOVehicle.h:62
virtual int getRouteValidity(bool update=true, bool silent=false, std::string *msgReturn=nullptr)=0
computes validity attributes for the current route
virtual void setChosenSpeedFactor(const double factor)=0
Definition of vehicle stop (position and duration)
std::string lane
The lane to stop at.
double startPos
The stopping position start.
double endPos
The stopping position end.
Structure representing possible vehicle parameter.
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
double departSpeed
(optional) The initial speed of the vehicle
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
double departPos
(optional) The position the vehicle shall depart from
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
std::string id
The vehicle's id.
bool wasSet(int what) const
Returns whether the given parameter was set.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
A scoped lock which only triggers on condition.
Definition: ScopedLocker.h:40
std::vector< std::string > getVector()
return vector of strings
edge type specific meso parameters
Definition: MESegment.h:55