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.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
20 // A road/street connecting two junctions
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #include <config.h>
28 
29 #include <algorithm>
30 #include <iostream>
31 #include <cassert>
35 #include <mesosim/MELoop.h>
36 #include <mesosim/MESegment.h>
37 #include <mesosim/MEVehicle.h>
38 #include "MSInsertionControl.h"
39 #include "MSJunction.h"
40 #include "MSLane.h"
41 #include "MSLaneChanger.h"
42 #include "MSLaneChangerSublane.h"
43 #include "MSGlobals.h"
44 #include "MSNet.h"
45 #include "MSVehicle.h"
46 #include "MSLeaderInfo.h"
47 #include "MSContainer.h"
48 #include "MSEdgeWeightsStorage.h"
49 #include "MSEdge.h"
50 
51 #define BEST_LANE_LOOKAHEAD 3000.0
52 
53 // ===========================================================================
54 // static member definitions
55 // ===========================================================================
58 
59 
60 // ===========================================================================
61 // member method definitions
62 // ===========================================================================
63 MSEdge::MSEdge(const std::string& id, int numericalID,
64  const SumoXMLEdgeFunc function,
65  const std::string& streetName,
66  const std::string& edgeType,
67  int priority,
68  double distance) :
69  Named(id), myNumericalID(numericalID), myLanes(nullptr),
70  myLaneChanger(nullptr), myFunction(function), myVaporizationRequests(0),
71  myLastFailedInsertionTime(-1),
72  myFromJunction(nullptr), myToJunction(nullptr),
73  myStreetName(streetName),
74  myEdgeType(edgeType),
75  myPriority(priority),
76  myDistance(distance),
77  myWidth(0.),
78  myLength(0.),
79  myEmptyTraveltime(0.),
80  myTimePenalty(0.),
81  myAmDelayed(false),
82  myAmRoundabout(false),
83  myAmFringe(true),
84  myBidiEdge(nullptr)
85 { }
86 
87 
89  delete myLaneChanger;
90 }
91 
92 
93 void
94 MSEdge::initialize(const std::vector<MSLane*>* lanes) {
95  assert(lanes != 0);
96  myLanes = std::shared_ptr<const std::vector<MSLane*> >(lanes);
99  }
100  for (MSLane* const lane : *lanes) {
101  lane->setRightSideOnEdge(myWidth, (int)mySublaneSides.size());
102  MSLeaderInfo ahead(lane);
103  for (int j = 0; j < ahead.numSublanes(); ++j) {
105  }
106  myWidth += lane->getWidth();
107  }
108 }
109 
110 
112  if (myLanes->empty()) {
113  return;
114  }
115  myLength = myLanes->front()->getLength();
117 
119  // add tls penalties to the minimum travel time
120  SUMOTime minPenalty = -1;
121  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
122  MSLane* l = *i;
123  const MSLinkCont& lc = l->getLinkCont();
124  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
125  MSLink* link = *j;
126  SUMOTime linkPenalty = link->getMesoTLSPenalty() + (link->havePriority() ? 0 : MSGlobals::gMesoMinorPenalty);
127  if (minPenalty == -1) {
128  minPenalty = linkPenalty;
129  } else {
130  minPenalty = MIN2(minPenalty, linkPenalty);
131  }
132  }
133  }
134  if (minPenalty > 0) {
135  myEmptyTraveltime += STEPS2TIME(minPenalty);
136  }
137  } else if (isInternal()) {
138  const MSLink* link = myLanes->front()->getIncomingLanes()[0].viaLink;
139  if (!link->isTLSControlled() && !link->havePriority()) {
142  }
143  }
144 }
145 
146 
147 void
149  for (MSLane* const lane : *myLanes) {
150  for (MSLink* const link : lane->getLinkCont()) {
151  link->initParallelLinks();
152  MSLane* const toL = link->getLane();
153  MSLane* const viaL = link->getViaLane();
154  if (toL != nullptr) {
155  MSEdge& to = toL->getEdge();
156  if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
157  mySuccessors.push_back(&to);
158  myViaSuccessors.push_back(std::make_pair(&to, (viaL == nullptr ? nullptr : &viaL->getEdge())));
159  }
160  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
161  to.myPredecessors.push_back(this);
162  }
163  if (link->getDirection() != LINKDIR_TURN) {
164  myAmFringe = false;
165  }
166  }
167  if (viaL != nullptr) {
168  MSEdge& to = viaL->getEdge();
169  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
170  to.myPredecessors.push_back(this);
171  }
172  }
173  }
174  lane->checkBufferType();
175  }
176  std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
178  recalcCache();
179  // segment building depends on the finished list of successors (for multi-queue)
180  if (MSGlobals::gUseMesoSim && !myLanes->empty()) {
182  }
183 }
184 
185 
186 void
188  if (!myLanes->empty()) {
189  const bool allowChanging = allowsLaneChanging();
191  // may always initiate sublane-change
192  myLaneChanger = new MSLaneChangerSublane(myLanes.get(), allowChanging);
193  } else {
195  myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
196  } else if (myLanes->size() > 1 || canChangeToOpposite()) {
197  myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
198  }
199  }
200  }
201 }
202 
203 
204 bool
206  if (isInternal()) {
207  // allow changing only if all links leading to this internal lane have priority
208  // or they are controlled by a traffic light
209  for (std::vector<MSLane*>::const_iterator it = myLanes->begin(); it != myLanes->end(); ++it) {
210  MSLane* pred = (*it)->getLogicalPredecessorLane();
211  MSLink* link = MSLinkContHelper::getConnectingLink(*pred, **it);
212  assert(link != 0);
213  LinkState state = link->getState();
214  if (state == LINKSTATE_MINOR
215  || state == LINKSTATE_EQUAL
216  || state == LINKSTATE_STOP
217  || state == LINKSTATE_ALLWAY_STOP
218  || state == LINKSTATE_DEADEND) {
219  return false;
220  }
221  }
222  }
223  return true;
224 }
225 
226 
227 void
228 MSEdge::addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const {
229  if (!allowedLanes->empty()) {
230  // recheck whether we had this list to save memory
231  for (auto& allowed : laneCont) {
232  if (*allowed.second == *allowedLanes) {
233  allowed.first |= permissions;
234  return;
235  }
236  }
237  laneCont.push_back(std::make_pair(permissions, allowedLanes));
238  }
239 }
240 
241 
242 void
244  // rebuild myMinimumPermissions and myCombinedPermissions
247  for (MSLane* const lane : *myLanes) {
248  myMinimumPermissions &= lane->getPermissions();
249  myCombinedPermissions |= lane->getPermissions();
250  }
251  // rebuild myAllowed
252  myAllowed.clear();
254  myAllowed.push_back(std::make_pair(SVC_IGNORING, myLanes));
255  for (int vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
256  if ((myCombinedPermissions & vclass) == vclass) {
257  std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
258  for (MSLane* const lane : *myLanes) {
259  if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
260  allowedLanes->push_back(lane);
261  }
262  }
264  }
265  }
266  }
267  rebuildAllowedTargets(false);
268 }
269 
270 
271 void
272 MSEdge::rebuildAllowedTargets(const bool updateVehicles) {
273  myAllowedTargets.clear();
274  for (const MSEdge* target : mySuccessors) {
275  bool universalMap = true; // whether the mapping for SVC_IGNORING is also valid for all vehicle classes
276  std::shared_ptr<std::vector<MSLane*> > allLanes = std::make_shared<std::vector<MSLane*> >();
277  // compute the mapping for SVC_IGNORING
278  for (MSLane* const lane : *myLanes) {
279  SVCPermissions combinedTargetPermissions = 0;
280  for (const MSLink* const link : lane->getLinkCont()) {
281  if (&link->getLane()->getEdge() == target) {
282  allLanes->push_back(lane);
283  combinedTargetPermissions |= link->getLane()->getPermissions();
284  }
285  }
286  if (combinedTargetPermissions == 0 || (lane->getPermissions() & combinedTargetPermissions) != lane->getPermissions()) {
287  universalMap = false;
288  }
289  }
290  if (universalMap) {
291  if (myAllowed.empty()) {
292  // we have no lane specific permissions
293  myAllowedTargets[target].push_back(std::make_pair(myMinimumPermissions, myLanes));
294  } else {
295  for (const auto& i : myAllowed) {
296  addToAllowed(i.first, i.second, myAllowedTargets[target]);
297  }
298  }
299  } else {
300  addToAllowed(SVC_IGNORING, allLanes, myAllowedTargets[target]);
301  // compute the vclass specific mapping
302  for (int vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
303  if ((myCombinedPermissions & vclass) == vclass) {
304  std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
305  for (MSLane* const lane : *myLanes) {
306  if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
307  for (const MSLink* const link : lane->getLinkCont()) {
308  if (link->getLane()->allowsVehicleClass((SUMOVehicleClass)vclass) && &link->getLane()->getEdge() == target && (link->getViaLane() == nullptr || link->getViaLane()->allowsVehicleClass((SUMOVehicleClass)vclass))) {
309  allowedLanes->push_back(lane);
310  }
311  }
312  }
313  }
314  addToAllowed(vclass, allowedLanes, myAllowedTargets[target]);
315  }
316  }
317  }
318  }
319  if (updateVehicles) {
320  for (const MSLane* const lane : *myLanes) {
321  const MSLane::VehCont& vehs = lane->getVehiclesSecure();
322  for (MSVehicle* veh : vehs) {
323  veh->updateBestLanes(true);
324  }
325  lane->releaseVehicles();
326  }
327  }
328  myClassesSuccessorMap.clear();
329 }
330 
331 
332 // ------------ Access to the edge's lanes
333 MSLane*
334 MSEdge::leftLane(const MSLane* const lane) const {
335  return parallelLane(lane, 1);
336 }
337 
338 
339 MSLane*
340 MSEdge::rightLane(const MSLane* const lane) const {
341  return parallelLane(lane, -1);
342 }
343 
344 
345 MSLane*
346 MSEdge::parallelLane(const MSLane* const lane, int offset, bool includeOpposite) const {
347  const int resultIndex = lane->getIndex() + offset;
348  if (resultIndex == (int)myLanes->size() && includeOpposite) {
349  return lane->getOpposite();
350  } else if (resultIndex >= (int)myLanes->size() || resultIndex < 0) {
351  return nullptr;
352  } else {
353  return (*myLanes)[resultIndex];
354  }
355 }
356 
357 
358 const std::vector<MSLane*>*
359 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
360  AllowedLanesByTarget::const_iterator i = myAllowedTargets.find(&destination);
361  if (i != myAllowedTargets.end()) {
362  for (const auto& allowed : i->second) {
363  if ((allowed.first & vclass) == vclass) {
364  return allowed.second.get();
365  }
366  }
367  }
368  return nullptr;
369 }
370 
371 
372 const std::vector<MSLane*>*
374  if ((myMinimumPermissions & vclass) == vclass) {
375  return myLanes.get();
376  } else {
377  if ((myCombinedPermissions & vclass) == vclass) {
378  for (const auto& allowed : myAllowed) {
379  if ((allowed.first & vclass) == vclass) {
380  return allowed.second.get();
381  }
382  }
383  }
384  return nullptr;
385  }
386 }
387 
388 
389 // ------------
390 SUMOTime
393  return 0;
394 }
395 
396 
397 SUMOTime
400  return 0;
401 }
402 
403 
404 MSLane*
405 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const {
406  if (allowed == nullptr) {
407  allowed = allowedLanes(vclass);
408  }
409  MSLane* res = nullptr;
410  if (allowed != nullptr) {
411  double largestGap = 0;
412  MSLane* resByGap = nullptr;
413  double leastOccupancy = std::numeric_limits<double>::max();
414  for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
415  const double occupancy = (*i)->getBruttoOccupancy();
416  if (occupancy < leastOccupancy) {
417  res = (*i);
418  leastOccupancy = occupancy;
419  }
420  const MSVehicle* last = (*i)->getLastFullVehicle();
421  const double lastGap = (last != nullptr ? last->getPositionOnLane() : myLength) - departPos;
422  if (lastGap > largestGap) {
423  largestGap = lastGap;
424  resByGap = (*i);
425  }
426  }
427  if (resByGap != nullptr) {
428  //if (res != resByGap) std::cout << SIMTIME << " edge=" << getID() << " departPos=" << departPos << " res=" << Named::getIDSecure(res) << " resByGap=" << Named::getIDSecure(resByGap) << " largestGap=" << largestGap << "\n";
429  res = resByGap;
430  }
431  }
432  return res;
433 }
434 
435 
436 double
437 MSEdge::getDepartPosBound(const MSVehicle& veh, bool upper) const {
438  const SUMOVehicleParameter& pars = veh.getParameter();
439  double pos = getLength();
440  // determine the position
441  switch (pars.departPosProcedure) {
442  case DEPART_POS_GIVEN:
443  pos = pars.departPos;
444  if (pos < 0.) {
445  pos += myLength;
446  }
447  break;
448  case DEPART_POS_RANDOM:
449  // could be any position on the edge
450  break;
452  // could be any position on the edge due to multiple random attempts
453  break;
454  case DEPART_POS_FREE:
455  // many candidate positions, upper bound could be computed exactly
456  // with much effort
457  break;
458  case DEPART_POS_LAST:
459  if (upper) {
460  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
461  MSVehicle* last = (*i)->getLastFullVehicle();
462  if (last != nullptr) {
463  pos = MIN2(pos, last->getPositionOnLane());
464  }
465  }
466  } else {
467  pos = 0;
468  }
469  case DEPART_POS_BASE:
470  case DEPART_POS_DEFAULT:
471  break;
472  default:
473  pos = MIN2(pos, veh.getVehicleType().getLength());
474  break;
475  }
476  return pos;
477 }
478 
479 
480 MSLane*
482  switch (veh.getParameter().departLaneProcedure) {
483  case DEPART_LANE_GIVEN:
484  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
485  return nullptr;
486  }
487  return (*myLanes)[veh.getParameter().departLane];
488  case DEPART_LANE_RANDOM:
490  case DEPART_LANE_FREE:
491  return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
493  if (veh.getRoute().size() == 1) {
494  return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
495  } else {
497  }
498  case DEPART_LANE_BEST_FREE: {
499  veh.updateBestLanes(false, myLanes->front());
500  const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes();
501  double bestLength = -1;
502  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
503  if ((*i).length > bestLength) {
504  bestLength = (*i).length;
505  }
506  }
507  // beyond a certain length, all lanes are suitable
508  // however, we still need to check departPos to avoid unsuitable insertion
509  // (this is only possible in some cases)
510  double departPos = 0;
511  if (bestLength > BEST_LANE_LOOKAHEAD) {
512  departPos = getDepartPosBound(veh);
513  bestLength = MIN2(bestLength - departPos, BEST_LANE_LOOKAHEAD);
514  }
515  std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
516  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
517  if (((*i).length - departPos) >= bestLength) {
518  bestLanes->push_back((*i).lane);
519  }
520  }
521  MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
522  delete bestLanes;
523  return ret;
524  }
525  case DEPART_LANE_DEFAULT:
527  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
528  if ((*i)->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
529  return *i;
530  }
531  }
532  return nullptr;
533  default:
534  break;
535  }
536  if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
537  return nullptr;
538  }
539  return (*myLanes)[0];
540 }
541 
542 
543 bool
544 MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly, const bool forceCheck) const {
545  // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal
546  if (isVaporizing() || isTazConnector()) {
547  return checkOnly;
548  }
549  const SUMOVehicleParameter& pars = v.getParameter();
550  const MSVehicleType& type = v.getVehicleType();
552  const std::vector<double>& speedFactorParams = type.getSpeedFactor().getParameter();
553  if (speedFactorParams[1] > 0.) {
555  if (v.getChosenSpeedFactor() > speedFactorParams[0] + 2 * speedFactorParams[1]) {
556  // only warn for significant deviation
557  WRITE_WARNING("Choosing new speed factor " + toString(v.getChosenSpeedFactor()) + " for vehicle '" + pars.id + "' to match departure speed.");
558  }
559  } else {
560  throw ProcessError("Departure speed for vehicle '" + pars.id +
561  "' is too high for the departure edge '" + getID() + "'.");
562  }
563  }
565  if (!forceCheck && myLastFailedInsertionTime == time) {
566  return false;
567  }
568  double pos = 0.0;
569  switch (pars.departPosProcedure) {
570  case DEPART_POS_GIVEN:
571  if (pars.departPos >= 0.) {
572  pos = pars.departPos;
573  } else {
574  pos = pars.departPos + getLength();
575  }
576  if (pos < 0 || pos > getLength()) {
577  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
578  v.getID() + "'. Inserting at lane end instead.");
579  pos = getLength();
580  }
581  break;
582  case DEPART_POS_RANDOM:
584  pos = RandHelper::rand(getLength());
585  break;
586  default:
587  break;
588  }
589  bool result = false;
590  MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
591  MEVehicle* veh = static_cast<MEVehicle*>(&v);
592  if (pars.departPosProcedure == DEPART_POS_FREE) {
593  while (segment != nullptr && !result) {
594  if (checkOnly) {
595  result = segment->hasSpaceFor(veh, time, true);
596  } else {
597  result = segment->initialise(veh, time);
598  }
599  segment = segment->getNextSegment();
600  }
601  } else {
602  if (checkOnly) {
603  result = segment->hasSpaceFor(veh, time, true);
604  } else {
605  result = segment->initialise(veh, time);
606  }
607  }
608  return result;
609  }
610  if (checkOnly) {
611  switch (v.getParameter().departLaneProcedure) {
612  case DEPART_LANE_GIVEN:
613  case DEPART_LANE_DEFAULT:
615  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
616  if (insertionLane == nullptr) {
617  WRITE_WARNING("could not insert vehicle '" + v.getID() + "' on any lane of edge '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()));
618  return false;
619  }
620  const double occupancy = insertionLane->getBruttoOccupancy();
621  return occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength;
622  }
623  default:
624  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
625  const double occupancy = (*i)->getBruttoOccupancy();
626  if (occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength) {
627  return true;
628  }
629  }
630  }
631  return false;
632  }
633  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
634  if (insertionLane == nullptr) {
635  return false;
636  }
637 
638  if (!forceCheck) {
639  if (myLastFailedInsertionTime == time) {
640  if (myFailedInsertionMemory.count(insertionLane->getIndex())) {
641  // A vehicle was already rejected for the proposed insertionLane in this timestep
642  return false;
643  }
644  } else {
645  // last rejection occurred in a previous timestep, clear cache
646  myFailedInsertionMemory.clear();
647  }
648  }
649 
650  bool success = insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
651 
652  if (!success) {
653  myFailedInsertionMemory.insert(insertionLane->getIndex());
654  }
655  return success;
656 }
657 
658 
659 void
661  if (myLaneChanger == nullptr) {
662  return;
663  }
665 }
666 
667 
668 const MSEdge*
669 MSEdge::getInternalFollowingEdge(const MSEdge* followerAfterInternal) const {
670  //@todo to be optimized
671  for (const MSLane* const l : *myLanes) {
672  for (const MSLink* const link : l->getLinkCont()) {
673  if (&link->getLane()->getEdge() == followerAfterInternal) {
674  if (link->getViaLane() != nullptr) {
675  return &link->getViaLane()->getEdge();
676  } else {
677  return nullptr; // network without internal links
678  }
679  }
680  }
681  }
682  return nullptr;
683 }
684 
685 
686 double
687 MSEdge::getInternalFollowingLengthTo(const MSEdge* followerAfterInternal) const {
688  assert(followerAfterInternal != 0);
689  assert(!followerAfterInternal->isInternal());
690  double dist = 0.;
691  const MSEdge* edge = getInternalFollowingEdge(followerAfterInternal);
692  // Take into account non-internal lengths until next non-internal edge
693  while (edge != nullptr && edge->isInternal()) {
694  dist += edge->getLength();
695  edge = edge->getInternalFollowingEdge(followerAfterInternal);
696  }
697  return dist;
698 }
699 
700 
701 const MSEdge*
703  const MSEdge* result = this;
704  while (result->isInternal()) {
705  assert(result->getPredecessors().size() == 1);
706  result = result->getPredecessors().front();
707  }
708  return result;
709 }
710 
711 double
713  double v = 0;
714  double no = 0;
716  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
717  const int vehNo = segment->getCarNumber();
718  if (vehNo > 0) {
719  v += vehNo * segment->getMeanSpeed();
720  no += vehNo;
721  }
722  }
723  if (no == 0) {
724  return getLength() / myEmptyTraveltime; // may include tls-penalty
725  }
726  } else {
727  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
728  const double vehNo = (double)(*i)->getVehicleNumber();
729  v += vehNo * (*i)->getMeanSpeed();
730  no += vehNo;
731  }
732  if (myBidiEdge != nullptr) {
733  for (const MSLane* lane : myBidiEdge->getLanes()) {
734  if (lane->getVehicleNumber() > 0) {
735  // do not route across edges which are already occupied in reverse direction
736  return 0;
737  }
738  }
739  }
740  if (no == 0) {
741  return getSpeedLimit();
742  }
743  }
744  return v / no;
745 }
746 
747 
748 double
749 MSEdge::getCurrentTravelTime(double minSpeed) const {
750  assert(minSpeed > 0);
751  if (!myAmDelayed) {
752  return myEmptyTraveltime;
753  }
754  return getLength() / MAX2(minSpeed, getMeanSpeed());
755 }
756 
757 
758 double
761 }
762 
763 
764 bool
765 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
766  DictType::iterator it = myDict.find(id);
767  if (it == myDict.end()) {
768  // id not in myDict.
769  myDict[id] = ptr;
770  while ((int)myEdges.size() < ptr->getNumericalID() + 1) {
771  myEdges.push_back(0);
772  }
773  myEdges[ptr->getNumericalID()] = ptr;
774  return true;
775  }
776  return false;
777 }
778 
779 
780 MSEdge*
781 MSEdge::dictionary(const std::string& id) {
782  DictType::iterator it = myDict.find(id);
783  if (it == myDict.end()) {
784  // id not in myDict.
785  return nullptr;
786  }
787  return it->second;
788 }
789 
790 
791 int
793  return (int)myDict.size();
794 }
795 
796 
797 const MSEdgeVector&
799  return myEdges;
800 }
801 
802 
803 void
805  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
806  delete (*i).second;
807  }
808  myDict.clear();
809  myEdges.clear();
810 }
811 
812 
813 void
814 MSEdge::insertIDs(std::vector<std::string>& into) {
815  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
816  into.push_back((*i).first);
817  }
818 }
819 
820 
821 void
822 MSEdge::parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
823  const std::string& rid) {
824  if (desc[0] == BinaryFormatter::BF_ROUTE) {
825  std::istringstream in(desc, std::ios::binary);
826  char c;
827  in >> c;
828  FileHelpers::readEdgeVector(in, into, rid);
829  } else {
830  StringTokenizer st(desc);
831  parseEdgesList(st.getVector(), into, rid);
832  }
833 }
834 
835 
836 void
837 MSEdge::parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
838  const std::string& rid) {
839  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
840  const MSEdge* edge = MSEdge::dictionary(*i);
841  // check whether the edge exists
842  if (edge == nullptr) {
843  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
844  + "\n The route can not be build.");
845  }
846  into.push_back(edge);
847  }
848 }
849 
850 
851 double
852 MSEdge::getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate) const {
853  assert(this != other);
854  if (doBoundaryEstimate) {
855  return myBoundary.distanceTo2D(other->myBoundary);
856  }
857  if (isTazConnector()) {
858  if (other->isTazConnector()) {
859  return myBoundary.distanceTo2D(other->myBoundary);
860  }
861  return myBoundary.distanceTo2D(other->getLanes()[0]->getShape()[0]);
862  }
863  if (other->isTazConnector()) {
864  return other->myBoundary.distanceTo2D(getLanes()[0]->getShape()[-1]);
865  }
866  return getLanes()[0]->getShape()[-1].distanceTo2D(other->getLanes()[0]->getShape()[0]);
867 }
868 
869 
870 const Position
872  return MSLane::dictionary(stop.lane)->geometryPositionAtOffset((stop.endPos + stop.startPos) / 2.);
873 }
874 
875 
876 double
878  // @note lanes might have different maximum speeds in theory
879  return myLanes->empty() ? 1 : getLanes()[0]->getSpeedLimit();
880 }
881 
882 
883 double
885  return myLanes->empty() ? 1 : getLanes()[0]->getLengthGeometryFactor();
886 }
887 
888 double
890  // @note lanes might have different maximum speeds in theory
891  return myLanes->empty() ? 1 : getLanes()[0]->getVehicleMaxSpeed(veh);
892 }
893 
894 
895 void
896 MSEdge::setMaxSpeed(double val) const {
897  if (myLanes != nullptr) {
898  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
899  (*i)->setMaxSpeed(val);
900  }
901  }
902 }
903 
904 
905 
906 std::vector<MSTransportable*>
907 MSEdge::getSortedPersons(SUMOTime timestep, bool includeRiding) const {
908  std::vector<MSTransportable*> result(myPersons.begin(), myPersons.end());
909  if (includeRiding) {
910  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
911  const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
912  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
913  const std::vector<MSTransportable*>& persons = (*j)->getPersons();
914  result.insert(result.end(), persons.begin(), persons.end());
915  }
916  (*i)->releaseVehicles();
917  }
918  }
919  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
920  return result;
921 }
922 
923 
924 std::vector<MSTransportable*>
925 MSEdge::getSortedContainers(SUMOTime timestep, bool /* includeRiding */) const {
926  std::vector<MSTransportable*> result(myContainers.begin(), myContainers.end());
927  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
928  return result;
929 }
930 
931 
932 int
934  const double pos1 = c1->getCurrentStage()->getEdgePos(myTime);
935  const double pos2 = c2->getCurrentStage()->getEdgePos(myTime);
936  if (pos1 != pos2) {
937  return pos1 < pos2;
938  }
939  return c1->getID() < c2->getID();
940 }
941 
942 
943 void
944 MSEdge::addSuccessor(MSEdge* edge, const MSEdge* via) {
945  mySuccessors.push_back(edge);
946  myViaSuccessors.push_back(std::make_pair(edge, via));
947  if (isTazConnector() && edge->getFromJunction() != nullptr) {
949  }
950 
951  edge->myPredecessors.push_back(this);
952  if (edge->isTazConnector() && getToJunction() != nullptr) {
953  edge->myBoundary.add(getToJunction()->getPosition());
954  }
955 }
956 
957 
958 const MSEdgeVector&
960  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == EDGEFUNC_CONNECTOR) {
961  return mySuccessors;
962  }
963 #ifdef HAVE_FOX
964  FXConditionalLock lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
965 #endif
966  std::map<SUMOVehicleClass, MSEdgeVector>::iterator i = myClassesSuccessorMap.find(vClass);
967  if (i == myClassesSuccessorMap.end()) {
968  // instantiate vector
969  myClassesSuccessorMap[vClass];
970  i = myClassesSuccessorMap.find(vClass);
971  // this vClass is requested for the first time. rebuild all successors
972  for (MSEdgeVector::const_iterator it = mySuccessors.begin(); it != mySuccessors.end(); ++it) {
973  if ((*it)->isTazConnector()) {
974  i->second.push_back(*it);
975  } else {
976  const std::vector<MSLane*>* allowed = allowedLanes(**it, vClass);
977  if (allowed != nullptr && allowed->size() > 0) {
978  i->second.push_back(*it);
979  }
980  }
981  }
982  }
983  // can use cached value
984  return i->second;
985 }
986 
987 
990  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == EDGEFUNC_CONNECTOR) {
991  return myViaSuccessors;
992  }
993 #ifdef HAVE_FOX
994  FXConditionalLock lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
995 #endif
996  auto i = myClassesViaSuccessorMap.find(vClass);
997  if (i != myClassesViaSuccessorMap.end()) {
998  // can use cached value
999  return i->second;
1000  }
1001  // instantiate vector
1003  // this vClass is requested for the first time. rebuild all successors
1004  for (const auto& viaPair : myViaSuccessors) {
1005  if (viaPair.first->isTazConnector()) {
1006  result.push_back(viaPair);
1007  } else {
1008  const std::vector<MSLane*>* allowed = allowedLanes(*viaPair.first, vClass);
1009  if (allowed != nullptr && allowed->size() > 0) {
1010  result.push_back(viaPair);
1011  }
1012  }
1013  }
1014  return result;
1015 }
1016 
1017 
1018 void
1020  myFromJunction = from;
1021  myToJunction = to;
1022  if (!isTazConnector()) {
1023  myBoundary.add(from->getPosition());
1024  myBoundary.add(to->getPosition());
1025  }
1026 }
1027 
1028 
1029 bool
1031  return (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr &&
1032  // do not change on curved internal lanes
1033  (!isInternal() || myLanes->back()->getIncomingLanes()[0].viaLink->getDirection() == LINKDIR_STRAIGHT));
1034 }
1035 
1036 
1037 const MSEdge*
1039  if (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr) {
1040  return &(myLanes->back()->getOpposite()->getEdge());
1041  } else {
1042  return nullptr;
1043  }
1044 }
1045 
1046 
1047 bool
1049  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
1050  const MSLinkCont& lc = (*i)->getLinkCont();
1051  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
1052  if (!(*j)->havePriority()) {
1053  return true;
1054  }
1055  }
1056  }
1057  return false;
1058 }
1059 
1060 
1061 void
1062 MSEdge::checkAndRegisterBiDirEdge(const std::string& bidiID) {
1063  if (bidiID != "") {
1064  myBidiEdge = dictionary(bidiID);
1065  if (myBidiEdge == nullptr) {
1066  WRITE_ERROR("Bidi-edge '" + bidiID + "' does not exist");
1067  }
1068  return;
1069  }
1070  if (getFunction() != EDGEFUNC_NORMAL) {
1071  return;
1072  }
1073  ConstMSEdgeVector candidates = myToJunction->getOutgoing();
1074  for (ConstMSEdgeVector::const_iterator it = candidates.begin(); it != candidates.end(); it++) {
1075  if ((*it)->getToJunction() == myFromJunction) { //reverse edge
1076  if (myBidiEdge != nullptr && isSuperposable(*it)) {
1077  WRITE_WARNING("Ambiguous superposable edges between junction '" + myToJunction->getID() + "' and '" + myFromJunction->getID() + "'.");
1078  break;
1079  }
1080  myBidiEdge = isSuperposable(*it) ? *it : nullptr;
1081  }
1082  }
1083 }
1084 
1085 
1086 bool
1088  if (other == nullptr || other->getLanes().size() != myLanes->size()) {
1089  return false;
1090  }
1091  std::vector<MSLane*>::const_iterator it1 = myLanes->begin();
1092  std::vector<MSLane*>::const_reverse_iterator it2 = other->getLanes().rbegin();
1093  do {
1094  if ((*it1)->getShape().reverse() != (*it2)->getShape()) {
1095  return false;
1096  }
1097  it1++;
1098  it2++;
1099  } while (it1 != myLanes->end());
1100 
1101  return true;
1102 }
1103 
1104 
1105 void
1107 #ifdef HAVE_FOX
1108  FXConditionalLock lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1109 #endif
1110  myWaiting.push_back(vehicle);
1111 }
1112 
1113 
1114 void
1115 MSEdge::removeWaiting(const SUMOVehicle* vehicle) const {
1116 #ifdef HAVE_FOX
1117  FXConditionalLock lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1118 #endif
1119  std::vector<SUMOVehicle*>::iterator it = std::find(myWaiting.begin(), myWaiting.end(), vehicle);
1120  if (it != myWaiting.end()) {
1121  myWaiting.erase(it);
1122  }
1123 }
1124 
1125 
1126 SUMOVehicle*
1127 MSEdge::getWaitingVehicle(MSTransportable* transportable, const double position) const {
1128 #ifdef HAVE_FOX
1129  FXConditionalLock lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1130 #endif
1131  for (SUMOVehicle* const vehicle : myWaiting) {
1132  if (transportable->isWaitingFor(vehicle)) {
1133  if (vehicle->isStoppedInRange(position, MSGlobals::gStopTolerance) ||
1134  (!vehicle->hasDeparted() &&
1135  (vehicle->getParameter().departProcedure == DEPART_TRIGGERED ||
1136  vehicle->getParameter().departProcedure == DEPART_CONTAINER_TRIGGERED))) {
1137  return vehicle;
1138  }
1139  // !!! this gives false warnings when there are two stops on the same edge
1140  WRITE_WARNING(transportable->getID() + " at edge '" + getID() + "' position " + toString(position) + " cannot use waiting vehicle '"
1141  + vehicle->getID() + "' at position " + toString(vehicle->getPositionOnLane()) + " because it is too far away.");
1142  }
1143  }
1144  return nullptr;
1145 }
1146 
1147 
1148 /****************************************************************************/
MSEdge::myFromJunction
MSJunction * myFromJunction
the junctions for this edge
Definition: MSEdge.h:819
MSEdge::canChangeToOpposite
bool canChangeToOpposite()
whether this edge allows changing to the opposite direction edge
Definition: MSEdge.cpp:1030
MSVehicleType
The car-following model and parameter.
Definition: MSVehicleType.h:65
MSEdge::by_id_sorter
Sorts edges by their ids.
Definition: MSEdge.h:753
MSVehicle::updateBestLanes
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:4698
MSEdge::getCurrentTravelTime
double getCurrentTravelTime(const double minSpeed=NUMERICAL_EPS) const
Computes and returns the current travel time for this edge.
Definition: MSEdge.cpp:749
MEVehicle
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:44
SUMOTrafficObject
Representation of a vehicle or person.
Definition: SUMOTrafficObject.h:47
SUMOVehicleClass
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
Definition: SUMOVehicleClass.h:133
MSEdge::getViaSuccessors
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges with internal vias, restricted by vClass.
Definition: MSEdge.cpp:989
MSLane::dictionary
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1866
MSBaseVehicle::getParameter
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
Definition: MSBaseVehicle.cpp:144
MSEdge::hasMinorLink
bool hasMinorLink() const
whether any lane has a minor link
Definition: MSEdge.cpp:1048
MSEdge::myDict
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSEdge.h:888
LINKSTATE_EQUAL
@ LINKSTATE_EQUAL
This is an uncontrolled, right-before-left link.
Definition: SUMOXMLDefinitions.h:1159
MSEdge::getSuccessors
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:959
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
MSConstEdgePairVector
std::vector< std::pair< const MSEdge *, const MSEdge * > > MSConstEdgePairVector
Definition: MSEdge.h:76
MSEdge::getNumericalID
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:265
MSEdge::getSpeedLimit
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:877
WRITE_WARNING
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:275
MSVehicle::getBestLanes
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:4692
MSNet.h
SUMOVehicle::setChosenSpeedFactor
virtual void setChosenSpeedFactor(const double factor)=0
MSLane
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
Named
Base class for objects which have an id.
Definition: Named.h:56
MSEdge::getVehicleMaxSpeed
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:889
MSEdge::isVaporizing
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:379
MSEdge::addWaiting
void addWaiting(SUMOVehicle *vehicle) const
Adds a vehicle to the list of waiting vehicles.
Definition: MSEdge.cpp:1106
SUMOVehicleParameter::Stop::lane
std::string lane
The lane to stop at.
Definition: SUMOVehicleParameter.h:586
MSLaneChanger.h
MSLaneChanger
Performs lane changing of vehicles.
Definition: MSLaneChanger.h:47
MSEdge::getSortedPersons
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's persons sorted by pos.
Definition: MSEdge.cpp:907
SUMOVehicle::getParameter
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
MESegment
A single mesoscopic segment (cell)
Definition: MESegment.h:49
MSJunction
The base class for an intersection.
Definition: MSJunction.h:60
MSEdge::getOppositeEdge
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
Definition: MSEdge.cpp:1038
Boundary::distanceTo2D
double distanceTo2D(const Position &p) const
returns the euclidean distance in the x-y-plane
Definition: Boundary.cpp:222
NUMERICAL_EPS
#define NUMERICAL_EPS
Definition: config.h:148
MSEdge::checkAndRegisterBiDirEdge
void checkAndRegisterBiDirEdge(const std::string &bidiID="")
check and register the opposite superposable edge if any
Definition: MSEdge.cpp:1062
MSEdge::myMinimumPermissions
SVCPermissions myMinimumPermissions
The intersection of lane permissions for this edge.
Definition: MSEdge.h:838
OptionsCont.h
MSEdge::myPredecessors
MSEdgeVector myPredecessors
The preceeding edges.
Definition: MSEdge.h:816
SUMOTrafficObject::getVehicleType
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.
SUMOVehicleParameter::departSpeed
double departSpeed
(optional) The initial speed of the vehicle
Definition: SUMOVehicleParameter.h:506
MSLeaderInfo.h
SUMOVehicleParameter::departPosProcedure
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
Definition: SUMOVehicleParameter.h:497
MSGlobals::gMinorPenalty
static double gMinorPenalty
time penalty for passing a minor link when routing
Definition: MSGlobals.h:132
MSEdge::myLastFailedInsertionTime
SUMOTime myLastFailedInsertionTime
The time of last insertion failure.
Definition: MSEdge.h:800
SUMOTrafficObject::getID
virtual const std::string & getID() const =0
Get the vehicle's ID.
MSEdge::myClassesSuccessorMap
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:898
MSEdge::DictType
std::map< std::string, MSEdge * > DictType
definition of the static dictionary type
Definition: MSEdge.h:883
MSEdge::myToJunction
MSJunction * myToJunction
Definition: MSEdge.h:820
MSEdge::myLaneChanger
MSLaneChanger * myLaneChanger
This member will do the lane-change.
Definition: MSEdge.h:791
MSEdge::getDepartPosBound
double getDepartPosBound(const MSVehicle &veh, bool upper=true) const
return upper bound for the depart position on this edge
Definition: MSEdge.cpp:437
MSEdge::myEdges
static MSEdgeVector myEdges
Static list of edges.
Definition: MSEdge.h:893
MESegment::initialise
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:278
DEPART_POS_DEFAULT
@ DEPART_POS_DEFAULT
No information given; use default.
Definition: SUMOVehicleParameter.h:142
MSEdge::myLength
double myLength
the length of the edge (cached value for speedup)
Definition: MSEdge.h:859
MSGlobals::gNumSimThreads
static int gNumSimThreads
how many threads to use for simulation
Definition: MSGlobals.h:123
MESegment::hasSpaceFor
bool hasSpaceFor(const MEVehicle *veh, SUMOTime entryTime, bool init=false) const
Returns whether the given vehicle would still fit into the segment.
Definition: MESegment.cpp:251
DEPART_LANE_BEST_FREE
@ DEPART_LANE_BEST_FREE
The least occupied lane from best lanes.
Definition: SUMOVehicleParameter.h:128
MSEdge::mySublaneSides
std::vector< double > mySublaneSides
the right side for each sublane on this edge
Definition: MSEdge.h:877
MSEdge::myAmFringe
bool myAmFringe
whether this edge is at the network fringe
Definition: MSEdge.h:874
DEPART_POS_LAST
@ DEPART_POS_LAST
Insert behind the last vehicle as close as possible to still allow the specified departSpeed....
Definition: SUMOVehicleParameter.h:152
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:34
SUMOVehicle
Representation of a vehicle.
Definition: SUMOVehicle.h:60
MSLane::VehCont
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:92
MSRoutingEngine::getAssumedSpeed
static double getAssumedSpeed(const MSEdge *edge)
return current travel speed assumption
Definition: MSRoutingEngine.cpp:147
MSBaseVehicle::getRoute
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:115
ConstMSEdgeVector
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:75
SumoXMLEdgeFunc
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
Definition: SUMOXMLDefinitions.h:1079
MSEdge::~MSEdge
virtual ~MSEdge()
Destructor.
Definition: MSEdge.cpp:88
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:57
MSEdge::recalcCache
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:111
MSGlobals::gUseMesoSim
static bool gUseMesoSim
Definition: MSGlobals.h:90
MSEdge::AllowedLanesCont
std::vector< std::pair< SVCPermissions, std::shared_ptr< const std::vector< MSLane * > > > > AllowedLanesCont
"Map" from vehicle class to allowed lanes
Definition: MSEdge.h:81
MSEdge::rebuildAllowedTargets
void rebuildAllowedTargets(const bool updateVehicles=true)
Definition: MSEdge.cpp:272
MSEdge::setJunctions
void setJunctions(MSJunction *from, MSJunction *to)
Definition: MSEdge.cpp:1019
MSTransportable::Stage::getEdgePos
virtual double getEdgePos(SUMOTime now) const
Definition: MSTransportable.cpp:75
SUMOVehicleParameter
Structure representing possible vehicle parameter.
Definition: SUMOVehicleParameter.h:297
MSEdge.h
MSEdge::getDistanceTo
double getDistanceTo(const MSEdge *other, const bool doBoundaryEstimate=false) const
optimistic air distance heuristic for use in routing
Definition: MSEdge.cpp:852
MSEdge::closeBuilding
void closeBuilding()
Definition: MSEdge.cpp:148
MSTransportable
Definition: MSTransportable.h:58
MSInsertionControl.h
MSLaneChangerSublane
Performs lane changing of vehicles.
Definition: MSLaneChangerSublane.h:42
MSEdge::getLength
double getLength() const
return the length of the edge
Definition: MSEdge.h:589
MSEdge::decVaporization
SUMOTime decVaporization(SUMOTime t)
Disables vaporization.
Definition: MSEdge.cpp:398
MSLane::getBruttoOccupancy
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2677
MSEdge::dictSize
static int dictSize()
Returns the number of edges.
Definition: MSEdge.cpp:792
MSGlobals::gLateralResolution
static double gLateralResolution
Definition: MSGlobals.h:84
MSVehicle.h
MSJunction::getOutgoing
const ConstMSEdgeVector & getOutgoing() const
Definition: MSJunction.h:107
MSEdge::myLanes
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:788
SVC_PRIVATE
@ SVC_PRIVATE
private vehicles
Definition: SUMOVehicleClass.h:141
MESegment.h
DEPART_LANE_ALLOWED_FREE
@ DEPART_LANE_ALLOWED_FREE
The least occupied lane from lanes which allow the continuation.
Definition: SUMOVehicleParameter.h:126
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
MSEdge::isInternal
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:235
SUMOTrafficObject::getChosenSpeedFactor
virtual double getChosenSpeedFactor() const =0
MSEdge::getLengthGeometryFactor
double getLengthGeometryFactor() const
return shape.length() / myLength
Definition: MSEdge.cpp:884
MSGlobals::gNumThreads
static int gNumThreads
how many threads to use
Definition: MSGlobals.h:126
MSLeaderInfo
Definition: MSLeaderInfo.h:49
MSEdge::leftLane
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:334
LINKDIR_TURN
@ LINKDIR_TURN
The link is a 180 degree turn.
Definition: SUMOXMLDefinitions.h:1180
MSRoute::size
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:81
MSEdge::getFromJunction
const MSJunction * getFromJunction() const
Definition: MSEdge.h:359
LinkState
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
Definition: SUMOXMLDefinitions.h:1137
RandHelper::rand
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:53
LINKDIR_STRAIGHT
@ LINKDIR_STRAIGHT
The link is a straight direction.
Definition: SUMOXMLDefinitions.h:1178
DEPART_LANE_RANDOM
@ DEPART_LANE_RANDOM
The lane is chosen randomly.
Definition: SUMOVehicleParameter.h:122
Distribution_Parameterized::getParameter
std::vector< double > & getParameter()
Returns the parameters of this distribution.
Definition: Distribution_Parameterized.cpp:110
MSVehicleType::computeChosenSpeedDeviation
double computeChosenSpeedDeviation(std::mt19937 *rng, const double minDev=-1.) const
Computes and returns the speed deviation.
Definition: MSVehicleType.cpp:82
MSGlobals::gMesoTLSPenalty
static double gMesoTLSPenalty
Definition: MSGlobals.h:99
MSVehicle::getPositionOnLane
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:392
MSTransportable::getCurrentStage
MSTransportable::Stage * getCurrentStage() const
Return the current stage.
Definition: MSTransportable.h:677
MSEdgeWeightsStorage.h
MSEdge::getMeanSpeed
double getMeanSpeed() const
get the mean speed
Definition: MSEdge.cpp:712
DEPART_POS_FREE
@ DEPART_POS_FREE
A free position is chosen.
Definition: SUMOVehicleParameter.h:148
SVCPermissions
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
Definition: SUMOVehicleClass.h:218
MSJunction.h
MSVehicleType::getLengthWithGap
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
Definition: MSVehicleType.h:117
MSGlobals::gMesoMinorPenalty
static SUMOTime gMesoMinorPenalty
Definition: MSGlobals.h:102
DEPART_SPEED_GIVEN
@ DEPART_SPEED_GIVEN
The speed is given.
Definition: SUMOVehicleParameter.h:196
StringTokenizer
Definition: StringTokenizer.h:61
MSEdge::isTazConnector
bool isTazConnector() const
Definition: MSEdge.h:258
MSEdge::dictionary
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:765
DEPART_LANE_GIVEN
@ DEPART_LANE_GIVEN
The lane is given.
Definition: SUMOVehicleParameter.h:120
MSEdge::clear
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:804
FXConditionalLock
A scoped lock which only triggers on condition.
Definition: FXConditionalLock.h:36
STEPS2TIME
#define STEPS2TIME(x)
Definition: SUMOTime.h:56
MSEdge::initialize
void initialize(const std::vector< MSLane * > *lanes)
Initialize the edge.
Definition: MSEdge.cpp:94
MSLane::insertVehicle
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:538
MSEdge::myBoundary
Boundary myBoundary
The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start ...
Definition: MSEdge.h:904
SUMOVehicleParameter::id
std::string id
The vehicle's id.
Definition: SUMOVehicleParameter.h:468
MSEdge::getStopPosition
static const Position getStopPosition(const SUMOVehicleParameter::Stop &stop)
return the coordinates of the center of the given stop
Definition: MSEdge.cpp:871
MELoop::getSegmentForEdge
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:292
MSEdge::myViaSuccessors
MSConstEdgePairVector myViaSuccessors
Definition: MSEdge.h:813
MSEdge::getFunction
SumoXMLEdgeFunc getFunction() const
Returns the edge type (SumoXMLEdgeFunc)
Definition: MSEdge.h:225
ProcessError
Definition: UtilExceptions.h:39
MSEdge::myWaiting
std::vector< SUMOVehicle * > myWaiting
List of waiting vehicles.
Definition: MSEdge.h:907
MSEdge::myAllowedTargets
AllowedLanesByTarget myAllowedTargets
From target edge to lanes allowed to be used to reach it.
Definition: MSEdge.h:835
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:38
FileHelpers::readEdgeVector
static void readEdgeVector(std::istream &in, std::vector< const E * > &edges, const std::string &rid)
Reads an edge vector binary.
Definition: FileHelpers.h:262
Boundary::add
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
time2string
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:67
RandHelper::getRandomFrom
static const T & getRandomFrom(const std::vector< T > &v, std::mt19937 *rng=0)
Returns a random element from the given vector.
Definition: RandHelper.h:149
MSGlobals.h
LINKSTATE_DEADEND
@ LINKSTATE_DEADEND
This is a dead end link.
Definition: SUMOXMLDefinitions.h:1167
MESegment::getNextSegment
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:151
MSEdge
A road/street connecting two junctions.
Definition: MSEdge.h:78
DEPART_TRIGGERED
@ DEPART_TRIGGERED
The departure is person triggered.
Definition: SUMOVehicleParameter.h:102
EDGEFUNC_CONNECTOR
@ EDGEFUNC_CONNECTOR
Definition: SUMOXMLDefinitions.h:1082
BinaryFormatter::BF_ROUTE
@ BF_ROUTE
Definition: BinaryFormatter.h:91
SUMOVehicleParameter::Stop::endPos
double endPos
The stopping position end.
Definition: SUMOVehicleParameter.h:604
MSEdge::getWaitingVehicle
SUMOVehicle * getWaitingVehicle(MSTransportable *transportable, const double position) const
Definition: MSEdge.cpp:1127
MSEdge::getToJunction
const MSJunction * getToJunction() const
Definition: MSEdge.h:363
MSEdge::rightLane
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:340
DEPART_POS_RANDOM
@ DEPART_POS_RANDOM
The position is chosen randomly.
Definition: SUMOVehicleParameter.h:146
LINKSTATE_MINOR
@ LINKSTATE_MINOR
This is an uncontrolled, minor link, has to brake.
Definition: SUMOXMLDefinitions.h:1157
MSBaseVehicle::getVehicleType
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:123
MSEdge::getInternalFollowingEdge
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal) const
Definition: MSEdge.cpp:669
EDGEFUNC_NORMAL
@ EDGEFUNC_NORMAL
Definition: SUMOXMLDefinitions.h:1081
MSRoutingEngine.h
MSEdge::allowedLanes
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:359
MSEdge::getDepartLane
MSLane * getDepartLane(MSVehicle &veh) const
Finds a depart lane for the given vehicle parameters.
Definition: MSEdge.cpp:481
MSLane::getLinkCont
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:2110
MSContainer.h
MSEdge::getRoutingSpeed
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:759
BEST_LANE_LOOKAHEAD
#define BEST_LANE_LOOKAHEAD
Definition: MSEdge.cpp:51
MSLaneChangerSublane.h
MSJunction::getPosition
const Position & getPosition() const
Definition: MSJunction.cpp:68
MSEdge::myCombinedPermissions
SVCPermissions myCombinedPermissions
The union of lane permissions for this edge.
Definition: MSEdge.h:840
MSVehicleType::getSpeedFactor
const Distribution_Parameterized & getSpeedFactor() const
Returns this type's speed factor.
Definition: MSVehicleType.h:209
MSEdge::getInternalFollowingLengthTo
double getInternalFollowingLengthTo(const MSEdge *followerAfterInternal) const
returns the length of all internal edges on the junction until reaching the non-internal edge followe...
Definition: MSEdge.cpp:687
MSTransportable::isWaitingFor
bool isWaitingFor(const SUMOVehicle *vehicle) const
Whether the transportable waits for the given vehicle in the current step.
Definition: MSTransportable.h:716
MSLane::getOpposite
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:3518
MSLane::getLogicalPredecessorLane
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2543
SUMOVehicleParameter::Stop::startPos
double startPos
The stopping position start.
Definition: SUMOVehicleParameter.h:601
MSEdge::incVaporization
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition: MSEdge.cpp:391
MSLane::getEdge
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:669
SUMOVehicleParameter::departLane
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
Definition: SUMOVehicleParameter.h:488
MSEdge::MSEdge
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:63
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
MSEdge::insertVehicle
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:544
MSEdge::myBidiEdge
const MSEdge * myBidiEdge
the oppositing superposable edge
Definition: MSEdge.h:920
SUMOVehicleParameter::departLaneProcedure
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
Definition: SUMOVehicleParameter.h:491
MSNet::getInstance
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
MSGlobals::gMesoNet
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:105
MSEdge::mySuccessors
MSEdgeVector mySuccessors
The succeeding edges.
Definition: MSEdge.h:811
MSEdge::getFreeLane
MSLane * getFreeLane(const std::vector< MSLane * > *allowed, const SUMOVehicleClass vclass, double departPos) const
Finds the emptiest lane allowing the vehicle class.
Definition: MSEdge.cpp:405
MSEdge::transportable_by_position_sorter::myTime
SUMOTime myTime
Definition: MSEdge.h:776
MSVehicleType::getLength
double getLength() const
Get vehicle's length [m].
Definition: MSVehicleType.h:109
MSEdge::allowsLaneChanging
bool allowsLaneChanging() const
Definition: MSEdge.cpp:205
MSEdge::myTimePenalty
double myTimePenalty
flat penalty when computing traveltime
Definition: MSEdge.h:865
MSEdge::transportable_by_position_sorter
Sorts transportables by their positions.
Definition: MSEdge.h:768
MSEdge::setMaxSpeed
void setMaxSpeed(double val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:896
MSEdge::addToAllowed
void addToAllowed(const SVCPermissions permissions, std::shared_ptr< const std::vector< MSLane * > > allowedLanes, AllowedLanesCont &laneCont) const
Definition: MSEdge.cpp:228
DEPART_POS_RANDOM_FREE
@ DEPART_POS_RANDOM_FREE
If a fixed number of random choices fails, a free position is chosen.
Definition: SUMOVehicleParameter.h:154
SVCAll
const SVCPermissions SVCAll
all VClasses are allowed
Definition: SUMOVehicleClass.cpp:146
MSEdgeVector
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:74
MELoop::buildSegmentsFor
void buildSegmentsFor(const MSEdge &e, const OptionsCont &oc)
Build the segments for a given edge.
Definition: MELoop.cpp:264
MSGlobals::gStopTolerance
static double gStopTolerance
The tolerance to apply when matching waiting persons and vehicles.
Definition: MSGlobals.h:141
MSTransportable::getID
const std::string & getID() const
returns the id of the transportable
Definition: MSTransportable.cpp:699
MSEdge::parseEdgesList
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:822
MSEdge::parallelLane
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:346
MEVehicle.h
MSEdge::myContainers
std::set< MSTransportable * > myContainers
Containers on the edge.
Definition: MSEdge.h:826
MSEdge::getLanes
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:167
MSEdge::insertIDs
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:814
MSEdge::myAmDelayed
bool myAmDelayed
whether this edge had a vehicle with less than max speed on it
Definition: MSEdge.h:868
DEPART_LANE_DEFAULT
@ DEPART_LANE_DEFAULT
No information given; use default.
Definition: SUMOVehicleParameter.h:118
MSRoute::begin
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:69
MSEdge::changeLanes
virtual void changeLanes(SUMOTime t)
Performs lane changing on this edge.
Definition: MSEdge.cpp:660
MSEdge::getNormalBefore
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition: MSEdge.cpp:702
StringTokenizer::getVector
std::vector< std::string > getVector()
return vector of strings
Definition: StringTokenizer.cpp:191
LINKSTATE_ALLWAY_STOP
@ LINKSTATE_ALLWAY_STOP
This is an uncontrolled, all-way stop link.
Definition: SUMOXMLDefinitions.h:1163
config.h
DEPART_POS_BASE
@ DEPART_POS_BASE
Back-at-zero position.
Definition: SUMOVehicleParameter.h:150
MSEdge::myWidth
double myWidth
Edge width [m].
Definition: MSEdge.h:856
StringTokenizer.h
MELoop.h
SUMOVehicleClass_MAX
const SUMOVehicleClass SUMOVehicleClass_MAX
Definition: SUMOVehicleClass.cpp:144
MSGlobals::gLaneChangeDuration
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:81
DEPART_POS_GIVEN
@ DEPART_POS_GIVEN
The position is given.
Definition: SUMOVehicleParameter.h:144
MSLane.h
MSEdge::lock
virtual void lock() const
grant exclusive access to the mesoscopic state
Definition: MSEdge.h:684
DEPART_CONTAINER_TRIGGERED
@ DEPART_CONTAINER_TRIGGERED
The departure is container triggered.
Definition: SUMOVehicleParameter.h:104
MSEdge::removeWaiting
void removeWaiting(const SUMOVehicle *vehicle) const
Removes a vehicle from the list of waiting vehicles.
Definition: MSEdge.cpp:1115
MSVehicleType::getVehicleClass
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
Definition: MSVehicleType.h:184
MSEdge::addSuccessor
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:944
MSEdge::transportable_by_position_sorter::operator()
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition: MSEdge.cpp:933
SVC_IGNORING
@ SVC_IGNORING
vehicles ignoring classes
Definition: SUMOVehicleClass.h:135
MSEdge::myFailedInsertionMemory
std::set< int > myFailedInsertionMemory
A cache for the rejected insertion attempts. Used to assure that no further insertion attempts are ma...
Definition: MSEdge.h:805
MSEdge::getAllEdges
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:798
MSEdge::myPersons
std::set< MSTransportable * > myPersons
Persons on the edge for drawing and pushbutton.
Definition: MSEdge.h:823
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:76
MSEdge::myAllowed
AllowedLanesCont myAllowed
Associative container from vehicle class to allowed-lanes.
Definition: MSEdge.h:832
WRITE_ERROR
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:283
MSEdge::myClassesViaSuccessorMap
std::map< SUMOVehicleClass, MSConstEdgePairVector > myClassesViaSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:901
DEPART_LANE_FREE
@ DEPART_LANE_FREE
The least occupied lane is used.
Definition: SUMOVehicleParameter.h:124
MSEdge::myVaporizationRequests
int myVaporizationRequests
Vaporizer counter.
Definition: MSEdge.h:797
MSEdge::buildLaneChanger
void buildLaneChanger()
Has to be called after all sucessors and predecessors have been set (after closeBuilding())
Definition: MSEdge.cpp:187
MSLane::getIndex
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:563
DEPART_LANE_FIRST_ALLOWED
@ DEPART_LANE_FIRST_ALLOWED
The rightmost lane the vehicle may use.
Definition: SUMOVehicleParameter.h:130
MSEdge::myEmptyTraveltime
double myEmptyTraveltime
the traveltime on the empty edge (cached value for speedup)
Definition: MSEdge.h:862
MSLaneChanger::laneChange
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge'e lanes.
Definition: MSLaneChanger.cpp:120
SUMOVehicleParameter::departPos
double departPos
(optional) The position the vehicle shall depart from
Definition: SUMOVehicleParameter.h:494
SUMOVehicleParameter::departSpeedProcedure
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
Definition: SUMOVehicleParameter.h:509
MSEdge::rebuildAllowedLanes
void rebuildAllowedLanes()
Definition: MSEdge.cpp:243
SUMOVehicleParameter::Stop
Definition of vehicle stop (position and duration)
Definition: SUMOVehicleParameter.h:572
MSLeaderInfo::numSublanes
int numSublanes() const
Definition: MSLeaderInfo.h:87
MSEdge::myFunction
const SumoXMLEdgeFunc myFunction
the purpose of the edge
Definition: MSEdge.h:794
LINKSTATE_STOP
@ LINKSTATE_STOP
This is an uncontrolled, minor link, has to stop.
Definition: SUMOXMLDefinitions.h:1161
MSEdge::getPredecessors
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:354
MSVehicle
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79
MSEdge::isSuperposable
bool isSuperposable(const MSEdge *other)
Definition: MSEdge.cpp:1087
MSEdge::getSortedContainers
std::vector< MSTransportable * > getSortedContainers(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's containers sorted by pos.
Definition: MSEdge.cpp:925