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