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-sim.org/
12 // Copyright (C) 2001-2014 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>
39 #include "MSVehicleType.h"
40 #include "MSEdge.h"
41 #include "MSLane.h"
42 #include "MSMoveReminder.h"
43 #include "MSBaseVehicle.h"
44 #include "MSNet.h"
45 #include "devices/MSDevice.h"
46 
47 #ifdef CHECK_MEMORY_LEAKS
48 #include <foreign/nvwa/debug_new.h>
49 #endif // CHECK_MEMORY_LEAKS
50 
51 // ===========================================================================
52 // static members
53 // ===========================================================================
55 #ifdef _DEBUG
56 std::set<std::string> MSBaseVehicle::myShallTraceMoveReminders;
57 #endif
58 
59 // ===========================================================================
60 // method definitions
61 // ===========================================================================
62 MSBaseVehicle::MSBaseVehicle(SUMOVehicleParameter* pars, const MSRoute* route, const MSVehicleType* type, const SUMOReal speedFactor) :
63  myParameter(pars),
64  myRoute(route),
65  myType(type),
66  myCurrEdge(route->begin()),
67  myChosenSpeedFactor(speedFactor),
68  myMoveReminders(0),
69  myDeparture(NOT_YET_DEPARTED),
70  myArrivalPos(-1),
71  myNumberReroutes(0)
72 #ifdef _DEBUG
73  , myTraceMoveReminders(myShallTraceMoveReminders.count(pars->id) > 0)
74 #endif
75 {
76  // init devices
78  //
79  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
80  myMoveReminders.push_back(std::make_pair(*dev, 0.));
81  }
84 }
85 
87  myRoute->release();
88  if (myParameter->repetitionNumber == 0) {
90  }
91  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
92  delete *dev;
93  }
94  delete myParameter;
95 }
96 
97 
98 const std::string&
100  return myParameter->id;
101 }
102 
103 
106  return *myParameter;
107 }
108 
109 
110 SUMOReal
112  return myType->getMaxSpeed();
113 }
114 
115 
116 const MSEdge*
117 MSBaseVehicle::succEdge(unsigned int nSuccs) const {
118  if (myCurrEdge + nSuccs < myRoute->end()) {
119  return *(myCurrEdge + nSuccs);
120  } else {
121  return 0;
122  }
123 }
124 
125 
126 const MSEdge*
128  return *myCurrEdge;
129 }
130 
131 
132 void
134  // check whether to reroute
135  std::vector<const MSEdge*> edges;
136  if (withTaz && MSEdge::dictionary(myParameter->fromTaz + "-source") && MSEdge::dictionary(myParameter->toTaz + "-sink")) {
137  router.compute(MSEdge::dictionary(myParameter->fromTaz + "-source"), MSEdge::dictionary(myParameter->toTaz + "-sink"), this, t, edges);
138  if (edges.size() >= 2) {
139  edges.erase(edges.begin());
140  edges.pop_back();
141  }
142  } else {
143  router.compute(getRerouteOrigin(), myRoute->getLastEdge(), this, t, edges);
144  }
145  if (edges.empty()) {
146  WRITE_WARNING("No route for vehicle '" + getID() + "' found.");
147  return;
148  }
149  replaceRouteEdges(edges, withTaz);
150 }
151 
152 
153 bool
155  // build a new id, first
156  std::string id = getID();
157  if (id[0] != '!') {
158  id = "!" + id;
159  }
160  if (myRoute->getID().find("!var#") != std::string::npos) {
161  id = myRoute->getID().substr(0, myRoute->getID().rfind("!var#") + 5) + toString(getNumberReroutes() + 1);
162  } else {
163  id = id + "!var#1";
164  }
165  const MSEdge* const origin = getRerouteOrigin();
166  if (origin != *myCurrEdge && edges.front() == origin) {
167  edges.insert(edges.begin(), *myCurrEdge);
168  }
169  const int oldSize = (int)edges.size();
170  edges.insert(edges.begin(), myRoute->begin(), myCurrEdge);
171  const RGBColor& c = myRoute->getColor();
172  MSRoute* newRoute = new MSRoute(id, edges, false, &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, (int)edges.size() - oldSize)) {
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 SUMOReal
194  return 0;
195 }
196 
197 
198 void
202 }
203 
204 
205 bool
207  return myDeparture != NOT_YET_DEPARTED;
208 }
209 
210 
211 bool
213  return succEdge(1) == 0;
214 }
215 
216 void
218 }
219 
220 
221 bool
222 MSBaseVehicle::hasValidRoute(std::string& msg) const {
223  MSRouteIterator last = myRoute->end() - 1;
224  // check connectivity, first
225  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
226  if ((*e)->allowedLanes(**(e + 1), myType->getVehicleClass()) == 0) {
227  msg = "No connection between '" + (*e)->getID() + "' and '" + (*(e + 1))->getID() + "'.";
228  return false;
229  }
230  }
231  last = myRoute->end();
232  // check usable lanes, then
233  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
234  if ((*e)->prohibits(this)) {
235  msg = "Edge '" + (*e)->getID() + "' prohibits.";
236  return false;
237  }
238  }
239  return true;
240 }
241 
242 
243 void
245 #ifdef _DEBUG
246  if (myTraceMoveReminders) {
247  traceMoveReminder("add", rem, 0, true);
248  }
249 #endif
250  myMoveReminders.push_back(std::make_pair(rem, 0.));
251 }
252 
253 
254 void
256  for (MoveReminderCont::iterator r = myMoveReminders.begin(); r != myMoveReminders.end(); ++r) {
257  if (r->first == rem) {
258 #ifdef _DEBUG
259  if (myTraceMoveReminders) {
260  traceMoveReminder("remove", rem, 0, false);
261  }
262 #endif
263  myMoveReminders.erase(r);
264  return;
265  }
266  }
267 }
268 
269 
270 void
272  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
273  if (rem->first->notifyEnter(*this, reason)) {
274 #ifdef _DEBUG
275  if (myTraceMoveReminders) {
276  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
277  }
278 #endif
279  ++rem;
280  } else {
281 #ifdef _DEBUG
282  if (myTraceMoveReminders) {
283  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
284  }
285 #endif
286  rem = myMoveReminders.erase(rem);
287  }
288  }
289 }
290 
291 
292 void
294  const SUMOReal lastLaneLength = (myRoute->getLastEdge()->getLanes())[0]->getLength();
295  switch (myParameter->arrivalPosProcedure) {
296  case ARRIVAL_POS_GIVEN:
297  if (fabs(myParameter->arrivalPos) > lastLaneLength) {
298  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given position!");
299  }
300  // Maybe we should warn the user about invalid inputs!
301  myArrivalPos = MIN2(myParameter->arrivalPos, lastLaneLength);
302  if (myArrivalPos < 0) {
303  myArrivalPos = MAX2(myArrivalPos + lastLaneLength, static_cast<SUMOReal>(0));
304  }
305  break;
306  case ARRIVAL_POS_RANDOM:
307  myArrivalPos = RandHelper::rand(static_cast<SUMOReal>(0), lastLaneLength);
308  break;
309  default:
310  myArrivalPos = lastLaneLength;
311  break;
312  }
313 }
314 
315 
316 SUMOReal
320 }
321 
322 
323 MSDevice*
324 MSBaseVehicle::getDevice(const std::type_info& type) const {
325  for (std::vector<MSDevice*>::const_iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
326  if (typeid(**dev) == type) {
327  return *dev;
328  }
329  }
330  return 0;
331 }
332 
333 
334 void
340  // here starts the vehicle internal part (see loading)
341  // @note: remember to close the vehicle tag when calling this in a subclass!
342 }
343 
344 
345 #ifdef _DEBUG
346 void
347 MSBaseVehicle::initMoveReminderOutput(const OptionsCont& oc) {
348  if (oc.isSet("movereminder-output.vehicles")) {
349  const std::vector<std::string> vehicles = oc.getStringVector("movereminder-output.vehicles");
350  myShallTraceMoveReminders.insert(vehicles.begin(), vehicles.end());
351  }
352 }
353 
354 
355 void
356 MSBaseVehicle::traceMoveReminder(const std::string& type, MSMoveReminder* rem, SUMOReal pos, bool keep) const {
357  OutputDevice& od = OutputDevice::getDeviceByOption("movereminder-output");
358  od.openTag("movereminder");
359  od.writeAttr(SUMO_ATTR_TIME, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()));
360  od.writeAttr("veh", getID());
362  od.writeAttr("type", type);
363  od.writeAttr("pos", toString(pos));
364  od.writeAttr("keep", toString(keep));
365  od.closeTag();
366 }
367 #endif
368 
369 /****************************************************************************/
370