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-2012 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_MESOSIM
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, unsigned int numericalID,
71  const std::string& streetName) :
72  myID(id), myNumericalID(numericalID), myLanes(0),
73  myLaneChanger(0), myVaporizationRequests(0), myLastFailedInsertionTime(-1),
74  myStreetName(streetName) {}
75 
76 
78  delete myLaneChanger;
79  for (AllowedLanesCont::iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); i1++) {
80  delete(*i1).second;
81  }
82  for (ClassedAllowedLanesCont::iterator i2 = myClassedAllowed.begin(); i2 != myClassedAllowed.end(); i2++) {
83  for (AllowedLanesCont::iterator i1 = (*i2).second.begin(); i1 != (*i2).second.end(); i1++) {
84  delete(*i1).second;
85  }
86  }
87  delete myLanes;
88  // Note: Lanes are delete using MSLane::clear();
89 }
90 
91 
92 void
93 MSEdge::initialize(std::vector<MSLane*>* lanes, EdgeBasicFunction function) {
94  assert(function == EDGEFUNCTION_DISTRICT || lanes != 0);
95  myLanes = lanes;
96  myFunction = function;
97  if (myLanes && myLanes->size() > 1 && function != EDGEFUNCTION_INTERNAL) {
98  myLaneChanger = new MSLaneChanger(myLanes, OptionsCont::getOptions().getBool("lanechange.allow-swap"));
99  }
100 }
101 
102 
103 void
105  myAllowed[0] = new std::vector<MSLane*>();
106  for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
107  myAllowed[0]->push_back(*i);
108  const MSLinkCont& lc = (*i)->getLinkCont();
109  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
110  MSLane* toL = (*j)->getLane();
111  if (toL != 0) {
112  MSEdge& to = toL->getEdge();
113  //
114  if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
115  mySuccessors.push_back(&to);
116  }
117  if (std::find(to.myPredeccesors.begin(), to.myPredeccesors.end(), this) == to.myPredeccesors.end()) {
118  to.myPredeccesors.push_back(this);
119  }
120  //
121  if (myAllowed.find(&to) == myAllowed.end()) {
122  myAllowed[&to] = new std::vector<MSLane*>();
123  }
124  myAllowed[&to]->push_back(*i);
125  }
126  }
127  }
128  std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
130 }
131 
132 
133 void
135  // clear myClassedAllowed.
136  // it will be rebuilt on demand
137  for (ClassedAllowedLanesCont::iterator i2 = myClassedAllowed.begin(); i2 != myClassedAllowed.end(); i2++) {
138  for (AllowedLanesCont::iterator i1 = (*i2).second.begin(); i1 != (*i2).second.end(); i1++) {
139  delete(*i1).second;
140  }
141  }
142  myClassedAllowed.clear();
143  // rebuild myMinimumPermissions and myCombinedPermissions
146  for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
147  myMinimumPermissions &= (*i)->getPermissions();
148  myCombinedPermissions |= (*i)->getPermissions();
149  }
150 }
151 
152 
153 // ------------ Access to the edge's lanes
154 MSLane*
155 MSEdge::leftLane(const MSLane* const lane) const {
156  std::vector<MSLane*>::iterator laneIt = find(myLanes->begin(), myLanes->end(), lane);
157  if (laneIt == myLanes->end() || laneIt == myLanes->end() - 1) {
158  return 0;
159  }
160  return *(laneIt + 1);
161 }
162 
163 
164 MSLane*
165 MSEdge::rightLane(const MSLane* const lane) const {
166  std::vector<MSLane*>::iterator laneIt = find(myLanes->begin(), myLanes->end(), lane);
167  if (laneIt == myLanes->end() || laneIt == myLanes->begin()) {
168  return 0;
169  }
170  return *(laneIt - 1);
171 }
172 
173 
174 const std::vector<MSLane*>*
175 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
176  return allowedLanes(&destination, vclass);
177 }
178 
179 
180 const std::vector<MSLane*>*
182  return allowedLanes(0, vclass);
183 }
184 
185 
186 const std::vector<MSLane*>*
188  AllowedLanesCont::const_iterator it = c.find(dest);
189  if (it == c.end()) {
190  return 0;
191  }
192  return it->second;
193 }
194 
195 
196 const std::vector<MSLane*>*
197 MSEdge::allowedLanes(const MSEdge* destination, SUMOVehicleClass vclass) const {
198  if ((myMinimumPermissions & vclass) == vclass) {
199  // all lanes allow vclass
200  return getAllowedLanesWithDefault(myAllowed, destination);
201  }
202  // look up cached result in myClassedAllowed
203  ClassedAllowedLanesCont::const_iterator i = myClassedAllowed.find(vclass);
204  if (i != myClassedAllowed.end()) {
205  // can use cached value
206  const AllowedLanesCont& c = (*i).second;
207  return getAllowedLanesWithDefault(c, destination);
208  } else {
209  // this vclass is requested for the first time. rebuild all destinations
210  // go through connected edges
211  for (AllowedLanesCont::const_iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); ++i1) {
212  const MSEdge* edge = i1->first;
213  const std::vector<MSLane*>* lanes = i1->second;
214  myClassedAllowed[vclass][edge] = new std::vector<MSLane*>();
215  // go through lanes approaching current edge
216  for (std::vector<MSLane*>::const_iterator i2 = lanes->begin(); i2 != lanes->end(); ++i2) {
217  // allows the current vehicle class?
218  if ((*i2)->allowsVehicleClass(vclass)) {
219  // -> may be used
220  myClassedAllowed[vclass][edge]->push_back(*i2);
221  }
222  }
223  // assert that 0 is returned if no connection is allowed for a class
224  if (myClassedAllowed[vclass][edge]->size() == 0) {
225  delete myClassedAllowed[vclass][edge];
226  myClassedAllowed[vclass][edge] = 0;
227  }
228  }
229  return myClassedAllowed[vclass][destination];
230  }
231 }
232 
233 
234 // ------------
235 SUMOTime
238  return 0;
239 }
240 
241 
242 SUMOTime
245  return 0;
246 }
247 
248 
249 MSLane*
250 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass) const {
251  if (allowed == 0) {
252  allowed = allowedLanes(vclass);
253  }
254  MSLane* res = 0;
255  if (allowed != 0) {
256  unsigned int noCars = INT_MAX;
257  for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
258  if ((*i)->getVehicleNumber() < noCars) {
259  res = (*i);
260  noCars = (*i)->getVehicleNumber();
261  }
262  }
263  }
264  return res;
265 }
266 
267 
268 MSLane*
269 MSEdge::getDepartLane(const MSVehicle& veh) const {
270  switch (veh.getParameter().departLaneProcedure) {
271  case DEPART_LANE_GIVEN:
272  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
273  return 0;
274  }
275  return (*myLanes)[veh.getParameter().departLane];
276  case DEPART_LANE_RANDOM:
278  case DEPART_LANE_FREE:
279  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
281  if (veh.getRoute().size() == 1) {
282  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
283  } else {
284  return getFreeLane(allowedLanes(**(veh.getRoute().begin() + 1)), veh.getVehicleType().getVehicleClass());
285  }
286  case DEPART_LANE_BEST_FREE: {
287  const std::vector<MSVehicle::LaneQ> &bl = veh.getBestLanes(false, (*myLanes)[0]);
288  SUMOReal bestLength = -1;
289  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
290  if ((*i).length > bestLength) {
291  bestLength = (*i).length;
292  }
293  }
294  std::vector<MSLane*> *bestLanes = new std::vector<MSLane*>();
295  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
296  if ((*i).length == bestLength) {
297  bestLanes->push_back((*i).lane);
298  }
299  }
300  MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass());
301  delete bestLanes;
302  return ret;
303  }
304  case DEPART_LANE_DEFAULT:
305  default:
306  break;
307  }
308  if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
309  return 0;
310  }
311  return (*myLanes)[0];
312 }
313 
314 
315 bool
317  // when vaporizing, no vehicles are inserted...
318  if (isVaporizing()) {
319  return false;
320  }
321 #ifdef HAVE_MESOSIM
323  const SUMOVehicleParameter& pars = v.getParameter();
324  SUMOReal pos = 0.0;
325  switch (pars.departPosProcedure) {
326  case DEPART_POS_GIVEN:
327  if (pars.departPos >= 0.) {
328  pos = pars.departPos;
329  } else {
330  pos = pars.departPos + getLength();
331  }
332  if (pos < 0 || pos > getLength()) {
333  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
334  v.getID() + "'. Inserting at lane end instead.");
335  pos = getLength();
336  }
337  break;
338  case DEPART_POS_RANDOM:
340  pos = RandHelper::rand(getLength());
341  break;
342  default:
343  break;
344  }
345  bool result = false;
346  MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
347  MEVehicle* veh = static_cast<MEVehicle*>(&v);
348  if (pars.departPosProcedure == DEPART_POS_FREE) {
349  while (segment != 0 && !result) {
350  result = segment->initialise(veh, time);
351  segment = segment->getNextSegment();
352  }
353  } else {
354  result = segment->initialise(veh, time);
355  }
356  return result;
357  }
358 #endif
359  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
360  return insertionLane != 0 && insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
361 }
362 
363 
364 void
367  return;
368  }
369  assert(myLaneChanger != 0);
371 }
372 
373 
374 
375 #ifdef HAVE_INTERNAL_LANES
376 const MSEdge*
377 MSEdge::getInternalFollowingEdge(MSEdge* followerAfterInternal) const {
378  //@todo to be optimized
379  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
380  MSLane* l = *i;
381  const MSLinkCont& lc = l->getLinkCont();
382  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
383  MSLink* link = *j;
384  if (&link->getLane()->getEdge() == followerAfterInternal) {
385  return &link->getViaLane()->getEdge();
386  }
387  }
388  }
389  return 0;
390 }
391 #endif
392 
393 
394 SUMOReal
396  SUMOReal v = 0;
397 #ifdef HAVE_MESOSIM
399  MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(*this);
400  unsigned segments = 0;
401  do {
402  v += first->getMeanSpeed();
403  first = first->getNextSegment();
404  segments++;
405  } while (first != 0);
406  v /= (SUMOReal) segments;
407  } else {
408 #endif
409  for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
410  v += (*i)->getMeanSpeed();
411  }
412  v /= (SUMOReal) myLanes->size();
413 #ifdef HAVE_MESOSIM
414  }
415 #endif
416  if (v != 0) {
417  return getLength() / v;
418  } else {
419  return 1000000.;
420  }
421 }
422 
423 
424 bool
425 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
426  DictType::iterator it = myDict.find(id);
427  if (it == myDict.end()) {
428  // id not in myDict.
429  myDict[id] = ptr;
430  while (myEdges.size() < ptr->getNumericalID() + 1) {
431  myEdges.push_back(0);
432  }
433  myEdges[ptr->getNumericalID()] = ptr;
434  return true;
435  }
436  return false;
437 }
438 
439 
440 MSEdge*
441 MSEdge::dictionary(const std::string& id) {
442  DictType::iterator it = myDict.find(id);
443  if (it == myDict.end()) {
444  // id not in myDict.
445  return 0;
446  }
447  return it->second;
448 }
449 
450 
451 MSEdge*
452 MSEdge::dictionary(size_t id) {
453  assert(myEdges.size() > id);
454  return myEdges[id];
455 }
456 
457 
458 size_t
460  return myDict.size();
461 }
462 
463 
464 void
466  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
467  delete(*i).second;
468  }
469  myDict.clear();
470 }
471 
472 
473 void
474 MSEdge::insertIDs(std::vector<std::string> &into) {
475  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
476  into.push_back((*i).first);
477  }
478 }
479 
480 
481 void
482 MSEdge::parseEdgesList(const std::string& desc, std::vector<const MSEdge*> &into,
483  const std::string& rid) {
484  StringTokenizer st(desc);
485  parseEdgesList(st.getVector(), into, rid);
486 }
487 
488 
489 void
490 MSEdge::parseEdgesList(const std::vector<std::string> &desc, std::vector<const MSEdge*> &into,
491  const std::string& rid) {
492  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
493  const MSEdge* edge = MSEdge::dictionary(*i);
494  // check whether the edge exists
495  if (edge == 0) {
496  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
497  + "\n The route can not be build.");
498  }
499  into.push_back(edge);
500  }
501 }
502 
503 
504 SUMOReal
505 MSEdge::getDistanceTo(const MSEdge* other) const {
506  return getLanes()[0]->getShape()[-1].distanceTo2D(other->getLanes()[0]->getShape()[0]);
507 }
508 
509 
510 SUMOReal
512  return getLanes()[0]->getLength();
513 }
514 
515 
516 SUMOReal
518  // @note lanes might have different maximum speeds in theory
519  return getLanes()[0]->getMaxSpeed();
520 }
521 
522 /****************************************************************************/
523