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-2016 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;
113  if (!lanes->empty()) {
114  recalcCache();
115  }
118  }
119  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
120  myWidth += (*i)->getWidth();
121  }
123  SUMOReal widthBefore = 0;
124  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
125  (*i)->setRightSideOnEdge(widthBefore, (int)mySublaneSides.size());
126  MSLeaderInfo ahead(*i);
127  for (int j = 0; j < ahead.numSublanes(); ++j) {
128  mySublaneSides.push_back(widthBefore + j * MSGlobals::gLateralResolution);
129  }
130  widthBefore += (*i)->getWidth();
131  }
132  }
133 }
134 
135 
137  if (myLanes->empty()) {
138  return;
139  }
140  myLength = myLanes->front()->getLength();
142 
143  if (MSGlobals::gMesoTLSPenalty > 0) {
144  // add tls penalties to the minimum travel time
145  SUMOTime minPenalty = -1;
146  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
147  MSLane* l = *i;
148  const MSLinkCont& lc = l->getLinkCont();
149  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
150  MSLink* link = *j;
151  if (minPenalty == -1) {
152  minPenalty = link->getMesoTLSPenalty();
153  } else {
154  minPenalty = MIN2(minPenalty, link->getMesoTLSPenalty());
155  }
156  }
157  }
158  if (minPenalty > 0) {
159  myEmptyTraveltime += STEPS2TIME(minPenalty);
160  }
161  }
162 }
163 
164 
165 void
167  myAllowed[0] = new std::vector<MSLane*>();
168  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
169  myAllowed[0]->push_back(*i);
170  const MSLinkCont& lc = (*i)->getLinkCont();
171  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
172  (*j)->initParallelLinks();
173  MSLane* toL = (*j)->getLane();
174  if (toL != 0) {
175  MSEdge& to = toL->getEdge();
176  //
177  if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
178  mySuccessors.push_back(&to);
179  }
180  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
181  to.myPredecessors.push_back(this);
182  }
183  //
184  if (myAllowed.find(&to) == myAllowed.end()) {
185  myAllowed[&to] = new std::vector<MSLane*>();
186  }
187  myAllowed[&to]->push_back(*i);
188  }
189 #ifdef HAVE_INTERNAL_LANES
190  toL = (*j)->getViaLane();
191  if (toL != 0) {
192  MSEdge& to = toL->getEdge();
193  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
194  to.myPredecessors.push_back(this);
195  }
196  }
197 #endif
198  }
199  }
200  std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
202  // segment building depends on the finished list of successors (for multi-queue)
203  if (MSGlobals::gUseMesoSim && !myLanes->empty()) {
205  }
206 }
207 
208 
209 void
211  if (!myLanes->empty()) {
212  const bool allowChanging = allowsLaneChanging();
214  // may always initiate sublane-change
215  myLaneChanger = new MSLaneChangerSublane(myLanes, allowChanging);
216  } else {
218  myLaneChanger = new MSLaneChanger(myLanes, allowChanging);
219  } else if (myLanes->size() > 1 || canChangeToOpposite()) {
220  myLaneChanger = new MSLaneChanger(myLanes, allowChanging);
221  }
222  }
223  }
224 }
225 
226 
227 bool
230  // allow changing only if all links leading to this internal lane have priority
231  // or they are controlled by a traffic light
232  for (std::vector<MSLane*>::const_iterator it = myLanes->begin(); it != myLanes->end(); ++it) {
233  MSLane* pred = (*it)->getLogicalPredecessorLane();
234  MSLink* link = MSLinkContHelper::getConnectingLink(*pred, **it);
235  assert(link != 0);
236  LinkState state = link->getState();
237  if (state == LINKSTATE_MINOR
238  || state == LINKSTATE_EQUAL
239  || state == LINKSTATE_STOP
240  || state == LINKSTATE_ALLWAY_STOP
241  || state == LINKSTATE_DEADEND) {
242  return false;
243  }
244  }
245  }
246  return true;
247 }
248 
249 
250 void
252  // clear myClassedAllowed.
253  // it will be rebuilt on demand
254  for (ClassedAllowedLanesCont::iterator i2 = myClassedAllowed.begin(); i2 != myClassedAllowed.end(); i2++) {
255  for (AllowedLanesCont::iterator i1 = (*i2).second.begin(); i1 != (*i2).second.end(); i1++) {
256  delete(*i1).second;
257  }
258  }
259  myClassedAllowed.clear();
260  myClassesSuccessorMap.clear();
261  // rebuild myMinimumPermissions and myCombinedPermissions
264  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
265  myMinimumPermissions &= (*i)->getPermissions();
266  myCombinedPermissions |= (*i)->getPermissions();
267  }
268 }
269 
270 
271 // ------------ Access to the edge's lanes
272 MSLane*
273 MSEdge::leftLane(const MSLane* const lane) const {
274  return parallelLane(lane, 1);
275 }
276 
277 
278 MSLane*
279 MSEdge::rightLane(const MSLane* const lane) const {
280  return parallelLane(lane, -1);
281 }
282 
283 
284 MSLane*
285 MSEdge::parallelLane(const MSLane* const lane, int offset) const {
286  const int index = (int)(find(myLanes->begin(), myLanes->end(), lane) - myLanes->begin());
287  if (index == (int)myLanes->size()) {
288  return 0;
289  }
290  const int resultIndex = index + offset;
291  if (resultIndex >= (int)myLanes->size() || resultIndex < 0) {
292  return 0;
293  } else {
294  return (*myLanes)[resultIndex];
295  }
296 }
297 
298 
299 const std::vector<MSLane*>*
300 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
301  return allowedLanes(&destination, vclass);
302 }
303 
304 
305 const std::vector<MSLane*>*
307  return allowedLanes(0, vclass);
308 }
309 
310 
311 const std::vector<MSLane*>*
313  AllowedLanesCont::const_iterator it = c.find(dest);
314  if (it == c.end()) {
315  return 0;
316  }
317  return it->second;
318 }
319 
320 
321 const std::vector<MSLane*>*
322 MSEdge::allowedLanes(const MSEdge* destination, SUMOVehicleClass vclass) const {
323  if (destination == 0 && (myMinimumPermissions & vclass) == vclass) {
324  // all lanes allow vclass
325  return getAllowedLanesWithDefault(myAllowed, destination);
326  }
327  // look up cached result in myClassedAllowed
328  ClassedAllowedLanesCont::const_iterator i = myClassedAllowed.find(vclass);
329  if (i != myClassedAllowed.end()) {
330  // can use cached value
331  const AllowedLanesCont& c = (*i).second;
332  return getAllowedLanesWithDefault(c, destination);
333  } else {
334  // this vclass is requested for the first time. rebuild all destinations
335  // go through connected edges
336 #ifdef HAVE_FOX
337  if (MSDevice_Routing::isParallel()) {
338  MSDevice_Routing::lock();
339  }
340 #endif
341  for (AllowedLanesCont::const_iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); ++i1) {
342  const MSEdge* edge = i1->first;
343  const std::vector<MSLane*>* lanes = i1->second;
344  myClassedAllowed[vclass][edge] = new std::vector<MSLane*>();
345  // go through lanes approaching current edge
346  for (std::vector<MSLane*>::const_iterator i2 = lanes->begin(); i2 != lanes->end(); ++i2) {
347  // origin lane allows the current vehicle class?
348  if ((*i2)->allowsVehicleClass(vclass)) {
349  if (edge == 0) {
350  myClassedAllowed[vclass][edge]->push_back(*i2);
351  } else {
352  // target lane allows the current vehicle class?
353  const MSLinkCont& lc = (*i2)->getLinkCont();
354  for (MSLinkCont::const_iterator it_link = lc.begin(); it_link != lc.end(); ++it_link) {
355  const MSLane* targetLane = (*it_link)->getLane();
356  if ((&(targetLane->getEdge()) == edge) && targetLane->allowsVehicleClass(vclass)) {
357  // -> may be used
358  myClassedAllowed[vclass][edge]->push_back(*i2);
359  break;
360  }
361  }
362  }
363  }
364  }
365  // assert that 0 is returned if no connection is allowed for a class
366  if (myClassedAllowed[vclass][edge]->size() == 0) {
367  delete myClassedAllowed[vclass][edge];
368  myClassedAllowed[vclass][edge] = 0;
369  }
370  }
371 #ifdef HAVE_FOX
372  if (MSDevice_Routing::isParallel()) {
373  MSDevice_Routing::unlock();
374  }
375 #endif
376  return myClassedAllowed[vclass][destination];
377  }
378 }
379 
380 
381 // ------------
382 SUMOTime
385  return 0;
386 }
387 
388 
389 SUMOTime
392  return 0;
393 }
394 
395 
396 MSLane*
397 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass) const {
398  if (allowed == 0) {
399  allowed = allowedLanes(vclass);
400  }
401  MSLane* res = 0;
402  if (allowed != 0) {
403  SUMOReal leastOccupancy = std::numeric_limits<SUMOReal>::max();;
404  for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
405  const SUMOReal occupancy = (*i)->getBruttoOccupancy();
406  if (occupancy < leastOccupancy) {
407  res = (*i);
408  leastOccupancy = occupancy;
409  }
410  }
411  }
412  return res;
413 }
414 
415 
416 MSLane*
418  switch (veh.getParameter().departLaneProcedure) {
419  case DEPART_LANE_GIVEN:
420  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
421  return 0;
422  }
423  return (*myLanes)[veh.getParameter().departLane];
424  case DEPART_LANE_RANDOM:
426  case DEPART_LANE_FREE:
427  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
429  if (veh.getRoute().size() == 1) {
430  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
431  } else {
432  return getFreeLane(allowedLanes(**(veh.getRoute().begin() + 1)), veh.getVehicleType().getVehicleClass());
433  }
434  case DEPART_LANE_BEST_FREE: {
435  veh.updateBestLanes(false, myLanes->front());
436  const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes();
437  SUMOReal bestLength = -1;
438  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
439  if ((*i).length > bestLength) {
440  bestLength = (*i).length;
441  }
442  }
443  std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
444  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
445  if ((*i).length == bestLength) {
446  bestLanes->push_back((*i).lane);
447  }
448  }
449  MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass());
450  delete bestLanes;
451  return ret;
452  }
453  case DEPART_LANE_DEFAULT:
455  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
456  if ((*i)->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
457  return *i;
458  }
459  }
460  return 0;
461  default:
462  break;
463  }
464  if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
465  return 0;
466  }
467  return (*myLanes)[0];
468 }
469 
470 
471 bool
472 MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly) const {
473  // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal
474  if (isVaporizing()) {
475  return checkOnly;
476  }
477  if (isTaz() && checkOnly) {
478  return true;
479  }
480  const SUMOVehicleParameter& pars = v.getParameter();
481  const MSVehicleType& type = v.getVehicleType();
483  if (type.getSpeedDeviation() > 0) {
485  if (v.getChosenSpeedFactor() > type.getSpeedFactor() * (2 * type.getSpeedDeviation() + 1)) {
486  // only warn for significant deviation
487  WRITE_WARNING("Choosing new speed factor " + toString(v.getChosenSpeedFactor()) + " for vehicle '" + pars.id + "' to match departure speed.");
488  }
489  } else {
490  throw ProcessError("Departure speed for vehicle '" + pars.id +
491  "' is too high for the departure edge '" + getID() + "'.");
492  }
493  }
494  if (!checkOnly) {
495  std::string msg;
496  if (!v.hasValidRoute(msg)) {
498  throw ProcessError("Vehicle '" + v.getID() + "' has no valid route. " + msg);
499  } else if (v.getEdge()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) {
500  WRITE_WARNING("Removing vehicle '" + pars.id + "' which has no valid route.");
502  return false;
503  }
504  }
505  }
507  SUMOReal pos = 0.0;
508  switch (pars.departPosProcedure) {
509  case DEPART_POS_GIVEN:
510  if (pars.departPos >= 0.) {
511  pos = pars.departPos;
512  } else {
513  pos = pars.departPos + getLength();
514  }
515  if (pos < 0 || pos > getLength()) {
516  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
517  v.getID() + "'. Inserting at lane end instead.");
518  pos = getLength();
519  }
520  break;
521  case DEPART_POS_RANDOM:
523  pos = RandHelper::rand(getLength());
524  break;
525  default:
526  break;
527  }
528  bool result = false;
529  MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
530  MEVehicle* veh = static_cast<MEVehicle*>(&v);
531  if (pars.departPosProcedure == DEPART_POS_FREE) {
532  while (segment != 0 && !result) {
533  if (checkOnly) {
534  result = segment->hasSpaceFor(veh, time, true);
535  } else {
536  result = segment->initialise(veh, time);
537  }
538  segment = segment->getNextSegment();
539  }
540  } else {
541  if (checkOnly) {
542  result = segment->hasSpaceFor(veh, time, true);
543  } else {
544  result = segment->initialise(veh, time);
545  }
546  }
547  return result;
548  }
549  if (checkOnly) {
550  switch (v.getParameter().departLaneProcedure) {
551  case DEPART_LANE_GIVEN:
552  case DEPART_LANE_DEFAULT:
554  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
555  if (insertionLane == 0) {
556  WRITE_WARNING("could not insert vehicle '" + v.getID() + "' on any lane of edge '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()));
557  return false;
558  }
559  const SUMOReal occupancy = insertionLane->getBruttoOccupancy();
560  return occupancy == (SUMOReal)0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength;
561  }
562  default:
563  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
564  const SUMOReal occupancy = (*i)->getBruttoOccupancy();
565  if (occupancy == (SUMOReal)0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength) {
566  return true;
567  }
568  }
569  }
570  return false;
571  }
572  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
573  return insertionLane != 0 && insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
574 }
575 
576 
577 void
579  if (myLaneChanger == 0) {
580  return;
581  }
583  // allow changing only if all links leading to this internal lane have priority
584  // or they are controlled by a traffic light
585  for (std::vector<MSLane*>::const_iterator it = myLanes->begin(); it != myLanes->end(); ++it) {
586  MSLane* pred = (*it)->getLogicalPredecessorLane();
587  MSLink* link = MSLinkContHelper::getConnectingLink(*pred, **it);
588  assert(link != 0);
589  LinkState state = link->getState();
590  if (state == LINKSTATE_MINOR
591  || state == LINKSTATE_EQUAL
592  || state == LINKSTATE_STOP
593  || state == LINKSTATE_ALLWAY_STOP
594  || state == LINKSTATE_ZIPPER
595  || state == LINKSTATE_DEADEND) {
596  return;
597  }
598  }
599  }
601 }
602 
603 
604 
605 #ifdef HAVE_INTERNAL_LANES
606 const MSEdge*
607 MSEdge::getInternalFollowingEdge(const MSEdge* followerAfterInternal) const {
608  //@todo to be optimized
609  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
610  MSLane* l = *i;
611  const MSLinkCont& lc = l->getLinkCont();
612  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
613  MSLink* link = *j;
614  if (&link->getLane()->getEdge() == followerAfterInternal) {
615  if (link->getViaLane() != 0) {
616  return &link->getViaLane()->getEdge();
617  } else {
618  return 0; // network without internal links
619  }
620  }
621  }
622  }
623  return 0;
624 }
625 #endif
626 
627 
628 SUMOReal
630  SUMOReal v = 0;
631  SUMOReal no = 0;
633  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
634  const SUMOReal vehNo = (SUMOReal) segment->getCarNumber();
635  v += vehNo * segment->getMeanSpeed();
636  no += vehNo;
637  }
638  if (no == 0) {
639  return getLength() / myEmptyTraveltime; // may include tls-penalty
640  }
641  } else {
642  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
643  const SUMOReal vehNo = (SUMOReal)(*i)->getVehicleNumber();
644  v += vehNo * (*i)->getMeanSpeed();
645  no += vehNo;
646  }
647  if (no == 0) {
648  return getSpeedLimit();
649  }
650  }
651  return v / no;
652 }
653 
654 
655 SUMOReal
657  assert(minSpeed > 0);
658  if (!myAmDelayed) {
659  return myEmptyTraveltime;
660  }
661  return getLength() / MAX2(minSpeed, getMeanSpeed());
662 }
663 
664 
665 SUMOReal
668 }
669 
670 
671 
672 bool
673 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
674  DictType::iterator it = myDict.find(id);
675  if (it == myDict.end()) {
676  // id not in myDict.
677  myDict[id] = ptr;
678  while ((int)myEdges.size() < ptr->getNumericalID() + 1) {
679  myEdges.push_back(0);
680  }
681  myEdges[ptr->getNumericalID()] = ptr;
682  return true;
683  }
684  return false;
685 }
686 
687 
688 MSEdge*
689 MSEdge::dictionary(const std::string& id) {
690  DictType::iterator it = myDict.find(id);
691  if (it == myDict.end()) {
692  // id not in myDict.
693  return 0;
694  }
695  return it->second;
696 }
697 
698 
699 int
701  return (int)myDict.size();
702 }
703 
704 
705 const MSEdgeVector&
707  return myEdges;
708 }
709 
710 
711 void
713  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
714  delete(*i).second;
715  }
716  myDict.clear();
717 }
718 
719 
720 void
721 MSEdge::insertIDs(std::vector<std::string>& into) {
722  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
723  into.push_back((*i).first);
724  }
725 }
726 
727 
728 void
729 MSEdge::parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
730  const std::string& rid) {
731  if (desc[0] == BinaryFormatter::BF_ROUTE) {
732  std::istringstream in(desc, std::ios::binary);
733  char c;
734  in >> c;
735  FileHelpers::readEdgeVector(in, into, rid);
736  } else {
737  StringTokenizer st(desc);
738  parseEdgesList(st.getVector(), into, rid);
739  }
740 }
741 
742 
743 void
744 MSEdge::parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
745  const std::string& rid) {
746  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
747  const MSEdge* edge = MSEdge::dictionary(*i);
748  // check whether the edge exists
749  if (edge == 0) {
750  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
751  + "\n The route can not be build.");
752  }
753  into.push_back(edge);
754  }
755 }
756 
757 
758 SUMOReal
759 MSEdge::getDistanceTo(const MSEdge* other) const {
760  if (getLanes().size() > 0 && other->getLanes().size() > 0) {
762  } else {
763  return 0; // optimism is just right for astar
764  }
765 }
766 
767 
768 SUMOReal
770  // @note lanes might have different maximum speeds in theory
771  return getLanes()[0]->getSpeedLimit();
772 }
773 
774 
775 SUMOReal
776 MSEdge::getVehicleMaxSpeed(const SUMOVehicle* const veh) const {
777  // @note lanes might have different maximum speeds in theory
778  return getLanes()[0]->getVehicleMaxSpeed(veh);
779 }
780 
781 
782 void
784  if (myLanes != 0) {
785  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
786  (*i)->setMaxSpeed(val);
787  }
788  }
789 }
790 
791 
792 
793 std::vector<MSTransportable*>
795  std::vector<MSTransportable*> result(myPersons.begin(), myPersons.end());
796  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
797  return result;
798 }
799 
800 
801 std::vector<MSTransportable*>
803  std::vector<MSTransportable*> result(myContainers.begin(), myContainers.end());
804  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
805  return result;
806 }
807 
808 
809 int
811  const SUMOReal pos1 = c1->getCurrentStage()->getEdgePos(myTime);
812  const SUMOReal pos2 = c2->getCurrentStage()->getEdgePos(myTime);
813  if (pos1 != pos2) {
814  return pos1 < pos2;
815  }
816  return c1->getID() < c2->getID();
817 }
818 
819 const MSEdgeVector&
821  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == EDGEFUNCTION_DISTRICT) {
822  return mySuccessors;
823  }
824 #ifdef HAVE_FOX
825  if (MSDevice_Routing::isParallel()) {
826  MSDevice_Routing::lock();
827  }
828 #endif
829  std::map<SUMOVehicleClass, MSEdgeVector>::iterator i = myClassesSuccessorMap.find(vClass);
830  if (i == myClassesSuccessorMap.end()) {
831  // instantiate vector
832  myClassesSuccessorMap[vClass];
833  i = myClassesSuccessorMap.find(vClass);
834  // this vClass is requested for the first time. rebuild all successors
835  for (MSEdgeVector::const_iterator it = mySuccessors.begin(); it != mySuccessors.end(); ++it) {
836  if ((*it)->getPurpose() == EDGEFUNCTION_DISTRICT) {
837  i->second.push_back(*it);
838  } else {
839  const std::vector<MSLane*>* allowed = allowedLanes(*it, vClass);
840  if (allowed != 0 && allowed->size() > 0) {
841  i->second.push_back(*it);
842  }
843  }
844  }
845  }
846  // can use cached value
847 #ifdef HAVE_FOX
848  if (MSDevice_Routing::isParallel()) {
849  MSDevice_Routing::unlock();
850  }
851 #endif
852  return i->second;
853 }
854 
855 
856 bool
858  return !myLanes->empty() && myLanes->back()->getOpposite() != 0;
859 }
860 
861 /****************************************************************************/
862 
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:834
bool allowsLaneChanging()
Definition: MSEdge.cpp:228
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:571
std::set< MSTransportable * > myContainers
Containers on the edge.
Definition: MSEdge.h:797
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:82
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:721
long long int SUMOTime
Definition: SUMOTime.h:43
SUMOReal myLength
the length of the edge (cached value for speedup)
Definition: MSEdge.h:828
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:718
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:52
bool insertVehicle(SUMOVehicle &v, SUMOTime time, const bool checkOnly=false) const
Tries to insert the given vehicle into the network.
Definition: MSEdge.cpp:472
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:759
static int dictSize()
Returns the number of edges.
Definition: MSEdge.cpp:700
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:272
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:136
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:856
const EdgeBasicFunction myFunction
the purpose of the edge
Definition: MSEdge.h:772
The position is given.
ClassedAllowedLanesCont myClassedAllowed
From vehicle class to lanes allowed to be used by it.
Definition: MSEdge.h:807
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:166
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
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:75
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:673
This is an uncontrolled, right-before-left link.
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition: MSEdge.cpp:383
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:397
The lane is chosen randomly.
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
const SVCPermissions SVCAll
int myVaporizationRequests
Vaporizer counter.
Definition: MSEdge.h:775
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:390
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:846
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.
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:399
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:861
void rebuildAllowedLanes()
Definition: MSEdge.cpp:251
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:591
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1954
#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:158
The edge is a district edge.
Definition: MSEdge.h:99
virtual void setChosenSpeedFactor(const SUMOReal factor)=0
Representation of a vehicle.
Definition: SUMOVehicle.h:66
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:803
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:2720
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:712
SVCPermissions myMinimumPermissions
The intersection of lane permissions for this edge.
Definition: MSEdge.h:810
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:90
MSEdgeVector mySuccessors
The succeeding edges.
Definition: MSEdge.h:784
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:273
MSLaneChanger * myLaneChanger
This member will do the lane-change.
Definition: MSEdge.h:769
#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.
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:406
T MIN2(T a, T b)
Definition: StdDefs.h:69
std::vector< SUMOReal > mySublaneSides
the right side for each sublane on this edge
Definition: MSEdge.h:840
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:766
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
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:769
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:2714
bool canChangeToOpposite()
whether this edge allows changing to the opposite direction edge
Definition: MSEdge.cpp:857
MSLane * getDepartLane(MSVehicle &veh) const
Finds a depart lane for the given vehicle parameters.
Definition: MSEdge.cpp:417
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:802
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:812
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:210
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:285
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:360
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:706
virtual void changeLanes(SUMOTime t)
Performs lane changing on this edge.
Definition: MSEdge.cpp:578
SUMOReal myEmptyTraveltime
the traveltime on the empty edge (cached value for speedup)
Definition: MSEdge.h:831
SUMOReal getMeanSpeed() const
get the mean speed
Definition: MSEdge.cpp:629
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:300
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:249
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:295
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:107
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:232
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSEdge.h:851
static void readEdgeVector(std::istream &in, std::vector< const E * > &edges, const std::string &rid)
Reads an edge vector binary.
Definition: FileHelpers.h:283
SUMOReal getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:666
#define SUMOReal
Definition: config.h:214
Sorts transportables by their positions.
Definition: MSEdge.h:733
const MSJunction * getFromJunction() const
Definition: MSEdge.h:383
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:353
#define NUMERICAL_EPS
Definition: config.h:161
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:776
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1512
A free position is chosen.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
SUMOReal myWidth
Edge width [m].
Definition: MSEdge.h:825
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:279
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition: MSEdge.cpp:810
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:312
SUMOReal getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2041
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:86
MSEdgeVector myPredecessors
The preceeding edges.
Definition: MSEdge.h:787
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:656
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:729
vehicles ignoring classes
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep) const
Returns this edge&#39;s persons sorted by pos.
Definition: MSEdge.cpp:794
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.
void setMaxSpeed(SUMOReal val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:783
const MSJunction * getToJunction() const
Definition: MSEdge.h:387
const Position & getPosition() const
Definition: MSJunction.cpp:67
std::set< MSTransportable * > myPersons
Persons on the edge for drawing and pushbutton.
Definition: MSEdge.h:794