SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MSDevice_Vehroutes.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // A device which collects info on the vehicle trip
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2009-2016 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
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 <microsim/MSGlobals.h>
34 #include <microsim/MSNet.h>
35 #include <microsim/MSLane.h>
36 #include <microsim/MSEdge.h>
37 #include <microsim/MSRoute.h>
38 #include <microsim/MSVehicleType.h>
42 #include "MSDevice_Vehroutes.h"
43 
44 #ifdef CHECK_MEMORY_LEAKS
45 #include <foreign/nvwa/debug_new.h>
46 #endif // CHECK_MEMORY_LEAKS
47 
48 
49 // ===========================================================================
50 // static member variables
51 // ===========================================================================
55 bool MSDevice_Vehroutes::mySorted = false;
59 std::map<const SUMOTime, int> MSDevice_Vehroutes::myDepartureCounts;
60 std::map<const SUMOTime, std::map<const std::string, std::string> > MSDevice_Vehroutes::myRouteInfos;
61 
62 
63 // ===========================================================================
64 // method definitions
65 // ===========================================================================
66 // ---------------------------------------------------------------------------
67 // static initialisation methods
68 // ---------------------------------------------------------------------------
69 void
71  if (OptionsCont::getOptions().isSet("vehroute-output")) {
72  OutputDevice::createDeviceByOption("vehroute-output", "routes", "routes_file.xsd");
73  mySaveExits = OptionsCont::getOptions().getBool("vehroute-output.exit-times");
74  myLastRouteOnly = OptionsCont::getOptions().getBool("vehroute-output.last-route");
75  myDUAStyle = OptionsCont::getOptions().getBool("vehroute-output.dua");
76  mySorted = myDUAStyle || OptionsCont::getOptions().getBool("vehroute-output.sorted");
77  myIntendedDepart = OptionsCont::getOptions().getBool("vehroute-output.intended-depart");
78  myRouteLength = OptionsCont::getOptions().getBool("vehroute-output.route-length");
80  }
81 }
82 
83 
85 MSDevice_Vehroutes::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*>& into, int maxRoutes) {
86  if (maxRoutes < INT_MAX) {
87  return new MSDevice_Vehroutes(v, "vehroute_" + v.getID(), maxRoutes);
88  }
89  if (OptionsCont::getOptions().isSet("vehroute-output")) {
90  if (myLastRouteOnly) {
91  maxRoutes = 0;
92  }
93  myStateListener.myDevices[&v] = new MSDevice_Vehroutes(v, "vehroute_" + v.getID(), maxRoutes);
94  into.push_back(myStateListener.myDevices[&v]);
95  return myStateListener.myDevices[&v];
96  }
97  return 0;
98 }
99 
100 
101 // ---------------------------------------------------------------------------
102 // MSDevice_Vehroutes::StateListener-methods
103 // ---------------------------------------------------------------------------
104 void
106  if (to == MSNet::VEHICLE_STATE_NEWROUTE) {
107  myDevices[vehicle]->addRoute();
108  }
109 }
110 
111 
112 // ---------------------------------------------------------------------------
113 // MSDevice_Vehroutes-methods
114 // ---------------------------------------------------------------------------
115 MSDevice_Vehroutes::MSDevice_Vehroutes(SUMOVehicle& holder, const std::string& id, int maxRoutes)
116  : MSDevice(holder, id), myCurrentRoute(&holder.getRoute()), myMaxRoutes(maxRoutes), myLastSavedAt(0) {
118 }
119 
120 
122  for (std::vector<RouteReplaceInfo>::iterator i = myReplacedRoutes.begin(); i != myReplacedRoutes.end(); ++i) {
123  (*i).route->release();
124  }
127 }
128 
129 
130 bool
133  if (mySorted && myStateListener.myDevices[&veh] == this) {
135  myDepartureCounts[departure]++;
136  }
137  }
138  return mySaveExits;
139 }
140 
141 
142 bool
144  if (mySaveExits && reason != NOTIFICATION_LANE_CHANGE) {
145  if (reason != NOTIFICATION_TELEPORT && myLastSavedAt == veh.getEdge()) { // need to check this for internal lanes
147  } else if (myLastSavedAt != veh.getEdge()) {
148  myExits.push_back(MSNet::getInstance()->getCurrentTimeStep());
149  myLastSavedAt = veh.getEdge();
150  }
151  }
152  return mySaveExits;
153 }
154 
155 
156 void
158  if (index == 0 && myReplacedRoutes[index].route->size() == 2 &&
159  myReplacedRoutes[index].route->getEdges().front()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT &&
160  myReplacedRoutes[index].route->getEdges().back()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) {
161  return;
162  }
163  // check if a previous route shall be written
165  if (index >= 0) {
166  assert((int)myReplacedRoutes.size() > index);
167  // write edge on which the vehicle was when the route was valid
168  os << " replacedOnEdge=\"";
169  if (myReplacedRoutes[index].edge) {
170  os << myReplacedRoutes[index].edge->getID();
171  }
172  // write the time at which the route was replaced
173  os << "\" replacedAtTime=\"" << time2string(myReplacedRoutes[index].time) << "\" probability=\"0\" edges=\"";
174  // get the route
175  int i = index;
176  while (i > 0 && myReplacedRoutes[i - 1].edge) {
177  i--;
178  }
179  const MSEdge* lastEdge = 0;
180  for (; i < index; ++i) {
181  myReplacedRoutes[i].route->writeEdgeIDs(os, lastEdge, myReplacedRoutes[i].edge);
182  lastEdge = myReplacedRoutes[i].edge;
183  }
184  myReplacedRoutes[index].route->writeEdgeIDs(os, lastEdge);
185  } else {
186  os << " edges=\"";
187  const MSEdge* lastEdge = 0;
188  int numWritten = 0;
189  if (myHolder.getNumberReroutes() > 0) {
190  assert((int)myReplacedRoutes.size() <= myHolder.getNumberReroutes());
191  int i = (int)myReplacedRoutes.size();
192  while (i > 0 && myReplacedRoutes[i - 1].edge) {
193  i--;
194  }
195  for (; i < (int)myReplacedRoutes.size(); ++i) {
196  numWritten += myReplacedRoutes[i].route->writeEdgeIDs(os, lastEdge, myReplacedRoutes[i].edge);
197  lastEdge = myReplacedRoutes[i].edge;
198  }
199  }
200  const MSEdge* upTo = 0;
201  if (mySaveExits) {
202  int remainingWithExitTime = (int)myExits.size() - numWritten;
203  assert(remainingWithExitTime >= 0);
204  assert(remainingWithExitTime <= (int)myCurrentRoute->size());
205  if (remainingWithExitTime < (int)myCurrentRoute->size()) {
206  upTo = *(myCurrentRoute->begin() + remainingWithExitTime);
207  }
208  }
209  myCurrentRoute->writeEdgeIDs(os, lastEdge, upTo);
210  if (mySaveExits) {
211  os << "\" exitTimes=\"";
212  for (std::vector<SUMOTime>::const_iterator it = myExits.begin(); it != myExits.end(); ++it) {
213  if (it != myExits.begin()) {
214  os << " ";
215  }
216  os << time2string(*it);
217  }
218  }
219  }
220  (os << "\"").closeTag();
221 }
222 
223 
224 void
226  OutputDevice& routeOut = OutputDevice::getDeviceByOption("vehroute-output");
227  OutputDevice_String od(routeOut.isBinary(), 1);
229  od.openTag(SUMO_TAG_VEHICLE).writeAttr(SUMO_ATTR_ID, myHolder.getID());
231  od.writeAttr(SUMO_ATTR_TYPE, myHolder.getVehicleType().getID());
232  }
233  od.writeAttr(SUMO_ATTR_DEPART, time2string(departure));
234  if (myHolder.hasArrived()) {
235  od.writeAttr("arrival", time2string(MSNet::getInstance()->getCurrentTimeStep()));
236  if (myRouteLength) {
237  const bool includeInternalLengths = MSGlobals::gUsingInternalLanes && MSNet::getInstance()->hasInternalLinks();
239  myHolder.getRoute().begin(), myHolder.getCurrentRouteEdge(), includeInternalLengths);
240  od.writeAttr("routeLength", routeLength);
241  }
242  }
245  }
247  od.writeAttr(SUMO_ATTR_TO_TAZ, myHolder.getParameter().toTaz);
248  }
249  if (myDUAStyle) {
251  if (routeDist != 0) {
252  const std::vector<const MSRoute*>& routes = routeDist->getVals();
253  unsigned index = 0;
254  while (index < routes.size() && routes[index] != myCurrentRoute) {
255  ++index;
256  }
257  od.openTag(SUMO_TAG_ROUTE_DISTRIBUTION).writeAttr(SUMO_ATTR_LAST, index);
258  const std::vector<SUMOReal>& probs = routeDist->getProbs();
259  for (int i = 0; i < (int)routes.size(); ++i) {
260  od.setPrecision();
261  od.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_COST, routes[i]->getCosts());
262  od.setPrecision(8);
263  od.writeAttr(SUMO_ATTR_PROB, probs[i]);
264  od.setPrecision();
265  od << " edges=\"";
266  routes[i]->writeEdgeIDs(od, *routes[i]->begin());
267  (od << "\"").closeTag();
268  }
269  od.closeTag();
270  } else {
271  writeXMLRoute(od);
272  }
273  } else {
274  if (myReplacedRoutes.size() > 0) {
275  od.openTag(SUMO_TAG_ROUTE_DISTRIBUTION);
276  for (int i = 0; i < (int)myReplacedRoutes.size(); ++i) {
277  writeXMLRoute(od, i);
278  }
279  }
280  writeXMLRoute(od);
281  if (myReplacedRoutes.size() > 0) {
282  od.closeTag();
283  }
284  }
285  for (std::map<std::string, std::string>::const_iterator j = myHolder.getParameter().getMap().begin(); j != myHolder.getParameter().getMap().end(); ++j) {
286  od.openTag(SUMO_TAG_PARAM);
287  od.writeAttr(SUMO_ATTR_KEY, (*j).first);
288  od.writeAttr(SUMO_ATTR_VALUE, (*j).second);
289  od.closeTag();
290  }
291  od.closeTag();
292  od.lf();
293  if (mySorted) {
294  myRouteInfos[departure][myHolder.getID()] = od.getString();
295  myDepartureCounts[departure]--;
296  std::map<const SUMOTime, int>::iterator it = myDepartureCounts.begin();
297  while (it != myDepartureCounts.end() && it->second == 0) {
298  std::map<const std::string, std::string>& infos = myRouteInfos[it->first];
299  for (std::map<const std::string, std::string>::const_iterator it2 = infos.begin(); it2 != infos.end(); ++it2) {
300  routeOut << it2->second;
301  }
302  myRouteInfos.erase(it->first);
303  myDepartureCounts.erase(it);
304  it = myDepartureCounts.begin();
305  }
306  } else {
307  routeOut << od.getString();
308  }
309 }
310 
311 
312 const MSRoute*
314  if (index < (int)myReplacedRoutes.size()) {
315  return myReplacedRoutes[index].route;
316  } else {
317  return 0;
318  }
319 }
320 
321 
322 void
324  if (myMaxRoutes > 0) {
325  if (myHolder.hasDeparted()) {
327  } else {
328  myReplacedRoutes.push_back(RouteReplaceInfo(0, MSNet::getInstance()->getCurrentTimeStep(), myCurrentRoute));
329  }
330  if ((int)myReplacedRoutes.size() > myMaxRoutes) {
331  myReplacedRoutes.front().route->release();
332  myReplacedRoutes.erase(myReplacedRoutes.begin());
333  }
334  } else {
336  }
339 }
340 
341 
342 void
344  for (std::map<const SUMOVehicle*, MSDevice_Vehroutes*, Named::NamedLikeComparatorIdLess<SUMOVehicle> >::const_iterator it = myStateListener.myDevices.begin();
345  it != myStateListener.myDevices.end(); ++it) {
346  if (it->first->hasDeparted()) {
347  it->second->generateOutput();
348  }
349  }
350 }
351 
352 
353 /****************************************************************************/
354 
const int VEHPARS_TO_TAZ_SET
static std::map< const SUMOTime, int > myDepartureCounts
Map needed to sort vehicles by departure time.
const int myMaxRoutes
The maximum number of routes to report.
long long int SUMOTime
Definition: SUMOTime.h:43
virtual bool hasDeparted() const =0
Returns whether this vehicle has departed.
const MSRoute * myCurrentRoute
The currently used route.
const std::vector< SUMOReal > & getProbs() const
Returns the probabilities assigned to the members of the distribution.
static StateListener myStateListener
A class that is notified about reroutings.
Function-object for stable sorting of objects acting like Named without being derived (SUMOVehicle) ...
Definition: Named.h:90
virtual const MSRoute & getRoute() const =0
Returns the current route.
int writeEdgeIDs(OutputDevice &os, const MSEdge *const from, const MSEdge *const upTo=0) const
Output the edge ids up to but not including the id of the given edge.
Definition: MSRoute.cpp:226
void vehicleStateChanged(const SUMOVehicle *const vehicle, MSNet::VehicleState to)
Called if a vehicle changes its state.
SUMOVehicle & myHolder
The vehicle that stores the device.
Definition: MSDevice.h:158
static bool myDUAStyle
A shortcut for the Option "vehroute-output.dua".
virtual SUMOReal getDepartPos() const =0
Returns this vehicle's real departure position.
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:639
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
std::vector< SUMOTime > myExits
The times the vehicle exites an edge.
static bool mySorted
A shortcut for the Option "vehroute-output.sorted".
const std::map< std::string, std::string > & getMap() const
Returns the inner key/value map.
static RandomDistributor< const MSRoute * > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition: MSRoute.cpp:165
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:254
const std::string DEFAULT_VTYPE_ID
static bool mySaveExits
A shortcut for the Option "vehroute-output.exit-times".
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
Definition: MSNet.cpp:756
bool notifyLeave(SUMOVehicle &veh, SUMOReal lastPos, Notification reason)
Saves exit times if needed.
static bool myIntendedDepart
A shortcut for the Option "vehroute-output.intended-depart".
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
std::string toTaz
The vehicle's destination zone (district)
const std::vector< T > & getVals() const
Returns the members of the distribution.
std::map< const SUMOVehicle *, MSDevice_Vehroutes *, SUMOVehicle::ComparatorIdLess > myDevices
A map for internal notification.
static void init()
Static intialization.
A road/street connecting two junctions.
Definition: MSEdge.h:80
The vehicle changes lanes (micro only) XXX: What if a vehicle changes lanes and passes a junction sim...
static bool myLastRouteOnly
A shortcut for the Option "vehroute-output.last-route".
The edge is a district edge.
Definition: MSEdge.h:99
The vehicle got a new route.
Definition: MSNet.h:549
void addRoute()
Called on route change.
Representation of a vehicle.
Definition: SUMOVehicle.h:66
bool wasSet(int what) const
Returns whether the given parameter was set.
SUMOReal getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:285
virtual int getNumberReroutes() const =0
Returns the number of new routes this vehicle got.
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:90
std::vector< RouteReplaceInfo > myReplacedRoutes
Prior routes.
SUMOTime depart
The vehicle's departure time.
std::string fromTaz
The vehicle's origin zone (district)
A class that is notified about reroutings.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:73
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:103
static void generateOutputForUnfinished()
generate vehroute output for vehicles which are still in the network
const int VEHPARS_FROM_TAZ_SET
static MSDevice_Vehroutes * buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into, int maxRoutes=INT_MAX)
Build devices for the given vehicle, if needed.
static bool myRouteLength
A shortcut for the Option "vehroute-output.route-length".
VehicleState
Definition of a vehicle state.
Definition: MSNet.h:537
Abstract in-vehicle device.
Definition: MSDevice.h:69
The vehicle has departed (was inserted into the network)
virtual SUMOTime getDeparture() const =0
Returns this vehicle's real departure time.
virtual bool hasArrived() const =0
Returns whether this vehicle has arrived.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
MSDevice_Vehroutes(SUMOVehicle &holder, const std::string &id, int maxRoutes)
Constructor.
const std::string & getID() const
Returns the name of the vehicle type.
void writeXMLRoute(OutputDevice &os, int index=-1) const
Called on route output.
A device which collects info on the vehicle trip (mainly on departure and arrival) ...
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="")
Creates the device using the output definition stored in the named option.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
#define SUMOReal
Definition: config.h:214
static std::map< const SUMOTime, std::map< const std::string, std::string > > myRouteInfos
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:109
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
virtual SUMOReal getArrivalPos() const =0
Returns this vehicle's desired arrivalPos for its current route (may change on reroute) ...
void generateOutput() const
Called on writing tripinfo output.
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason)
Does nothing, returns true only if exit times should be collected.
virtual const std::string & getID() const =0
Get the vehicle's ID.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
An output device that encapsulates an ofstream.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:78
The vehicle is being teleported.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
const MSRoute * getRoute(int index) const
Called on route retrieval.
const MSEdge * myLastSavedAt
The last edge the exit time was saved for.
bool isBinary() const
Returns whether we have a binary output.
Definition: OutputDevice.h:245
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.
~MSDevice_Vehroutes()
Destructor.
Information about a replaced route.