SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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.dlr.de/
12 // Copyright (C) 2001-2016 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"
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 #ifdef _DEBUG
57 std::set<std::string> MSBaseVehicle::myShallTraceMoveReminders;
58 #endif
59 
60 // ===========================================================================
61 // method definitions
62 // ===========================================================================
64  const MSVehicleType* type, const SUMOReal speedFactor) :
65  myParameter(pars),
66  myRoute(route),
67  myType(type),
68  myCurrEdge(route->begin()),
69  myChosenSpeedFactor(speedFactor),
70  myMoveReminders(0),
71  myDeparture(NOT_YET_DEPARTED),
72  myDepartPos(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  if (!MSRoute::dictionary(id, newRoute)) {
205  delete newRoute;
206  return false;
207  }
208  if (!replaceRoute(newRoute, onInit, (int)edges.size() - oldSize)) {
209  newRoute->addReference();
210  newRoute->release();
211  return false;
212  }
214  return true;
215 }
216 
217 
218 SUMOReal
220  return 0;
221 }
222 
223 
224 SUMOReal
226  return 0;
227 }
228 
229 
230 void
235 }
236 
237 
238 bool
240  return myDeparture != NOT_YET_DEPARTED;
241 }
242 
243 
244 bool
246  return succEdge(1) == 0;
247 }
248 
249 void
251 }
252 
253 void
255 }
256 
257 bool
258 MSBaseVehicle::hasValidRoute(std::string& msg) const {
259  MSRouteIterator last = myRoute->end() - 1;
260  // check connectivity, first
261  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
262  if ((*e)->allowedLanes(**(e + 1), myType->getVehicleClass()) == 0) {
263  msg = "No connection between edge '" + (*e)->getID() + "' and edge '" + (*(e + 1))->getID() + "'.";
264  return false;
265  }
266  }
267  last = myRoute->end();
268  // check usable lanes, then
269  for (MSRouteIterator e = myCurrEdge; e != last; ++e) {
270  if ((*e)->prohibits(this)) {
271  msg = "Edge '" + (*e)->getID() + "' prohibits.";
272  return false;
273  }
274  }
275  return true;
276 }
277 
278 
279 void
281 #ifdef _DEBUG
282  if (myTraceMoveReminders) {
283  traceMoveReminder("add", rem, 0, true);
284  }
285 #endif
286  myMoveReminders.push_back(std::make_pair(rem, 0.));
287 }
288 
289 
290 void
292  for (MoveReminderCont::iterator r = myMoveReminders.begin(); r != myMoveReminders.end(); ++r) {
293  if (r->first == rem) {
294 #ifdef _DEBUG
295  if (myTraceMoveReminders) {
296  traceMoveReminder("remove", rem, 0, false);
297  }
298 #endif
299  myMoveReminders.erase(r);
300  return;
301  }
302  }
303 }
304 
305 
306 void
308  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
309  if (rem->first->notifyEnter(*this, reason)) {
310 #ifdef _DEBUG
311  if (myTraceMoveReminders) {
312  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
313  }
314 #endif
315  ++rem;
316  } else {
317 #ifdef _DEBUG
318  if (myTraceMoveReminders) {
319  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
320  }
321 #endif
322  rem = myMoveReminders.erase(rem);
323  }
324  }
325 }
326 
327 
328 void
330  const std::vector<MSLane*>& lanes = myRoute->getLastEdge()->getLanes();
331  const SUMOReal lastLaneLength = lanes[0]->getLength();
332  switch (myParameter->arrivalPosProcedure) {
333  case ARRIVAL_POS_GIVEN:
334  if (fabs(myParameter->arrivalPos) > lastLaneLength) {
335  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given position!");
336  }
337  // Maybe we should warn the user about invalid inputs!
338  myArrivalPos = MIN2(myParameter->arrivalPos, lastLaneLength);
339  if (myArrivalPos < 0) {
340  myArrivalPos = MAX2(myArrivalPos + lastLaneLength, static_cast<SUMOReal>(0));
341  }
342  break;
343  case ARRIVAL_POS_RANDOM:
344  myArrivalPos = RandHelper::rand(static_cast<SUMOReal>(0), lastLaneLength);
345  break;
346  default:
347  myArrivalPos = lastLaneLength;
348  break;
349  }
351  if (myParameter->arrivalLane >= (int)lanes.size() || !lanes[myParameter->arrivalLane]->allowsVehicleClass(myType->getVehicleClass())) {
352  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given lane '" + myRoute->getLastEdge()->getID() + "_" + toString(myParameter->arrivalLane) + "'!");
353  }
354  myArrivalLane = MIN2(myParameter->arrivalLane, (int)(lanes.size() - 1));
355  }
357  for (std::vector<MSLane*>::const_iterator l = lanes.begin(); l != lanes.end(); ++l) {
358  if (myParameter->arrivalSpeed <= (*l)->getVehicleMaxSpeed(this)) {
359  return;
360  }
361  }
362  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive with the given speed!");
363  }
364 }
365 
366 
367 SUMOReal
371 // Alternavite to avoid time to teleport effect on the simulation. No effect if time to teleport is -1
372 // return MAX2((SUMOReal)0, MIN2((SUMOReal)1, getVehicleType().getImpatience()));
373 }
374 
375 
376 MSDevice*
377 MSBaseVehicle::getDevice(const std::type_info& type) const {
378  for (std::vector<MSDevice*>::const_iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
379  if (typeid(**dev) == type) {
380  return *dev;
381  }
382  }
383  return 0;
384 }
385 
386 
387 void
393  // here starts the vehicle internal part (see loading)
394  // @note: remember to close the vehicle tag when calling this in a subclass!
395 }
396 
397 
398 void
399 MSBaseVehicle::addStops(const bool ignoreStopErrors) {
400  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = myParameter->stops.begin(); i != myParameter->stops.end(); ++i) {
401  std::string errorMsg;
402  if (!addStop(*i, errorMsg) && !ignoreStopErrors) {
403  throw ProcessError(errorMsg);
404  }
405  if (errorMsg != "") {
406  WRITE_WARNING(errorMsg);
407  }
408  }
409  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = myRoute->getStops().begin(); i != myRoute->getStops().end(); ++i) {
410  std::string errorMsg;
411  if (!addStop(*i, errorMsg) && !ignoreStopErrors) {
412  throw ProcessError(errorMsg);
413  }
414  if (errorMsg != "") {
415  WRITE_WARNING(errorMsg);
416  }
417  }
418 }
419 
420 
421 #ifdef _DEBUG
422 void
423 MSBaseVehicle::initMoveReminderOutput(const OptionsCont& oc) {
424  if (oc.isSet("movereminder-output.vehicles")) {
425  const std::vector<std::string> vehicles = oc.getStringVector("movereminder-output.vehicles");
426  myShallTraceMoveReminders.insert(vehicles.begin(), vehicles.end());
427  }
428 }
429 
430 
431 void
432 MSBaseVehicle::traceMoveReminder(const std::string& type, MSMoveReminder* rem, SUMOReal pos, bool keep) const {
433  OutputDevice& od = OutputDevice::getDeviceByOption("movereminder-output");
434  od.openTag("movereminder");
435  od.writeAttr(SUMO_ATTR_TIME, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()));
436  od.writeAttr("veh", getID());
438  od.writeAttr("type", type);
439  od.writeAttr("pos", toString(pos));
440  od.writeAttr("keep", toString(keep));
441  od.closeTag();
442 }
443 #endif
444 
445 /****************************************************************************/
446 
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:185
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:96
virtual SUMOReal getPositionOnLane() const =0
Get the vehicle's position along the lane.
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:59
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:160
T MAX2(T a, T b)
Definition: StdDefs.h:75
virtual bool 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...
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:578
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
int myArrivalLane
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:358
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: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.
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:80
virtual void addPerson(MSTransportable *person)
Adds a person to this vehicle.
The edge is a district edge.
Definition: MSEdge.h:99
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:65
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:128
T MIN2(T a, T b)
Definition: StdDefs.h:69
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:54
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:103
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:84
#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:63
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:90
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:349
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:214
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:109
virtual SUMOReal getSlope() const
Returns the slope of the road at vehicle's position.
SUMOReal myDepartPos
The real depart 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:194
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:78
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:122
The arrival position is chosen randomly.