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 // static members
54 // ===========================================================================
56 
57 // ===========================================================================
58 // method definitions
59 // ===========================================================================
60 MSBaseVehicle::MSBaseVehicle(SUMOVehicleParameter* pars, const MSRoute* route, const MSVehicleType* type, SUMOReal speedFactor) :
61  myParameter(pars),
62  myRoute(route),
63  myType(type),
64  myCurrEdge(route->begin()),
65  myChosenSpeedFactor(speedFactor),
66  myMoveReminders(0),
67  myDeparture(NOT_YET_DEPARTED),
68  myArrivalPos(-1),
69  myNumberReroutes(0) {
70  // init devices
75  //
76  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
77  myMoveReminders.push_back(std::make_pair(*dev, 0.));
78  }
81 }
82 
84  myRoute->release();
85  delete myParameter;
86  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
87  delete(*dev);
88  }
89 }
90 
91 
92 const std::string&
94  return myParameter->id;
95 }
96 
97 
100  return *myParameter;
101 }
102 
103 
104 const MSRoute&
106  return *myRoute;
107 }
108 
109 
110 const MSVehicleType&
112  return *myType;
113 }
114 
115 
116 SUMOReal
118  return myType->getMaxSpeed();
119 }
120 
121 
122 const MSEdge*
123 MSBaseVehicle::succEdge(unsigned int nSuccs) const {
124  if (myCurrEdge + nSuccs < myRoute->end()) {
125  return *(myCurrEdge + nSuccs);
126  } else {
127  return 0;
128  }
129 }
130 
131 
132 const MSEdge*
134  return *myCurrEdge;
135 }
136 
137 
138 void
140  // check whether to reroute
141  std::vector<const MSEdge*> edges;
142  if (withTaz && MSEdge::dictionary(myParameter->fromTaz + "-source") && MSEdge::dictionary(myParameter->toTaz + "-sink")) {
143  router.compute(MSEdge::dictionary(myParameter->fromTaz + "-source"), MSEdge::dictionary(myParameter->toTaz + "-sink"), this, t, edges);
144  if (edges.size() >= 2) {
145  edges.erase(edges.begin());
146  edges.pop_back();
147  }
148  } else {
149  router.compute(*myCurrEdge, myRoute->getLastEdge(), this, t, edges);
150  }
151  if (edges.empty()) {
152  WRITE_WARNING("No route for vehicle '" + getID() + "' found.");
153  return;
154  }
155  replaceRouteEdges(edges, withTaz);
156 }
157 
158 
159 bool
160 MSBaseVehicle::replaceRouteEdges(const MSEdgeVector& edges, bool onInit) {
161  // build a new id, first
162  std::string id = getID();
163  if (id[0] != '!') {
164  id = "!" + id;
165  }
166  if (myRoute->getID().find("!var#") != std::string::npos) {
167  id = myRoute->getID().substr(0, myRoute->getID().rfind("!var#") + 4) + toString(getNumberReroutes() + 1);
168  } else {
169  id = id + "!var#1";
170  }
171  const RGBColor& c = myRoute->getColor();
172  MSRoute* newRoute = new MSRoute(id, edges, 0, &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), myRoute->getStops());
173  if (!MSRoute::dictionary(id, newRoute)) {
174  delete newRoute;
175  return false;
176  }
177  if (!replaceRoute(newRoute, onInit)) {
178  newRoute->addReference();
179  newRoute->release();
180  return false;
181  }
182  return true;
183 }
184 
185 
186 SUMOReal
188  return 0;
189 }
190 
191 
192 void
196 }
197 
198 
199 bool
201  return myDeparture != NOT_YET_DEPARTED;
202 }
203 
204 
205 bool
207  return succEdge(1) == 0;
208 }
209 
210 void
212 }
213 
214 
215 bool
216 MSBaseVehicle::hasValidRoute(std::string& msg) const {
217  MSRouteIterator last = myRoute->end() - 1;
218  // check connectivity, first
219  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
220  if ((*e)->allowedLanes(**(e + 1), myType->getVehicleClass()) == 0) {
221  msg = "No connection between '" + (*e)->getID() + "' and '" + (*(e + 1))->getID() + "'.";
222  return false;
223  }
224  }
225  last = myRoute->end();
226  // check usable lanes, then
227  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
228  if ((*e)->prohibits(this)) {
229  msg = "Edge '" + (*e)->getID() + "' prohibits.";
230  return false;
231  }
232  }
233  return true;
234 }
235 
236 
237 void
239  myMoveReminders.push_back(std::make_pair(rem, 0.));
240 }
241 
242 
243 void
245  for (MoveReminderCont::iterator r = myMoveReminders.begin(); r != myMoveReminders.end(); ++r) {
246  if (r->first == rem) {
247  myMoveReminders.erase(r);
248  return;
249  }
250  }
251 }
252 
253 
254 void
256  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
257  if (rem->first->notifyEnter(*this, reason)) {
258  ++rem;
259  } else {
260  rem = myMoveReminders.erase(rem);
261  }
262  }
263 }
264 
265 
266 void
268  const SUMOReal lastLaneLength = (myRoute->getLastEdge()->getLanes())[0]->getLength();
269  switch (myParameter->arrivalPosProcedure) {
270  case ARRIVAL_POS_GIVEN:
271  if (fabs(myParameter->arrivalPos) > lastLaneLength) {
272  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given position!");
273  }
274  // Maybe we should warn the user about invalid inputs!
275  myArrivalPos = MIN2(myParameter->arrivalPos, lastLaneLength);
276  if (myArrivalPos < 0) {
277  myArrivalPos = MAX2(myArrivalPos + lastLaneLength, static_cast<SUMOReal>(0));
278  }
279  break;
280  case ARRIVAL_POS_RANDOM:
281  myArrivalPos = RandHelper::rand(static_cast<SUMOReal>(0), lastLaneLength);
282  break;
283  default:
284  myArrivalPos = lastLaneLength;
285  break;
286  }
287 }
288 
289 
290 /****************************************************************************/
291