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  myArrivalLane(-1),
75  myNumberReroutes(0)
76 #ifdef _DEBUG
77  , myTraceMoveReminders(myShallTraceMoveReminders.count(pars->id) > 0)
78 #endif
79 {
80  // init devices
82  //
83  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
84  myMoveReminders.push_back(std::make_pair(*dev, 0.));
85  }
87  if (!pars->wasSet(VEHPARS_FORCE_REROUTE)) {
89  }
90 }
91 
93  myRoute->release();
94  if (myParameter->repetitionNumber == 0) {
96  }
97  for (std::vector< MSDevice* >::iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
98  delete *dev;
99  }
100  delete myParameter;
101 }
102 
103 
104 const std::string&
106  return myParameter->id;
107 }
108 
109 
112  return *myParameter;
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
139 MSBaseVehicle::reroute(SUMOTime t, SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, const bool onInit, const bool withTaz) {
140  // check whether to reroute
141  const MSEdge* source = withTaz && onInit ? MSEdge::dictionary(myParameter->fromTaz + "-source") : getRerouteOrigin();
142  if (source == 0) {
143  source = getRerouteOrigin();
144  }
145  const MSEdge* sink = withTaz ? MSEdge::dictionary(myParameter->toTaz + "-sink") : myRoute->getLastEdge();
146  if (sink == 0) {
147  sink = myRoute->getLastEdge();
148  }
149  ConstMSEdgeVector edges;
150  const ConstMSEdgeVector stops = getStopEdges();
151  for (MSRouteIterator s = stops.begin(); s != stops.end(); ++s) {
152  if (*s != source) {
153  // !!! need to adapt t here
154  router.compute(source, *s, this, t, edges);
155  source = *s;
156  edges.pop_back();
157  }
158  }
159  router.compute(source, sink, this, t, edges);
160  if (!edges.empty() && edges.front()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) {
161  edges.erase(edges.begin());
162  }
163  if (!edges.empty() && edges.back()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) {
164  edges.pop_back();
165  }
166  replaceRouteEdges(edges, onInit);
167 }
168 
169 
170 bool
172  if (edges.empty()) {
173  WRITE_WARNING("No route for vehicle '" + getID() + "' found.");
174  return false;
175  }
176  // build a new id, first
177  std::string id = getID();
178  if (id[0] != '!') {
179  id = "!" + id;
180  }
181  if (myRoute->getID().find("!var#") != std::string::npos) {
182  id = myRoute->getID().substr(0, myRoute->getID().rfind("!var#") + 5) + toString(getNumberReroutes() + 1);
183  } else {
184  id = id + "!var#1";
185  }
186  int oldSize = (int)edges.size();
187  if (!onInit) {
188  const MSEdge* const origin = getRerouteOrigin();
189  if (origin != *myCurrEdge && edges.front() == origin) {
190  edges.insert(edges.begin(), *myCurrEdge);
191  oldSize = (int)edges.size();
192  }
193  edges.insert(edges.begin(), myRoute->begin(), myCurrEdge);
194  }
195  if (edges == myRoute->getEdges()) {
196  if (onInit) {
197  // if edges = 'from to' we still need to calculate the arrivalPos once
199  }
200  return true;
201  }
202  const RGBColor& c = myRoute->getColor();
203  MSRoute* newRoute = new MSRoute(id, edges, false, &c == &RGBColor::DEFAULT_COLOR ? 0 : new RGBColor(c), myRoute->getStops());
204 #ifdef HAVE_FOX
205  MSDevice_Routing::lock();
206 #endif
207  if (!MSRoute::dictionary(id, newRoute)) {
208 #ifdef HAVE_FOX
209  MSDevice_Routing::unlock();
210 #endif
211  delete newRoute;
212  return false;
213  }
214 #ifdef HAVE_FOX
215  MSDevice_Routing::unlock();
216 #endif
217  if (!replaceRoute(newRoute, onInit, (int)edges.size() - oldSize)) {
218  newRoute->addReference();
219 #ifdef HAVE_FOX
220  MSDevice_Routing::lock();
221 #endif
222  newRoute->release();
223 #ifdef HAVE_FOX
224  MSDevice_Routing::unlock();
225 #endif
226  return false;
227  }
229  return true;
230 }
231 
232 
233 SUMOReal
235  return 0;
236 }
237 
238 
239 SUMOReal
241  return 0;
242 }
243 
244 
245 void
249 }
250 
251 
252 bool
254  return myDeparture != NOT_YET_DEPARTED;
255 }
256 
257 
258 bool
260  return succEdge(1) == 0;
261 }
262 
263 void
265 }
266 
267 void
269 }
270 
271 bool
272 MSBaseVehicle::hasValidRoute(std::string& msg) const {
273  MSRouteIterator last = myRoute->end() - 1;
274  // check connectivity, first
275  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
276  if ((*e)->allowedLanes(**(e + 1), myType->getVehicleClass()) == 0) {
277  msg = "No connection between edge '" + (*e)->getID() + "' and edge '" + (*(e + 1))->getID() + "'.";
278  return false;
279  }
280  }
281  last = myRoute->end();
282  // check usable lanes, then
283  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
284  if ((*e)->prohibits(this)) {
285  msg = "Edge '" + (*e)->getID() + "' prohibits.";
286  return false;
287  }
288  }
289  return true;
290 }
291 
292 
293 void
295 #ifdef _DEBUG
296  if (myTraceMoveReminders) {
297  traceMoveReminder("add", rem, 0, true);
298  }
299 #endif
300  myMoveReminders.push_back(std::make_pair(rem, 0.));
301 }
302 
303 
304 void
306  for (MoveReminderCont::iterator r = myMoveReminders.begin(); r != myMoveReminders.end(); ++r) {
307  if (r->first == rem) {
308 #ifdef _DEBUG
309  if (myTraceMoveReminders) {
310  traceMoveReminder("remove", rem, 0, false);
311  }
312 #endif
313  myMoveReminders.erase(r);
314  return;
315  }
316  }
317 }
318 
319 
320 void
322  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
323  if (rem->first->notifyEnter(*this, reason)) {
324 #ifdef _DEBUG
325  if (myTraceMoveReminders) {
326  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
327  }
328 #endif
329  ++rem;
330  } else {
331 #ifdef _DEBUG
332  if (myTraceMoveReminders) {
333  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
334  }
335 #endif
336  rem = myMoveReminders.erase(rem);
337  }
338  }
339 }
340 
341 
342 void
344  const std::vector<MSLane*>& lanes = myRoute->getLastEdge()->getLanes();
345  const SUMOReal lastLaneLength = lanes[0]->getLength();
346  switch (myParameter->arrivalPosProcedure) {
347  case ARRIVAL_POS_GIVEN:
348  if (fabs(myParameter->arrivalPos) > lastLaneLength) {
349  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given position!");
350  }
351  // Maybe we should warn the user about invalid inputs!
352  myArrivalPos = MIN2(myParameter->arrivalPos, lastLaneLength);
353  if (myArrivalPos < 0) {
354  myArrivalPos = MAX2(myArrivalPos + lastLaneLength, static_cast<SUMOReal>(0));
355  }
356  break;
357  case ARRIVAL_POS_RANDOM:
358  myArrivalPos = RandHelper::rand(static_cast<SUMOReal>(0), lastLaneLength);
359  break;
360  default:
361  myArrivalPos = lastLaneLength;
362  break;
363  }
365  if (myParameter->arrivalLane >= (int)lanes.size() || !lanes[myParameter->arrivalLane]->allowsVehicleClass(myType->getVehicleClass())) {
366  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given lane '" + myRoute->getLastEdge()->getID() + "_" + toString(myParameter->arrivalLane) + "'!");
367  }
368  myArrivalLane = MIN2(myParameter->arrivalLane, (int)(lanes.size() - 1));
369  }
371  for (std::vector<MSLane*>::const_iterator l = lanes.begin(); l != lanes.end(); ++l) {
372  if (myParameter->arrivalSpeed <= (*l)->getVehicleMaxSpeed(this)) {
373  return;
374  }
375  }
376  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive with the given speed!");
377  }
378 }
379 
380 
381 SUMOReal
385 }
386 
387 
388 MSDevice*
389 MSBaseVehicle::getDevice(const std::type_info& type) const {
390  for (std::vector<MSDevice*>::const_iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
391  if (typeid(**dev) == type) {
392  return *dev;
393  }
394  }
395  return 0;
396 }
397 
398 
399 void
405  // here starts the vehicle internal part (see loading)
406  // @note: remember to close the vehicle tag when calling this in a subclass!
407 }
408 
409 
410 void
411 MSBaseVehicle::addStops(const bool ignoreStopErrors) {
412  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = myParameter->stops.begin(); i != myParameter->stops.end(); ++i) {
413  std::string errorMsg;
414  if (!addStop(*i, errorMsg) && !ignoreStopErrors) {
415  throw ProcessError(errorMsg);
416  }
417  if (errorMsg != "") {
418  WRITE_WARNING(errorMsg);
419  }
420  }
421  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = myRoute->getStops().begin(); i != myRoute->getStops().end(); ++i) {
422  std::string errorMsg;
423  if (!addStop(*i, errorMsg) && !ignoreStopErrors) {
424  throw ProcessError(errorMsg);
425  }
426  if (errorMsg != "") {
427  WRITE_WARNING(errorMsg);
428  }
429  }
430 }
431 
432 
433 #ifdef _DEBUG
434 void
435 MSBaseVehicle::initMoveReminderOutput(const OptionsCont& oc) {
436  if (oc.isSet("movereminder-output.vehicles")) {
437  const std::vector<std::string> vehicles = oc.getStringVector("movereminder-output.vehicles");
438  myShallTraceMoveReminders.insert(vehicles.begin(), vehicles.end());
439  }
440 }
441 
442 
443 void
444 MSBaseVehicle::traceMoveReminder(const std::string& type, MSMoveReminder* rem, SUMOReal pos, bool keep) const {
445  OutputDevice& od = OutputDevice::getDeviceByOption("movereminder-output");
446  od.openTag("movereminder");
447  od.writeAttr(SUMO_ATTR_TIME, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()));
448  od.writeAttr("veh", getID());
450  od.writeAttr("type", type);
451  od.writeAttr("pos", toString(pos));
452  od.writeAttr("keep", toString(keep));
453  od.closeTag();
454 }
455 #endif
456 
457 /****************************************************************************/
458 
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&#39;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&#39;s maximum speed [m/s].
long long int SUMOTime
Definition: SUMOTime.h:43
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&#39;s vehicle class.
const std::string & getDescription() const
SUMOReal myArrivalPos
the position on the destination lane where the vehicle stops
MoveReminderCont myMoveReminders
Current lane&#39;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&#39;s lanes.
Definition: MSEdge.h:186
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
The speed is given.
SUMOReal getImpatience() const
Returns this vehicles impatience.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:93
SUMOReal arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
Notification
Definition of a vehicle state.
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:61
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:162
T MAX2(T a, T b)
Definition: StdDefs.h:79
virtual ~MSBaseVehicle()
Destructor.
const MSRoute * myRoute
This Vehicle&#39;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&#39;t already in the dictionary...
Definition: MSEdge.cpp:579
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:79
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
int myArrivalLane
the position on the destination lane where the vehicle stops
const SUMOVehicleParameter * myParameter
This Vehicle&#39;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:255
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:75
#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&#39;s destination zone (district)
std::vector< Stop > stops
List of the stops the vehicle will make.
void calculateArrivalParams()
(Re-)Calculates the arrival position and lane from the vehicle parameters
const std::string & getID() const
Returns the id.
Definition: Named.h:65
A road/street connecting two junctions.
Definition: MSEdge.h:81
virtual void addPerson(MSTransportable *person)
Adds a person to this vehicle.
The edge is a district edge.
Definition: MSEdge.h:100
std::string routeid
The vehicle&#39;s route id.
virtual SUMOReal getAcceleration() const
Returns the vehicle&#39;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:308
const MSEdge * succEdge(unsigned int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:61
int arrivalLane
(optional) The lane the vehicle shall arrive on (not used yet)
SUMOTime depart
The vehicle&#39;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:73
std::string fromTaz
The vehicle&#39;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&#39;s type definition.
Definition: MSBaseVehicle.h:93
virtual bool hasArrived() const
Returns whether this vehicle has already arived (by default this is true if the vehicle has reached i...
virtual const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
The arrival lane is given.
const std::string & getID() const
Returns the name of the vehicle type.
static SUMOTime gTimeToGridlock
Definition: MSGlobals.h:65
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
virtual SUMOTime getWaitingTime() const =0
unsigned size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:87
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:214
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&#39;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&#39;s position.
void addReminder(MSMoveReminder *rem)
Adds a MoveReminder dynamically.
std::vector< MSDevice * > myDevices
The devices this vehicle has.
virtual void addContainer(MSTransportable *container)
Adds a container to this vehicle.
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&#39;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.