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'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].
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'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
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'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:579
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:79
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
int myArrivalLane
the position on the destination lane where the vehicle stops
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: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'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'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:308
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
int arrivalLane
(optional) The lane the vehicle shall arrive on (not used yet)
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:73
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: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'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:215
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.
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'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.