Eclipse 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-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // A device which collects info on the vehicle trip
19 /****************************************************************************/
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <microsim/MSGlobals.h>
27 #include <microsim/MSNet.h>
28 #include <microsim/MSLane.h>
29 #include <microsim/MSEdge.h>
30 #include <microsim/MSVehicle.h>
32 #include <mesosim/MEVehicle.h>
36 #include "MSDevice_Tripinfo.h"
37 
38 #define NOT_ARRIVED TIME2STEPS(-1)
39 
40 
41 // ===========================================================================
42 // static members
43 // ===========================================================================
44 std::set<const MSDevice_Tripinfo*, ComparatorNumericalIdLess> MSDevice_Tripinfo::myPendingOutput;
45 
53 
58 
67 
68 // ===========================================================================
69 // method definitions
70 // ===========================================================================
71 // ---------------------------------------------------------------------------
72 // static initialisation methods
73 // ---------------------------------------------------------------------------
74 void
75 MSDevice_Tripinfo::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
76  if (OptionsCont::getOptions().isSet("tripinfo-output") || OptionsCont::getOptions().getBool("duration-log.statistics")) {
77  MSDevice_Tripinfo* device = new MSDevice_Tripinfo(v, "tripinfo_" + v.getID());
78  into.push_back(device);
79  myPendingOutput.insert(device);
80  }
81 }
82 
83 
84 // ---------------------------------------------------------------------------
85 // MSDevice_Tripinfo-methods
86 // ---------------------------------------------------------------------------
87 MSDevice_Tripinfo::MSDevice_Tripinfo(SUMOVehicle& holder, const std::string& id) :
88  MSVehicleDevice(holder, id),
89  myDepartLane(""),
90  myDepartSpeed(-1),
91  myDepartPosLat(0),
92  myWaitingTime(0),
93  myAmWaiting(false),
94  myWaitingCount(0),
95  myStoppingTime(0),
98  myArrivalLane(""),
99  myArrivalPos(-1),
100  myArrivalPosLat(0.),
101  myArrivalSpeed(-1),
102  myMesoTimeLoss(0),
103  myRouteLength(0.) {
104 }
105 
106 
108  // ensure clean up for vaporized vehicles which do not generate output
109  myPendingOutput.erase(this);
110 }
111 
112 void
114  myVehicleCount = 0;
115  myTotalRouteLength = 0;
116  myTotalDuration = 0;
117  myTotalWaitingTime = 0;
118  myTotalTimeLoss = 0;
119  myTotalDepartDelay = 0;
121 
122  myWalkCount = 0;
126 
127  myRideCount = 0;
128  myRideBusCount = 0;
129  myRideRailCount = 0;
130  myRideBikeCount = 0;
131  myRideAbortCount = 0;
135 }
136 
137 bool
139  double /*newPos*/, double newSpeed) {
140  if (veh.isStopped()) {
142  } else if (newSpeed <= SUMO_const_haltingSpeed) {
144  if (!myAmWaiting) {
145  myWaitingCount++;
146  myAmWaiting = true;
147  }
148  } else {
149  myAmWaiting = false;
150  }
151  return true;
152 }
153 
154 
155 void
157  const double /* frontOnLane */,
158  const double timeOnLane,
159  const double /* meanSpeedFrontOnLane */,
160  const double meanSpeedVehicleOnLane,
161  const double /* travelledDistanceFrontOnLane */,
162  const double /* travelledDistanceVehicleOnLane */,
163  const double /* meanLengthOnLane */) {
164 
165  // called by meso
166  const MEVehicle* mesoVeh = dynamic_cast<const MEVehicle*>(&veh);
167  assert(mesoVeh);
168  const double vmax = veh.getEdge()->getVehicleMaxSpeed(&veh);
169  if (vmax > 0) {
170  myMesoTimeLoss += TIME2STEPS(timeOnLane * (vmax - meanSpeedVehicleOnLane) / vmax);
171  }
172  myWaitingTime += veh.getWaitingTime();
174 }
175 
176 
177 bool
180  if (!MSGlobals::gUseMesoSim) {
181  myDepartLane = static_cast<MSVehicle&>(veh).getLane()->getID();
182  myDepartPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
183  }
184  myDepartSpeed = veh.getSpeed();
186  } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
187  // notifyMove is not called while parking
188  // @note insertion delay when resuming after parking is included
190  }
191  return true;
192 }
193 
194 
195 bool
197  MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
198  if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
200  if (!MSGlobals::gUseMesoSim) {
201  myArrivalLane = static_cast<MSVehicle&>(veh).getLane()->getID();
202  myArrivalPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
203  }
204  // @note vehicle may have moved past its arrivalPos during the last step
205  // due to non-zero arrivalspeed but we consider it as arrived at the desired position
206  // However, vaporization may happen anywhere (via TraCI)
209  } else {
211  }
212  myArrivalSpeed = veh.getSpeed();
213  } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
215  } else if (reason == NOTIFICATION_JUNCTION || reason == NOTIFICATION_TELEPORT) {
218  } else {
219  myRouteLength += static_cast<MSVehicle&>(veh).getLane()->getLength();
220  }
221  }
222  return true;
223 }
224 
225 
226 void
228  const SUMOTime timeLoss = MSGlobals::gUseMesoSim ? myMesoTimeLoss : static_cast<MSVehicle&>(myHolder).getTimeLoss();
229  const double routeLength = myRouteLength + (myArrivalTime == NOT_ARRIVED ? myHolder.getPositionOnLane() : myArrivalPos);
230  const SUMOTime duration = (myArrivalTime == NOT_ARRIVED ? SIMSTEP : myArrivalTime) - myHolder.getDeparture();
231 
232  myVehicleCount++;
233  myTotalRouteLength += routeLength;
234  myTotalDuration += duration;
236  myTotalTimeLoss += timeLoss;
238  if (!OptionsCont::getOptions().isSet("tripinfo-output")) {
239  return;
240  }
241  myPendingOutput.erase(this);
242 
243  // write
244  OutputDevice& os = OutputDevice::getDeviceByOption("tripinfo-output");
245  os.openTag("tripinfo").writeAttr("id", myHolder.getID());
246  os.writeAttr("depart", time2string(myHolder.getDeparture()));
247  os.writeAttr("departLane", myDepartLane);
248  os.writeAttr("departPos", myHolder.getDepartPos());
250  os.writeAttr("departPosLat", myDepartPosLat);
251  }
252  os.writeAttr("departSpeed", myDepartSpeed);
253  os.writeAttr("departDelay", time2string(myHolder.getDepartDelay()));
254  os.writeAttr("arrival", time2string(myArrivalTime));
255  os.writeAttr("arrivalLane", myArrivalLane);
256  os.writeAttr("arrivalPos", myArrivalPos);
258  os.writeAttr("arrivalPosLat", myArrivalPosLat);
259  }
260  os.writeAttr("arrivalSpeed", myArrivalSpeed);
261  os.writeAttr("duration", time2string(duration));
262  os.writeAttr("routeLength", routeLength);
263  os.writeAttr("waitingTime", time2string(myWaitingTime));
264  os.writeAttr("waitingCount", myWaitingCount);
265  os.writeAttr("stopTime", time2string(myStoppingTime));
266  os.writeAttr("timeLoss", time2string(timeLoss));
267  os.writeAttr("rerouteNo", myHolder.getNumberReroutes());
268  os.writeAttr("devices", toString(myHolder.getDevices()));
269  os.writeAttr("vType", myHolder.getVehicleType().getID());
270  os.writeAttr("speedFactor", myHolder.getChosenSpeedFactor());
271  os.writeAttr("vaporized", (myHolder.getEdge() == *(myHolder.getRoute().end() - 1) ? "" : "0"));
272  // cannot close tag because emission device output might follow
273 }
274 
275 
276 void
278  MSNet* net = MSNet::getInstance();
279  const bool writeTripinfos = OptionsCont::getOptions().isSet("tripinfo-output");
281  int undeparted = 0;
282  int departed = 0;
283  const SUMOTime t = net->getCurrentTimeStep();
284  while (myPendingOutput.size() > 0) {
285  const MSDevice_Tripinfo* d = *myPendingOutput.begin();
286  if (d->myHolder.hasDeparted()) {
287  departed++;
288  d->generateOutput();
289  if (writeTripinfos) {
290  // @todo also generate emission output if holder has a device
291  OutputDevice::getDeviceByOption("tripinfo-output").closeTag();
292  } else {
293  myPendingOutput.erase(d);
294  }
295  } else {
296  undeparted++;
298  myPendingOutput.erase(d);
299  }
300  }
301  if (myWaitingDepartDelay > 0) {
302  myWaitingDepartDelay /= undeparted;
303  }
304  // unfinished persons
305  if (net->hasPersons()) {
307  while (pc.loadedBegin() != pc.loadedEnd()) {
308  pc.erase(pc.loadedBegin()->second);
309  }
310  }
311 
312 }
313 
314 
315 void
316 MSDevice_Tripinfo::addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss) {
317  myWalkCount++;
318  myTotalWalkRouteLength += walkLength;
319  myTotalWalkDuration += walkDuration;
320  myTotalWalkTimeLoss += walkTimeLoss;
321 }
322 
323 
324 void
325 MSDevice_Tripinfo::addRideData(double rideLength, SUMOTime rideDuration, SUMOVehicleClass vClass, const std::string& line, SUMOTime waitingTime) {
326  myRideCount++;
327  if (rideDuration > 0) {
328  myTotalRideWaitingTime += waitingTime;
329  myTotalRideRouteLength += rideLength;
330  myTotalRideDuration += rideDuration;
331  if (vClass == SVC_BICYCLE) {
332  myRideBikeCount++;
333  } else if (!line.empty()) {
334  if (isRailway(vClass)) {
335  myRideRailCount++;
336  } else {
337  // some kind of road vehicle
338  myRideBusCount++;
339  }
340  }
341  } else {
343  }
344 }
345 
346 
347 std::string
349  std::ostringstream msg;
350  msg.setf(msg.fixed);
351  msg.precision(gPrecision);
352  msg << "Statistics (avg):\n"
353  << " RouteLength: " << getAvgRouteLength() << "\n"
354  << " Duration: " << getAvgDuration() << "\n"
355  << " WaitingTime: " << getAvgWaitingTime() << "\n"
356  << " TimeLoss: " << getAvgTimeLoss() << "\n"
357  << " DepartDelay: " << getAvgDepartDelay() << "\n";
358  if (myWaitingDepartDelay >= 0) {
359  msg << " DepartDelayWaiting: " << STEPS2TIME(myWaitingDepartDelay) << "\n";
360  }
361  if (myWalkCount > 0) {
362  msg << "Pedestrian Statistics (avg of " << myWalkCount << " walks):\n"
363  << " RouteLength: " << getAvgWalkRouteLength() << "\n"
364  << " Duration: " << getAvgWalkDuration() << "\n"
365  << " TimeLoss: " << getAvgWalkTimeLoss() << "\n";
366  }
367  if (myRideCount > 0) {
368  msg << "Ride Statistics (avg of " << myRideCount << " rides):\n"
369  << " WaitingTime: " << getAvgRideWaitingTime() << "\n"
370  << " RouteLength: " << getAvgRideRouteLength() << "\n"
371  << " Duration: " << getAvgRideDuration() << "\n"
372  << " Bus: " << myRideBusCount << "\n"
373  << " Train: " << myRideRailCount << "\n"
374  << " Bike: " << myRideBikeCount << "\n"
375  << " Aborted: " << myRideAbortCount << "\n";
376  }
377  return msg.str();
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 double
401  if (myVehicleCount > 0) {
403  } else {
404  return 0;
405  }
406 }
407 
408 
409 double
411  if (myVehicleCount > 0) {
413  } else {
414  return 0;
415  }
416 }
417 
418 
419 double
421  if (myVehicleCount > 0) {
423  } else {
424  return 0;
425  }
426 }
427 
428 
429 double
431  if (myWalkCount > 0) {
433  } else {
434  return 0;
435  }
436 }
437 
438 double
440  if (myWalkCount > 0) {
442  } else {
443  return 0;
444  }
445 }
446 
447 
448 double
450  if (myWalkCount > 0) {
452  } else {
453  return 0;
454  }
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 double
478  if (myRideCount > 0) {
480  } else {
481  return 0;
482  }
483 }
484 
485 
486 void
489  out.writeAttr(SUMO_ATTR_ID, getID());
490  std::vector<std::string> internals;
491  if (!MSGlobals::gUseMesoSim) {
492  internals.push_back(myDepartLane);
493  internals.push_back(toString(myDepartPosLat));
494  }
495  internals.push_back(toString(myDepartSpeed));
496  internals.push_back(toString(myRouteLength));
497  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
498  out.closeTag();
499 }
500 
501 
502 void
504  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
505  if (!MSGlobals::gUseMesoSim) {
506  bis >> myDepartLane;
507  bis >> myDepartPosLat;
508  }
509  bis >> myDepartSpeed;
510  bis >> myRouteLength;
511 }
512 
513 
514 /****************************************************************************/
static SUMOTime myTotalWalkDuration
static double getAvgRideRouteLength()
static int myRideBikeCount
static SUMOTime myTotalWalkTimeLoss
static double gLateralResolution
Definition: MSGlobals.h:85
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:256
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
long long int SUMOTime
Definition: SUMOTime.h:35
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) ...
bool hasPersons() const
Returns whether persons are simulated.
Definition: MSNet.h:354
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:45
static SUMOTime myTotalWaitingTime
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:928
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
virtual const MSRoute & getRoute() const =0
Returns the current route.
static double myTotalRouteLength
A device which collects info on the vehicle trip (mainly on departure and arrival) ...
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:27
static double getAvgTimeLoss()
The vehicle arrived at a junction.
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves arrival info.
vehicle is a bicycle
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
Notification
Definition of a vehicle state.
SUMOVehicle & myHolder
The vehicle that stores the device.
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:65
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:168
MSDevice_Tripinfo(SUMOVehicle &holder, const std::string &id)
Constructor.
~MSDevice_Tripinfo()
Destructor.
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:541
The vehicle got vaporized.
static double myVehicleCount
global tripinfo statistics
const std::string & getID() const
Returns the id.
Definition: Named.h:77
#define TIME2STEPS(x)
Definition: SUMOTime.h:59
static SUMOTime myWaitingDepartDelay
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
SUMOTime myStoppingTime
The overall intentional stopping time.
virtual double getChosenSpeedFactor() const =0
double getLength() const
return the length of the edge
Definition: MSEdge.h:582
static double getAvgRideWaitingTime()
static std::set< const MSDevice_Tripinfo *, ComparatorNumericalIdLess > myPendingOutput
devices which may still need to produce output
double myArrivalSpeed
The speed when arriving.
The simulated network and simulation perfomer.
Definition: MSNet.h:92
virtual void erase(MSTransportable *transportable)
removes a single transportable
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
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 double getAvgWalkTimeLoss()
int myWaitingCount
The overall number of unintended stops.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getCurrentStoppingTimeSeconds() const
Returns the delay that is accrued due to option –meso-tls-penalty or –meso-minor-penalty.
Definition: MEVehicle.cpp:276
static void generateOutputForUnfinished()
generate output for vehicles which are still in the network
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
static std::string printStatistics()
get statistics for printing to stdout
Representation of a vehicle.
Definition: SUMOVehicle.h:61
static double getAvgWalkRouteLength()
Encapsulated SAX-Attributes.
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:798
virtual int getNumberReroutes() const =0
Returns the number of new routes this vehicle got.
SUMOTime myParkingStarted
The time when parking started.
static SUMOTime myTotalDuration
virtual const std::vector< MSVehicleDevice * > & getDevices() const =0
Returns this vehicle&#39;s devices.
#define SIMSTEP
Definition: SUMOTime.h:63
constVehIt loadedBegin() const
Returns the begin of the internal transportables map.
The vehicle arrived at its destination (is deleted)
#define STEPS2TIME(x)
Definition: SUMOTime.h:57
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:284
static double myTotalRideWaitingTime
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice *> &into)
Build devices for the given vehicle, if needed.
double myArrivalPosLat
The lateral position on the lane the vehicle arrived at.
static double getAvgWalkDuration()
std::string myDepartLane
The lane the vehicle departed at.
static void cleanup()
resets counters
static SUMOTime myTotalRideDuration
static double getAvgRideDuration()
static double getAvgWaitingTime()
virtual double getDepartPos() const =0
Returns this vehicle&#39;s real departure position.
virtual SUMOTime getDepartDelay() const =0
The vehicle starts or ends parking.
The vehicle has departed (was inserted into the network)
static double myTotalWalkRouteLength
Representation of a vehicle or person.
std::string myArrivalLane
The lane the vehicle arrived at.
virtual SUMOTime getDeparture() const =0
Returns this vehicle&#39;s real departure time.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
double myDepartSpeed
The speed on departure.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
static SUMOTime myTotalDepartDelay
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves departure info on insertion.
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:94
constVehIt loadedEnd() const
Returns the end of the internal transportables map.
Abstract in-vehicle device.
static double getAvgRouteLength()
accessors for GUINet-Parameters
static double myTotalRideRouteLength
double myRouteLength
The route length.
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:61
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks for waiting steps when the vehicle moves.
static double getAvgDepartDelay()
static int myRideAbortCount
virtual double getPositionOnLane() const =0
Get the vehicle&#39;s position along the lane.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static int myRideRailCount
void generateOutput() const
Called on writing tripinfo output.
void notifyMoveInternal(const SUMOTrafficObject &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() ...
static SUMOTime myTotalTimeLoss
SUMOTime myMesoTimeLoss
The time loss when compared to the desired and allowed speed.
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:91
Representation of a lane in the micro simulation.
Definition: MSLane.h:83
virtual bool isStopped() const =0
Returns whether the vehicle is at a stop.
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:76
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
void saveState(OutputDevice &out) const
Saves the state of the device.
bool myAmWaiting
Whether the vehicle is currently waiting.
The vehicle is being teleported.
virtual SUMOTime getWaitingTime() const =0