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 insertVehicle(SUMOVehicle &v, SUMOTime time, const bool checkOnly=false) const
Tries to insert the given vehicle into the network.
Definition: MSEdge.cpp:472
SUMOReal getCurrentTravelTime(const SUMOReal minSpeed=NUMERICAL_EPS) const
Computes and returns the current travel time for this edge.
Definition: MSEdge.cpp:656
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:158
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1954
bool allowsLaneChanging()
Definition: MSEdge.cpp:228
std::set< MSTransportable * > myContainers
Containers on the edge.
Definition: MSEdge.h:797
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:571
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
void descheduleDeparture(SUMOVehicle *veh)
stops trying to emit the given vehicle (and delete it)
Sorts edges by their ids.
Definition: MSEdge.h:718
SUMOReal getSpeedDeviation() const
Returns this type&#39;s speed deviation.
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:52
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
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:700
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:272
static void readEdgeVector(std::istream &in, std::vector< const E *> &edges, const std::string &rid)
Reads an edge vector binary.
Definition: FileHelpers.h:283
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
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
The least occupied lane is used.
virtual SUMOReal getEdgePos(SUMOTime now) const =0
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
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
This is a dead end link.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:192
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
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
The lane is chosen randomly.
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
void initialize(const std::vector< MSLane *> *lanes)
Initialize the edge.
Definition: MSEdge.cpp:110
const std::string & getID() const
Returns the id.
Definition: Named.h:66
const SVCPermissions SVCAll
int myVaporizationRequests
Vaporizer counter.
Definition: MSEdge.h:775
EdgeBasicFunction
Defines possible edge types.
Definition: MSEdge.h:89
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition: MSEdge.cpp:810
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:90
const MSJunction * getToJunction() const
Definition: MSEdge.h:387
The least occupied lane from best lanes.
The position is chosen randomly.
SUMOTime decVaporization(SUMOTime t)
Disables vaporization.
Definition: MSEdge.cpp:390
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:275
This is an uncontrolled, all-way stop link.
std::vector< MSTransportable * > getSortedContainers(SUMOTime timestep) const
Returns this edge&#39;s containers sorted by pos.
Definition: MSEdge.cpp:802
SUMOReal getDistanceTo(const MSEdge *other) const
optimistic air distance heuristic for use in routing
Definition: MSEdge.cpp:759
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
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:406
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
Performs lane changing of vehicles.
The lane is given.
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
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
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:232
virtual SUMOReal getChosenSpeedFactor() const =0
Performs lane changing of vehicles.
Definition: MSLaneChanger.h:55
A road/street connecting two junctions.
Definition: MSEdge.h:80
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:399
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:776
MSTransportable::Stage * getCurrentStage() const
Return the current stage.
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:861
void rebuildAllowedLanes()
Definition: MSEdge.cpp:251
SUMOReal computeChosenSpeedDeviation(MTRand *rng, const SUMOReal minDevFactor=0.2) const
Computes and returns the speed deviation.
#define max(a, b)
Definition: polyfonts.c:65
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
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.
This is an uncontrolled, minor link, has to brake.
AllowedLanesCont myAllowed
Associative container from destination-edge to allowed-lanes.
Definition: MSEdge.h:803
virtual bool hasValidRoute(std::string &msg, const MSRoute *route=0) const =0
Validates the current or given route.
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
SUMOReal getSpeedFactor() const
Returns this type&#39;s speed factor.
MSLane * getFreeLane(const std::vector< MSLane *> *allowed, const SUMOVehicleClass vclass) const
Finds the emptiest lane allowing the vehicle class.
Definition: MSEdge.cpp:397
MSEdgeVector mySuccessors
The succeeding edges.
Definition: MSEdge.h:784
SUMOReal getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:666
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.
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
T MIN2(T a, T b)
Definition: StdDefs.h:69
const Position & getPosition() const
Definition: MSJunction.cpp:67
const std::string & getID() const
returns the id of the transportable
MSLane * getDepartLane(MSVehicle &veh) const
Finds a depart lane for the given vehicle parameters.
Definition: MSEdge.cpp:417
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
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
If a fixed number of random choices fails, a free position is chosen.
bool canChangeToOpposite()
whether this edge allows changing to the opposite direction edge
Definition: MSEdge.cpp:857
Base class for objects which have an id.
Definition: Named.h:46
The rightmost lane the vehicle may use.
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
SUMOReal getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2041
std::vector< std::string > getVector()
SVCPermissions myCombinedPermissions
The union of lane permissions for this edge.
Definition: MSEdge.h:812
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
Structure representing possible vehicle parameter.
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
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
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
const MSJunction * getFromJunction() const
Definition: MSEdge.h:383
SUMOReal myEmptyTraveltime
the traveltime on the empty edge (cached value for speedup)
Definition: MSEdge.h:831
A single mesoscopic segment (cell)
Definition: MESegment.h:57
SUMOReal getMeanSpeed() const
get the mean speed
Definition: MSEdge.cpp:629
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:591
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
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:353
bool isTaz() const
Definition: MSEdge.h:268
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:107
SUMOReal departPos
(optional) The position the vehicle shall depart from
void setMaxSpeed(SUMOReal val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:783
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:695
std::map< const MSEdge *, std::vector< MSLane * > *> AllowedLanesCont
Suceeding edges (keys) and allowed lanes to reach these edges (values).
Definition: MSEdge.h:108
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSEdge.h:851
#define SUMOReal
Definition: config.h:213
Sorts transportables by their positions.
Definition: MSEdge.h:733
#define NUMERICAL_EPS
Definition: config.h:160
int numSublanes() const
Definition: MSLeaderInfo.h:86
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:78
A free position is chosen.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
SUMOReal myWidth
Edge width [m].
Definition: MSEdge.h:825
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1512
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2714
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep) const
Returns this edge&#39;s persons sorted by pos.
Definition: MSEdge.cpp:794
static SUMOReal gMesoTLSPenalty
Definition: MSGlobals.h:104
The edge is an internal edge.
Definition: MSEdge.h:97
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
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
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
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:312
vehicles ignoring classes
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
SUMOReal getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
std::string id
The vehicle&#39;s id.
std::set< MSTransportable * > myPersons
Persons on the edge for drawing and pushbutton.
Definition: MSEdge.h:794
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.