Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-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/****************************************************************************/
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// ===========================================================================
64
65// ===========================================================================
66// member method definitions
67// ===========================================================================
68MSEdge::MSEdge(const std::string& id, int numericalID,
69 const SumoXMLEdgeFunc function,
70 const std::string& streetName,
71 const std::string& edgeType,
72 const std::string& routingType,
73 int priority,
74 double distance) :
75 Named(id), myNumericalID(numericalID), myLanes(nullptr),
76 myLaneChanger(nullptr), myFunction(function), myVaporizationRequests(0),
77 myLastFailedInsertionTime(-1),
78 myFromJunction(nullptr), myToJunction(nullptr),
79 myHaveTransientPermissions(false),
80 myOtherTazConnector(nullptr),
81 myStreetName(streetName),
82 myEdgeType(edgeType),
83 myRoutingType(routingType),
84 myPriority(priority),
85 myDistance(distance),
86 myWidth(0.),
87 myLength(0.),
88 myEmptyTraveltime(0.),
89 myTimePenalty(0.),
90 myAmDelayed(false),
91 myAmRoundabout(false),
92 myAmFringe(true),
93 myBidiEdge(nullptr)
94{ }
95
96
102
103
104void
105MSEdge::initialize(const std::vector<MSLane*>* lanes) {
106 assert(lanes != 0);
107 myLanes = std::shared_ptr<const std::vector<MSLane*> >(lanes);
110 }
111 for (MSLane* const lane : *lanes) {
112 lane->setRightSideOnEdge(myWidth, (int)mySublaneSides.size());
113 MSLeaderInfo ahead(lane->getWidth());
114 for (int j = 0; j < ahead.numSublanes(); ++j) {
116 }
117 myWidth += lane->getWidth();
118 }
119}
120
121
123 if (myLanes->empty()) {
124 return;
125 }
126 myLength = myLanes->front()->getLength();
127 myEmptyTraveltime = myLength / MAX2(getSpeedLimit(), NUMERICAL_EPS);
129 SUMOTime minorPenalty = 0;
130 bool haveTLSPenalty = MSGlobals::gTLSPenalty > 0;
133 minorPenalty = edgeType.minorPenalty;
134 haveTLSPenalty = edgeType.tlsPenalty > 0;
135 }
136 if (haveTLSPenalty || minorPenalty > 0) {
137 // add tls penalties to the minimum travel time
138 SUMOTime minPenalty = -1;
139 for (const MSLane* const l : *myLanes) {
140 for (const MSLink* const link : l->getLinkCont()) {
141 if (link->getLane()->isWalkingArea() && link->getLaneBefore()->isNormal()) {
142 continue;
143 }
144 SUMOTime linkPenalty = link->isTLSControlled() ? link->getMesoTLSPenalty() : (link->havePriority() ? 0 : minorPenalty);
145 if (minPenalty == -1) {
146 minPenalty = linkPenalty;
147 } else {
148 minPenalty = MIN2(minPenalty, linkPenalty);
149 }
150 }
151 }
152 if (minPenalty > 0) {
153 myEmptyTraveltime += STEPS2TIME(minPenalty);
154 myTimePenalty = STEPS2TIME(minPenalty);
155 }
156 }
157 } else if (isCrossing() && MSGlobals::gTLSPenalty > 0) {
158 // penalties are recorded for the entering link
159 for (const auto& ili : myLanes->front()->getIncomingLanes()) {
160 double penalty = STEPS2TIME(ili.viaLink->getMesoTLSPenalty());
161 if (!ili.viaLink->haveOffPriority()) {
162 penalty = MAX2(penalty, MSGlobals::gMinorPenalty);
163 }
164 if (penalty > 0) {
165 myEmptyTraveltime += penalty;
166 myTimePenalty = penalty;
167 }
168 }
170 const MSLink* link = myLanes->front()->getIncomingLanes()[0].viaLink;
171 if (!link->isTLSControlled() && !link->havePriority()) {
172 if (link->isTurnaround()) {
175 } else {
178 }
179 }
180 }
181}
182
183
184void
186 mySuccessors.clear();
187 myPredecessors.clear();
188 for (const MSEdge* edge : junction->getIncoming()) {
189 if (!edge->isInternal()) {
190 MSEdgeVector& succ = const_cast<MSEdgeVector&>(edge->mySuccessors);
191 MSConstEdgePairVector& succVia = const_cast<MSConstEdgePairVector&>(edge->myViaSuccessors);
192 MSEdgeVector& pred = const_cast<MSEdgeVector&>(edge->myPredecessors);
193 auto it = std::find(succ.begin(), succ.end(), this);
194 auto it2 = std::find(succVia.begin(), succVia.end(), std::make_pair(const_cast<const MSEdge*>(this), (const MSEdge*)nullptr));
195 auto it3 = std::find(pred.begin(), pred.end(), this);
196 if (it != succ.end()) {
197 succ.erase(it);
198 succVia.erase(it2);
199 }
200 if (it3 != pred.end()) {
201 pred.erase(it3);
202 }
203 }
204 }
205}
206
207void
209 for (MSLane* const lane : *myLanes) {
210 for (MSLink* const link : lane->getLinkCont()) {
211 link->initParallelLinks();
212 MSLane* const toL = link->getLane();
213 MSLane* const viaL = link->getViaLane();
214 if (toL != nullptr) {
215 MSEdge& to = toL->getEdge();
216 if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
217 mySuccessors.push_back(&to);
218 myViaSuccessors.push_back(std::make_pair(&to, (viaL == nullptr ? nullptr : &viaL->getEdge())));
219 }
220 if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
221 to.myPredecessors.push_back(this);
222 }
223 if (link->getDirection() != LinkDirection::TURN) {
224 myAmFringe = false;
225 }
226 }
227 if (viaL != nullptr) {
228 MSEdge& to = viaL->getEdge();
229 if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
230 to.myPredecessors.push_back(this);
231 }
232 }
233 }
234 lane->checkBufferType();
235 }
236 std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
238 recalcCache();
239
240 // extend lookup table for sublane model after all edges are read
241 if (myLanes->back()->getOpposite() != nullptr) {
242 MSLane* opposite = myLanes->back()->getOpposite();
243 MSLeaderInfo ahead(opposite->getWidth());
244 for (int j = 0; j < ahead.numSublanes(); ++j) {
246 }
247 }
248}
249
250
251void
254 if (!myLanes->empty()) {
256 }
257}
258
259
260void
262 if (!myLanes->empty()) {
263 const bool allowChanging = allowsLaneChanging();
265 // may always initiate sublane-change
267 myLaneChanger = new MSLaneChangerSublane(myLanes.get(), allowChanging);
268 }
269 } else {
271 myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
272 } else if (myLanes->size() > 1 || canChangeToOpposite()) {
273 myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
274 }
275 }
276 }
277}
278
279
280bool
283 // allow changing only if all links leading to this internal lane have priority
284 // or they are controlled by a traffic light
285 for (const MSLane* const lane : *myLanes) {
286 const MSLink* const link = lane->getLogicalPredecessorLane()->getLinkTo(lane);
287 assert(link != nullptr);
288 const LinkState state = link->getState();
289 if ((state == LINKSTATE_MINOR && lane->getBidiLane() == nullptr)
290 || state == LINKSTATE_EQUAL
291 || state == LINKSTATE_STOP
292 || state == LINKSTATE_ALLWAY_STOP
293 || state == LINKSTATE_DEADEND) {
294 return false;
295 }
296 }
297 }
298 return true;
299}
300
301
302void
303MSEdge::addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const {
304 if (!allowedLanes->empty()) {
305 // recheck whether we had this list to save memory
306 for (auto& allowed : laneCont) {
307 if (*allowed.second == *allowedLanes) {
308 allowed.first |= permissions;
309 return;
310 }
311 }
312 laneCont.push_back(std::make_pair(permissions, allowedLanes));
313 }
314}
315
316
319 SVCPermissions ignored = myMesoIgnoredVClasses & ~ignoreIgnored;
320 return (p | ignored) == ignored ? 0 : p;
321}
322
323
324void
325MSEdge::rebuildAllowedLanes(const bool onInit, bool updateVehicles) {
326 // rebuild myMinimumPermissions and myCombinedPermissions
329 bool lanesChangedPermission = false;
330 for (MSLane* const lane : *myLanes) {
331 // same dedicated lanes are ignored in meso to avoid capacity errors.
332 // Here we have to make sure that vehicles which are set to depart on
333 // such lanes trigger an error.
334 SVCPermissions allow = getMesoPermissions(lane->getPermissions(), SVC_PEDESTRIAN);
335 myMinimumPermissions &= allow;
336 myCombinedPermissions |= allow;
337 lanesChangedPermission |= lane->hadPermissionChanges();
338 }
339 if (!onInit && !myHaveTransientPermissions && lanesChangedPermission) {
341 // backup original structures when first needed
345 }
346 // rebuild myAllowed
347 myAllowed.clear();
349 myAllowed.push_back(std::make_pair(SVC_IGNORING, myLanes));
350 for (SVCPermissions vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
351 if ((myCombinedPermissions & vclass) == vclass) {
352 std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
353 for (MSLane* const lane : *myLanes) {
354 if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
355 allowedLanes->push_back(lane);
356 }
357 }
359 }
360 }
361 }
362 if (onInit) {
365 } else {
366 rebuildAllowedTargets(updateVehicles);
367 for (MSEdge* pred : myPredecessors) {
368 if (myHaveTransientPermissions && !pred->myHaveTransientPermissions) {
369 pred->myOrigAllowed = pred->myAllowed;
370 pred->myOrigAllowedTargets = pred->myAllowedTargets;
371 pred->myOrigClassesViaSuccessorMap = pred->myClassesViaSuccessorMap;
372 pred->myHaveTransientPermissions = true;
373 }
374 pred->rebuildAllowedTargets(updateVehicles);
375 }
377 for (MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(*this); s != nullptr; s = s->getNextSegment()) {
378 s->updatePermissions();
379 }
380 }
381 }
382}
383
384
385void
386MSEdge::rebuildAllowedTargets(const bool updateVehicles) {
387 myAllowedTargets.clear();
388 for (const MSEdge* target : mySuccessors) {
389 bool universalMap = true; // whether the mapping for SVC_IGNORING is also valid for all vehicle classes
390 std::shared_ptr<std::vector<MSLane*> > allLanes = std::make_shared<std::vector<MSLane*> >();
391 // compute the mapping for SVC_IGNORING
392 for (MSLane* const lane : *myLanes) {
393 SVCPermissions combinedTargetPermissions = 0;
394 for (const MSLink* const link : lane->getLinkCont()) {
395 if (&link->getLane()->getEdge() == target) {
396 allLanes->push_back(lane);
397 combinedTargetPermissions |= link->getLane()->getPermissions();
398 if (link->getViaLane() != nullptr &&
399 ((lane->getPermissions() & link->getLane()->getPermissions()) != link->getViaLane()->getPermissions())) {
400 // custom connection permissions
401 universalMap = false;
402 }
403 }
404 }
405 if (combinedTargetPermissions == 0 || (lane->getPermissions() & combinedTargetPermissions) != lane->getPermissions()) {
406 universalMap = false;
407 }
408 }
409 if (universalMap) {
410 if (myAllowed.empty()) {
411 // we have no lane specific permissions
412 myAllowedTargets[target].push_back(std::make_pair(myMinimumPermissions, myLanes));
413 } else {
414 for (const auto& i : myAllowed) {
415 addToAllowed(i.first, i.second, myAllowedTargets[target]);
416 }
417 }
418 } else {
419 addToAllowed(SVC_IGNORING, allLanes, myAllowedTargets[target]);
420 // compute the vclass specific mapping
421 for (SVCPermissions vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
422 if ((myCombinedPermissions & vclass) == vclass) {
423 std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
424 for (MSLane* const lane : *myLanes) {
425 if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
426 for (const MSLink* const link : lane->getLinkCont()) {
427 if (link->getLane()->allowsVehicleClass((SUMOVehicleClass)vclass) && &link->getLane()->getEdge() == target && (link->getViaLane() == nullptr || link->getViaLane()->allowsVehicleClass((SUMOVehicleClass)vclass))) {
428 allowedLanes->push_back(lane);
429 }
430 }
431 }
432 }
434 }
435 }
436 }
437 }
438 if (updateVehicles) {
439 for (const MSLane* const lane : *myLanes) {
440 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
441 for (MSVehicle* veh : vehs) {
442 veh->updateBestLanes(true);
443 }
444 lane->releaseVehicles();
445 }
446 }
447 myClassesSuccessorMap.clear();
448}
449
450
451// ------------ Access to the edge's lanes
452MSLane*
453MSEdge::leftLane(const MSLane* const lane) const {
454 return parallelLane(lane, 1);
455}
456
457
458MSLane*
459MSEdge::rightLane(const MSLane* const lane) const {
460 return parallelLane(lane, -1);
461}
462
463
464MSLane*
465MSEdge::parallelLane(const MSLane* const lane, int offset, bool includeOpposite) const {
466 const int resultIndex = lane->getIndex() + offset;
467 if (resultIndex >= getNumLanes() && includeOpposite) {
468 const MSEdge* opposite = getOppositeEdge();
469 if (opposite != nullptr && resultIndex < getNumLanes() + opposite->getNumLanes()) {
470 return opposite->getLanes()[opposite->getNumLanes() + getNumLanes() - resultIndex - 1];
471 }
472 return nullptr;
473 } else if (resultIndex >= (int)myLanes->size() || resultIndex < 0) {
474 return nullptr;
475 } else {
476 return (*myLanes)[resultIndex];
477 }
478}
479
480
481const std::vector<MSLane*>*
482MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass, bool ignoreTransientPermissions) const {
483 const auto& targets = ignoreTransientPermissions && myHaveTransientPermissions ? myOrigAllowedTargets : myAllowedTargets;
484 AllowedLanesByTarget::const_iterator i = targets.find(&destination);
485 if (i != targets.end()) {
486 for (const auto& allowed : i->second) {
487 if ((allowed.first & vclass) == vclass) {
488 return allowed.second.get();
489 }
490 }
491 }
492 return nullptr;
493}
494
495
496const std::vector<MSLane*>*
498 if ((myMinimumPermissions & vclass) == vclass) {
499 return myLanes.get();
500 } else {
501 if ((myCombinedPermissions & vclass) == vclass) {
502 for (const auto& allowed : myAllowed) {
503 if ((allowed.first & vclass) == vclass) {
504 return allowed.second.get();
505 }
506 }
507 }
508 return nullptr;
509 }
510}
511
512
513// ------------
519
520
526
527
528MSLane*
529MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const {
530 if (allowed == nullptr) {
531 allowed = allowedLanes(vclass);
532 }
533 MSLane* res = nullptr;
534 if (allowed != nullptr) {
535 double largestGap = 0;
536 MSLane* resByGap = nullptr;
537 double leastOccupancy = std::numeric_limits<double>::max();
538 for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
539 const double occupancy = (*i)->getBruttoOccupancy();
540 if (occupancy < leastOccupancy) {
541 res = (*i);
542 leastOccupancy = occupancy;
543 }
544 const MSVehicle* last = (*i)->getLastFullVehicle();
545 const double lastGap = (last != nullptr ? last->getPositionOnLane() : myLength) - departPos;
546 if (lastGap > largestGap) {
547 largestGap = lastGap;
548 resByGap = (*i);
549 }
550 }
551 if (resByGap != nullptr) {
552 //if (res != resByGap) std::cout << SIMTIME << " edge=" << getID() << " departPos=" << departPos << " res=" << Named::getIDSecure(res) << " resByGap=" << Named::getIDSecure(resByGap) << " largestGap=" << largestGap << "\n";
553 res = resByGap;
554 }
555 }
556 return res;
557}
558
559
560MSLane*
561MSEdge::getProbableLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos, double maxSpeed) const {
562 if (allowed == nullptr) {
563 allowed = allowedLanes(vclass);
564 }
565 MSLane* res = nullptr;
566 if (allowed != nullptr) {
567 double largestGap = 0;
568 double largestSpeed = 0;
569 MSLane* resByGap = nullptr;
570 double leastOccupancy = std::numeric_limits<double>::max();
571 int aIndex = 0;
572 for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i, aIndex++) {
573 const double occupancy = (*i)->getBruttoOccupancy();
574 if (occupancy < leastOccupancy) {
575 res = (*i);
576 leastOccupancy = occupancy;
577 }
578 const MSVehicle* last = (*i)->getLastFullVehicle();
579 double lastGap = (last != nullptr ? last->getPositionOnLane() : myLength) - departPos;
580 // never insert to the left of a vehicle with a larger speedFactor
581 if (lastGap > largestGap && maxSpeed >= largestSpeed) {
582 largestGap = lastGap;
583 resByGap = (*i);
584 }
585 if (last != nullptr) {
586 largestSpeed = MAX2(largestSpeed, getVehicleMaxSpeed(last));
587 }
588 }
589 if (resByGap != nullptr) {
590 //if (res != resByGap) std::cout << SIMTIME << " edge=" << getID() << " departPos=" << departPos << " res=" << Named::getIDSecure(res) << " resByGap=" << Named::getIDSecure(resByGap) << " largestGap=" << largestGap << "\n";
591 res = resByGap;
592 }
593 }
594 return res;
595}
596
597
598double
599MSEdge::getDepartPosBound(const MSVehicle& veh, bool upper) const {
600 const SUMOVehicleParameter& pars = veh.getParameter();
601 double pos = getLength();
602 // determine the position
603 switch (pars.departPosProcedure) {
605 pos = pars.departPos;
606 if (pos < 0.) {
607 pos += myLength;
608 }
609 break;
611 // could be any position on the edge
612 break;
614 // could be any position on the edge due to multiple random attempts
615 break;
617 // many candidate positions, upper bound could be computed exactly
618 // with much effort
619 break;
621 if (upper) {
622 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
623 MSVehicle* last = (*i)->getLastFullVehicle();
624 if (last != nullptr) {
625 pos = MIN2(pos, last->getPositionOnLane());
626 }
627 }
628 } else {
629 pos = 0;
630 }
631 break;
634 if (!upper) {
635 pos = 0;
636 }
637 break;
638 default:
639 pos = MIN2(pos, veh.getVehicleType().getLength());
640 break;
641 }
642 return pos;
643}
644
645MSLane*
648 if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
649 return nullptr;
650 }
651 return (*myLanes)[veh.getParameter().departLane];
652 }
653 return (*myLanes)[0];
654}
655
656MSLane*
659 int departLane = veh.getParameter().departLane;
662 departLane = myDefaultDepartLane;
663 }
664 switch (dld) {
666 if ((int) myLanes->size() <= departLane || !(*myLanes)[departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
667 return nullptr;
668 }
669 return (*myLanes)[departLane];
673 return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
675 if (veh.getRoute().size() == 1) {
676 return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
677 } else {
679 }
682 veh.updateBestLanes(false, myLanes->front());
683 const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes();
684 double bestLength = -1;
685 for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
686 if ((*i).length > bestLength) {
687 bestLength = (*i).length;
688 }
689 }
690 // beyond a certain length, all lanes are suitable
691 // however, we still need to check departPos to avoid unsuitable insertion
692 // (this is only possible in some cases)
693 double departPos = 0;
694 if (bestLength > BEST_LANE_LOOKAHEAD) {
695 departPos = getDepartPosBound(veh);
696 bestLength = MIN2(bestLength - departPos, BEST_LANE_LOOKAHEAD);
697 }
698 std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
699 for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
700 if (((*i).length - departPos) >= bestLength) {
701 if (isInternal()) {
702 for (MSLane* lane : *myLanes) {
703 if (lane->getNormalSuccessorLane() == (*i).lane) {
704 bestLanes->push_back(lane);
705 }
706 }
707 } else {
708 bestLanes->push_back((*i).lane);
709 }
710 }
711 }
712 MSLane* ret = nullptr;
714 ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
715 } else {
716 ret = getProbableLane(bestLanes, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false), getVehicleMaxSpeed(&veh));
717 }
718 delete bestLanes;
719 return ret;
720 }
724 default:
725 break;
726 }
727 if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
728 return nullptr;
729 }
730 return (*myLanes)[0];
731}
732
733
734MSLane*
735MSEdge::getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst) const {
736 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
737 if ((*i)->allowsVehicleClass(vClass)) {
738 return *i;
739 }
740 }
741 return defaultFirst && !myLanes->empty() ? myLanes->front() : nullptr;
742}
743
744
745bool
747 const SUMOVehicleParameter& pars = v.getParameter();
748 const MSVehicleType& type = v.getVehicleType();
750 // departSpeed could have been rounded down in the output
751 double vMax = getVehicleMaxSpeed(&v) + SPEED_EPS;
752 if (pars.departSpeed > vMax) {
753 // check departLane (getVehicleMaxSpeed checks lane 0)
754 MSLane* departLane = MSGlobals::gMesoNet ? getDepartLaneMeso(v) : getDepartLane(dynamic_cast<MSVehicle&>(v));
755 if (departLane != nullptr) {
756 vMax = departLane->getVehicleMaxSpeed(&v);
758 // speedFactor could have been rounded down in the output
759 vMax *= (1 + SPEED_EPS);
760 }
761 // additive term must come after multiplication!
762 vMax += SPEED_EPS;
763 if (pars.departSpeed > vMax) {
764 if (type.getSpeedFactor().getParameter(1) > 0.) {
766 if (v.getChosenSpeedFactor() > type.getSpeedFactor().getParameter(0) + 2 * type.getSpeedFactor().getParameter(1)) {
767 // only warn for significant deviation
768 WRITE_WARNINGF(TL("Choosing new speed factor % for vehicle '%' to match departure speed % (max %)."),
769 toString(v.getChosenSpeedFactor()), pars.id, pars.departSpeed, vMax);
770 }
771 } else {
772 return false;
773 }
774 }
775 }
776 }
777 }
778 return true;
779}
780
781
782bool
783MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly, const bool forceCheck) const {
784 // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal
786 || v.getRouteValidity(true, checkOnly) != MSBaseVehicle::ROUTE_VALID) {
787 return checkOnly;
788 }
789 const SUMOVehicleParameter& pars = v.getParameter();
790 if (!validateDepartSpeed(v)) {
792 throw ProcessError(TLF("Departure speed for vehicle '%' is too high for the departure edge '%', time=%.",
793 pars.id, getID(), time2string(time)));
794 } else {
795 WRITE_WARNINGF(TL("Departure speed for vehicle '%' is too high for the departure edge '%', time=%."),
796 pars.id, getID(), time2string(time));
797 }
798 }
800 if (!forceCheck && myLastFailedInsertionTime == time) {
801 return false;
802 }
803 double pos = 0.0;
804 switch (pars.departPosProcedure) {
806 if (pars.departPos >= 0.) {
807 pos = pars.departPos;
808 } else {
809 pos = pars.departPos + getLength();
810 }
811 if (pos < 0 || pos > getLength()) {
812 WRITE_WARNINGF(TL("Invalid departPos % given for vehicle '%', time=%. Inserting at lane end instead."),
813 pos, v.getID(), time2string(time));
814 pos = getLength();
815 }
816 break;
820 break;
821 default:
822 break;
823 }
824 bool result = false;
825 MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
826 MEVehicle* veh = static_cast<MEVehicle*>(&v);
827 int qIdx;
829 while (segment != nullptr && !result) {
830 if (checkOnly) {
831 result = segment->hasSpaceFor(veh, time, qIdx, true) == time;
832 } else {
833 result = segment->initialise(veh, time);
834 }
835 segment = segment->getNextSegment();
836 }
837 } else {
838 if (checkOnly) {
839 result = segment->hasSpaceFor(veh, time, qIdx, true) == time;
840 } else {
841 result = segment->initialise(veh, time);
842 }
843 }
844 return result;
845 }
846 if (checkOnly) {
847 switch (v.getParameter().departLaneProcedure) {
851 MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
852 if (insertionLane == nullptr) {
853 WRITE_WARNINGF(TL("Could not insert vehicle '%' on any lane of edge '%', time=%."),
854 v.getID(), getID(), time2string(time));
855 return false;
856 }
857 const double occupancy = insertionLane->getBruttoOccupancy();
858 return (occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength ||
860 }
861 default:
862 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
863 const double occupancy = (*i)->getBruttoOccupancy();
864 if (occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength ||
866 return true;
867 }
868 }
869 }
870 return false;
871 }
872 MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
873 if (insertionLane == nullptr) {
874 return false;
875 }
876
877 if (!forceCheck) {
878 if (myLastFailedInsertionTime == time) {
879 if (myFailedInsertionMemory.count(insertionLane->getIndex())) {
880 // A vehicle was already rejected for the proposed insertionLane in this timestep
881 return false;
882 }
883 } else {
884 // last rejection occurred in a previous timestep, clear cache
886 }
887 }
888
889 bool success = insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
890
891 if (!success) {
892 // constraints may enforce explicit re-ordering so we need to try other vehicles after failure
893 if (!insertionLane->hasParameter("insertionOrder" + v.getID())) {
894 myFailedInsertionMemory.insert(insertionLane->getIndex());
895 }
896 }
897 return success;
898}
899
900
901void
903 if (myLaneChanger != nullptr) {
905 }
906}
907
908
909const MSEdge*
910MSEdge::getInternalFollowingEdge(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const {
911 //@todo to be optimized
912 for (const MSLane* const l : *myLanes) {
913 for (const MSLink* const link : l->getLinkCont()) {
914 if (&link->getLane()->getEdge() == followerAfterInternal) {
915 if (link->getViaLane() != nullptr) {
916 if (link->getViaLane()->allowsVehicleClass(vClass)) {
917 return &link->getViaLane()->getEdge();
918 } else {
919 continue;
920 }
921 } else {
922 return nullptr; // network without internal links
923 }
924 }
925 }
926 }
927 return nullptr;
928}
929
930
931double
932MSEdge::getInternalFollowingLengthTo(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const {
933 assert(followerAfterInternal != 0);
934 assert(!followerAfterInternal->isInternal());
935 double dist = 0.;
936 const MSEdge* edge = getInternalFollowingEdge(followerAfterInternal, vClass);
937 // Take into account non-internal lengths until next non-internal edge
938 while (edge != nullptr && edge->isInternal()) {
939 dist += edge->getLength();
940 edge = edge->getInternalFollowingEdge(followerAfterInternal, vClass);
941 }
942 return dist;
943}
944
945
946const MSEdge*
948 const MSEdge* result = this;
949 while (result->isInternal() && MSGlobals::gUsingInternalLanes) {
950 assert(result->getPredecessors().size() == 1);
951 result = result->getPredecessors().front();
952 }
953 return result;
954}
955
956const MSEdge*
958 const MSEdge* result = this;
959 while (result->isInternal()) {
960 assert(result->getSuccessors().size() == 1);
961 result = result->getSuccessors().front();
962 }
963 return result;
964}
965
966double
968 double v = 0;
969 double totalNumVehs = 0;
971 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
972 const int numVehs = segment->getCarNumber();
973 if (numVehs > 0) {
974 v += numVehs * segment->getMeanSpeed();
975 totalNumVehs += numVehs;
976 }
977 }
978 if (totalNumVehs == 0) {
979 return getLength() / myEmptyTraveltime; // may include tls-penalty
980 }
981 } else {
982 for (const MSLane* const lane : *myLanes) {
983 int numVehs = lane->getVehicleNumber();
984 if (numVehs == 0) {
985 // take speed limit but with lowest possible weight
986 numVehs = 1;
987 }
988 v += numVehs * lane->getMeanSpeed();
989 totalNumVehs += numVehs;
990 }
991 if (myBidiEdge != nullptr) {
992 for (const MSLane* const lane : myBidiEdge->getLanes()) {
993 if (lane->getVehicleNumber() > 0) {
994 // do not route across edges which are already occupied in reverse direction
995 return 0;
996 }
997 }
998 }
999 if (totalNumVehs == 0) {
1000 return getSpeedLimit();
1001 }
1002 }
1003 return v / totalNumVehs;
1004}
1005
1006
1007double
1009 double f = 0.;
1010 for (const MSLane* const lane : *myLanes) {
1011 f += lane->getFrictionCoefficient();
1012 }
1013 if (!myLanes->empty()) {
1014 return f / (double)myLanes->size();
1015 }
1016 return 1.;
1017}
1018
1019
1020double
1023 // no separate bicycle speeds in meso
1024 return getMeanSpeed();
1025 }
1026 double v = 0;
1027 double totalNumVehs = 0;
1028 for (const MSLane* const lane : *myLanes) {
1029 const int numVehs = lane->getVehicleNumber();
1030 v += numVehs * lane->getMeanSpeedBike();
1031 totalNumVehs += numVehs;
1032 }
1033 if (totalNumVehs == 0) {
1034 return getSpeedLimit();
1035 }
1036 return v / totalNumVehs;
1037}
1038
1039
1040double
1041MSEdge::getCurrentTravelTime(double minSpeed) const {
1042 assert(minSpeed > 0);
1043 if (!myAmDelayed) {
1044 return myEmptyTraveltime;
1045 }
1046 return getLength() / MAX2(minSpeed, getMeanSpeed());
1047}
1048
1049
1050double
1052 return MSRoutingEngine::getAssumedSpeed(this, nullptr);
1053}
1054
1055
1056bool
1057MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
1058 const DictType::iterator it = myDict.lower_bound(id);
1059 if (it == myDict.end() || it->first != id) {
1060 // id not in myDict
1061 myDict.emplace_hint(it, id, ptr);
1062 while (ptr->getNumericalID() >= (int)myEdges.size()) {
1063 myEdges.push_back(nullptr);
1064 }
1065 myEdges[ptr->getNumericalID()] = ptr;
1066 return true;
1067 }
1068 return false;
1069}
1070
1071
1072MSEdge*
1073MSEdge::dictionary(const std::string& id) {
1074 const DictType::iterator it = myDict.find(id);
1075 if (it == myDict.end()) {
1076 return nullptr;
1077 }
1078 return it->second;
1079}
1080
1081
1082MSEdge*
1083MSEdge::dictionaryHint(const std::string& id, const int startIdx) {
1084 // this method is mainly useful when parsing connections from the net.xml which are sorted by "from" id
1085 if (myEdges[startIdx] != nullptr && myEdges[startIdx]->getID() == id) {
1086 return myEdges[startIdx];
1087 }
1088 if (startIdx + 1 < (int)myEdges.size() && myEdges[startIdx + 1] != nullptr && myEdges[startIdx + 1]->getID() == id) {
1089 return myEdges[startIdx + 1];
1090 }
1091 return dictionary(id);
1092}
1093
1094
1095const MSEdgeVector&
1097 return myEdges;
1098}
1099
1100
1101void
1103 for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1104 delete (*i).second;
1105 }
1106 myDict.clear();
1107 myEdges.clear();
1108}
1109
1110
1111void
1112MSEdge::insertIDs(std::vector<std::string>& into) {
1113 for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1114 into.push_back((*i).first);
1115 }
1116}
1117
1118
1119void
1120MSEdge::parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
1121 const std::string& rid) {
1122 StringTokenizer st(desc);
1123 parseEdgesList(st.getVector(), into, rid);
1124}
1125
1126
1127void
1128MSEdge::parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
1129 const std::string& rid) {
1130 for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
1131 const MSEdge* edge = MSEdge::dictionary(*i);
1132 // check whether the edge exists
1133 if (edge == nullptr) {
1134 throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
1135 + "\n The route can not be build.");
1136 }
1137 into.push_back(edge);
1138 }
1139}
1140
1141
1142double
1143MSEdge::getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate) const {
1144 assert(this != other);
1145 if (doBoundaryEstimate) {
1146 return myBoundary.distanceTo2D(other->myBoundary);
1147 }
1148 if (isTazConnector()) {
1149 if (other->isTazConnector()) {
1150 return myBoundary.distanceTo2D(other->myBoundary);
1151 }
1152 return myBoundary.distanceTo2D(other->getLanes()[0]->getShape()[0]);
1153 }
1154 if (other->isTazConnector()) {
1155 return other->myBoundary.distanceTo2D(getLanes()[0]->getShape()[-1]);
1156 }
1157 return getLanes()[0]->getShape()[-1].distanceTo2D(other->getLanes()[0]->getShape()[0]);
1158}
1159
1160
1161const Position
1163 return MSLane::dictionary(stop.lane)->geometryPositionAtOffset((stop.endPos + stop.startPos) / 2.);
1164}
1165
1166
1167double
1169 // @note lanes might have different maximum speeds in theory
1170 return myLanes->empty() ? 1 : getLanes()[0]->getSpeedLimit();
1171}
1172
1173
1174double
1176 return myLanes->empty() ? 1 : getLanes()[0]->getLengthGeometryFactor();
1177}
1178
1179double
1181 // @note lanes might have different maximum speeds in theory
1182 return myLanes->empty() ? 1 : getLanes()[0]->getVehicleMaxSpeed(veh);
1183}
1184
1185
1186void
1187MSEdge::setMaxSpeed(double val, double jamThreshold) {
1188 assert(val >= 0);
1189 if (myLanes != nullptr) {
1190 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
1191 (*i)->setMaxSpeed(val, false, false, jamThreshold);
1192 }
1193 }
1194}
1195
1196
1197void
1199 if (t->isPerson()) {
1200 myPersons.insert(t);
1201 } else {
1202 myContainers.insert(t);
1203 }
1204}
1205
1206void
1208 std::set<MSTransportable*, ComparatorNumericalIdLess>& tc = t->isPerson() ? myPersons : myContainers;
1209 auto it = tc.find(t);
1210 if (it != tc.end()) {
1211 tc.erase(it);
1212 }
1213}
1214
1215std::vector<MSTransportable*>
1216MSEdge::getSortedPersons(SUMOTime timestep, bool includeRiding) const {
1217 std::vector<MSTransportable*> result(myPersons.begin(), myPersons.end());
1218 if (includeRiding) {
1219 for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
1220 const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
1221 for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
1222 const std::vector<MSTransportable*>& persons = (*j)->getPersons();
1223 result.insert(result.end(), persons.begin(), persons.end());
1224 }
1225 (*i)->releaseVehicles();
1226 }
1227 }
1228 sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
1229 return result;
1230}
1231
1232
1233std::vector<MSTransportable*>
1234MSEdge::getSortedContainers(SUMOTime timestep, bool /* includeRiding */) const {
1235 std::vector<MSTransportable*> result(myContainers.begin(), myContainers.end());
1236 sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
1237 return result;
1238}
1239
1240
1241int
1243 const double pos1 = c1->getCurrentStage()->getEdgePos(myTime);
1244 const double pos2 = c2->getCurrentStage()->getEdgePos(myTime);
1245 if (pos1 != pos2) {
1246 return pos1 < pos2;
1247 }
1248 return c1->getID() < c2->getID();
1249}
1250
1251
1252void
1254 mySuccessors.push_back(edge);
1255 myViaSuccessors.push_back(std::make_pair(edge, via));
1256 if (isTazConnector() && edge->getFromJunction() != nullptr) {
1258 }
1259
1260 edge->myPredecessors.push_back(this);
1261 if (edge->isTazConnector() && getToJunction() != nullptr) {
1262 edge->myBoundary.add(getToJunction()->getPosition());
1263 }
1264}
1265
1266
1267const MSEdgeVector&
1269 if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == SumoXMLEdgeFunc::CONNECTOR) {
1270 return mySuccessors;
1271 }
1272#ifdef HAVE_FOX
1273 ScopedLocker<> lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
1274#endif
1275 std::map<SUMOVehicleClass, MSEdgeVector>::iterator i = myClassesSuccessorMap.find(vClass);
1276 if (i == myClassesSuccessorMap.end()) {
1277 // instantiate vector
1278 myClassesSuccessorMap[vClass];
1279 i = myClassesSuccessorMap.find(vClass);
1280 // this vClass is requested for the first time. rebuild all successors
1281 for (MSEdgeVector::const_iterator it = mySuccessors.begin(); it != mySuccessors.end(); ++it) {
1282 if ((*it)->isTazConnector()) {
1283 i->second.push_back(*it);
1284 } else {
1285 const std::vector<MSLane*>* allowed = allowedLanes(**it, vClass);
1286 if (allowed != nullptr && allowed->size() > 0) {
1287 i->second.push_back(*it);
1288 }
1289 }
1290 }
1291 }
1292 // can use cached value
1293 return i->second;
1294}
1295
1296
1298MSEdge::getViaSuccessors(SUMOVehicleClass vClass, bool ignoreTransientPermissions) const {
1299 if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == SumoXMLEdgeFunc::CONNECTOR) {
1300 return myViaSuccessors;
1301 }
1302#ifdef HAVE_FOX
1303 ScopedLocker<> lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
1304#endif
1305 auto& viaMap = ignoreTransientPermissions && myHaveTransientPermissions ? myOrigClassesViaSuccessorMap : myClassesViaSuccessorMap;
1306 auto i = viaMap.find(vClass);
1307 if (i != viaMap.end()) {
1308 // can use cached value
1309 return i->second;
1310 }
1311 // instantiate vector
1312 MSConstEdgePairVector& result = viaMap[vClass];
1313 // this vClass is requested for the first time. rebuild all successors
1314 for (const auto& viaPair : myViaSuccessors) {
1315 if (viaPair.first->isTazConnector()) {
1316 result.push_back(viaPair);
1317 } else {
1318 const std::vector<MSLane*>* allowed = allowedLanes(*viaPair.first, vClass, ignoreTransientPermissions);
1319 if (allowed != nullptr && allowed->size() > 0) {
1320 result.push_back(viaPair);
1321 }
1322 }
1323 }
1324 return result;
1325}
1326
1327
1328void
1330 myFromJunction = from;
1331 myToJunction = to;
1332 if (!isTazConnector()) {
1333 myBoundary.add(from->getPosition());
1334 myBoundary.add(to->getPosition());
1335 }
1336}
1337
1338
1339bool
1341 return (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr &&
1342 // do not change on curved internal lanes
1343 (!isInternal()
1345 && myLanes->back()->getIncomingLanes()[0].viaLink->getDirection() == LinkDirection::STRAIGHT)));
1346}
1347
1348
1349const MSEdge*
1351 if (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr) {
1352 return &(myLanes->back()->getOpposite()->getEdge());
1353 } else {
1354 return nullptr;
1355 }
1356}
1357
1358
1359bool
1361 for (const MSLane* const l : *myLanes) {
1362 for (const MSLink* const link : l->getLinkCont()) {
1363 if (!link->havePriority()) {
1364 return true;
1365 }
1366 }
1367 }
1368 return false;
1369}
1370
1371bool
1373 if (myLanes->size() == 1) {
1374 return false;
1375 }
1376 for (const MSLane* const l : *myLanes) {
1377 if (l->getIndex() <= index && !l->allowsChangingRight(svc) && l->getIndex() > 0) {
1378 return true;
1379 } else if (l->getIndex() >= index && !l->allowsChangingLeft(svc) && l->getIndex() < (int)(myLanes->size() - 1)) {
1380 return true;
1381 }
1382 }
1383 return false;
1384}
1385
1386void
1387MSEdge::checkAndRegisterBiDirEdge(const std::string& bidiID) {
1388 if (bidiID != "") {
1389 myBidiEdge = dictionary(bidiID);
1390 if (myBidiEdge == nullptr) {
1391 WRITE_ERRORF(TL("Bidi-edge '%' does not exist"), bidiID);
1392 }
1393 setBidiLanes();
1394 return;
1395 }
1397 return;
1398 }
1399 // legacy networks (no bidi attribute)
1401 for (ConstMSEdgeVector::const_iterator it = candidates.begin(); it != candidates.end(); it++) {
1402 if ((*it)->getToJunction() == myFromJunction) { //reverse edge
1403 if (myBidiEdge != nullptr && isSuperposable(*it)) {
1404 WRITE_WARNINGF(TL("Ambiguous superposable edges between junction '%' and '%'."), myToJunction->getID(), myFromJunction->getID());
1405 break;
1406 }
1407 if (isSuperposable(*it)) {
1408 myBidiEdge = *it;
1409 setBidiLanes();
1410 }
1411 }
1412 }
1413}
1414
1415
1416void
1418 assert(myBidiEdge != nullptr);
1419 if (getNumLanes() == 1 && myBidiEdge->getNumLanes() == 1) {
1420 // the other way round is set when this method runs for the bidiEdge
1421 getLanes()[0]->setBidiLane(myBidiEdge->getLanes()[0]);
1422 } else {
1423 // find lanes with matching reversed shapes
1424 int numBidiLanes = 0;
1425 for (MSLane* l1 : *myLanes) {
1426 for (MSLane* l2 : *myBidiEdge->myLanes) {
1427 if (l1->getShape().reverse().almostSame(l2->getShape(), POSITION_EPS * 2)) {
1428 l1->setBidiLane(l2);
1429 numBidiLanes++;
1430 }
1431 }
1432 }
1433 // warn only once for each pair
1434 if (numBidiLanes == 0 && getNumericalID() < myBidiEdge->getNumericalID()) {
1435 WRITE_WARNINGF(TL("Edge '%' and bidi edge '%' have no matching bidi lanes"), getID(), myBidiEdge->getID());
1436 }
1437 }
1438}
1439
1440
1441bool
1443 if (other == nullptr || other->getLanes().size() != myLanes->size()) {
1444 return false;
1445 }
1446 std::vector<MSLane*>::const_iterator it1 = myLanes->begin();
1447 std::vector<MSLane*>::const_reverse_iterator it2 = other->getLanes().rbegin();
1448 do {
1449 if ((*it1)->getShape().reverse() != (*it2)->getShape()) {
1450 return false;
1451 }
1452 it1++;
1453 it2++;
1454 } while (it1 != myLanes->end());
1455
1456 return true;
1457}
1458
1459
1460void
1462#ifdef HAVE_FOX
1463 ScopedLocker<> lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1464#endif
1465 myWaiting.push_back(vehicle);
1466}
1467
1468
1469void
1470MSEdge::removeWaiting(const SUMOVehicle* vehicle) const {
1471#ifdef HAVE_FOX
1472 ScopedLocker<> lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1473#endif
1474 std::vector<SUMOVehicle*>::iterator it = std::find(myWaiting.begin(), myWaiting.end(), vehicle);
1475 if (it != myWaiting.end()) {
1476 myWaiting.erase(it);
1477 }
1478}
1479
1480
1482MSEdge::getWaitingVehicle(MSTransportable* transportable, const double position) const {
1483#ifdef HAVE_FOX
1484 ScopedLocker<> lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1485#endif
1486 for (SUMOVehicle* const vehicle : myWaiting) {
1487 if (transportable->isWaitingFor(vehicle)) {
1488 if (vehicle->isStoppedInRange(position, MSGlobals::gStopTolerance) ||
1489 (!vehicle->hasDeparted() &&
1490 (vehicle->getParameter().departProcedure == DepartDefinition::TRIGGERED ||
1491 vehicle->getParameter().departProcedure == DepartDefinition::CONTAINER_TRIGGERED))) {
1492 return vehicle;
1493 }
1494 if (!vehicle->isLineStop(position) && vehicle->allowsBoarding(transportable)) {
1495 WRITE_WARNING((transportable->isPerson() ? "Person '" : "Container '")
1496 + transportable->getID() + "' at edge '" + getID() + "' position " + toString(position) + " cannot use waiting vehicle '"
1497 + vehicle->getID() + "' at position " + toString(vehicle->getPositionOnLane()) + " because it is too far away.");
1498 }
1499 }
1500 }
1501 return nullptr;
1502}
1503
1504std::vector<const SUMOVehicle*>
1506 std::vector<const SUMOVehicle*> result;
1508 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1509 std::vector<const MEVehicle*> segmentVehs = segment->getVehicles();
1510 result.insert(result.end(), segmentVehs.begin(), segmentVehs.end());
1511 }
1512 } else {
1513 for (MSLane* lane : getLanes()) {
1514 for (auto veh : lane->getVehiclesSecure()) {
1515 result.push_back(veh);
1516 }
1517 lane->releaseVehicles();
1518 }
1519 }
1520 return result;
1521}
1522
1523int
1525 int result = 0;
1526 SVCPermissions filter = SVCAll;
1528 filter = ~(SVC_PEDESTRIAN | SVC_WHEELCHAIR);
1529 } else if ((myCombinedPermissions & (SVC_PEDESTRIAN | SVC_WHEELCHAIR)) != 0) {
1530 // filter out green verge
1531 filter = (SVC_PEDESTRIAN | SVC_WHEELCHAIR);
1532 }
1533 for (const MSLane* const l : *myLanes) {
1534 if ((l->getPermissions() & filter) != 0) {
1535 result++;
1536 }
1537 }
1538 return result;
1539}
1540
1541int
1543 return (int)getVehicles().size();
1544}
1545
1546
1547bool
1551 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1552 if (segment->getCarNumber() > 0) {
1553 return false;
1554 }
1555 }
1556 } else {
1557 for (MSLane* lane : getLanes()) {
1558 if (lane->getVehicleNumber() > 0) {
1559 return false;
1560 }
1561 }
1562 }
1563 return true;
1564}
1565
1566
1567double
1569 double wtime = 0;
1571 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1572 wtime += segment->getWaitingSeconds();
1573 }
1574 } else {
1575 for (MSLane* lane : getLanes()) {
1576 wtime += lane->getWaitingSeconds();
1577 }
1578 }
1579 return wtime;
1580}
1581
1582
1583double
1585 if (myLanes->size() == 0) {
1586 return 0;
1587 }
1590 double sum = 0;
1591 for (const SUMOVehicle* veh : getVehicles()) {
1592 sum += dynamic_cast<const MEVehicle*>(veh)->getVehicleType().getLength();
1593 }
1594 return sum / (myLength * (double)myLanes->size());
1595 } else {
1596 double sum = 0;
1597 for (auto lane : getLanes()) {
1598 sum += lane->getNettoOccupancy();
1599 }
1600 return sum / (double)myLanes->size();
1601 }
1602}
1603
1604
1605double
1607 if (myLanes->size() == 0) {
1608 return 0;
1609 }
1610 double flow = 0;
1611 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1612 flow += (double) segment->getCarNumber() * segment->getMeanSpeed();
1613 }
1614 return 3600 * flow / (*myLanes)[0]->getLength();
1615}
1616
1617
1618double
1620 if (myLanes->size() == 0) {
1621 return 0;
1622 }
1623 double occ = 0;
1624 for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1625 occ += segment->getBruttoOccupancy();
1626 }
1627 return occ / (*myLanes)[0]->getLength() / (double)(myLanes->size());
1628}
1629
1630double
1631MSEdge::getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double /*time*/) {
1632 return edge->getLength() / MIN2(MSRoutingEngine::getAssumedSpeed(edge, veh), veh->getMaxSpeed());
1633}
1634
1635
1636void
1638 // @note must be called after closeBuilding() to ensure successors and
1639 // predecessors are set
1640 if (isInternal() && myEdgeType == "") {
1641 const std::string typeBefore = getNormalBefore()->getEdgeType();
1642 if (typeBefore != "") {
1643 const std::string typeAfter = getNormalSuccessor()->getEdgeType();
1644 if (typeBefore == typeAfter) {
1645 myEdgeType = typeBefore;
1646 } else if (typeAfter != "") {
1647 MSNet* net = MSNet::getInstance();
1648 auto resBefore = net->getRestrictions(typeBefore);
1649 auto resAfter = net->getRestrictions(typeAfter);
1650 if (resBefore != nullptr && resAfter != nullptr) {
1651 // create new restrictions for this type-combination
1652 myEdgeType = typeBefore + "|" + typeAfter;
1653 if (net->getRestrictions(myEdgeType) == nullptr) {
1654 for (const auto& item : *resBefore) {
1655 const SUMOVehicleClass svc = item.first;
1656 const double speed = item.second;
1657 const auto it = (*resAfter).find(svc);
1658 if (it != (*resAfter).end()) {
1659 const double speed2 = it->second;
1660 const double newSpeed = (MSNet::getInstance()->hasJunctionHigherSpeeds()
1661 ? MAX2(speed, speed2) : (speed + speed2) / 2);
1662 net->addRestriction(myEdgeType, svc, newSpeed);
1663 }
1664 }
1665 }
1666 }
1667 }
1668 }
1669 }
1670}
1671
1672
1673double
1674MSEdge::getDistanceAt(double pos) const {
1675 // negative values of myDistances indicate descending kilometrage
1676 return fabs(myDistance + pos);
1677}
1678
1679
1680bool
1684
1685
1686std::pair<double, SUMOTime>
1687MSEdge::getLastBlocked(int index) const {
1688 if (myLaneChanger != nullptr) {
1689 return myLaneChanger->getLastBlocked(index);
1690 }
1691 return std::make_pair(-1, -1);
1692}
1693
1694
1695double
1699
1700void
1702 myPersons.clear();
1703 myContainers.clear();
1704 myWaiting.clear();
1705}
1706
1707/****************************************************************************/
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:287
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:91
#define STEPS2TIME(x)
Definition SUMOTime.h:55
const SVCPermissions SVCAll
all VClasses are allowed
const SUMOVehicleClass SUMOVehicleClass_MAX
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PRIVATE
private vehicles
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_WHEELCHAIR
@ SVC_PEDESTRIAN
pedestrian
DepartLaneDefinition
Possible ways to choose a lane on depart.
@ 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.
@ BEST_PROB
The lane most likely according the speedFactor (from best lanes)
@ RANDOM
A random position is chosen.
@ 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.
@ GIVEN
The speed is given.
const long long int VEHPARS_SPEEDFACTOR_SET
@ SPLIT
The departure is triggered by a train split.
@ 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:80
T MAX2(T a, T b)
Definition StdDefs.h:86
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:75
double distanceTo2D(const Position &p) const
returns the euclidean distance in the x-y-plane
Definition Boundary.cpp:262
double getParameter(const int index) const
Returns the nth parameter of this distribution.
void updateSegmentsForEdge(const MSEdge &e)
Update segments after loading meso edge type parameters from additional file.
Definition MELoop.cpp:327
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition MELoop.cpp:340
A single mesoscopic segment (cell)
Definition MESegment.h:50
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
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.
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition MESegment.h:236
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:887
Sorts transportables by their positions.
Definition MSEdge.h:902
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition MSEdge.cpp:1242
A road/street connecting two junctions.
Definition MSEdge.h:77
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition MSEdge.cpp:1096
SUMOVehicle * getWaitingVehicle(MSTransportable *transportable, const double position) const
Definition MSEdge.cpp:1482
void addToAllowed(const SVCPermissions permissions, std::shared_ptr< const std::vector< MSLane * > > allowedLanes, AllowedLanesCont &laneCont) const
Definition MSEdge.cpp:303
void changeLanes(SUMOTime t) const
Performs lane changing on this edge.
Definition MSEdge.cpp:902
double getBruttoOccupancy() const
Definition MSEdge.cpp:1619
SVCPermissions myCombinedPermissions
The union of lane permissions for this edge.
Definition MSEdge.h:976
double getFlow() const
return flow based on meanSpead
Definition MSEdge.cpp:1606
Boundary myBoundary
The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start ...
Definition MSEdge.h:1060
double myWidth
Edge width [m].
Definition MSEdge.h:1006
AllowedLanesByTarget myAllowedTargets
From target edge to lanes allowed to be used to reach it.
Definition MSEdge.h:970
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition MSEdge.h:273
MSLane * getDepartLane(MSVehicle &veh) const
Finds a depart lane for the given vehicle parameters.
Definition MSEdge.cpp:657
SUMOTime myLastFailedInsertionTime
The time of last insertion failure.
Definition MSEdge.h:934
std::set< MSTransportable *, ComparatorNumericalIdLess > myContainers
Containers on the edge.
Definition MSEdge.h:960
std::pair< double, SUMOTime > getLastBlocked(int index) const
retrieve properties of a blocked vehicle that wants to chane to the lane with the given index
Definition MSEdge.cpp:1687
static void clear()
Clears the dictionary.
Definition MSEdge.cpp:1102
void inferEdgeType()
Definition MSEdge.cpp:1637
void setJunctions(MSJunction *from, MSJunction *to)
Definition MSEdge.cpp:1329
double getMeanSpeedBike() const
get the mean speed of all bicycles on this edge
Definition MSEdge.cpp:1021
static MSEdgeVector myEdges
Static list of edges.
Definition MSEdge.h:1043
AllowedLanesCont myAllowed
Associative container from vehicle class to allowed-lanes.
Definition MSEdge.h:966
double myEmptyTraveltime
the traveltime on the empty edge (cached value for speedup)
Definition MSEdge.h:1012
void updateMesoType()
update meso segment parameters
Definition MSEdge.cpp:252
bool myAmFringe
whether this edge is at the network fringe
Definition MSEdge.h:1024
static double getTravelTimeAggregated(const MSEdge *const edge, const SUMOVehicle *const veh, double time)
Definition MSEdge.cpp:1631
MSJunction * myToJunction
Definition MSEdge.h:954
void checkAndRegisterBiDirEdge(const std::string &bidiID="")
check and register the opposite superposable edge if any
Definition MSEdge.cpp:1387
virtual ~MSEdge()
Destructor.
Definition MSEdge.cpp:97
double getDepartPosBound(const MSVehicle &veh, bool upper=true) const
return upper bound for the depart position on this edge
Definition MSEdge.cpp:599
const double myDistance
the kilometrage/mileage at the start of the edge
Definition MSEdge.h:1003
void clearState()
Remove all transportables before quick-loading state.
Definition MSEdge.cpp:1701
MSLane * getDepartLaneMeso(SUMOVehicle &veh) const
consider given departLane parameter (only for validating speeds)
Definition MSEdge.cpp:646
bool hasTransientPermissions() const
Definition MSEdge.cpp:1681
const MSEdge * myBidiEdge
the oppositing superposable edge
Definition MSEdge.h:1076
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:453
std::string myEdgeType
the type of the edge (optionally used during network creation)
Definition MSEdge.h:994
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:168
int getNumDrivingLanes() const
return the number of lanes that permit non-weak modes if the edge allows non weak modes and the numbe...
Definition MSEdge.cpp:1524
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
Definition MSEdge.cpp:1350
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:1120
double getLengthGeometryFactor() const
return shape.length() / myLength
Definition MSEdge.cpp:1175
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:1253
friend class MSLaneChangerSublane
Definition MSEdge.h:87
std::vector< SUMOVehicle * > myWaiting
List of waiting vehicles.
Definition MSEdge.h:1063
const MSEdge * getNormalSuccessor() const
if this edge is an internal edge, return its first normal successor, otherwise the edge itself
Definition MSEdge.cpp:957
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Get the allowed lanes to reach the destination-edge.
Definition MSEdge.cpp:482
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:932
bool isNormal() const
return whether this edge is an internal edge
Definition MSEdge.h:263
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's persons sorted by pos.
Definition MSEdge.cpp:1216
MSEdge(const std::string &id, int numericalID, const SumoXMLEdgeFunc function, const std::string &streetName, const std::string &edgeType, const std::string &routingType, int priority, double distance)
Constructor.
Definition MSEdge.cpp:68
bool isSuperposable(const MSEdge *other)
Definition MSEdge.cpp:1442
bool validateDepartSpeed(SUMOVehicle &v) const
check whether the given departSpeed is valid for this edge
Definition MSEdge.cpp:746
double getDistanceTo(const MSEdge *other, const bool doBoundaryEstimate=false) const
optimistic air distance heuristic for use in routing
Definition MSEdge.cpp:1143
void setMaxSpeed(double val, double jamThreshold=-1)
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition MSEdge.cpp:1187
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:1083
MSLaneChanger * myLaneChanger
This member will do the lane-change.
Definition MSEdge.h:925
double getOccupancy() const
return mean occupancy on this edges lanes or segments
Definition MSEdge.cpp:1584
static int myDefaultDepartLane
Definition MSEdge.h:1048
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Returns the following edges with internal vias, restricted by vClass.
Definition MSEdge.cpp:1298
std::vector< MSTransportable * > getSortedContainers(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's containers sorted by pos.
Definition MSEdge.cpp:1234
const SumoXMLEdgeFunc myFunction
the purpose of the edge
Definition MSEdge.h:928
MSLane * getProbableLane(const std::vector< MSLane * > *allowed, const SUMOVehicleClass vclass, double departPos, double maxSpeed) const
Finds the most probable lane allowing the vehicle class.
Definition MSEdge.cpp:561
void recalcCache()
Recalculates the cached values.
Definition MSEdge.cpp:122
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:1168
SVCPermissions myOriginalCombinedPermissions
The original union of lane permissions for this edge (before temporary modifications)
Definition MSEdge.h:981
bool myAmDelayed
whether this edge had a vehicle with less than max speed on it
Definition MSEdge.h:1018
SVCPermissions myOriginalMinimumPermissions
The original intersection of lane permissions for this edge (before temporary modifications)
Definition MSEdge.h:979
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition MSEdge.h:1053
SUMOTime decVaporization(SUMOTime t)
Disables vaporization.
Definition MSEdge.cpp:522
MSEdgeVector myPredecessors
The preceeding edges.
Definition MSEdge.h:950
bool hasChangeProhibitions(SUMOVehicleClass svc, int index) const
return whether this edge prohibits changing for the given vClass when starting on the given lane inde...
Definition MSEdge.cpp:1372
void rebuildAllowedTargets(const bool updateVehicles=true)
Definition MSEdge.cpp:386
static SVCPermissions myMesoIgnoredVClasses
Definition MSEdge.h:1045
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:426
double getLength() const
return the length of the edge
Definition MSEdge.h:693
void initialize(const std::vector< MSLane * > *lanes)
Initialize the edge.
Definition MSEdge.cpp:105
bool myHaveTransientPermissions
whether transient permission changes were applied to this edge or a predecessor
Definition MSEdge.h:984
virtual void closeBuilding()
Definition MSEdge.cpp:208
static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored=0)
Definition MSEdge.cpp:318
bool canChangeToOpposite() const
whether this edge allows changing to the opposite direction edge
Definition MSEdge.cpp:1340
std::set< int > myFailedInsertionMemory
A cache for the rejected insertion attempts. Used to assure that no further insertion attempts are ma...
Definition MSEdge.h:939
const MSJunction * getFromJunction() const
Definition MSEdge.h:422
double getMeanSpeed() const
get the mean speed
Definition MSEdge.cpp:967
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition MSEdge.h:1038
std::set< MSTransportable *, ComparatorNumericalIdLess > myPersons
Persons on the edge for drawing and pushbutton.
Definition MSEdge.h:957
bool isTazConnector() const
Definition MSEdge.h:291
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:1674
const std::string & getRoutingType() const
Returns the type of the edge.
Definition MSEdge.h:325
MSConstEdgePairVector myViaSuccessors
Definition MSEdge.h:947
void setBidiLanes()
Definition MSEdge.cpp:1417
MSEdgeVector mySuccessors
The succeeding edges.
Definition MSEdge.h:945
static DepartLaneDefinition myDefaultDepartLaneDefinition
Definition MSEdge.h:1047
bool isInternal() const
return whether this edge is an internal edge
Definition MSEdge.h:268
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:459
double getCurrentTravelTime(const double minSpeed=NUMERICAL_EPS) const
Computes and returns the current travel time for this edge.
Definition MSEdge.cpp:1041
std::map< SUMOVehicleClass, MSConstEdgePairVector > myOrigClassesViaSuccessorMap
Definition MSEdge.h:1057
AllowedLanesByTarget myOrigAllowedTargets
Definition MSEdge.h:971
int getNumericalID() const
Returns the numerical id of the edge.
Definition MSEdge.h:306
void resetTAZ(MSJunction *junction)
Definition MSEdge.cpp:185
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition MSEdge.h:442
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:783
static const Position getStopPosition(const SUMOVehicleParameter::Stop &stop)
return the coordinates of the center of the given stop
Definition MSEdge.cpp:1162
void addWaiting(SUMOVehicle *vehicle) const
Adds a vehicle to the list of waiting vehicles.
Definition MSEdge.cpp:1461
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:465
ReversedEdge< MSEdge, SUMOVehicle > * myReversedRoutingEdge
a reversed version for backward routing
Definition MSEdge.h:1079
const std::string & getEdgeType() const
Returns the type of the edge.
Definition MSEdge.h:319
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:1057
std::vector< const SUMOVehicle * > getVehicles() const
return vehicles on this edges lanes or segments
Definition MSEdge.cpp:1505
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition MSEdge.cpp:1112
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition MSEdge.cpp:1180
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition MSEdge.cpp:515
MSJunction * myFromJunction
the junctions for this edge
Definition MSEdge.h:953
double getMeanFriction() const
get the mean friction over the lanes
Definition MSEdge.cpp:1008
std::map< std::string, MSEdge * > DictType
definition of the static dictionary type
Definition MSEdge.h:1033
bool hasMinorLink() const
whether any lane has a minor link
Definition MSEdge.cpp:1360
double getPreference(const SUMOVTypeParameter &pars) const
Definition MSEdge.cpp:1696
std::map< SUMOVehicleClass, MSConstEdgePairVector > myClassesViaSuccessorMap
The successors available for a given vClass.
Definition MSEdge.h:1056
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition MSEdge.cpp:947
int getVehicleNumber() const
return total number of vehicles on this edges lanes or segments
Definition MSEdge.cpp:1542
const MSEdgeVector & getPredecessors() const
Definition MSEdge.h:417
virtual void removeTransportable(MSTransportable *t) const
Definition MSEdge.cpp:1207
SumoXMLEdgeFunc getFunction() const
Returns the edge type (SumoXMLEdgeFunc)
Definition MSEdge.h:258
bool allowsLaneChanging() const
Definition MSEdge.cpp:281
bool isEmpty() const
whether this edge has no vehicles
Definition MSEdge.cpp:1548
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal, SUMOVehicleClass vClass) const
Definition MSEdge.cpp:910
void buildLaneChanger()
Has to be called after all sucessors and predecessors have been set (after closeBuilding())
Definition MSEdge.cpp:261
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition MSEdge.cpp:1051
virtual void lock() const
grant exclusive access to the mesoscopic state
Definition MSEdge.h:785
void removeWaiting(const SUMOVehicle *vehicle) const
Removes a vehicle from the list of waiting vehicles.
Definition MSEdge.cpp:1470
MSLane * getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst=false) const
Definition MSEdge.cpp:735
std::vector< double > mySublaneSides
the right side for each sublane on this edge
Definition MSEdge.h:1027
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition MSEdge.cpp:1268
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:922
AllowedLanesCont myOrigAllowed
Definition MSEdge.h:967
double getWaitingSeconds() const
return accumated waiting time for all vehicles on this edges lanes or segments
Definition MSEdge.cpp:1568
int myVaporizationRequests
Vaporizer counter.
Definition MSEdge.h:931
double myTimePenalty
flat penalty when computing traveltime
Definition MSEdge.h:1015
SVCPermissions myMinimumPermissions
The intersection of lane permissions for this edge.
Definition MSEdge.h:974
MSLane * getFreeLane(const std::vector< MSLane * > *allowed, const SUMOVehicleClass vclass, double departPos) const
Finds the emptiest lane allowing the vehicle class.
Definition MSEdge.cpp:529
void rebuildAllowedLanes(const bool onInit=false, bool updateVehicles=false)
Definition MSEdge.cpp:325
virtual void addTransportable(MSTransportable *t) const
Definition MSEdge.cpp:1198
RailEdge< MSEdge, SUMOVehicle > * myRailwayRoutingEdge
Definition MSEdge.h:1080
double myLength
the length of the edge (cached value for speedup)
Definition MSEdge.h:1009
static double gStopTolerance
The tolerance to apply when matching waiting persons and vehicles.
Definition MSGlobals.h:168
static bool gUseMesoSim
Definition MSGlobals.h:106
static double gMinorPenalty
(minimum) time penalty for passing a minor link when routing
Definition MSGlobals.h:155
static bool gCheckRoutes
Definition MSGlobals.h:91
static double gTLSPenalty
scaled (minimum) time penalty for passing a tls link when routing
Definition MSGlobals.h:157
static double gTurnaroundPenalty
(minimum) time penalty for passing a turnaround link when routing
Definition MSGlobals.h:159
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition MSGlobals.h:112
static double gLateralResolution
Definition MSGlobals.h:100
static int gNumSimThreads
how many threads to use for simulation
Definition MSGlobals.h:146
static SUMOTime gLaneChangeDuration
Definition MSGlobals.h:97
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition MSGlobals.h:81
static int gNumThreads
how many threads to use
Definition MSGlobals.h:149
The base class for an intersection.
Definition MSJunction.h:58
const ConstMSEdgeVector & getOutgoing() const
Definition MSJunction.h:114
const Position & getPosition(bool secondaryShape=false) const
const ConstMSEdgeVector & getIncoming() const
Definition MSJunction.h:108
Performs lane changing of vehicles.
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge'e lanes.
std::pair< double, SUMOTime > getLastBlocked(int index) const
retrieve properties of a blocked vehicle that wants to chane to the lane with the given index
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:690
bool empty() const
Returns true if there is not a single vehicle on the lane.
Definition MSLane.h:744
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:574
int getIndex() const
Returns the lane's index.
Definition MSLane.h:647
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition MSLane.cpp:3397
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition MSLane.cpp:2490
MSLane * getOpposite() const
return the neighboring opposite direction lane for lane changing or nullptr
Definition MSLane.cpp:4384
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:769
double getWidth() const
Returns the lane's width.
Definition MSLane.h:640
int numSublanes() const
The simulated network and simulation perfomer.
Definition MSNet.h:89
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
double getPreference(const std::string &routingType, const SUMOVTypeParameter &pars) const
retriefe edge type specific routing preference
Definition MSNet.cpp:364
bool hasJunctionHigherSpeeds() const
return whether the network was built with higher junction speeds
Definition MSNet.h:799
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:354
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition MSNet.cpp:348
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:412
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:83
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
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition MSVehicle.h:374
The car-following model and parameter.
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
double getDesiredMaxSpeed() const
Returns the vehicles's desired maximum speed.
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 hasParameter(const std::string &key) const
Returns whether the parameter is set.
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)
static const T & getRandomFrom(const std::vector< T > &v, SumoRNG *rng=nullptr)
Returns a random element from the given vector.
Definition RandHelper.h:208
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)
Structure representing possible vehicle parameter.
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.
bool wasSet(long long int what) const
Returns whether the given parameter was set.
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.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
A scoped lock which only triggers on condition.
std::vector< std::string > getVector()
return vector of strings
edge type specific meso parameters
Definition MESegment.h:57