SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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.sourceforge.net/
16 // Copyright (C) 2001-2013 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 "MSLane.h"
44 #include "MSLaneChanger.h"
45 #include "MSGlobals.h"
46 #include "MSVehicle.h"
47 #include "MSEdgeWeightsStorage.h"
48 
49 #ifdef HAVE_INTERNAL
50 #include <mesosim/MELoop.h>
51 #include <mesosim/MESegment.h>
52 #include <mesosim/MEVehicle.h>
53 #endif
54 
55 #ifdef CHECK_MEMORY_LEAKS
56 #include <foreign/nvwa/debug_new.h>
57 #endif // CHECK_MEMORY_LEAKS
58 
59 
60 // ===========================================================================
61 // static member definitions
62 // ===========================================================================
64 std::vector<MSEdge*> MSEdge::myEdges;
65 
66 
67 // ===========================================================================
68 // member method definitions
69 // ===========================================================================
70 MSEdge::MSEdge(const std::string& id, int numericalID,
71  const EdgeBasicFunction function,
72  const std::string& streetName) :
73  Named(id), myNumericalID(numericalID), myLanes(0),
74  myLaneChanger(0), myFunction(function), myVaporizationRequests(0),
75  myLastFailedInsertionTime(-1), myStreetName(streetName) {}
76 
77 
79  delete myLaneChanger;
80  for (AllowedLanesCont::iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); i1++) {
81  delete(*i1).second;
82  }
83  for (ClassedAllowedLanesCont::iterator i2 = myClassedAllowed.begin(); i2 != myClassedAllowed.end(); i2++) {
84  for (AllowedLanesCont::iterator i1 = (*i2).second.begin(); i1 != (*i2).second.end(); i1++) {
85  delete(*i1).second;
86  }
87  }
88  delete myLanes;
89  // Note: Lanes are delete using MSLane::clear();
90 }
91 
92 
93 void
94 MSEdge::initialize(std::vector<MSLane*>* lanes) {
95  assert(myFunction == EDGEFUNCTION_DISTRICT || lanes != 0);
96  myLanes = lanes;
97  if (myLanes && myLanes->size() > 1 && myFunction != EDGEFUNCTION_INTERNAL) {
98  myLaneChanger = new MSLaneChanger(myLanes, OptionsCont::getOptions().getBool("lanechange.allow-swap"));
99  }
102  }
103 }
104 
105 
106 void
108  myAllowed[0] = new std::vector<MSLane*>();
109  for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
110  myAllowed[0]->push_back(*i);
111  const MSLinkCont& lc = (*i)->getLinkCont();
112  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
113  MSLane* toL = (*j)->getLane();
114  if (toL != 0) {
115  MSEdge& to = toL->getEdge();
116  //
117  if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
118  mySuccessors.push_back(&to);
119  }
120  if (std::find(to.myPredeccesors.begin(), to.myPredeccesors.end(), this) == to.myPredeccesors.end()) {
121  to.myPredeccesors.push_back(this);
122  }
123  //
124  if (myAllowed.find(&to) == myAllowed.end()) {
125  myAllowed[&to] = new std::vector<MSLane*>();
126  }
127  myAllowed[&to]->push_back(*i);
128  }
129 #ifdef HAVE_INTERNAL_LANES
130  toL = (*j)->getViaLane();
131  if (toL != 0) {
132  MSEdge& to = toL->getEdge();
133  to.myPredeccesors.push_back(this);
134  }
135 #endif
136  }
137  }
138  std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
140 }
141 
142 
143 void
145  // clear myClassedAllowed.
146  // it will be rebuilt on demand
147  for (ClassedAllowedLanesCont::iterator i2 = myClassedAllowed.begin(); i2 != myClassedAllowed.end(); i2++) {
148  for (AllowedLanesCont::iterator i1 = (*i2).second.begin(); i1 != (*i2).second.end(); i1++) {
149  delete(*i1).second;
150  }
151  }
152  myClassedAllowed.clear();
153  // rebuild myMinimumPermissions and myCombinedPermissions
156  for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
157  myMinimumPermissions &= (*i)->getPermissions();
158  myCombinedPermissions |= (*i)->getPermissions();
159  }
160 }
161 
162 
163 // ------------ Access to the edge's lanes
164 MSLane*
165 MSEdge::leftLane(const MSLane* const lane) const {
166  std::vector<MSLane*>::iterator laneIt = find(myLanes->begin(), myLanes->end(), lane);
167  if (laneIt == myLanes->end() || laneIt == myLanes->end() - 1) {
168  return 0;
169  }
170  return *(laneIt + 1);
171 }
172 
173 
174 MSLane*
175 MSEdge::rightLane(const MSLane* const lane) const {
176  std::vector<MSLane*>::iterator laneIt = find(myLanes->begin(), myLanes->end(), lane);
177  if (laneIt == myLanes->end() || laneIt == myLanes->begin()) {
178  return 0;
179  }
180  return *(laneIt - 1);
181 }
182 
183 
184 const std::vector<MSLane*>*
185 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
186  return allowedLanes(&destination, vclass);
187 }
188 
189 
190 const std::vector<MSLane*>*
192  return allowedLanes(0, vclass);
193 }
194 
195 
196 const std::vector<MSLane*>*
198  AllowedLanesCont::const_iterator it = c.find(dest);
199  if (it == c.end()) {
200  return 0;
201  }
202  return it->second;
203 }
204 
205 
206 const std::vector<MSLane*>*
207 MSEdge::allowedLanes(const MSEdge* destination, SUMOVehicleClass vclass) const {
208  if ((myMinimumPermissions & vclass) == vclass) {
209  // all lanes allow vclass
210  return getAllowedLanesWithDefault(myAllowed, destination);
211  }
212  // look up cached result in myClassedAllowed
213  ClassedAllowedLanesCont::const_iterator i = myClassedAllowed.find(vclass);
214  if (i != myClassedAllowed.end()) {
215  // can use cached value
216  const AllowedLanesCont& c = (*i).second;
217  return getAllowedLanesWithDefault(c, destination);
218  } else {
219  // this vclass is requested for the first time. rebuild all destinations
220  // go through connected edges
221  for (AllowedLanesCont::const_iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); ++i1) {
222  const MSEdge* edge = i1->first;
223  const std::vector<MSLane*>* lanes = i1->second;
224  myClassedAllowed[vclass][edge] = new std::vector<MSLane*>();
225  // go through lanes approaching current edge
226  for (std::vector<MSLane*>::const_iterator i2 = lanes->begin(); i2 != lanes->end(); ++i2) {
227  // allows the current vehicle class?
228  if ((*i2)->allowsVehicleClass(vclass)) {
229  // -> may be used
230  myClassedAllowed[vclass][edge]->push_back(*i2);
231  }
232  }
233  // assert that 0 is returned if no connection is allowed for a class
234  if (myClassedAllowed[vclass][edge]->size() == 0) {
235  delete myClassedAllowed[vclass][edge];
236  myClassedAllowed[vclass][edge] = 0;
237  }
238  }
239  return myClassedAllowed[vclass][destination];
240  }
241 }
242 
243 
244 // ------------
245 SUMOTime
248  return 0;
249 }
250 
251 
252 SUMOTime
255  return 0;
256 }
257 
258 
259 MSLane*
260 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass) const {
261  if (allowed == 0) {
262  allowed = allowedLanes(vclass);
263  }
264  MSLane* res = 0;
265  if (allowed != 0) {
266  unsigned int noCars = INT_MAX;
267  for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
268  if ((*i)->getVehicleNumber() < noCars) {
269  res = (*i);
270  noCars = (*i)->getVehicleNumber();
271  }
272  }
273  }
274  return res;
275 }
276 
277 
278 MSLane*
279 MSEdge::getDepartLane(const MSVehicle& veh) const {
280  switch (veh.getParameter().departLaneProcedure) {
281  case DEPART_LANE_GIVEN:
282  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
283  return 0;
284  }
285  return (*myLanes)[veh.getParameter().departLane];
286  case DEPART_LANE_RANDOM:
288  case DEPART_LANE_FREE:
289  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
291  if (veh.getRoute().size() == 1) {
292  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
293  } else {
294  return getFreeLane(allowedLanes(**(veh.getRoute().begin() + 1)), veh.getVehicleType().getVehicleClass());
295  }
296  case DEPART_LANE_BEST_FREE: {
297  const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes(false, (*myLanes)[0]);
298  SUMOReal bestLength = -1;
299  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
300  if ((*i).length > bestLength) {
301  bestLength = (*i).length;
302  }
303  }
304  std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
305  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
306  if ((*i).length == bestLength) {
307  bestLanes->push_back((*i).lane);
308  }
309  }
310  MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass());
311  delete bestLanes;
312  return ret;
313  }
314  case DEPART_LANE_DEFAULT:
315  default:
316  break;
317  }
318  if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
319  return 0;
320  }
321  return (*myLanes)[0];
322 }
323 
324 
325 bool
327  // when vaporizing, no vehicles are inserted...
328  if (isVaporizing()) {
329  return false;
330  }
331 #ifdef HAVE_INTERNAL
333  const SUMOVehicleParameter& pars = v.getParameter();
334  SUMOReal pos = 0.0;
335  switch (pars.departPosProcedure) {
336  case DEPART_POS_GIVEN:
337  if (pars.departPos >= 0.) {
338  pos = pars.departPos;
339  } else {
340  pos = pars.departPos + getLength();
341  }
342  if (pos < 0 || pos > getLength()) {
343  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
344  v.getID() + "'. Inserting at lane end instead.");
345  pos = getLength();
346  }
347  break;
348  case DEPART_POS_RANDOM:
350  pos = RandHelper::rand(getLength());
351  break;
352  default:
353  break;
354  }
355  bool result = false;
356  MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
357  MEVehicle* veh = static_cast<MEVehicle*>(&v);
358  if (pars.departPosProcedure == DEPART_POS_FREE) {
359  while (segment != 0 && !result) {
360  result = segment->initialise(veh, time);
361  segment = segment->getNextSegment();
362  }
363  } else {
364  result = segment->initialise(veh, time);
365  }
366  return result;
367  }
368 #else
369  UNUSED_PARAMETER(time);
370 #endif
371  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
372  return insertionLane != 0 && insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
373 }
374 
375 
376 void
379  return;
380  }
381  assert(myLaneChanger != 0);
383 }
384 
385 
386 
387 #ifdef HAVE_INTERNAL_LANES
388 const MSEdge*
389 MSEdge::getInternalFollowingEdge(MSEdge* followerAfterInternal) const {
390  //@todo to be optimized
391  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
392  MSLane* l = *i;
393  const MSLinkCont& lc = l->getLinkCont();
394  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
395  MSLink* link = *j;
396  if (&link->getLane()->getEdge() == followerAfterInternal) {
397  if (link->getViaLane() != 0) {
398  return &link->getViaLane()->getEdge();
399  } else {
400  return 0; // network without internal links
401  }
402  }
403  }
404  }
405  return 0;
406 }
407 #endif
408 
409 
410 SUMOReal
412  assert(minSpeed > 0);
413  SUMOReal v = 0;
414 #ifdef HAVE_INTERNAL
416  MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(*this);
417  unsigned segments = 0;
418  do {
419  v += first->getMeanSpeed();
420  first = first->getNextSegment();
421  segments++;
422  } while (first != 0);
423  v /= (SUMOReal) segments;
424  } else {
425 #endif
426  for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
427  v += (*i)->getMeanSpeed();
428  }
429  v /= (SUMOReal) myLanes->size();
430 #ifdef HAVE_INTERNAL
431  }
432 #endif
433  v = MAX2(minSpeed, v);
434  return getLength() / v;
435 }
436 
437 
438 bool
439 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
440  DictType::iterator it = myDict.find(id);
441  if (it == myDict.end()) {
442  // id not in myDict.
443  myDict[id] = ptr;
444  if (ptr->getNumericalID() != -1) {
445  while ((int)myEdges.size() < ptr->getNumericalID() + 1) {
446  myEdges.push_back(0);
447  }
448  myEdges[ptr->getNumericalID()] = ptr;
449  }
450  return true;
451  }
452  return false;
453 }
454 
455 
456 MSEdge*
457 MSEdge::dictionary(const std::string& id) {
458  DictType::iterator it = myDict.find(id);
459  if (it == myDict.end()) {
460  // id not in myDict.
461  return 0;
462  }
463  return it->second;
464 }
465 
466 
467 MSEdge*
468 MSEdge::dictionary(size_t id) {
469  assert(myEdges.size() > id);
470  return myEdges[id];
471 }
472 
473 
474 size_t
476  return myDict.size();
477 }
478 
479 
480 size_t
482  return myEdges.size();
483 }
484 
485 
486 void
488  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
489  delete(*i).second;
490  }
491  myDict.clear();
492 }
493 
494 
495 void
496 MSEdge::insertIDs(std::vector<std::string>& into) {
497  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
498  into.push_back((*i).first);
499  }
500 }
501 
502 
503 void
504 MSEdge::parseEdgesList(const std::string& desc, std::vector<const MSEdge*>& into,
505  const std::string& rid) {
506  if (desc[0] == BinaryFormatter::BF_ROUTE) {
507  std::istringstream in(desc, std::ios::binary);
508  char c;
509  in >> c;
510  FileHelpers::readEdgeVector(in, into, rid);
511  } else {
512  StringTokenizer st(desc);
513  parseEdgesList(st.getVector(), into, rid);
514  }
515 }
516 
517 
518 void
519 MSEdge::parseEdgesList(const std::vector<std::string>& desc, std::vector<const MSEdge*>& into,
520  const std::string& rid) {
521  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
522  const MSEdge* edge = MSEdge::dictionary(*i);
523  // check whether the edge exists
524  if (edge == 0) {
525  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
526  + "\n The route can not be build.");
527  }
528  into.push_back(edge);
529  }
530 }
531 
532 
533 SUMOReal
534 MSEdge::getDistanceTo(const MSEdge* other) const {
535  if (getLanes().size() > 0 && other->getLanes().size() > 0) {
536  return getLanes()[0]->getShape()[-1].distanceTo2D(other->getLanes()[0]->getShape()[0]);
537  } else {
538  return 0; // optimism is just right for astar
539  }
540 }
541 
542 
543 SUMOReal
545  return getLanes()[0]->getLength();
546 }
547 
548 
549 SUMOReal
551  // @note lanes might have different maximum speeds in theory
552  return getLanes()[0]->getSpeedLimit();
553 }
554 
555 
556 SUMOReal
557 MSEdge::getVehicleMaxSpeed(const SUMOVehicle* const veh) const {
558  // @note lanes might have different maximum speeds in theory
559  return getLanes()[0]->getVehicleMaxSpeed(veh);
560 }
561 
562 /****************************************************************************/
563