SUMO - Simulation of Urban MObility
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.dlr.de/
12 // Copyright (C) 2001-2015 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 "MSGlobals.h"
40 #include "MSVehicleType.h"
41 #include "MSEdge.h"
42 #include "MSLane.h"
43 #include "MSMoveReminder.h"
44 #include "MSBaseVehicle.h"
45 #include "MSNet.h"
46 #include "devices/MSDevice.h"
48 
49 #ifdef CHECK_MEMORY_LEAKS
50 #include <foreign/nvwa/debug_new.h>
51 #endif // CHECK_MEMORY_LEAKS
52 
53 // ===========================================================================
54 // static members
55 // ===========================================================================
57 #ifdef _DEBUG
58 std::set<std::string> MSBaseVehicle::myShallTraceMoveReminders;
59 #endif
60 
61 // ===========================================================================
62 // method definitions
63 // ===========================================================================
65  const MSVehicleType* type, const SUMOReal speedFactor) :
66  myParameter(pars),
67  myRoute(route),
68  myType(type),
69  myCurrEdge(route->begin()),
70  myChosenSpeedFactor(speedFactor),
71  myMoveReminders(0),
72  myDeparture(NOT_YET_DEPARTED),
73  myArrivalPos(-1),
74  myNumberReroutes(0)
75 #ifdef _DEBUG
76  , myTraceMoveReminders(myShallTraceMoveReminders.count(pars->id) > 0)
77 #endif
78 {
79  // init devices
81  //
82  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
83  myMoveReminders.push_back(std::make_pair(*dev, 0.));
84  }
86  if (!pars->wasSet(VEHPARS_FORCE_REROUTE)) {
88  }
89 }
90 
92  myRoute->release();
93  if (myParameter->repetitionNumber == 0) {
95  }
96  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
97  delete *dev;
98  }
99  delete myParameter;
100 }
101 
102 
103 const std::string&
105  return myParameter->id;
106 }
107 
108 
111  return *myParameter;
112 }
113 
114 
115 SUMOReal
117  return myType->getMaxSpeed();
118 }
119 
120 
121 const MSEdge*
122 MSBaseVehicle::succEdge(unsigned int nSuccs) const {
123  if (myCurrEdge + nSuccs < myRoute->end()) {
124  return *(myCurrEdge + nSuccs);
125  } else {
126  return 0;
127  }
128 }
129 
130 
131 const MSEdge*
133  return *myCurrEdge;
134 }
135 
136 
137 void
138 MSBaseVehicle::reroute(SUMOTime t, SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, const bool onInit, const bool withTaz) {
139  // check whether to reroute
140  const MSEdge* source = withTaz && onInit ? MSEdge::dictionary(myParameter->fromTaz + "-source") : getRerouteOrigin();
141  if (source == 0) {
142  source = getRerouteOrigin();
143  }
144  const MSEdge* sink = withTaz ? MSEdge::dictionary(myParameter->toTaz + "-sink") : myRoute->getLastEdge();
145  if (sink == 0) {
146  sink = myRoute->getLastEdge();
147  }
148  ConstMSEdgeVector edges;
149  const ConstMSEdgeVector stops = getStopEdges();
150  for (MSRouteIterator s = stops.begin(); s != stops.end(); ++s) {
151  if (*s != source) {
152  // !!! need to adapt t here
153  router.compute(source, *s, this, t, edges);
154  source = *s;
155  edges.pop_back();
156  }
157  }
158  router.compute(source, sink, this, t, edges);
159  if (!edges.empty() && edges.front()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) {
160  edges.erase(edges.begin());
161  }
162  if (!edges.empty() && edges.back()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) {
163  edges.pop_back();
164  }
165  replaceRouteEdges(edges, onInit);
166 }
167 
168 
169 bool
171  if (edges.empty()) {
172  WRITE_WARNING("No route for vehicle '" + getID() + "' found.");
173  return false;
174  }
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#") + 5) + toString(getNumberReroutes() + 1);
182  } else {
183  id = id + "!var#1";
184  }
185  const MSEdge* const origin = getRerouteOrigin();
186  if (origin != *myCurrEdge && edges.front() == origin) {
187  edges.insert(edges.begin(), *myCurrEdge);
188  }
189  const int oldSize = (int)edges.size();
190  edges.insert(edges.begin(), myRoute->begin(), myCurrEdge);
191  if (edges == myRoute->getEdges()) {
192  return true;
193  }
194  const RGBColor& c = myRoute->getColor();
195  MSRoute* newRoute = new MSRoute(id, edges, false, &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), myRoute->getStops());
196 #ifdef HAVE_FOX
197  MSDevice_Routing::lock();
198 #endif
199  if (!MSRoute::dictionary(id, newRoute)) {
200 #ifdef HAVE_FOX
201  MSDevice_Routing::unlock();
202 #endif
203  delete newRoute;
204  return false;
205  }
206 #ifdef HAVE_FOX
207  MSDevice_Routing::unlock();
208 #endif
209  if (!replaceRoute(newRoute, onInit, (int)edges.size() - oldSize)) {
210  newRoute->addReference();
211 #ifdef HAVE_FOX
212  MSDevice_Routing::lock();
213 #endif
214  newRoute->release();
215 #ifdef HAVE_FOX
216  MSDevice_Routing::unlock();
217 #endif
218  return false;
219  }
220  return true;
221 }
222 
223 
224 SUMOReal
226  return 0;
227 }
228 
229 
230 SUMOReal
232  return 0;
233 }
234 
235 
236 void
240 }
241 
242 
243 bool
245  return myDeparture != NOT_YET_DEPARTED;
246 }
247 
248 
249 bool
251  return succEdge(1) == 0;
252 }
253 
254 void
256 }
257 
258 void
260 }
261 
262 bool
263 MSBaseVehicle::hasValidRoute(std::string& msg) const {
264  MSRouteIterator last = myRoute->end() - 1;
265  // check connectivity, first
266  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
267  if ((*e)->allowedLanes(**(e + 1), myType->getVehicleClass()) == 0) {
268  msg = "No connection between '" + (*e)->getID() + "' and '" + (*(e + 1))->getID() + "'.";
269  return false;
270  }
271  }
272  last = myRoute->end();
273  // check usable lanes, then
274  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
275  if ((*e)->prohibits(this)) {
276  msg = "Edge '" + (*e)->getID() + "' prohibits.";
277  return false;
278  }
279  }
280  return true;
281 }
282 
283 
284 void
286 #ifdef _DEBUG
287  if (myTraceMoveReminders) {
288  traceMoveReminder("add", rem, 0, true);
289  }
290 #endif
291  myMoveReminders.push_back(std::make_pair(rem, 0.));
292 }
293 
294 
295 void
297  for (MoveReminderCont::iterator r = myMoveReminders.begin(); r != myMoveReminders.end(); ++r) {
298  if (r->first == rem) {
299 #ifdef _DEBUG
300  if (myTraceMoveReminders) {
301  traceMoveReminder("remove", rem, 0, false);
302  }
303 #endif
304  myMoveReminders.erase(r);
305  return;
306  }
307  }
308 }
309 
310 
311 void
313  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
314  if (rem->first->notifyEnter(*this, reason)) {
315 #ifdef _DEBUG
316  if (myTraceMoveReminders) {
317  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
318  }
319 #endif
320  ++rem;
321  } else {
322 #ifdef _DEBUG
323  if (myTraceMoveReminders) {
324  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
325  }
326 #endif
327  rem = myMoveReminders.erase(rem);
328  }
329  }
330 }
331 
332 
333 void
335  const SUMOReal lastLaneLength = (myRoute->getLastEdge()->getLanes())[0]->getLength();
336  switch (myParameter->arrivalPosProcedure) {
337  case ARRIVAL_POS_GIVEN:
338  if (fabs(myParameter->arrivalPos) > lastLaneLength) {
339  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given position!");
340  }
341  // Maybe we should warn the user about invalid inputs!
342  myArrivalPos = MIN2(myParameter->arrivalPos, lastLaneLength);
343  if (myArrivalPos < 0) {
344  myArrivalPos = MAX2(myArrivalPos + lastLaneLength, static_cast<SUMOReal>(0));
345  }
346  break;
347  case ARRIVAL_POS_RANDOM:
348  myArrivalPos = RandHelper::rand(static_cast<SUMOReal>(0), lastLaneLength);
349  break;
350  default:
351  myArrivalPos = lastLaneLength;
352  break;
353  }
354 }
355 
356 
357 SUMOReal
361 }
362 
363 
364 MSDevice*
365 MSBaseVehicle::getDevice(const std::type_info& type) const {
366  for (std::vector<MSDevice*>::const_iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
367  if (typeid(**dev) == type) {
368  return *dev;
369  }
370  }
371  return 0;
372 }
373 
374 
375 void
381  // here starts the vehicle internal part (see loading)
382  // @note: remember to close the vehicle tag when calling this in a subclass!
383 }
384 
385 
386 void
387 MSBaseVehicle::addStops(const bool ignoreStopErrors) {
388  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = myParameter->stops.begin(); i != myParameter->stops.end(); ++i) {
389  std::string errorMsg;
390  if (!addStop(*i, errorMsg) && !ignoreStopErrors) {
391  throw ProcessError(errorMsg);
392  }
393  if (errorMsg != "") {
394  WRITE_WARNING(errorMsg);
395  }
396  }
397  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = myRoute->getStops().begin(); i != myRoute->getStops().end(); ++i) {
398  std::string errorMsg;
399  if (!addStop(*i, errorMsg) && !ignoreStopErrors) {
400  throw ProcessError(errorMsg);
401  }
402  if (errorMsg != "") {
403  WRITE_WARNING(errorMsg);
404  }
405  }
406 }
407 
408 
409 #ifdef _DEBUG
410 void
411 MSBaseVehicle::initMoveReminderOutput(const OptionsCont& oc) {
412  if (oc.isSet("movereminder-output.vehicles")) {
413  const std::vector<std::string> vehicles = oc.getStringVector("movereminder-output.vehicles");
414  myShallTraceMoveReminders.insert(vehicles.begin(), vehicles.end());
415  }
416 }
417 
418 
419 void
420 MSBaseVehicle::traceMoveReminder(const std::string& type, MSMoveReminder* rem, SUMOReal pos, bool keep) const {
421  OutputDevice& od = OutputDevice::getDeviceByOption("movereminder-output");
422  od.openTag("movereminder");
423  od.writeAttr(SUMO_ATTR_TIME, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()));
424  od.writeAttr("veh", getID());
426  od.writeAttr("type", type);
427  od.writeAttr("pos", toString(pos));
428  od.writeAttr("keep", toString(keep));
429  od.closeTag();
430 }
431 #endif
432 
433 /****************************************************************************/
434 
virtual void addContainer(MSContainer *container)
Adds a container to this vehicle.
void removeReminder(MSMoveReminder *rem)
Removes a MoveReminder dynamically.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
const MSVehicleType * myType
This Vehicle's type.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
MSDevice * getDevice(const std::type_info &type) const
Returns a device of the given type if it exists or 0.
SUMOReal getMaxSpeed() const
Get vehicle's maximum speed [m/s].
const int VEHPARS_FORCE_REROUTE
unsigned int getNumberReroutes() const
Returns the number of new routes this vehicle got.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
const std::string & getDescription() const
SUMOReal myArrivalPos
the position on the destination lane where the vehicle stops
MoveReminderCont myMoveReminders
Current lane's move reminder.
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
SUMOReal getMaxSpeed() const
Returns the maximum speed.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:186
virtual void addPerson(MSPerson *person)
Adds a person to this vehicle.
SUMOReal getImpatience() const
Returns this vehicles impatience.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:93
Notification
Definition of a vehicle state.
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
SUMOReal arrivalPos
(optional) The position the vehicle shall arrive on
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
T MAX2(T a, T b)
Definition: StdDefs.h:74
virtual ~MSBaseVehicle()
Destructor.
const MSRoute * myRoute
This Vehicle's route.
bool hasDeparted() const
Returns whether this vehicle has already departed.
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary...
Definition: MSEdge.cpp:531
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:79
const SUMOVehicleParameter * myParameter
This Vehicle's parameter.
The arrival position is given.
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:337
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:235
MSBaseVehicle(SUMOVehicleParameter *pars, const MSRoute *route, const MSVehicleType *type, const SUMOReal speedFactor)
Constructor.
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into)
Build devices for the given vehicle, if needed.
Definition: MSDevice.cpp:73
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The car-following model and parameter.
Definition: MSVehicleType.h:74
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
virtual bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0)=0
Adds a stop.
std::string toTaz
The vehicle's destination zone (district)
std::vector< Stop > stops
List of the stops the vehicle will make.
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:81
The edge is a district edge.
Definition: MSEdge.h:100
std::string routeid
The vehicle's route id.
virtual SUMOReal getAcceleration() const
Returns the vehicle's acceleration.
bool wasSet(int what) const
Returns whether the given parameter was set.
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:200
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:288
const MSEdge * succEdge(unsigned int nSuccs) const
Returns the nSuccs'th successor of edge the vehicle is currently at.
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:61
SUMOTime depart
The vehicle's departure time.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:124
T MIN2(T a, T b)
Definition: StdDefs.h:68
std::string fromTaz
The vehicle's origin zone (district)
virtual const ConstMSEdgeVector getStopEdges() const =0
Returns the list of still pending stop edges.
Something on a lane to be noticed about vehicle movement.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:100
bool replaceRouteEdges(ConstMSEdgeVector &edges, bool onInit=false)
Replaces the current route by the given edges.
Abstract in-vehicle device.
Definition: MSDevice.h:69
void addStops(const bool ignoreStopErrors)
Adds stops to the built vehicle.
Structure representing possible vehicle parameter.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:81
#define SUMOTime_MAX
Definition: SUMOTime.h:44
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
virtual void activateReminders(const MSMoveReminder::Notification reason)
"Activates" all current move reminder
void onDepart()
Called when the vehicle is inserted into the network.
A storage for options typed value containers)
Definition: OptionsCont.h:108
virtual bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)=0
Replaces the current route by the given one.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:90
virtual bool hasArrived() const
Returns whether this vehicle has already arived (by default this is true if the vehicle has reached i...
void calculateArrivalPos()
(Re-)Calculates the arrival position from the vehicle parameters
virtual const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
const std::string & getID() const
Returns the name of the vehicle type.
int SUMOTime
Definition: SUMOTime.h:43
static SUMOTime gTimeToGridlock
Definition: MSGlobals.h:65
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
virtual SUMOTime getWaitingTime() const =0
bool hasValidRoute(std::string &msg) const
Validates the current route.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:328
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:218
virtual void compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
MSRouteIterator myCurrEdge
Iterator to current route-edge.
void reroute(SUMOTime t, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, const bool onInit=false, const bool withTaz=false)
Performs a rerouting using the given router.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
void vehicleDeparted(const SUMOVehicle &v)
Informs this control about a vehicle's departure.
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:106
virtual SUMOReal getSlope() const
Returns the slope of the road at vehicle's position.
void addReminder(MSMoveReminder *rem)
Adds a MoveReminder dynamically.
std::vector< MSDevice * > myDevices
The devices this vehicle has.
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition: MSRoute.cpp:173
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
SUMOTime myDeparture
The real departure time.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:75
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
static const SUMOTime NOT_YET_DEPARTED
std::string id
The vehicle's id.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
const std::string & getID() const
Returns the name of the vehicle.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:116
The arrival position is chosen randomly.