SUMO - Simulation of Urban MObility
MSDevice_Tripinfo.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2009-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
20 // A device which collects info on the vehicle trip
21 /****************************************************************************/
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <microsim/MSGlobals.h>
33 #include <microsim/MSNet.h>
34 #include <microsim/MSLane.h>
35 #include <microsim/MSEdge.h>
36 #include <microsim/MSVehicle.h>
40 #include "MSDevice_Tripinfo.h"
41 
42 #define NOT_ARRIVED TIME2STEPS(-1)
43 
44 
45 // ===========================================================================
46 // static members
47 // ===========================================================================
49 
56 
61 
70 
71 // ===========================================================================
72 // method definitions
73 // ===========================================================================
74 // ---------------------------------------------------------------------------
75 // static initialisation methods
76 // ---------------------------------------------------------------------------
77 void
78 MSDevice_Tripinfo::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*>& into) {
79  if (OptionsCont::getOptions().isSet("tripinfo-output") || OptionsCont::getOptions().getBool("duration-log.statistics")) {
80  MSDevice_Tripinfo* device = new MSDevice_Tripinfo(v, "tripinfo_" + v.getID());
81  into.push_back(device);
82  myPendingOutput.insert(device);
83  }
84 }
85 
86 
87 // ---------------------------------------------------------------------------
88 // MSDevice_Tripinfo-methods
89 // ---------------------------------------------------------------------------
90 MSDevice_Tripinfo::MSDevice_Tripinfo(SUMOVehicle& holder, const std::string& id) :
91  MSDevice(holder, id),
92  myDepartLane(""),
93  myDepartSpeed(-1),
94  myDepartPosLat(0),
95  myWaitingTime(0),
97  myArrivalLane(""),
98  myArrivalPos(-1),
99  myArrivalPosLat(0),
100  myArrivalSpeed(-1),
101  myMesoTimeLoss(0) {
102 }
103 
104 
106  // ensure clean up for vaporized vehicles which do not generate output
107  myPendingOutput.erase(this);
108 }
109 
110 void
112  myVehicleCount = 0;
113  myTotalRouteLength = 0;
114  myTotalDuration = 0;
115  myTotalWaitingTime = 0;
116  myTotalTimeLoss = 0;
117  myTotalDepartDelay = 0;
118 
119  myWalkCount = 0;
123 
124  myRideCount = 0;
125  myRideBusCount = 0;
126  myRideRailCount = 0;
127  myRideBikeCount = 0;
128  myRideAbortCount = 0;
132 }
133 
134 bool
136  double /*newPos*/, double newSpeed) {
137  if (veh.isStopped()) {
138  return true;
139  }
140  if (newSpeed <= SUMO_const_haltingSpeed) {
142  }
143  return true;
144 }
145 
146 void
148  const double /* frontOnLane */,
149  const double timeOnLane,
150  const double /* meanSpeedFrontOnLane */,
151  const double meanSpeedVehicleOnLane,
152  const double /* travelledDistanceFrontOnLane */,
153  const double /* travelledDistanceVehicleOnLane */,
154  const double /* meanLengthOnLane */) {
155 
156  // called by meso
157  const double vmax = veh.getEdge()->getVehicleMaxSpeed(&veh);
158  if (vmax > 0) {
159  myMesoTimeLoss += TIME2STEPS(timeOnLane * (vmax - meanSpeedVehicleOnLane) / vmax);
160  }
161  myWaitingTime += veh.getWaitingTime();
162 }
163 
164 bool
167  if (!MSGlobals::gUseMesoSim) {
168  myDepartLane = static_cast<MSVehicle&>(veh).getLane()->getID();
169  myDepartPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
170  }
171  myDepartSpeed = veh.getSpeed();
172  }
173  return true;
174 }
175 
176 
177 bool
179  MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
180  if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
182  if (!MSGlobals::gUseMesoSim) {
183  myArrivalLane = static_cast<MSVehicle&>(veh).getLane()->getID();
184  myArrivalPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
185  }
186  // @note vehicle may have moved past its arrivalPos during the last step
187  // due to non-zero arrivalspeed but we consider it as arrived at the desired position
188  // However, vaporization may happen anywhere (via TraCI)
191  } else {
193  }
194  myArrivalSpeed = veh.getSpeed();
195  }
196  return true;
197 }
198 
199 void
200 MSDevice_Tripinfo::computeLengthAndDuration(double& routeLength, SUMOTime& duration) const {
201  SUMOTime finalTime;
202  double finalPos;
203  double finalPosOnInternal = 0;
204  if (myArrivalTime == NOT_ARRIVED) {
205  finalTime = MSNet::getInstance()->getCurrentTimeStep();
206  finalPos = myHolder.getPositionOnLane();
207  if (!MSGlobals::gUseMesoSim) {
208  const MSLane* lane = static_cast<MSVehicle&>(myHolder).getLane();
209  if (lane->getEdge().isInternal()) {
210  finalPosOnInternal = finalPos;
211  finalPos = myHolder.getEdge()->getLength();
212  }
213  }
214  } else {
215  finalTime = myArrivalTime;
216  finalPos = myArrivalPos;
217  }
218  const bool includeInternalLengths = MSGlobals::gUsingInternalLanes && MSNet::getInstance()->hasInternalLinks();
219  routeLength = myHolder.getRoute().getDistanceBetween(myHolder.getDepartPos(), finalPos,
220  myHolder.getRoute().begin(), myHolder.getCurrentRouteEdge(), includeInternalLengths) + finalPosOnInternal;
221 
222  duration = finalTime - myHolder.getDeparture();
223 }
224 
225 
226 void
228  const SUMOTime timeLoss = MSGlobals::gUseMesoSim ? myMesoTimeLoss : static_cast<MSVehicle&>(myHolder).getTimeLoss();
229  updateStatistics(timeLoss);
230  if (!OptionsCont::getOptions().isSet("tripinfo-output")) {
231  return;
232  }
233  myPendingOutput.erase(this);
234  double routeLength;
235  SUMOTime duration;
236  computeLengthAndDuration(routeLength, duration);
237 
238  // write
239  OutputDevice& os = OutputDevice::getDeviceByOption("tripinfo-output");
240  os.openTag("tripinfo").writeAttr("id", myHolder.getID());
241  os.writeAttr("depart", time2string(myHolder.getDeparture()));
242  os.writeAttr("departLane", myDepartLane);
243  os.writeAttr("departPos", myHolder.getDepartPos());
245  os.writeAttr("departPosLat", myDepartPosLat);
246  }
247  os.writeAttr("departSpeed", myDepartSpeed);
248  os.writeAttr("departDelay", time2string(myHolder.getDepartDelay()));
249  os.writeAttr("arrival", time2string(myArrivalTime));
250  os.writeAttr("arrivalLane", myArrivalLane);
251  os.writeAttr("arrivalPos", myArrivalPos);
253  os.writeAttr("arrivalPosLat", myArrivalPosLat);
254  }
255  os.writeAttr("arrivalSpeed", myArrivalSpeed);
256  os.writeAttr("duration", time2string(duration));
257  os.writeAttr("routeLength", routeLength);
258  os.writeAttr("waitSteps", myWaitingTime / DELTA_T);
259  os.writeAttr("timeLoss", time2string(timeLoss));
260  os.writeAttr("rerouteNo", myHolder.getNumberReroutes());
261  const std::vector<MSDevice*>& devices = myHolder.getDevices();
262  std::ostringstream str;
263  for (std::vector<MSDevice*>::const_iterator i = devices.begin(); i != devices.end(); ++i) {
264  if (i != devices.begin()) {
265  str << ' ';
266  }
267  str << (*i)->getID();
268  }
269  os.writeAttr("devices", str.str());
270  os.writeAttr("vType", myHolder.getVehicleType().getID());
271  os.writeAttr("speedFactor", myHolder.getChosenSpeedFactor());
272  os.writeAttr("vaporized", (myHolder.getEdge() == *(myHolder.getRoute().end() - 1) ? "" : "0"));
273  // cannot close tag because emission device output might follow
274 }
275 
276 
277 void
279  while (myPendingOutput.size() > 0) {
280  const MSDevice_Tripinfo* d = *myPendingOutput.begin();
281  if (d->myHolder.hasDeparted()) {
282  d->generateOutput();
283  if (!OptionsCont::getOptions().isSet("tripinfo-output")) {
284  return;
285  }
286  // @todo also generate emission output if holder has a device
287  OutputDevice::getDeviceByOption("tripinfo-output").closeTag();
288  } else {
289  myPendingOutput.erase(d);
290  }
291  }
292 }
293 
294 
295 void
297  double routeLength;
298  SUMOTime duration;
299  computeLengthAndDuration(routeLength, duration);
300 
301  myVehicleCount++;
302  myTotalRouteLength += routeLength;
303  myTotalDuration += duration;
305  myTotalTimeLoss += timeLoss;
307 }
308 
309 
310 void
311 MSDevice_Tripinfo::addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss) {
312  myWalkCount++;
313  myTotalWalkRouteLength += walkLength;
314  myTotalWalkDuration += walkDuration;
315  myTotalWalkTimeLoss += walkTimeLoss;
316 }
317 
318 void
319 MSDevice_Tripinfo::addRideData(double rideLength, SUMOTime rideDuration, SUMOVehicleClass vClass, const std::string& line, SUMOTime waitingTime) {
320  myRideCount++;
321  if (rideDuration > 0) {
322  myTotalRideWaitingTime += waitingTime;
323  myTotalRideRouteLength += rideLength;
324  myTotalRideDuration += rideDuration;
325  if (!line.empty()) {
326  if (isRailway(vClass)) {
327  myRideRailCount++;
328  } else if (vClass == SVC_BICYCLE) {
329  myRideBikeCount++;
330  } else {
331  // some kind of road vehicle
332  myRideBusCount++;
333  }
334  }
335  } else {
337  }
338 }
339 
340 
341 std::string
343  std::ostringstream msg;
344  msg.setf(msg.fixed);
345  msg.precision(gPrecision);
346  msg << "Statistics (avg):\n"
347  << " RouteLength: " << getAvgRouteLength() << "\n"
348  << " Duration: " << getAvgDuration() << "\n"
349  << " WaitingTime: " << getAvgWaitingTime() << "\n"
350  << " TimeLoss: " << getAvgTimeLoss() << "\n"
351  << " DepartDelay: " << getAvgDepartDelay() << "\n";
352  if (myWalkCount > 0) {
353  msg << "Pedestrian Statistics (avg of " << myWalkCount << " walks):\n"
354  << " RouteLength: " << getAvgWalkRouteLength() << "\n"
355  << " Duration: " << getAvgWalkDuration() << "\n"
356  << " TimeLoss: " << getAvgWalkTimeLoss() << "\n";
357  }
358  if (myRideCount > 0) {
359  msg << "Ride Statistics (avg of " << myRideCount << " rides):\n"
360  << " WaitingTime: " << getAvgRideWaitingTime() << "\n"
361  << " RouteLength: " << getAvgRideRouteLength() << "\n"
362  << " Duration: " << getAvgRideDuration() << "\n"
363  << " Bus: " << myRideBusCount << "\n"
364  << " Train: " << myRideRailCount << "\n"
365  << " Bike: " << myRideBikeCount << "\n"
366  << " Aborted: " << myRideAbortCount << "\n";
367  }
368  return msg.str();
369 }
370 
371 
372 double
374  if (myVehicleCount > 0) {
376  } else {
377  return 0;
378  }
379 }
380 
381 double
383  if (myVehicleCount > 0) {
385  } else {
386  return 0;
387  }
388 }
389 
390 double
392  if (myVehicleCount > 0) {
394  } else {
395  return 0;
396  }
397 }
398 
399 
400 double
402  if (myVehicleCount > 0) {
404  } else {
405  return 0;
406  }
407 }
408 
409 
410 double
412  if (myVehicleCount > 0) {
414  } else {
415  return 0;
416  }
417 }
418 
419 
420 double
422  if (myWalkCount > 0) {
424  } else {
425  return 0;
426  }
427 }
428 
429 double
431  if (myWalkCount > 0) {
433  } else {
434  return 0;
435  }
436 }
437 
438 
439 double
441  if (myWalkCount > 0) {
443  } else {
444  return 0;
445  }
446 }
447 
448 
449 double
451  if (myRideCount > 0) {
453  } else {
454  return 0;
455  }
456 }
457 
458 double
460  if (myRideCount > 0) {
462  } else {
463  return 0;
464  }
465 }
466 
467 double
469  if (myRideCount > 0) {
471  } else {
472  return 0;
473  }
474 }
475 
476 
477 void
480  out.writeAttr(SUMO_ATTR_ID, getID());
481  std::vector<std::string> internals;
482  internals.push_back(myDepartLane);
483  internals.push_back(toString(myDepartPosLat));
484  internals.push_back(toString(myDepartSpeed));
485  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
486  out.closeTag();
487 }
488 
489 
490 void
492  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
493  bis >> myDepartLane;
494  bis >> myDepartPosLat;
495  bis >> myDepartSpeed;
496 }
497 
498 
499 /****************************************************************************/
static SUMOTime myTotalWalkDuration
static double getAvgRideRouteLength()
static int myRideBikeCount
static SUMOTime myTotalWalkTimeLoss
static double gLateralResolution
Definition: MSGlobals.h:91
const MSLane * getLane() const
Returns the lane the reminder works on.
SUMOTime myArrivalTime
The vehicle&#39;s arrival time.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:260
void computeLengthAndDuration(double &routeLength, SUMOTime &duration) const
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:607
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
static void addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss)
record tripinfo data for pedestrians
virtual bool hasDeparted() const =0
Returns whether this vehicle has departed.
virtual double getArrivalPos() const =0
Returns this vehicle&#39;s desired arrivalPos for its current route (may change on reroute) ...
static SUMOTime myTotalWaitingTime
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves departure info on insertion.
virtual const MSRoute & getRoute() const =0
Returns the current route.
void updateStatistics(SUMOTime timeLoss) const
update tripinfo statistics
static double myTotalRouteLength
bool notifyLeave(SUMOVehicle &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves arrival info.
A device which collects info on the vehicle trip (mainly on departure and arrival) ...
SUMOVehicle & myHolder
The vehicle that stores the device.
Definition: MSDevice.h:188
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:29
static double getAvgTimeLoss()
vehicle is a bicycle
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice *> &into)
Build devices for the given vehicle, if needed.
Notification
Definition of a vehicle state.
double getDistanceBetween(double fromPos, double 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:280
static void addRideData(double rideLength, SUMOTime rideDuration, SUMOVehicleClass vClass, const std::string &line, SUMOTime waitingTime)
record tripinfo data for rides
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:167
~MSDevice_Tripinfo()
Destructor.
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
The vehicle got vaporized.
static double myVehicleCount
global tripinfo statistics
const std::string & getID() const
Returns the id.
Definition: Named.h:74
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
double getLength() const
return the length of the edge
Definition: MSEdge.h:569
static double getAvgRideWaitingTime()
std::set< const MSDevice_Tripinfo *, ComparatorIdLess > DeviceSet
devices which may still need to produce output
double myArrivalSpeed
The speed when arriving.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:64
static double getAvgDuration()
SUMOTime myWaitingTime
The overall waiting time.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
#define NOT_ARRIVED
The state of a link.
static DeviceSet myPendingOutput
static double getAvgWalkTimeLoss()
virtual const std::vector< MSDevice * > & getDevices() const =0
Returns this vehicle&#39;s devices.
static void generateOutputForUnfinished()
generate output for vehicles which are still in the network
void notifyMoveInternal(const SUMOVehicle &veh, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double)
Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal() ...
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
static std::string printStatistics()
get statistics for printing to stdout
Representation of a vehicle.
Definition: SUMOVehicle.h:66
static double getAvgWalkRouteLength()
Encapsulated SAX-Attributes.
virtual int getNumberReroutes() const =0
Returns the number of new routes this vehicle got.
static SUMOTime myTotalDuration
The vehicle arrived at its destination (is deleted)
#define STEPS2TIME(x)
Definition: SUMOTime.h:64
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:253
static double myTotalRideWaitingTime
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:587
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:75
double myArrivalPosLat
The lateral position on the lane the vehicle arrived at.
static double getAvgWalkDuration()
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:229
virtual double getChosenSpeedFactor() const =0
std::string myDepartLane
The lane the vehicle departed at.
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:858
static void cleanup()
resets counters
static SUMOTime myTotalRideDuration
static double getAvgRideDuration()
Abstract in-vehicle device.
Definition: MSDevice.h:70
static double getAvgWaitingTime()
virtual double getDepartPos() const =0
Returns this vehicle&#39;s real departure position.
virtual SUMOTime getDepartDelay() const =0
The vehicle has departed (was inserted into the network)
bool notifyMove(SUMOVehicle &veh, double oldPos, double newPos, double newSpeed)
Checks for waiting steps when the vehicle moves.
static double myTotalWalkRouteLength
std::string myArrivalLane
The lane the vehicle arrived at.
virtual SUMOTime getDeparture() const =0
Returns this vehicle&#39;s real departure time.
virtual double getPositionOnLane() const =0
Get the vehicle&#39;s position along the lane.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
double myDepartSpeed
The speed on departure.
MSDevice_Tripinfo()
dummy constructor
static SUMOTime myTotalDepartDelay
const std::string & getID() const
Returns the name of the vehicle type.
virtual SUMOTime getWaitingTime() const =0
static double getAvgRouteLength()
accessors for GUINet-Parameters
static double myTotalRideRouteLength
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:57
static double getAvgDepartDelay()
static int myRideAbortCount
virtual bool isStopped() const =0
Returns whether the vehicle is at a stop.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
bool closeTag()
Closes the most recently opened tag.
static int myRideRailCount
long long int SUMOTime
Definition: TraCIDefs.h:51
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:73
void generateOutput() const
Called on writing tripinfo output.
static SUMOTime myTotalTimeLoss
SUMOTime myMesoTimeLoss
The time loss when compared to the desired and allowed speed.
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
double myDepartPosLat
The lateral depart position.
virtual double getSpeed() const =0
Returns the vehicle&#39;s current speed.
void loadState(const SUMOSAXAttributes &attrs)
Loads the state of the device from the given description.
static bool gUseMesoSim
Definition: MSGlobals.h:97
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
double myArrivalPos
The position on the lane the vehicle arrived at.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:79
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
void saveState(OutputDevice &out) const
Saves the state of the device.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.