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