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