SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSBaseVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // A base class for vehicle implementations
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
12 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <iostream>
34 #include <cassert>
35 #include <utils/common/StdDefs.h>
37 #include "MSVehicleType.h"
38 #include "MSEdge.h"
39 #include "MSLane.h"
40 #include "MSMoveReminder.h"
46 #include "MSBaseVehicle.h"
47 
48 #ifdef CHECK_MEMORY_LEAKS
49 #include <foreign/nvwa/debug_new.h>
50 #endif // CHECK_MEMORY_LEAKS
51 
52 
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
57  myParameter(pars),
58  myRoute(route),
59  myType(type),
60  myCurrEdge(route->begin()),
61  myIndividualMaxSpeed(0.0),
62  myHasIndividualMaxSpeed(false),
63  myReferenceSpeed(-1.0),
64  myMoveReminders(0),
65  myDeparture(-1),
66  myArrivalPos(-1),
67  myNumberReroutes(0) {
68  // init devices
73  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
74  myMoveReminders.push_back(std::make_pair(*dev, 0.));
75  }
78 }
79 
81  myRoute->release();
82  delete myParameter;
83  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
84  delete(*dev);
85  }
86 }
87 
88 
89 const std::string&
91  return myParameter->id;
92 }
93 
94 
97  return *myParameter;
98 }
99 
100 
101 const MSRoute&
103  return *myRoute;
104 }
105 
106 
107 const MSVehicleType&
109  return *myType;
110 }
111 
112 
113 SUMOReal
116  return myIndividualMaxSpeed;
117  }
118  return myType->getMaxSpeed();
119 }
120 
121 
122 SUMOReal
124  if (myType->hasSpeedDeviation() && referenceSpeed != myReferenceSpeed) {
127  myReferenceSpeed = referenceSpeed;
128  }
130  return myIndividualMaxSpeed;
131  }
132  return MIN2(myType->getMaxSpeed(), referenceSpeed);
133 }
134 
135 
136 const MSEdge*
137 MSBaseVehicle::succEdge(unsigned int nSuccs) const {
138  if (myCurrEdge + nSuccs < myRoute->end()) {
139  return *(myCurrEdge + nSuccs);
140  } else {
141  return 0;
142  }
143 }
144 
145 
146 const MSEdge*
148  return *myCurrEdge;
149 }
150 
151 
152 void
154  // check whether to reroute
155  std::vector<const MSEdge*> edges;
156  if (withTaz && MSEdge::dictionary(myParameter->fromTaz + "-source") && MSEdge::dictionary(myParameter->toTaz + "-sink")) {
157  router.compute(MSEdge::dictionary(myParameter->fromTaz + "-source"), MSEdge::dictionary(myParameter->toTaz + "-sink"), this, t, edges);
158  if (edges.size() >= 2) {
159  edges.erase(edges.begin());
160  edges.pop_back();
161  }
162  } else {
163  router.compute(*myCurrEdge, myRoute->getLastEdge(), this, t, edges);
164  }
165  if (edges.empty()) {
166  WRITE_WARNING("No route for vehicle '" + getID() + "' found.");
167  return;
168  }
169  replaceRouteEdges(edges, withTaz);
170 }
171 
172 
173 bool
174 MSBaseVehicle::replaceRouteEdges(const MSEdgeVector& edges, bool onInit) {
175  // build a new id, first
176  std::string id = getID();
177  if (id[0] != '!') {
178  id = "!" + id;
179  }
180  if (myRoute->getID().find("!var#") != std::string::npos) {
181  id = myRoute->getID().substr(0, myRoute->getID().rfind("!var#") + 4) + toString(getNumberReroutes() + 1);
182  } else {
183  id = id + "!var#1";
184  }
185  MSRoute* newRoute = new MSRoute(id, edges, 0, myRoute->getColor(), myRoute->getStops());
186  if (!MSRoute::dictionary(id, newRoute)) {
187  delete newRoute;
188  return false;
189  }
190  if (!replaceRoute(newRoute, onInit)) {
191  newRoute->addReference();
192  newRoute->release();
193  return false;
194  }
195  return true;
196 }
197 
198 
199 SUMOReal
201  return 0;
202 }
203 
204 
205 void
209 }
210 
211 
212 SUMOTime
214  return myDeparture;
215 }
216 
217 
218 unsigned int
220  return myNumberReroutes;
221 }
222 
223 
224 void
226 }
227 
228 
229 bool
230 MSBaseVehicle::hasValidRoute(std::string& msg) const {
231  MSRouteIterator last = myRoute->end() - 1;
232  // check connectivity, first
233  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
234  if ((*e)->allowedLanes(**(e + 1), myType->getVehicleClass()) == 0) {
235  msg = "No connection between '" + (*e)->getID() + "' and '" + (*(e + 1))->getID() + "'.";
236  return false;
237  }
238  }
239  last = myRoute->end();
240  // check usable lanes, then
241  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
242  if ((*e)->prohibits(this)) {
243  msg = "Edge '" + (*e)->getID() + "' prohibits.";
244  return false;
245  }
246  }
247  return true;
248 }
249 
250 
251 void
253  myMoveReminders.push_back(std::make_pair(rem, 0.));
254 }
255 
256 
257 void
259  for (MoveReminderCont::iterator r = myMoveReminders.begin(); r != myMoveReminders.end(); ++r) {
260  if (r->first == rem) {
261  myMoveReminders.erase(r);
262  return;
263  }
264  }
265 }
266 
267 
268 void
270  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
271  if (rem->first->notifyEnter(*this, reason)) {
272  ++rem;
273  } else {
274  rem = myMoveReminders.erase(rem);
275  }
276  }
277 }
278 
279 
280 void
282  const SUMOReal lastLaneLength = (myRoute->getLastEdge()->getLanes())[0]->getLength();
283  switch (myParameter->arrivalPosProcedure) {
284  case ARRIVAL_POS_GIVEN:
285  if (fabs(myParameter->arrivalPos) > lastLaneLength) {
286  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given position!");
287  }
288  // Maybe we should warn the user about invalid inputs!
289  myArrivalPos = MIN2(myParameter->arrivalPos, lastLaneLength);
290  if (myArrivalPos < 0) {
291  myArrivalPos = MAX2(myArrivalPos + lastLaneLength, static_cast<SUMOReal>(0));
292  }
293  break;
294  case ARRIVAL_POS_RANDOM:
295  myArrivalPos = RandHelper::rand(static_cast<SUMOReal>(0), lastLaneLength);
296  break;
297  case ARRIVAL_POS_MAX:
298  case ARRIVAL_POS_DEFAULT:
299  myArrivalPos = lastLaneLength;
300  break;
301  }
302 }
303 
304 
305 /****************************************************************************/
306