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