SUMO - Simulation of Urban MObility
MSEdge.cpp
Go to the documentation of this file.
1 /****************************************************************************/
13 // A road/street connecting two junctions
14 /****************************************************************************/
15 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
16 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
17 /****************************************************************************/
18 //
19 // This file is part of SUMO.
20 // SUMO is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 /****************************************************************************/
26 
27 
28 // ===========================================================================
29 // included modules
30 // ===========================================================================
31 #ifdef _MSC_VER
32 #include <windows_config.h>
33 #else
34 #include <config.h>
35 #endif
36 
37 #include <algorithm>
38 #include <iostream>
39 #include <cassert>
42 #include "MSEdge.h"
43 #include "MSInsertionControl.h"
44 #include "MSJunction.h"
45 #include "MSLane.h"
46 #include "MSLaneChanger.h"
47 #include "MSLaneChangerSublane.h"
48 #include "MSGlobals.h"
49 #include "MSNet.h"
50 #include "MSVehicle.h"
51 #include "MSLeaderInfo.h"
52 #include "MSContainer.h"
53 #include "MSEdgeWeightsStorage.h"
55 
56 #include <mesosim/MELoop.h>
57 #include <mesosim/MESegment.h>
58 #include <mesosim/MEVehicle.h>
59 
60 #ifdef CHECK_MEMORY_LEAKS
61 #include <foreign/nvwa/debug_new.h>
62 #endif // CHECK_MEMORY_LEAKS
63 
64 
65 // ===========================================================================
66 // static member definitions
67 // ===========================================================================
70 
71 
72 // ===========================================================================
73 // member method definitions
74 // ===========================================================================
75 MSEdge::MSEdge(const std::string& id, int numericalID,
76  const EdgeBasicFunction function,
77  const std::string& streetName,
78  const std::string& edgeType,
79  int priority) :
80  Named(id), myNumericalID(numericalID), myLanes(0),
81  myLaneChanger(0), myFunction(function), myVaporizationRequests(0),
82  myLastFailedInsertionTime(-1),
83  myFromJunction(0), myToJunction(0),
84  myStreetName(streetName),
85  myEdgeType(edgeType),
86  myPriority(priority),
87  myWidth(0),
88  myLength(-1.),
89  myEmptyTraveltime(-1.),
90  myAmDelayed(false),
91  myAmRoundabout(false) {}
92 
93 
95  delete myLaneChanger;
96  for (AllowedLanesCont::iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); i1++) {
97  delete(*i1).second;
98  }
99  for (ClassedAllowedLanesCont::iterator i2 = myClassedAllowed.begin(); i2 != myClassedAllowed.end(); i2++) {
100  for (AllowedLanesCont::iterator i1 = (*i2).second.begin(); i1 != (*i2).second.end(); i1++) {
101  delete(*i1).second;
102  }
103  }
104  delete myLanes;
105  // Note: Lanes are delete using MSLane::clear();
106 }
107 
108 
109 void
110 MSEdge::initialize(const std::vector<MSLane*>* lanes) {
111  assert(lanes != 0);
112  myLanes = lanes;
115  }
116  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
117  myWidth += (*i)->getWidth();
118  }
120  SUMOReal widthBefore = 0;
121  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
122  (*i)->setRightSideOnEdge(widthBefore, (int)mySublaneSides.size());
123  MSLeaderInfo ahead(*i);
124  for (int j = 0; j < ahead.numSublanes(); ++j) {
125  mySublaneSides.push_back(widthBefore + j * MSGlobals::gLateralResolution);
126  }
127  widthBefore += (*i)->getWidth();
128  }
129  }
130 }
131 
132 
134  if (myLanes->empty()) {
135  return;
136  }
137  myLength = myLanes->front()->getLength();
139 
141  // add tls penalties to the minimum travel time
142  SUMOTime minPenalty = -1;
143  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
144  MSLane* l = *i;
145  const MSLinkCont& lc = l->getLinkCont();
146  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
147  MSLink* link = *j;
148  SUMOTime linkPenalty = link->getMesoTLSPenalty() + (link->havePriority() ? 0 : MSGlobals::gMesoMinorPenalty);
149  if (minPenalty == -1) {
150  minPenalty = linkPenalty;
151  } else {
152  minPenalty = MIN2(minPenalty, linkPenalty);
153  }
154  }
155  }
156  if (minPenalty > 0) {
157  myEmptyTraveltime += STEPS2TIME(minPenalty);
158  }
159  }
160 }
161 
162 
163 void
165  myAllowed[0] = new std::vector<MSLane*>();
166  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
167  myAllowed[0]->push_back(*i);
168  const MSLinkCont& lc = (*i)->getLinkCont();
169  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
170  (*j)->initParallelLinks();
171  MSLane* toL = (*j)->getLane();
172  if (toL != 0) {
173  MSEdge& to = toL->getEdge();
174  //
175  if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
176  mySuccessors.push_back(&to);
177  }
178  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
179  to.myPredecessors.push_back(this);
180  }
181  //
182  if (myAllowed.find(&to) == myAllowed.end()) {
183  myAllowed[&to] = new std::vector<MSLane*>();
184  }
185  myAllowed[&to]->push_back(*i);
186  }
187 #ifdef HAVE_INTERNAL_LANES
188  toL = (*j)->getViaLane();
189  if (toL != 0) {
190  MSEdge& to = toL->getEdge();
191  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
192  to.myPredecessors.push_back(this);
193  }
194  }
195 #endif
196  }
197  }
198  std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
200  recalcCache();
201  // segment building depends on the finished list of successors (for multi-queue)
202  if (MSGlobals::gUseMesoSim && !myLanes->empty()) {
204  }
205 }
206 
207 
208 void
210  if (!myLanes->empty()) {
211  const bool allowChanging = allowsLaneChanging();
213  // may always initiate sublane-change
214  myLaneChanger = new MSLaneChangerSublane(myLanes, allowChanging);
215  } else {
217  myLaneChanger = new MSLaneChanger(myLanes, allowChanging);
218  } else if (myLanes->size() > 1 || canChangeToOpposite()) {
219  myLaneChanger = new MSLaneChanger(myLanes, allowChanging);
220  }
221  }
222  }
223 }
224 
225 
226 bool
229  // allow changing only if all links leading to this internal lane have priority
230  // or they are controlled by a traffic light
231  for (std::vector<MSLane*>::const_iterator it = myLanes->begin(); it != myLanes->end(); ++it) {
232  MSLane* pred = (*it)->getLogicalPredecessorLane();
233  MSLink* link = MSLinkContHelper::getConnectingLink(*pred, **it);
234  assert(link != 0);
235  LinkState state = link->getState();
236  if (state == LINKSTATE_MINOR
237  || state == LINKSTATE_EQUAL
238  || state == LINKSTATE_STOP
239  || state == LINKSTATE_ALLWAY_STOP
240  || state == LINKSTATE_DEADEND) {
241  return false;
242  }
243  }
244  }
245  return true;
246 }
247 
248 
249 void
251  // clear myClassedAllowed.
252  // it will be rebuilt on demand
253  for (ClassedAllowedLanesCont::iterator i2 = myClassedAllowed.begin(); i2 != myClassedAllowed.end(); i2++) {
254  for (AllowedLanesCont::iterator i1 = (*i2).second.begin(); i1 != (*i2).second.end(); i1++) {
255  delete(*i1).second;
256  }
257  }
258  myClassedAllowed.clear();
259  myClassesSuccessorMap.clear();
260  // rebuild myMinimumPermissions and myCombinedPermissions
263  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
264  myMinimumPermissions &= (*i)->getPermissions();
265  myCombinedPermissions |= (*i)->getPermissions();
266  }
267 }
268 
269 
270 // ------------ Access to the edge's lanes
271 MSLane*
272 MSEdge::leftLane(const MSLane* const lane) const {
273  return parallelLane(lane, 1);
274 }
275 
276 
277 MSLane*
278 MSEdge::rightLane(const MSLane* const lane) const {
279  return parallelLane(lane, -1);
280 }
281 
282 
283 MSLane*
284 MSEdge::parallelLane(const MSLane* const lane, int offset) const {
285  const int index = (int)(find(myLanes->begin(), myLanes->end(), lane) - myLanes->begin());
286  if (index == (int)myLanes->size()) {
287  return 0;
288  }
289  const int resultIndex = index + offset;
290  if (resultIndex >= (int)myLanes->size() || resultIndex < 0) {
291  return 0;
292  } else {
293  return (*myLanes)[resultIndex];
294  }
295 }
296 
297 
298 const std::vector<MSLane*>*
299 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
300  return allowedLanes(&destination, vclass);
301 }
302 
303 
304 const std::vector<MSLane*>*
306  return allowedLanes(0, vclass);
307 }
308 
309 
310 const std::vector<MSLane*>*
312  AllowedLanesCont::const_iterator it = c.find(dest);
313  if (it == c.end()) {
314  return 0;
315  }
316  return it->second;
317 }
318 
319 
320 const std::vector<MSLane*>*
321 MSEdge::allowedLanes(const MSEdge* destination, SUMOVehicleClass vclass) const {
322  if (destination == 0 && (myMinimumPermissions & vclass) == vclass) {
323  // all lanes allow vclass
324  return getAllowedLanesWithDefault(myAllowed, destination);
325  }
326  // look up cached result in myClassedAllowed
327  ClassedAllowedLanesCont::const_iterator i = myClassedAllowed.find(vclass);
328  if (i != myClassedAllowed.end()) {
329  // can use cached value
330  const AllowedLanesCont& c = (*i).second;
331  return getAllowedLanesWithDefault(c, destination);
332  } else {
333  // this vclass is requested for the first time. rebuild all destinations
334  // go through connected edges
335 #ifdef HAVE_FOX
336  if (MSDevice_Routing::isParallel()) {
337  MSDevice_Routing::lock();
338  }
339 #endif
340  for (AllowedLanesCont::const_iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); ++i1) {
341  const MSEdge* edge = i1->first;
342  const std::vector<MSLane*>* lanes = i1->second;
343  myClassedAllowed[vclass][edge] = new std::vector<MSLane*>();
344  // go through lanes approaching current edge
345  for (std::vector<MSLane*>::const_iterator i2 = lanes->begin(); i2 != lanes->end(); ++i2) {
346  // origin lane allows the current vehicle class?
347  if ((*i2)->allowsVehicleClass(vclass)) {
348  if (edge == 0) {
349  myClassedAllowed[vclass][edge]->push_back(*i2);
350  } else {
351  // target lane allows the current vehicle class?
352  const MSLinkCont& lc = (*i2)->getLinkCont();
353  for (MSLinkCont::const_iterator it_link = lc.begin(); it_link != lc.end(); ++it_link) {
354  const MSLane* targetLane = (*it_link)->getLane();
355  if ((&(targetLane->getEdge()) == edge) && targetLane->allowsVehicleClass(vclass)) {
356  // -> may be used
357  myClassedAllowed[vclass][edge]->push_back(*i2);
358  break;
359  }
360  }
361  }
362  }
363  }
364  // assert that 0 is returned if no connection is allowed for a class
365  if (myClassedAllowed[vclass][edge]->size() == 0) {
366  delete myClassedAllowed[vclass][edge];
367  myClassedAllowed[vclass][edge] = 0;
368  }
369  }
370 #ifdef HAVE_FOX
371  if (MSDevice_Routing::isParallel()) {
372  MSDevice_Routing::unlock();
373  }
374 #endif
375  return myClassedAllowed[vclass][destination];
376  }
377 }
378 
379 
380 // ------------
381 SUMOTime
384  return 0;
385 }
386 
387 
388 SUMOTime
391  return 0;
392 }
393 
394 
395 MSLane*
396 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass) const {
397  if (allowed == 0) {
398  allowed = allowedLanes(vclass);
399  }
400  MSLane* res = 0;
401  if (allowed != 0) {
402  SUMOReal leastOccupancy = std::numeric_limits<SUMOReal>::max();;
403  for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
404  const SUMOReal occupancy = (*i)->getBruttoOccupancy();
405  if (occupancy < leastOccupancy) {
406  res = (*i);
407  leastOccupancy = occupancy;
408  }
409  }
410  }
411  return res;
412 }
413 
414 
415 MSLane*
417  switch (veh.getParameter().departLaneProcedure) {
418  case DEPART_LANE_GIVEN:
419  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
420  return 0;
421  }
422  return (*myLanes)[veh.getParameter().departLane];
423  case DEPART_LANE_RANDOM:
425  case DEPART_LANE_FREE:
426  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
428  if (veh.getRoute().size() == 1) {
429  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
430  } else {
431  return getFreeLane(allowedLanes(**(veh.getRoute().begin() + 1)), veh.getVehicleType().getVehicleClass());
432  }
433  case DEPART_LANE_BEST_FREE: {
434  veh.updateBestLanes(false, myLanes->front());
435  const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes();
436  SUMOReal bestLength = -1;
437  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
438  if ((*i).length > bestLength) {
439  bestLength = (*i).length;
440  }
441  }
442  std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
443  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
444  if ((*i).length == bestLength) {
445  bestLanes->push_back((*i).lane);
446  }
447  }
448  MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass());
449  delete bestLanes;
450  return ret;
451  }
452  case DEPART_LANE_DEFAULT:
454  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
455  if ((*i)->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
456  return *i;
457  }
458  }
459  return 0;
460  default:
461  break;
462  }
463  if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
464  return 0;
465  }
466  return (*myLanes)[0];
467 }
468 
469 
470 bool
471 MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly, const bool forceCheck) const {
472  // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal
473  if (isVaporizing()) {
474  return checkOnly;
475  }
476  if (isTaz() && checkOnly) {
477  return true;
478  }
479  const SUMOVehicleParameter& pars = v.getParameter();
480  const MSVehicleType& type = v.getVehicleType();
482  if (type.getSpeedDeviation() > 0) {
484  if (v.getChosenSpeedFactor() > type.getSpeedFactor() * (2 * type.getSpeedDeviation() + 1)) {
485  // only warn for significant deviation
486  WRITE_WARNING("Choosing new speed factor " + toString(v.getChosenSpeedFactor()) + " for vehicle '" + pars.id + "' to match departure speed.");
487  }
488  } else {
489  throw ProcessError("Departure speed for vehicle '" + pars.id +
490  "' is too high for the departure edge '" + getID() + "'.");
491  }
492  }
493  if (!checkOnly) {
494  std::string msg;
495  if (!v.hasValidRoute(msg)) {
497  throw ProcessError("Vehicle '" + v.getID() + "' has no valid route. " + msg);
498  } else if (v.getEdge()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) {
499  WRITE_WARNING("Removing vehicle '" + pars.id + "' which has no valid route.");
501  return false;
502  }
503  }
504  }
506  SUMOReal pos = 0.0;
507  switch (pars.departPosProcedure) {
508  case DEPART_POS_GIVEN:
509  if (pars.departPos >= 0.) {
510  pos = pars.departPos;
511  } else {
512  pos = pars.departPos + getLength();
513  }
514  if (pos < 0 || pos > getLength()) {
515  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
516  v.getID() + "'. Inserting at lane end instead.");
517  pos = getLength();
518  }
519  break;
520  case DEPART_POS_RANDOM:
522  pos = RandHelper::rand(getLength());
523  break;
524  default:
525  break;
526  }
527  bool result = false;
528  MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
529  MEVehicle* veh = static_cast<MEVehicle*>(&v);
530  if (pars.departPosProcedure == DEPART_POS_FREE) {
531  while (segment != 0 && !result) {
532  if (checkOnly) {
533  result = segment->hasSpaceFor(veh, time, true);
534  } else {
535  result = segment->initialise(veh, time);
536  }
537  segment = segment->getNextSegment();
538  }
539  } else {
540  if (checkOnly) {
541  result = segment->hasSpaceFor(veh, time, true);
542  } else {
543  result = segment->initialise(veh, time);
544  }
545  }
546  return result;
547  }
548  if (checkOnly) {
549  switch (v.getParameter().departLaneProcedure) {
550  case DEPART_LANE_GIVEN:
551  case DEPART_LANE_DEFAULT:
553  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
554  if (insertionLane == 0) {
555  WRITE_WARNING("could not insert vehicle '" + v.getID() + "' on any lane of edge '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()));
556  return false;
557  }
558  const SUMOReal occupancy = insertionLane->getBruttoOccupancy();
559  return occupancy == (SUMOReal)0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength;
560  }
561  default:
562  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
563  const SUMOReal occupancy = (*i)->getBruttoOccupancy();
564  if (occupancy == (SUMOReal)0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength) {
565  return true;
566  }
567  }
568  }
569  return false;
570  }
571  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
572  if (insertionLane == 0) {
573  return false;
574  }
575 
576  if (!forceCheck) {
577  if (myLastFailedInsertionTime == time) {
578  if (myFailedInsertionMemory.count(insertionLane->getIndex())) {
579  // A vehicle was already rejected for the proposed insertionLane in this timestep
580  return false;
581  }
582  } else {
583  // last rejection occured in a previous timestep, clear cache
584  myFailedInsertionMemory.clear();
585  }
586  }
587 
588  bool success = insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
589 
590  if (!success) {
591  myFailedInsertionMemory.insert(insertionLane->getIndex());
592  }
593  return success;
594 }
595 
596 
597 void
599  if (myLaneChanger == 0) {
600  return;
601  }
603  // allow changing only if all links leading to this internal lane have priority
604  // or they are controlled by a traffic light
605  for (std::vector<MSLane*>::const_iterator it = myLanes->begin(); it != myLanes->end(); ++it) {
606  MSLane* pred = (*it)->getLogicalPredecessorLane();
607  MSLink* link = MSLinkContHelper::getConnectingLink(*pred, **it);
608  assert(link != 0);
609  LinkState state = link->getState();
610  if (state == LINKSTATE_MINOR
611  || state == LINKSTATE_EQUAL
612  || state == LINKSTATE_STOP
613  || state == LINKSTATE_ALLWAY_STOP
614  || state == LINKSTATE_ZIPPER
615  || state == LINKSTATE_DEADEND) {
616  return;
617  }
618  }
619  }
621 }
622 
623 
624 
625 #ifdef HAVE_INTERNAL_LANES
626 const MSEdge*
627 MSEdge::getInternalFollowingEdge(const MSEdge* followerAfterInternal) const {
628  //@todo to be optimized
629  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
630  MSLane* l = *i;
631  const MSLinkCont& lc = l->getLinkCont();
632  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
633  MSLink* link = *j;
634  if (&link->getLane()->getEdge() == followerAfterInternal) {
635  if (link->getViaLane() != 0) {
636  return &link->getViaLane()->getEdge();
637  } else {
638  return 0; // network without internal links
639  }
640  }
641  }
642  }
643  return 0;
644 }
645 #endif
646 
647 
648 SUMOReal
650  SUMOReal v = 0;
651  SUMOReal no = 0;
653  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
654  const SUMOReal vehNo = (SUMOReal) segment->getCarNumber();
655  v += vehNo * segment->getMeanSpeed();
656  no += vehNo;
657  }
658  if (no == 0) {
659  return getLength() / myEmptyTraveltime; // may include tls-penalty
660  }
661  } else {
662  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
663  const SUMOReal vehNo = (SUMOReal)(*i)->getVehicleNumber();
664  v += vehNo * (*i)->getMeanSpeed();
665  no += vehNo;
666  }
667  if (no == 0) {
668  return getSpeedLimit();
669  }
670  }
671  return v / no;
672 }
673 
674 
675 SUMOReal
677  assert(minSpeed > 0);
678  if (!myAmDelayed) {
679  return myEmptyTraveltime;
680  }
681  return getLength() / MAX2(minSpeed, getMeanSpeed());
682 }
683 
684 
685 SUMOReal
688 }
689 
690 
691 
692 bool
693 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
694  DictType::iterator it = myDict.find(id);
695  if (it == myDict.end()) {
696  // id not in myDict.
697  myDict[id] = ptr;
698  while ((int)myEdges.size() < ptr->getNumericalID() + 1) {
699  myEdges.push_back(0);
700  }
701  myEdges[ptr->getNumericalID()] = ptr;
702  return true;
703  }
704  return false;
705 }
706 
707 
708 MSEdge*
709 MSEdge::dictionary(const std::string& id) {
710  DictType::iterator it = myDict.find(id);
711  if (it == myDict.end()) {
712  // id not in myDict.
713  return 0;
714  }
715  return it->second;
716 }
717 
718 
719 int
721  return (int)myDict.size();
722 }
723 
724 
725 const MSEdgeVector&
727  return myEdges;
728 }
729 
730 
731 void
733  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
734  delete(*i).second;
735  }
736  myDict.clear();
737 }
738 
739 
740 void
741 MSEdge::insertIDs(std::vector<std::string>& into) {
742  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
743  into.push_back((*i).first);
744  }
745 }
746 
747 
748 void
749 MSEdge::parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
750  const std::string& rid) {
751  if (desc[0] == BinaryFormatter::BF_ROUTE) {
752  std::istringstream in(desc, std::ios::binary);
753  char c;
754  in >> c;
755  FileHelpers::readEdgeVector(in, into, rid);
756  } else {
757  StringTokenizer st(desc);
758  parseEdgesList(st.getVector(), into, rid);
759  }
760 }
761 
762 
763 void
764 MSEdge::parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
765  const std::string& rid) {
766  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
767  const MSEdge* edge = MSEdge::dictionary(*i);
768  // check whether the edge exists
769  if (edge == 0) {
770  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
771  + "\n The route can not be build.");
772  }
773  into.push_back(edge);
774  }
775 }
776 
777 
778 SUMOReal
779 MSEdge::getDistanceTo(const MSEdge* other) const {
780  if (getLanes().size() > 0 && other->getLanes().size() > 0) {
782  } else {
783  return 0; // optimism is just right for astar
784  }
785 }
786 
787 
788 SUMOReal
790  // @note lanes might have different maximum speeds in theory
791  return getLanes()[0]->getSpeedLimit();
792 }
793 
794 
795 SUMOReal
796 MSEdge::getVehicleMaxSpeed(const SUMOVehicle* const veh) const {
797  // @note lanes might have different maximum speeds in theory
798  return getLanes()[0]->getVehicleMaxSpeed(veh);
799 }
800 
801 
802 void
804  if (myLanes != 0) {
805  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
806  (*i)->setMaxSpeed(val);
807  }
808  }
809 }
810 
811 
812 
813 std::vector<MSTransportable*>
815  std::vector<MSTransportable*> result(myPersons.begin(), myPersons.end());
816  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
817  return result;
818 }
819 
820 
821 std::vector<MSTransportable*>
823  std::vector<MSTransportable*> result(myContainers.begin(), myContainers.end());
824  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
825  return result;
826 }
827 
828 
829 int
831  const SUMOReal pos1 = c1->getCurrentStage()->getEdgePos(myTime);
832  const SUMOReal pos2 = c2->getCurrentStage()->getEdgePos(myTime);
833  if (pos1 != pos2) {
834  return pos1 < pos2;
835  }
836  return c1->getID() < c2->getID();
837 }
838 
839 const MSEdgeVector&
841  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == EDGEFUNCTION_DISTRICT) {
842  return mySuccessors;
843  }
844 #ifdef HAVE_FOX
845  if (MSDevice_Routing::isParallel()) {
846  MSDevice_Routing::lock();
847  }
848 #endif
849  std::map<SUMOVehicleClass, MSEdgeVector>::iterator i = myClassesSuccessorMap.find(vClass);
850  if (i == myClassesSuccessorMap.end()) {
851  // instantiate vector
852  myClassesSuccessorMap[vClass];
853  i = myClassesSuccessorMap.find(vClass);
854  // this vClass is requested for the first time. rebuild all successors
855  for (MSEdgeVector::const_iterator it = mySuccessors.begin(); it != mySuccessors.end(); ++it) {
856  if ((*it)->getPurpose() == EDGEFUNCTION_DISTRICT) {
857  i->second.push_back(*it);
858  } else {
859  const std::vector<MSLane*>* allowed = allowedLanes(*it, vClass);
860  if (allowed != 0 && allowed->size() > 0) {
861  i->second.push_back(*it);
862  }
863  }
864  }
865  }
866  // can use cached value
867 #ifdef HAVE_FOX
868  if (MSDevice_Routing::isParallel()) {
869  MSDevice_Routing::unlock();
870  }
871 #endif
872  return i->second;
873 }
874 
875 
876 bool
878  return (!myLanes->empty() && myLanes->back()->getOpposite() != 0 &&
879  // do not change on curved internal lanes
880  (!isInternal() || myLanes->back()->getIncomingLanes()[0].viaLink->getDirection() == LINKDIR_STRAIGHT));
881 }
882 
883 
884 bool
886  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
887  const MSLinkCont& lc = (*i)->getLinkCont();
888  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
889  if (!(*j)->havePriority()) {
890  return true;
891  }
892  }
893  }
894  return false;
895 }
896 
897 
898 /****************************************************************************/
899 
static const T & getRandomFrom(const std::vector< T > &v)
Returns a random element from the given vector.
Definition: RandHelper.h:114
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge&#39;e lanes.
bool myAmDelayed
whether this edge had a vehicle with less than max speed on it
Definition: MSEdge.h:831
bool allowsLaneChanging()
Definition: MSEdge.cpp:227
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:571
std::set< MSTransportable * > myContainers
Containers on the edge.
Definition: MSEdge.h:794
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:741
long long int SUMOTime
Definition: SUMOTime.h:43
SUMOReal myLength
the length of the edge (cached value for speedup)
Definition: MSEdge.h:825
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
void descheduleDeparture(SUMOVehicle *veh)
stops trying to emit the given vehicle (and delete it)
Sorts edges by their ids.
Definition: MSEdge.h:710
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:52
virtual SUMOReal getEdgePos(SUMOTime now) const =0
int numSublanes() const
Definition: MSLeaderInfo.h:86
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
SUMOReal getDistanceTo(const MSEdge *other) const
optimistic air distance heuristic for use in routing
Definition: MSEdge.cpp:779
static int dictSize()
Returns the number of edges.
Definition: MSEdge.cpp:720
void initialize(const std::vector< MSLane * > *lanes)
Initialize the edge.
Definition: MSEdge.cpp:110
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:292
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:192
SUMOReal getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:133
This is an uncontrolled, minor link, has to stop.
SUMOReal departSpeed
(optional) The initial speed of the vehicle
static MSEdgeVector myEdges
Static list of edges.
Definition: MSEdge.h:853
const EdgeBasicFunction myFunction
the purpose of the edge
Definition: MSEdge.h:764
The position is given.
ClassedAllowedLanesCont myClassedAllowed
From vehicle class to lanes allowed to be used by it.
Definition: MSEdge.h:804
The least occupied lane is used.
void buildSegmentsFor(const MSEdge &e, const OptionsCont &oc)
Build the segments for a given edge.
Definition: MELoop.cpp:265
void closeBuilding()
Definition: MSEdge.cpp:164
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
virtual ~MSEdge()
Destructor.
Definition: MSEdge.cpp:94
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
This is a dead end link.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
T MAX2(T a, T b)
Definition: StdDefs.h:70
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:97
const std::string & getID() const
returns the id of the transportable
SUMOReal computeChosenSpeedDeviation(MTRand *rng, const SUMOReal minDevFactor=0.2) const
Computes and returns the speed deviation.
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:693
This is an uncontrolled, right-before-left link.
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition: MSEdge.cpp:382
MSTransportable::Stage * getCurrentStage() const
Return the current stage.
MSLane * getFreeLane(const std::vector< MSLane * > *allowed, const SUMOVehicleClass vclass) const
Finds the emptiest lane allowing the vehicle class.
Definition: MSEdge.cpp:396
The lane is chosen randomly.
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
bool hasMinorLink() const
whether any lane has a minor link
Definition: MSEdge.cpp:885
const SVCPermissions SVCAll
int myVaporizationRequests
Vaporizer counter.
Definition: MSEdge.h:767
EdgeBasicFunction
Defines possible edge types.
Definition: MSEdge.h:89
The least occupied lane from best lanes.
The position is chosen randomly.
SUMOTime decVaporization(SUMOTime t)
Disables vaporization.
Definition: MSEdge.cpp:389
This is an uncontrolled, all-way stop link.
virtual bool hasValidRoute(std::string &msg, const MSRoute *route=0) const =0
Validates the current or given route.
This is an uncontrolled, zipper-merge link.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The speed is given.
std::map< std::string, MSEdge * > DictType
definition of the static dictionary type
Definition: MSEdge.h:843
The car-following model and parameter.
Definition: MSVehicleType.h:74
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
Performs lane changing of vehicles.
The lane is given.
The link is a straight direction.
Performs lane changing of vehicles.
Definition: MSLaneChanger.h:55
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:80
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:419
SUMOTime myLastFailedInsertionTime
The time of last insertion failure.
Definition: MSEdge.h:770
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:858
void rebuildAllowedLanes()
Definition: MSEdge.cpp:250
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:580
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1994
#define max(a, b)
Definition: polyfonts.c:65
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
SUMOReal getSpeedDeviation() const
Returns this type&#39;s speed deviation.
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:695
bool isTaz() const
Definition: MSEdge.h:268
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:157
The edge is a district edge.
Definition: MSEdge.h:99
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
virtual void setChosenSpeedFactor(const SUMOReal factor)=0
Representation of a vehicle.
Definition: SUMOVehicle.h:67
static bool gCheckRoutes
Definition: MSGlobals.h:83
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
The least occupied lane from lanes which allow the continuation.
virtual SUMOReal getChosenSpeedFactor() const =0
This is an uncontrolled, minor link, has to brake.
AllowedLanesCont myAllowed
Associative container from destination-edge to allowed-lanes.
Definition: MSEdge.h:800
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:2899
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:732
SVCPermissions myMinimumPermissions
The intersection of lane permissions for this edge.
Definition: MSEdge.h:807
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:90
MSEdgeVector mySuccessors
The succeeding edges.
Definition: MSEdge.h:781
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:272
MSLaneChanger * myLaneChanger
This member will do the lane-change.
Definition: MSEdge.h:761
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
MSEdge(const std::string &id, int numericalID, const EdgeBasicFunction function, const std::string &streetName, const std::string &edgeType, int priority)
Constructor.
Definition: MSEdge.cpp:75
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
static SUMOTime gMesoMinorPenalty
Definition: MSGlobals.h:107
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:392
T MIN2(T a, T b)
Definition: StdDefs.h:64
std::vector< SUMOReal > mySublaneSides
the right side for each sublane on this edge
Definition: MSEdge.h:837
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:471
const std::vector< MSLane * > * myLanes
Container for the edge&#39;s lane; should be sorted: (right-hand-traffic) the more left the lane...
Definition: MSEdge.h:758
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
int getIndex() const
Returns the lane&#39;s index.
Definition: MSLane.h:503
SUMOReal getSpeedLimit() const
Returns the speed limit of the edge The speed limit of the first lane is retured; should probably be...
Definition: MSEdge.cpp:789
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:254
If a fixed number of random choices fails, a free position is chosen.
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2893
bool canChangeToOpposite()
whether this edge allows changing to the opposite direction edge
Definition: MSEdge.cpp:877
MSLane * getDepartLane(MSVehicle &veh) const
Finds a depart lane for the given vehicle parameters.
Definition: MSEdge.cpp:416
Base class for objects which have an id.
Definition: Named.h:46
The rightmost lane the vehicle may use.
std::vector< MSTransportable * > getSortedContainers(SUMOTime timestep) const
Returns this edge&#39;s containers sorted by pos.
Definition: MSEdge.cpp:822
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
std::vector< std::string > getVector()
SVCPermissions myCombinedPermissions
The union of lane permissions for this edge.
Definition: MSEdge.h:809
SUMOReal getSpeedFactor() const
Returns this type&#39;s speed factor.
No information given; use default.
void buildLaneChanger()
Has to be called after all sucessors and predecessors have been set (after closeBuilding()) ...
Definition: MSEdge.cpp:209
static SUMOReal getAssumedSpeed(const MSEdge *edge)
return current travel speed assumption
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
Structure representing possible vehicle parameter.
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:275
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:284
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:361
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:726
virtual void changeLanes(SUMOTime t)
Performs lane changing on this edge.
Definition: MSEdge.cpp:598
SUMOReal myEmptyTraveltime
the traveltime on the empty edge (cached value for speedup)
Definition: MSEdge.h:828
SUMOReal getMeanSpeed() const
get the mean speed
Definition: MSEdge.cpp:649
A single mesoscopic segment (cell)
Definition: MESegment.h:57
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:299
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:265
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
static SUMOReal gLateralResolution
Definition: MSGlobals.h:89
MESegment * getSegmentForEdge(const MSEdge &e, SUMOReal pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:293
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:110
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
SUMOReal departPos
(optional) The position the vehicle shall depart from
std::map< const MSEdge *, std::vector< MSLane * > * > AllowedLanesCont
Suceeding edges (keys) and allowed lanes to reach these edges (values).
Definition: MSEdge.h:108
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSEdge.h:848
static void readEdgeVector(std::istream &in, std::vector< const E * > &edges, const std::string &rid)
Reads an edge vector binary.
Definition: FileHelpers.h:274
SUMOReal getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:686
#define SUMOReal
Definition: config.h:208
Sorts transportables by their positions.
Definition: MSEdge.h:725
const MSJunction * getFromJunction() const
Definition: MSEdge.h:369
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:339
#define NUMERICAL_EPS
Definition: config.h:158
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:796
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1545
A free position is chosen.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
SUMOReal myWidth
Edge width [m].
Definition: MSEdge.h:822
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:278
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition: MSEdge.cpp:830
static SUMOReal gMesoTLSPenalty
Definition: MSGlobals.h:104
The edge is an internal edge.
Definition: MSEdge.h:97
const std::vector< MSLane * > * getAllowedLanesWithDefault(const AllowedLanesCont &c, const MSEdge *dest) const
lookup in map and return 0 if not found
Definition: MSEdge.cpp:311
SUMOReal getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2081
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:86
MSEdgeVector myPredecessors
The preceeding edges.
Definition: MSEdge.h:784
static bool gUseMesoSim
Definition: MSGlobals.h:95
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
SUMOReal getCurrentTravelTime(const SUMOReal minSpeed=NUMERICAL_EPS) const
Computes and returns the current travel time for this edge.
Definition: MSEdge.cpp:676
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:749
vehicles ignoring classes
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep) const
Returns this edge&#39;s persons sorted by pos.
Definition: MSEdge.cpp:814
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:78
std::string id
The vehicle&#39;s id.
std::set< int > myFailedInsertionMemory
A cache for the rejected insertion attempts. Used to assure that no further insertion attempts are ma...
Definition: MSEdge.h:775
void setMaxSpeed(SUMOReal val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:803
const MSJunction * getToJunction() const
Definition: MSEdge.h:373
const Position & getPosition() const
Definition: MSJunction.cpp:67
std::set< MSTransportable * > myPersons
Persons on the edge for drawing and pushbutton.
Definition: MSEdge.h:791