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_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  }
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 #ifdef HAVE_INTERNAL_LANES
127  toL = (*j)->getViaLane();
128  if (toL != 0) {
129  MSEdge& to = toL->getEdge();
130  to.myPredeccesors.push_back(this);
131  }
132 #endif
133  }
134  }
135  std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
137 }
138 
139 
140 void
142  // clear myClassedAllowed.
143  // it will be rebuilt on demand
144  for (ClassedAllowedLanesCont::iterator i2 = myClassedAllowed.begin(); i2 != myClassedAllowed.end(); i2++) {
145  for (AllowedLanesCont::iterator i1 = (*i2).second.begin(); i1 != (*i2).second.end(); i1++) {
146  delete(*i1).second;
147  }
148  }
149  myClassedAllowed.clear();
150  // rebuild myMinimumPermissions and myCombinedPermissions
153  for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
154  myMinimumPermissions &= (*i)->getPermissions();
155  myCombinedPermissions |= (*i)->getPermissions();
156  }
157 }
158 
159 
160 // ------------ Access to the edge's lanes
161 MSLane*
162 MSEdge::leftLane(const MSLane* const lane) const {
163  std::vector<MSLane*>::iterator laneIt = find(myLanes->begin(), myLanes->end(), lane);
164  if (laneIt == myLanes->end() || laneIt == myLanes->end() - 1) {
165  return 0;
166  }
167  return *(laneIt + 1);
168 }
169 
170 
171 MSLane*
172 MSEdge::rightLane(const MSLane* const lane) const {
173  std::vector<MSLane*>::iterator laneIt = find(myLanes->begin(), myLanes->end(), lane);
174  if (laneIt == myLanes->end() || laneIt == myLanes->begin()) {
175  return 0;
176  }
177  return *(laneIt - 1);
178 }
179 
180 
181 const std::vector<MSLane*>*
182 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
183  return allowedLanes(&destination, vclass);
184 }
185 
186 
187 const std::vector<MSLane*>*
189  return allowedLanes(0, vclass);
190 }
191 
192 
193 const std::vector<MSLane*>*
195  AllowedLanesCont::const_iterator it = c.find(dest);
196  if (it == c.end()) {
197  return 0;
198  }
199  return it->second;
200 }
201 
202 
203 const std::vector<MSLane*>*
204 MSEdge::allowedLanes(const MSEdge* destination, SUMOVehicleClass vclass) const {
205  if ((myMinimumPermissions & vclass) == vclass) {
206  // all lanes allow vclass
207  return getAllowedLanesWithDefault(myAllowed, destination);
208  }
209  // look up cached result in myClassedAllowed
210  ClassedAllowedLanesCont::const_iterator i = myClassedAllowed.find(vclass);
211  if (i != myClassedAllowed.end()) {
212  // can use cached value
213  const AllowedLanesCont& c = (*i).second;
214  return getAllowedLanesWithDefault(c, destination);
215  } else {
216  // this vclass is requested for the first time. rebuild all destinations
217  // go through connected edges
218  for (AllowedLanesCont::const_iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); ++i1) {
219  const MSEdge* edge = i1->first;
220  const std::vector<MSLane*>* lanes = i1->second;
221  myClassedAllowed[vclass][edge] = new std::vector<MSLane*>();
222  // go through lanes approaching current edge
223  for (std::vector<MSLane*>::const_iterator i2 = lanes->begin(); i2 != lanes->end(); ++i2) {
224  // allows the current vehicle class?
225  if ((*i2)->allowsVehicleClass(vclass)) {
226  // -> may be used
227  myClassedAllowed[vclass][edge]->push_back(*i2);
228  }
229  }
230  // assert that 0 is returned if no connection is allowed for a class
231  if (myClassedAllowed[vclass][edge]->size() == 0) {
232  delete myClassedAllowed[vclass][edge];
233  myClassedAllowed[vclass][edge] = 0;
234  }
235  }
236  return myClassedAllowed[vclass][destination];
237  }
238 }
239 
240 
241 // ------------
242 SUMOTime
245  return 0;
246 }
247 
248 
249 SUMOTime
252  return 0;
253 }
254 
255 
256 MSLane*
257 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass) const {
258  if (allowed == 0) {
259  allowed = allowedLanes(vclass);
260  }
261  MSLane* res = 0;
262  if (allowed != 0) {
263  unsigned int noCars = INT_MAX;
264  for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
265  if ((*i)->getVehicleNumber() < noCars) {
266  res = (*i);
267  noCars = (*i)->getVehicleNumber();
268  }
269  }
270  }
271  return res;
272 }
273 
274 
275 MSLane*
276 MSEdge::getDepartLane(const MSVehicle& veh) const {
277  switch (veh.getParameter().departLaneProcedure) {
278  case DEPART_LANE_GIVEN:
279  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
280  return 0;
281  }
282  return (*myLanes)[veh.getParameter().departLane];
283  case DEPART_LANE_RANDOM:
285  case DEPART_LANE_FREE:
286  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
288  if (veh.getRoute().size() == 1) {
289  return getFreeLane(0, veh.getVehicleType().getVehicleClass());
290  } else {
291  return getFreeLane(allowedLanes(**(veh.getRoute().begin() + 1)), veh.getVehicleType().getVehicleClass());
292  }
293  case DEPART_LANE_BEST_FREE: {
294  const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes(false, (*myLanes)[0]);
295  SUMOReal bestLength = -1;
296  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
297  if ((*i).length > bestLength) {
298  bestLength = (*i).length;
299  }
300  }
301  std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
302  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
303  if ((*i).length == bestLength) {
304  bestLanes->push_back((*i).lane);
305  }
306  }
307  MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass());
308  delete bestLanes;
309  return ret;
310  }
311  case DEPART_LANE_DEFAULT:
312  default:
313  break;
314  }
315  if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
316  return 0;
317  }
318  return (*myLanes)[0];
319 }
320 
321 
322 bool
324  // when vaporizing, no vehicles are inserted...
325  if (isVaporizing()) {
326  return false;
327  }
328 #ifdef HAVE_INTERNAL
330  const SUMOVehicleParameter& pars = v.getParameter();
331  SUMOReal pos = 0.0;
332  switch (pars.departPosProcedure) {
333  case DEPART_POS_GIVEN:
334  if (pars.departPos >= 0.) {
335  pos = pars.departPos;
336  } else {
337  pos = pars.departPos + getLength();
338  }
339  if (pos < 0 || pos > getLength()) {
340  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
341  v.getID() + "'. Inserting at lane end instead.");
342  pos = getLength();
343  }
344  break;
345  case DEPART_POS_RANDOM:
347  pos = RandHelper::rand(getLength());
348  break;
349  default:
350  break;
351  }
352  bool result = false;
353  MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
354  MEVehicle* veh = static_cast<MEVehicle*>(&v);
355  if (pars.departPosProcedure == DEPART_POS_FREE) {
356  while (segment != 0 && !result) {
357  result = segment->initialise(veh, time);
358  segment = segment->getNextSegment();
359  }
360  } else {
361  result = segment->initialise(veh, time);
362  }
363  return result;
364  }
365 #else
366  UNUSED_PARAMETER(time);
367 #endif
368  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
369  return insertionLane != 0 && insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
370 }
371 
372 
373 void
376  return;
377  }
378  assert(myLaneChanger != 0);
380 }
381 
382 
383 
384 #ifdef HAVE_INTERNAL_LANES
385 const MSEdge*
386 MSEdge::getInternalFollowingEdge(MSEdge* followerAfterInternal) const {
387  //@todo to be optimized
388  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
389  MSLane* l = *i;
390  const MSLinkCont& lc = l->getLinkCont();
391  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
392  MSLink* link = *j;
393  if (&link->getLane()->getEdge() == followerAfterInternal) {
394  if (link->getViaLane() != 0) {
395  return &link->getViaLane()->getEdge();
396  } else {
397  return 0; // network without internal links
398  }
399  }
400  }
401  }
402  return 0;
403 }
404 #endif
405 
406 
407 SUMOReal
409  assert(minSpeed > 0);
410  SUMOReal v = 0;
411 #ifdef HAVE_INTERNAL
413  MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(*this);
414  unsigned segments = 0;
415  do {
416  v += first->getMeanSpeed();
417  first = first->getNextSegment();
418  segments++;
419  } while (first != 0);
420  v /= (SUMOReal) segments;
421  } else {
422 #endif
423  for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
424  v += (*i)->getMeanSpeed();
425  }
426  v /= (SUMOReal) myLanes->size();
427 #ifdef HAVE_INTERNAL
428  }
429 #endif
430  v = MAX2(minSpeed, v);
431  return getLength() / v;
432 }
433 
434 
435 bool
436 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
437  DictType::iterator it = myDict.find(id);
438  if (it == myDict.end()) {
439  // id not in myDict.
440  myDict[id] = ptr;
441  if (ptr->getNumericalID() != -1) {
442  while ((int)myEdges.size() < ptr->getNumericalID() + 1) {
443  myEdges.push_back(0);
444  }
445  myEdges[ptr->getNumericalID()] = ptr;
446  }
447  return true;
448  }
449  return false;
450 }
451 
452 
453 MSEdge*
454 MSEdge::dictionary(const std::string& id) {
455  DictType::iterator it = myDict.find(id);
456  if (it == myDict.end()) {
457  // id not in myDict.
458  return 0;
459  }
460  return it->second;
461 }
462 
463 
464 MSEdge*
465 MSEdge::dictionary(size_t id) {
466  assert(myEdges.size() > id);
467  return myEdges[id];
468 }
469 
470 
471 size_t
473  return myDict.size();
474 }
475 
476 
477 size_t
479  return myEdges.size();
480 }
481 
482 
483 void
485  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
486  delete(*i).second;
487  }
488  myDict.clear();
489 }
490 
491 
492 void
493 MSEdge::insertIDs(std::vector<std::string>& into) {
494  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
495  into.push_back((*i).first);
496  }
497 }
498 
499 
500 void
501 MSEdge::parseEdgesList(const std::string& desc, std::vector<const MSEdge*>& into,
502  const std::string& rid) {
503  if (desc[0] == BinaryFormatter::BF_ROUTE) {
504  std::istringstream in(desc, std::ios::binary);
505  char c;
506  in >> c;
507  FileHelpers::readEdgeVector(in, into, rid);
508  } else {
509  StringTokenizer st(desc);
510  parseEdgesList(st.getVector(), into, rid);
511  }
512 }
513 
514 
515 void
516 MSEdge::parseEdgesList(const std::vector<std::string>& desc, std::vector<const MSEdge*>& into,
517  const std::string& rid) {
518  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
519  const MSEdge* edge = MSEdge::dictionary(*i);
520  // check whether the edge exists
521  if (edge == 0) {
522  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
523  + "\n The route can not be build.");
524  }
525  into.push_back(edge);
526  }
527 }
528 
529 
530 SUMOReal
531 MSEdge::getDistanceTo(const MSEdge* other) const {
532  if (getLanes().size() > 0 && other->getLanes().size() > 0) {
533  return getLanes()[0]->getShape()[-1].distanceTo2D(other->getLanes()[0]->getShape()[0]);
534  } else {
535  return 0; // optimism is just right for astar
536  }
537 }
538 
539 
540 SUMOReal
542  return getLanes()[0]->getLength();
543 }
544 
545 
546 SUMOReal
548  // @note lanes might have different maximum speeds in theory
549  return getLanes()[0]->getSpeedLimit();
550 }
551 
552 
553 SUMOReal
554 MSEdge::getVehicleMaxSpeed(const SUMOVehicle* const veh) const {
555  // @note lanes might have different maximum speeds in theory
556  return getLanes()[0]->getVehicleMaxSpeed(veh);
557 }
558 
559 /****************************************************************************/
560