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
double getLength() const
return the length of the edge
Definition: MSEdge.h:569
static double gLateralResolution
Definition: MSGlobals.h:91
SUMOTime myArrivalTime
The vehicle&#39;s arrival time.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:260
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.
static double myTotalRouteLength
void computeLengthAndDuration(double &routeLength, SUMOTime &duration) const
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
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:587
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
Notification
Definition of a vehicle state.
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
void generateOutput() const
Called on writing tripinfo output.
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into)
Build devices for the given vehicle, if needed.
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
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:253
static double getAvgRideWaitingTime()
const MSLane * getLane() const
Returns the lane the reminder works on.
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()
const std::string & getID() const
Returns the id.
Definition: Named.h:65
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
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:858
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
void updateStatistics(SUMOTime timeLoss) const
update tripinfo statistics
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
void saveState(OutputDevice &out) const
Saves the state of the device.
static double myTotalRideWaitingTime
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.
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
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:79
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
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 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
std::set< const MSDevice_Tripinfo *, Named::NamedLikeComparatorIdLess< MSDevice_Tripinfo > > DeviceSet
devices which may still need to produce 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.
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:73
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.