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 double vehNo = (double) segment->getCarNumber();
702  v += vehNo * segment->getMeanSpeed();
703  no += vehNo;
704  }
705  if (no == 0) {
706  return getLength() / myEmptyTraveltime; // may include tls-penalty
707  }
708  } else {
709  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
710  const double vehNo = (double)(*i)->getVehicleNumber();
711  v += vehNo * (*i)->getMeanSpeed();
712  no += vehNo;
713  }
714  if (no == 0) {
715  return getSpeedLimit();
716  }
717  }
718  return v / no;
719 }
720 
721 
722 double
723 MSEdge::getCurrentTravelTime(double minSpeed) const {
724  assert(minSpeed > 0);
725  if (!myAmDelayed) {
726  return myEmptyTraveltime;
727  }
728  return getLength() / MAX2(minSpeed, getMeanSpeed());
729 }
730 
731 
732 double
735 }
736 
737 
738 
739 bool
740 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
741  DictType::iterator it = myDict.find(id);
742  if (it == myDict.end()) {
743  // id not in myDict.
744  myDict[id] = ptr;
745  while ((int)myEdges.size() < ptr->getNumericalID() + 1) {
746  myEdges.push_back(0);
747  }
748  myEdges[ptr->getNumericalID()] = ptr;
749  return true;
750  }
751  return false;
752 }
753 
754 
755 MSEdge*
756 MSEdge::dictionary(const std::string& id) {
757  DictType::iterator it = myDict.find(id);
758  if (it == myDict.end()) {
759  // id not in myDict.
760  return 0;
761  }
762  return it->second;
763 }
764 
765 
766 int
768  return (int)myDict.size();
769 }
770 
771 
772 const MSEdgeVector&
774  return myEdges;
775 }
776 
777 
778 void
780  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
781  delete(*i).second;
782  }
783  myDict.clear();
784  myEdges.clear();
785 }
786 
787 
788 void
789 MSEdge::insertIDs(std::vector<std::string>& into) {
790  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
791  into.push_back((*i).first);
792  }
793 }
794 
795 
796 void
797 MSEdge::parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
798  const std::string& rid) {
799  if (desc[0] == BinaryFormatter::BF_ROUTE) {
800  std::istringstream in(desc, std::ios::binary);
801  char c;
802  in >> c;
803  FileHelpers::readEdgeVector(in, into, rid);
804  } else {
805  StringTokenizer st(desc);
806  parseEdgesList(st.getVector(), into, rid);
807  }
808 }
809 
810 
811 void
812 MSEdge::parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
813  const std::string& rid) {
814  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
815  const MSEdge* edge = MSEdge::dictionary(*i);
816  // check whether the edge exists
817  if (edge == 0) {
818  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
819  + "\n The route can not be build.");
820  }
821  into.push_back(edge);
822  }
823 }
824 
825 
826 double
827 MSEdge::getDistanceTo(const MSEdge* other) const {
828  if (isTazConnector()) {
829  if (other->isTazConnector()) {
831  }
833  }
834  if (other->isTazConnector()) {
835  return other->myTazBoundary.distanceTo2D(getToJunction()->getPosition());
836  }
838 }
839 
840 
841 double
843  // @note lanes might have different maximum speeds in theory
844  return myLanes->empty() ? 1 : getLanes()[0]->getSpeedLimit();
845 }
846 
847 
848 double
850  return myLanes->empty() ? 1 : getLanes()[0]->getLengthGeometryFactor();
851 }
852 
853 double
854 MSEdge::getVehicleMaxSpeed(const SUMOVehicle* const veh) const {
855  // @note lanes might have different maximum speeds in theory
856  return myLanes->empty() ? 1 : getLanes()[0]->getVehicleMaxSpeed(veh);
857 }
858 
859 
860 void
861 MSEdge::setMaxSpeed(double val) const {
862  if (myLanes != 0) {
863  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
864  (*i)->setMaxSpeed(val);
865  }
866  }
867 }
868 
869 
870 
871 std::vector<MSTransportable*>
872 MSEdge::getSortedPersons(SUMOTime timestep, bool includeRiding) const {
873  std::vector<MSTransportable*> result(myPersons.begin(), myPersons.end());
874  if (includeRiding) {
875  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
876  const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
877  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
878  const std::vector<MSTransportable*>& persons = (*j)->getPersons();
879  result.insert(result.end(), persons.begin(), persons.end());
880  }
881  (*i)->releaseVehicles();
882  }
883  }
884  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
885  return result;
886 }
887 
888 
889 std::vector<MSTransportable*>
890 MSEdge::getSortedContainers(SUMOTime timestep, bool /* includeRiding */) const {
891  std::vector<MSTransportable*> result(myContainers.begin(), myContainers.end());
892  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
893  return result;
894 }
895 
896 
897 int
899  const double pos1 = c1->getCurrentStage()->getEdgePos(myTime);
900  const double pos2 = c2->getCurrentStage()->getEdgePos(myTime);
901  if (pos1 != pos2) {
902  return pos1 < pos2;
903  }
904  return c1->getID() < c2->getID();
905 }
906 
907 
908 void
909 MSEdge::addSuccessor(MSEdge* edge, const MSEdge* via) {
910  mySuccessors.push_back(edge);
911  myViaSuccessors.push_back(std::make_pair(edge, via));
912  if (isTazConnector() && edge->getFromJunction() != 0) {
914  }
915 
916  edge->myPredecessors.push_back(this);
917  if (edge->isTazConnector() && getToJunction() != 0) {
918  edge->myTazBoundary.add(getToJunction()->getPosition());
919  }
920 }
921 
922 
923 const MSEdgeVector&
925  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == EDGEFUNC_CONNECTOR) {
926  return mySuccessors;
927  }
928 #ifdef HAVE_FOX
929  if (MSDevice_Routing::isParallel()) {
930  MSDevice_Routing::lock();
931  }
932 #endif
933  std::map<SUMOVehicleClass, MSEdgeVector>::iterator i = myClassesSuccessorMap.find(vClass);
934  if (i == myClassesSuccessorMap.end()) {
935  // instantiate vector
936  myClassesSuccessorMap[vClass];
937  i = myClassesSuccessorMap.find(vClass);
938  // this vClass is requested for the first time. rebuild all successors
939  for (MSEdgeVector::const_iterator it = mySuccessors.begin(); it != mySuccessors.end(); ++it) {
940  if ((*it)->isTazConnector()) {
941  i->second.push_back(*it);
942  } else {
943  const std::vector<MSLane*>* allowed = allowedLanes(*it, vClass);
944  if (allowed != 0 && allowed->size() > 0) {
945  i->second.push_back(*it);
946  }
947  }
948  }
949  }
950  // can use cached value
951 #ifdef HAVE_FOX
952  if (MSDevice_Routing::isParallel()) {
953  MSDevice_Routing::unlock();
954  }
955 #endif
956  return i->second;
957 }
958 
959 
962  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == EDGEFUNC_CONNECTOR) {
963  return myViaSuccessors;
964  }
965 #ifdef HAVE_FOX
966  if (MSDevice_Routing::isParallel()) {
967  MSDevice_Routing::lock();
968  }
969 #endif
970  auto i = myClassesViaSuccessorMap.find(vClass);
971  if (i != myClassesViaSuccessorMap.end()) {
972  // can use cached value
973  return i->second;
974  }
975  // instantiate vector
977  // this vClass is requested for the first time. rebuild all successors
978  for (const auto& viaPair : myViaSuccessors) {
979  if (viaPair.first->isTazConnector()) {
980  result.push_back(viaPair);
981  } else {
982  const std::vector<MSLane*>* allowed = allowedLanes(viaPair.first, vClass);
983  if (allowed != nullptr && allowed->size() > 0) {
984  result.push_back(viaPair);
985  }
986  }
987  }
988 #ifdef HAVE_FOX
989  if (MSDevice_Routing::isParallel()) {
990  MSDevice_Routing::unlock();
991  }
992 #endif
993  return result;
994 }
995 
996 
997 bool
999  return (!myLanes->empty() && myLanes->back()->getOpposite() != 0 &&
1000  // do not change on curved internal lanes
1001  (!isInternal() || myLanes->back()->getIncomingLanes()[0].viaLink->getDirection() == LINKDIR_STRAIGHT));
1002 }
1003 
1004 
1005 
1006 const MSEdge*
1008  if (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr) {
1009  return &(myLanes->back()->getEdge());
1010  } else {
1011  return nullptr;
1012  }
1013 }
1014 
1015 
1016 bool
1018  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
1019  const MSLinkCont& lc = (*i)->getLinkCont();
1020  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
1021  if (!(*j)->havePriority()) {
1022  return true;
1023  }
1024  }
1025  }
1026  return false;
1027 }
1028 
1029 
1031  myBidiEdge = 0;
1032  if (getFunction() != EDGEFUNC_NORMAL) {
1033  return;
1034  }
1035  ConstMSEdgeVector candidates = myToJunction->getOutgoing();
1036  for (ConstMSEdgeVector::const_iterator it = candidates.begin(); it != candidates.end(); it++) {
1037  if ((*it)->getToJunction() == myFromJunction) { //reverse edge
1038  if (myBidiEdge != 0 && isSuperposable(*it)) {
1039  WRITE_WARNING("Ambiguous superposable edges between junction '" + myToJunction->getID() + "' and '" + myFromJunction->getID() + "'.");
1040  break;
1041  }
1042  myBidiEdge = isSuperposable(*it) ? *it : 0;
1043  }
1044  }
1045 }
1046 
1047 
1048 bool MSEdge::isSuperposable(const MSEdge* other) {
1049  if (other == 0 || other->getLanes().size() != myLanes->size()) {
1050  return false;
1051  }
1052  std::vector<MSLane*>::const_iterator it1 = myLanes->begin();
1053  std::vector<MSLane*>::const_reverse_iterator it2 = other->getLanes().rbegin();
1054  do {
1055  if ((*it1)->getShape().reverse() != (*it2)->getShape()) {
1056  return false;
1057  }
1058  it1++;
1059  it2++;
1060  } while (it1 != myLanes->end());
1061 
1062  return true;
1063 }
1064 
1065 /****************************************************************************/
1066 
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:766
bool myAmDelayed
whether this edge had a vehicle with less than max speed on it
Definition: MSEdge.h:835
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:2497
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:2370
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:798
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:789
long long int SUMOTime
Definition: SUMOTime.h:36
Sorts edges by their ids.
Definition: MSEdge.h:710
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:849
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:767
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:909
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:294
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:860
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:808
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:68
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:740
std::vector< double > mySublaneSides
the right side for each sublane on this edge
Definition: MSEdge.h:844
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:785
const SVCPermissions SVCAll
all VClasses are allowed
int myVaporizationRequests
Vaporizer counter.
Definition: MSEdge.h:769
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition: MSEdge.cpp:898
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:872
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:842
#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:850
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:723
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:267
void checkAndRegisterBiDirEdge()
check and register the opposite superposable edge if any
Definition: MSEdge.cpp:1030
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:486
SUMOTime myLastFailedInsertionTime
The time of last insertion failure.
Definition: MSEdge.h:772
MSTransportable::Stage * getCurrentStage() const
Return the current stage.
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:865
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:829
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:804
bool hasMinorLink() const
whether any lane has a minor link
Definition: MSEdge.cpp:1017
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
Definition: MSEdge.cpp:1007
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:4045
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:779
SVCPermissions myMinimumPermissions
The intersection of lane permissions for this edge.
Definition: MSEdge.h:811
MSEdgeVector mySuccessors
The succeeding edges.
Definition: MSEdge.h:783
MSJunction * myToJunction
Definition: MSEdge.h:792
MSLaneChanger * myLaneChanger
This member will do the lane-change.
Definition: MSEdge.h:763
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:733
#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:62
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:841
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:961
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:760
const MSEdge * myBidiEdge
the oppositing superposble edge
Definition: MSEdge.h:876
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:1048
bool canChangeToOpposite()
whether this edge allows changing to the opposite direction edge
Definition: MSEdge.cpp:998
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:854
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:813
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:924
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:868
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:773
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:826
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:791
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:861
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:855
Sorts transportables by their positions.
Definition: MSEdge.h:725
double getDistanceTo(const MSEdge *other) const
optimistic air distance heuristic for use in routing
Definition: MSEdge.cpp:827
#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:1940
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:4039
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:871
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:82
MSEdgeVector myPredecessors
The preceeding edges.
Definition: MSEdge.h:788
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:890
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:832
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:797
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:777
std::set< MSTransportable * > myPersons
Persons on the edge for drawing and pushbutton.
Definition: MSEdge.h:795
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.