Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSDevice_Tripinfo.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2009-2024 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
21// A device which collects info on the vehicle trip
22/****************************************************************************/
23#include <config.h>
24
25#include <microsim/MSGlobals.h>
26#include <microsim/MSNet.h>
27#include <microsim/MSLane.h>
28#include <microsim/MSEdge.h>
29#include <microsim/MSVehicle.h>
31#include <mesosim/MEVehicle.h>
35#include "MSDevice_Vehroutes.h"
36#include "MSDevice_Tripinfo.h"
37
38#define NOT_ARRIVED TIME2STEPS(-1)
39#define STATE_EMPTY_ARRIVALLANE "NONE"
40
41
42// ===========================================================================
43// static members
44// ===========================================================================
45std::set<const MSDevice_Tripinfo*, ComparatorNumericalIdLess> MSDevice_Tripinfo::myPendingOutput;
46
56
64
69std::vector<int> MSDevice_Tripinfo::myRideCount({0, 0});
70std::vector<int> MSDevice_Tripinfo::myRideBusCount({0, 0});
71std::vector<int> MSDevice_Tripinfo::myRideRailCount({0, 0});
72std::vector<int> MSDevice_Tripinfo::myRideTaxiCount({0, 0});
73std::vector<int> MSDevice_Tripinfo::myRideBikeCount({0, 0});
74std::vector<int> MSDevice_Tripinfo::myRideAbortCount({0, 0});
75std::vector<SUMOTime> MSDevice_Tripinfo::myTotalRideWaitingTime({0, 0});
76std::vector<double> MSDevice_Tripinfo::myTotalRideRouteLength({0., 0.});
77std::vector<SUMOTime> MSDevice_Tripinfo::myTotalRideDuration({0, 0});
78
79// ===========================================================================
80// method definitions
81// ===========================================================================
82// ---------------------------------------------------------------------------
83// static initialisation methods
84// ---------------------------------------------------------------------------
85void
87 oc.addOptionSubTopic("Tripinfo Device");
88 insertDefaultAssignmentOptions("tripinfo", "Tripinfo Device", oc);
89}
90
91
92void
93MSDevice_Tripinfo::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
95 const bool enableByOutputOption = oc.isSet("tripinfo-output") || oc.getBool("duration-log.statistics");
96 if (equippedByDefaultAssignmentOptions(oc, "tripinfo", v, enableByOutputOption)) {
97 MSDevice_Tripinfo* device = new MSDevice_Tripinfo(v, "tripinfo_" + v.getID());
98 into.push_back(device);
99 myPendingOutput.insert(device);
100 }
101}
102
103
104// ---------------------------------------------------------------------------
105// MSDevice_Tripinfo-methods
106// ---------------------------------------------------------------------------
107MSDevice_Tripinfo::MSDevice_Tripinfo(SUMOVehicle& holder, const std::string& id) :
108 MSVehicleDevice(holder, id),
109 myDepartLane(""),
110 myDepartSpeed(-1),
111 myDepartPosLat(0),
112 myWaitingTime(0),
113 myAmWaiting(false),
114 myWaitingCount(0),
115 myStoppingTime(0),
116 myParkingStarted(-1),
117 myArrivalTime(NOT_ARRIVED),
118 myArrivalLane(""),
119 myArrivalPos(-1),
120 myArrivalPosLat(0.),
121 myArrivalSpeed(-1),
122 myArrivalReason(MSMoveReminder::NOTIFICATION_ARRIVED),
123 myMesoTimeLoss(0),
124 myRouteLength(0.) {
125}
126
127
129 // ensure clean up for vaporized vehicles which do not generate output
130 myPendingOutput.erase(this);
131}
132
133void
135 myVehicleCount = 0;
137 myTotalSpeed = 0;
138 myTotalDuration = 0;
140 myTotalTimeLoss = 0;
143
144 myBikeCount = 0;
151
152 myWalkCount = 0;
156
157 myRideCount = {0, 0};
158 myRideBusCount = {0, 0};
159 myRideRailCount = {0, 0};
160 myRideTaxiCount = {0, 0};
161 myRideBikeCount = {0, 0};
162 myRideAbortCount = {0, 0};
163 myTotalRideWaitingTime = {0, 0};
164 myTotalRideRouteLength = {0., 0.};
165 myTotalRideDuration = {0, 0};
166}
167
168bool
170 if (veh.isVehicle()) {
172 if (!myAmWaiting) {
174 myAmWaiting = true;
175 }
176 }
177 return true;
178}
179
180
181bool
183 double /*newPos*/, double newSpeed) {
184 if (veh.isStopped()) {
185 if (newSpeed <= SUMO_const_haltingSpeed) {
187 }
188 } else if (newSpeed <= SUMO_const_haltingSpeed && lowAcceleration(veh)) {
190 if (!myAmWaiting) {
192 myAmWaiting = true;
193 }
194 } else {
195 myAmWaiting = false;
196 }
197 return true;
198}
199
200
201bool
204 // acceleration is not modelled
205 return false;
206 } else {
207 const MSVehicle& v = dynamic_cast<const MSVehicle&>(veh);
209 }
210}
211
212
213void
215 const double /* frontOnLane */,
216 const double timeOnLane,
217 const double /* meanSpeedFrontOnLane */,
218 const double meanSpeedVehicleOnLane,
219 const double /* travelledDistanceFrontOnLane */,
220 const double /* travelledDistanceVehicleOnLane */,
221 const double /* meanLengthOnLane */) {
222
223 // called by meso
224 const double vmax = veh.getEdge()->getVehicleMaxSpeed(&veh);
225 if (vmax > 0) {
226 myMesoTimeLoss += TIME2STEPS(timeOnLane * (vmax - meanSpeedVehicleOnLane) / vmax);
227 }
229}
230
231
232void
239
240bool
244 myDepartLane = static_cast<MSVehicle&>(veh).getLane()->getID();
245 myDepartPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
246 } else {
247 myDepartLane = veh.getEdge()->getFirstAllowed(veh.getVClass(), true)->getID();
248 }
249 myDepartSpeed = veh.getSpeed();
251 } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
252 // notifyMove is not called while parking
253 // @note insertion delay when resuming after parking is included
255 }
256 return true;
257}
258
259
260bool
262 MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
265 myArrivalReason = reason;
267 myArrivalLane = static_cast<MSVehicle&>(veh).getLane()->getID();
268 myArrivalPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
269 } else {
270 myArrivalLane = veh.getEdge()->getFirstAllowed(veh.getVClass(), true)->getID();
271 }
272 // @note vehicle may have moved past its arrivalPos during the last step
273 // due to non-zero arrivalspeed but we consider it as arrived at the desired position
274 // However, vaporization may happen anywhere (via TraCI)
276 // vaporized
278 } else {
280 }
281 myArrivalSpeed = veh.getSpeed();
283 } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
285 } else if (reason == NOTIFICATION_JUNCTION
286 || reason == NOTIFICATION_TELEPORT
290 } else {
291 const MSLane* lane = static_cast<MSVehicle&>(veh).getLane();
292 if (lane != nullptr) {
293 myRouteLength += lane->getLength();
294 }
295 }
296 }
297 return true;
298}
299
300
301void
303 const SUMOTime timeLoss = MSGlobals::gUseMesoSim ? myMesoTimeLoss : static_cast<MSVehicle&>(myHolder).getTimeLoss();
304 const double routeLength = myRouteLength + (myArrivalTime == NOT_ARRIVED ? myHolder.getPositionOnLane() : myArrivalPos);
305 SUMOTime duration = 0;
306 if (myHolder.hasDeparted()) {
308 if (myHolder.getVClass() == SVC_BICYCLE) {
309 myBikeCount++;
310 myTotalBikeRouteLength += routeLength;
311 myTotalBikeSpeed += routeLength / STEPS2TIME(duration);
312 myTotalBikeDuration += duration;
314 myTotalBikeTimeLoss += timeLoss;
316 } else {
318 myTotalRouteLength += routeLength;
319 myTotalSpeed += routeLength / STEPS2TIME(duration);
320 myTotalDuration += duration;
322 myTotalTimeLoss += timeLoss;
324 }
325 }
326
327 myPendingOutput.erase(this);
328 if (tripinfoOut == nullptr) {
329 return;
330 }
331 // write
332 OutputDevice& os = *tripinfoOut;
333 os.openTag("tripinfo").writeAttr("id", myHolder.getID());
335 os.writeAttr("departLane", myDepartLane);
336 os.writeAttr("departPos", myHolder.getDepartPos());
338 os.writeAttr("departPosLat", myDepartPosLat);
339 }
340 os.writeAttr("departSpeed", myDepartSpeed);
341 SUMOTime departDelay = myHolder.getDepartDelay();
343 if (!myHolder.hasDeparted()) {
344 assert(param.depart <= SIMSTEP || param.departProcedure != DepartDefinition::GIVEN);
345 departDelay = SIMSTEP - param.depart;
346 }
347 os.writeAttr("departDelay", time2string(departDelay));
348 os.writeAttr("arrival", time2string(myArrivalTime));
349 os.writeAttr("arrivalLane", myArrivalLane);
350 os.writeAttr("arrivalPos", myArrivalPos);
352 os.writeAttr("arrivalPosLat", myArrivalPosLat);
353 }
354 os.writeAttr("arrivalSpeed", myArrivalSpeed);
355 os.writeAttr("duration", time2string(duration));
356 os.writeAttr("routeLength", routeLength);
361 os.writeAttr("rerouteNo", myHolder.getNumberReroutes());
362 os.writeAttr("devices", toString(myHolder.getDevices()));
363 os.writeAttr("vType", myHolder.getVehicleType().getID());
364 os.writeAttr("speedFactor", myHolder.getChosenSpeedFactor());
365 std::string vaporized;
366 switch (myArrivalReason) {
368 vaporized = "calibrator";
369 break;
371 vaporized = "gui";
372 break;
374 vaporized = "collision";
375 break;
377 vaporized = "vaporizer";
378 break;
380 vaporized = "traci";
381 break;
383 vaporized = "teleport";
384 break;
385 default:
387 (param.arrivalEdge >= 0 && myHolder.getRoutePosition() >= param.arrivalEdge)) {
388 vaporized = "";
389 } else {
390 vaporized = "end";
391 }
392 break;
393 }
394 os.writeAttr("vaporized", vaporized);
395 // cannot close tag because emission device output might follow
396}
397
398
399void
401 MSNet* net = MSNet::getInstance();
402 OutputDevice* tripinfoOut = (OptionsCont::getOptions().isSet("tripinfo-output") ?
403 &OutputDevice::getDeviceByOption("tripinfo-output") : nullptr);
406 const bool writeUndeparted = OptionsCont::getOptions().getBool("tripinfo-output.write-undeparted");
407 const SUMOTime t = net->getCurrentTimeStep();
408 while (myPendingOutput.size() > 0) {
409 const MSDevice_Tripinfo* d = *myPendingOutput.begin();
410 const bool departed = d->myHolder.hasDeparted();
411 const bool departDelayed = d->myHolder.getParameter().depart <= t;
412 if (!departed && departDelayed) {
415 }
416 if (departed || (writeUndeparted && departDelayed)) {
417 const_cast<MSDevice_Tripinfo*>(d)->updateParkingStopTime();
418 d->generateOutput(tripinfoOut);
419 if (tripinfoOut != nullptr) {
420 for (MSVehicleDevice* const dev : d->myHolder.getDevices()) {
421 if (typeid(*dev) == typeid(MSDevice_Tripinfo) || typeid(*dev) == typeid(MSDevice_Vehroutes)) {
422 // tripinfo is special and vehroute has its own write-unfinished option
423 continue;
424 }
425 dev->generateOutput(tripinfoOut);
426 }
427 OutputDevice::getDeviceByOption("tripinfo-output").closeTag();
428 }
429 } else {
430 myPendingOutput.erase(d);
431 }
432 }
433 // unfinished persons
434 if (net->hasPersons()) {
436 while (pc.loadedBegin() != pc.loadedEnd()) {
437 pc.erase(pc.loadedBegin()->second);
438 }
439 }
440
441}
442
443
444void
445MSDevice_Tripinfo::addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss) {
446 myWalkCount++;
447 myTotalWalkRouteLength += walkLength;
448 myTotalWalkDuration += walkDuration;
449 myTotalWalkTimeLoss += walkTimeLoss;
450}
451
452
453void
454MSDevice_Tripinfo::addRideTransportData(const bool isPerson, const double distance, const SUMOTime duration,
455 const SUMOVehicleClass vClass, const std::string& line, const SUMOTime waitingTime) {
456 const int index = isPerson ? 0 : 1;
457 myRideCount[index]++;
458 if (duration > 0) {
459 myTotalRideWaitingTime[index] += waitingTime;
460 myTotalRideRouteLength[index] += distance;
461 myTotalRideDuration[index] += duration;
462 if (vClass == SVC_BICYCLE) {
463 myRideBikeCount[index]++;
464 } else if (!line.empty()) {
465 if (isRailway(vClass)) {
466 myRideRailCount[index]++;
467 } else if (vClass == SVC_TAXI) {
468 myRideTaxiCount[index]++;
469 } else {
470 // some kind of road vehicle
471 myRideBusCount[index]++;
472 }
473 }
474 } else {
475 myRideAbortCount[index]++;
476 }
477}
478
479
480std::string
482 std::ostringstream msg;
483 msg.setf(msg.fixed);
484 msg.precision(gPrecision);
485 if (myBikeCount == 0 || myVehicleCount > 0) {
486 msg << "Statistics (avg of " << myVehicleCount << "):\n";
487 msg << " RouteLength: " << getAvgRouteLength() << "\n"
488 << " Speed: " << getAvgTripSpeed() << "\n"
489 << " Duration: " << getAvgDuration() << "\n"
490 << " WaitingTime: " << getAvgWaitingTime() << "\n"
491 << " TimeLoss: " << getAvgTimeLoss() << "\n"
492 << " DepartDelay: " << getAvgDepartDelay() << "\n";
493 }
494 if (myBikeCount > 0) {
495 msg << "Bike Statistics (avg of " << myBikeCount << "):\n"
496 << " RouteLength: " << getAvgBikeRouteLength() << "\n"
497 << " Speed: " << getAvgBikeTripSpeed() << "\n"
498 << " Duration: " << getAvgBikeDuration() << "\n"
499 << " WaitingTime: " << getAvgBikeWaitingTime() << "\n"
500 << " TimeLoss: " << getAvgBikeTimeLoss() << "\n"
501 << " DepartDelay: " << getAvgBikeDepartDelay() << "\n";
502 if (myVehicleCount > 0 && myWaitingDepartDelay >= 0) {
503 msg << "Statistics (avg of " << (myVehicleCount + myBikeCount) << "):\n";
504 }
505 }
506 if (myWaitingDepartDelay >= 0) {
507 msg << " DepartDelayWaiting: " << getAvgDepartDelayWaiting() << "\n";
508 }
509 if (myWalkCount > 0) {
510 msg << "Pedestrian Statistics (avg of " << myWalkCount << " walks):\n"
511 << " RouteLength: " << getAvgWalkRouteLength() << "\n"
512 << " Duration: " << getAvgWalkDuration() << "\n"
513 << " TimeLoss: " << getAvgWalkTimeLoss() << "\n";
514 }
515 printRideStatistics(msg, "Ride", "rides", 0);
516 printRideStatistics(msg, "Transport", "transports", 1);
517 return msg.str();
518}
519
520void
521MSDevice_Tripinfo::printRideStatistics(std::ostringstream& msg, const std::string& category, const std::string& modeName, const int index) {
522 if (myRideCount[index] > 0) {
523 msg << category << " Statistics (avg of " << myRideCount[index] << " " << modeName << "):\n";
524 msg << " WaitingTime: " << STEPS2TIME(myTotalRideWaitingTime[index] / myRideCount[index]) << "\n";
525 msg << " RouteLength: " << myTotalRideRouteLength[index] / myRideCount[index] << "\n";
526 msg << " Duration: " << STEPS2TIME(myTotalRideDuration[index] / myRideCount[index]) << "\n";
527 if (myRideBusCount[index] > 0) {
528 msg << " Bus: " << myRideBusCount[index] << "\n";
529 }
530 if (myRideRailCount[index] > 0) {
531 msg << " Train: " << myRideRailCount[index] << "\n";
532 }
533 if (myRideTaxiCount[index] > 0) {
534 msg << " Taxi: " << myRideTaxiCount[index] << "\n";
535 }
536 if (myRideBikeCount[index] > 0) {
537 msg << " Bike: " << myRideBikeCount[index] << "\n";
538 }
539 if (myRideAbortCount[index] > 0) {
540 msg << " Aborted: " << myRideAbortCount[index] << "\n";
541 }
542 }
543
544}
545
546
547void
550 od.openTag("vehicleTripStatistics");
551 od.writeAttr("count", myVehicleCount);
552 od.writeAttr("routeLength", getAvgRouteLength());
553 od.writeAttr("speed", getAvgTripSpeed());
554 od.writeAttr("duration", getAvgDuration());
555 od.writeAttr("waitingTime", getAvgWaitingTime());
556 od.writeAttr("timeLoss", getAvgTimeLoss());
557 od.writeAttr("departDelay", getAvgDepartDelay());
558 od.writeAttr("departDelayWaiting", getAvgDepartDelayWaiting());
559 od.writeAttr("totalTravelTime", time2string(myTotalDuration));
561 od.closeTag();
562 if (myBikeCount > 0) {
563 od.openTag("bikeTripStatistics");
564 od.writeAttr("count", myBikeCount);
565 od.writeAttr("routeLength", getAvgBikeRouteLength());
566 od.writeAttr("speed", getAvgBikeTripSpeed());
567 od.writeAttr("duration", getAvgBikeDuration());
568 od.writeAttr("waitingTime", getAvgBikeWaitingTime());
569 od.writeAttr("timeLoss", getAvgBikeTimeLoss());
570 od.writeAttr("departDelay", getAvgBikeDepartDelay());
571 od.writeAttr("totalTravelTime", time2string(myTotalBikeDuration));
572 od.closeTag();
573 }
574 od.openTag("pedestrianStatistics");
575 od.writeAttr("number", myWalkCount);
576 od.writeAttr("routeLength", getAvgWalkRouteLength());
577 od.writeAttr("duration", getAvgWalkDuration());
578 od.writeAttr("timeLoss", getAvgWalkTimeLoss());
579 od.closeTag();
580 writeRideStatistics(od, "rideStatistics", 0);
581 writeRideStatistics(od, "transportStatistics", 1);
582}
583
584void
585MSDevice_Tripinfo::writeRideStatistics(OutputDevice& od, const std::string& category, const int index) {
586 od.openTag(category);
587 od.writeAttr("number", myRideCount[index]);
588 if (myRideCount[index] > 0) {
589 od.writeAttr("waitingTime", STEPS2TIME(myTotalRideWaitingTime[index] / myRideCount[index]));
590 od.writeAttr("routeLength", myTotalRideRouteLength[index] / myRideCount[index]);
591 od.writeAttr("duration", STEPS2TIME(myTotalRideDuration[index] / myRideCount[index]));
592 od.writeAttr("bus", myRideBusCount[index]);
593 od.writeAttr("train", myRideRailCount[index]);
594 od.writeAttr("taxi", myRideTaxiCount[index]);
595 od.writeAttr("bike", myRideBikeCount[index]);
596 od.writeAttr("aborted", myRideAbortCount[index]);
597 }
598 od.closeTag();
599}
600
601
602double
604 if (myVehicleCount > 0) {
606 } else {
607 return 0;
608 }
609}
610
611double
613 if (myVehicleCount > 0) {
615 } else {
616 return 0;
617 }
618}
619
620double
622 if (myVehicleCount > 0) {
624 } else {
625 return 0;
626 }
627}
628
629double
631 if (myVehicleCount > 0) {
633 } else {
634 return 0;
635 }
636}
637
638
639double
641 if (myVehicleCount > 0) {
643 } else {
644 return 0;
645 }
646}
647
648
649double
651 if (myVehicleCount > 0) {
653 } else {
654 return 0;
655 }
656}
657
658double
660 if (myWaitingDepartDelay >= 0) {
662 } else {
663 return -1;
664 }
665}
666
667
668double
672
673double
675 if (myBikeCount > 0) {
677 } else {
678 return 0;
679 }
680}
681
682double
684 if (myBikeCount > 0) {
686 } else {
687 return 0;
688 }
689}
690
691double
693 if (myBikeCount > 0) {
695 } else {
696 return 0;
697 }
698}
699
700double
702 if (myBikeCount > 0) {
704 } else {
705 return 0;
706 }
707}
708
709
710double
712 if (myBikeCount > 0) {
714 } else {
715 return 0;
716 }
717}
718
719double
721 if (myBikeCount > 0) {
723 } else {
724 return 0;
725 }
726}
727
728
729double
733
734double
736 if (myWalkCount > 0) {
738 } else {
739 return 0;
740 }
741}
742
743double
745 if (myWalkCount > 0) {
747 } else {
748 return 0;
749 }
750}
751
752
753double
755 if (myWalkCount > 0) {
757 } else {
758 return 0;
759 }
760}
761
762
763double
765 if (myRideCount[0] > 0) {
767 } else {
768 return 0;
769 }
770}
771
772double
774 if (myRideCount[0] > 0) {
776 } else {
777 return 0;
778 }
779}
780
781double
783 if (myRideCount[0] > 0) {
784 return myTotalRideRouteLength[0] / myRideCount[0];
785 } else {
786 return 0;
787 }
788}
789
790
791std::string
792MSDevice_Tripinfo::getParameter(const std::string& key) const {
793 if (key == toString(SUMO_ATTR_WAITINGTIME)) {
795 } else if (key == toString(SUMO_ATTR_WAITINGCOUNT)) {
796 return toString(myWaitingCount);
797 } else if (key == toString(SUMO_ATTR_STOPTIME)) {
799 } else if (key == toString(SUMO_ATTR_ARRIVALTIME)) {
801 } else if (key == toString(SUMO_ATTR_ARRIVALLANE)) {
802 return toString(myArrivalLane);
803 } else if (key == toString(SUMO_ATTR_ARRIVALPOS)) {
804 return toString(myArrivalPos);
805 } else if (key == toString(SUMO_ATTR_ARRIVALPOS_LAT)) {
807 } else if (key == toString(SUMO_ATTR_ARRIVALSPEED)) {
808 return toString(myArrivalSpeed);
809 }
810 throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
811}
812
813
814std::string
815MSDevice_Tripinfo::getGlobalParameter(const std::string& prefixedKey) {
816 std::string key = prefixedKey; // by default, assume vehicleTripStatistics;
817 const std::string err = "Parameter '" + prefixedKey + "' is not supported for device of type 'tripinfo'";
818 if (StringUtils::startsWith(key, "vehicleTripStatistics.")) {
819 key = prefixedKey.substr(22);
820 } else if (StringUtils::startsWith(key, "bikeTripStatistics.")) {
821 key = prefixedKey.substr(19);
822 if (key == toString(SUMO_ATTR_COUNT)) {
823 return toString(myBikeCount);
824 } else if (key == "routeLength") {
826 } else if (key == toString(SUMO_ATTR_SPEED)) {
828 } else if (key == toString(SUMO_ATTR_DURATION)) {
830 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
832 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
834 } else if (key == "departDelay") {
836 } else if (key == "totalTravelTime") {
837 // avoid human readable output
839 }
840 throw InvalidArgument(err);
841
842 } else if (StringUtils::startsWith(key, "pedestrianStatistics.")) {
843 key = prefixedKey.substr(21);
844 if (key == toString(SUMO_ATTR_NUMBER) || key == toString(SUMO_ATTR_COUNT)) {
845 return toString(myWalkCount);
846 } else if (key == "routeLength") {
848 } else if (key == toString(SUMO_ATTR_DURATION)) {
850 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
852 }
853 throw InvalidArgument(err);
854
855 } else if (StringUtils::startsWith(key, "rideStatistics.") ||
856 StringUtils::startsWith(key, "transportStatistics.")) {
857 int index = 0;
858 if (StringUtils::startsWith(key, "rideStatistics.")) {
859 key = prefixedKey.substr(15);
860 } else {
861 index = 1;
862 key = prefixedKey.substr(20);
863 }
864 if (key == toString(SUMO_ATTR_NUMBER) || key == toString(SUMO_ATTR_COUNT)) {
865 return toString(myRideCount[index]);
866 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
867 return toString(STEPS2TIME(myTotalRideWaitingTime[index] / MAX2(1, myRideCount[index])));
868 } else if (key == "routeLength") {
869 return toString(myTotalRideRouteLength[index] / MAX2(1, myRideCount[index]));
870 } else if (key == toString(SUMO_ATTR_DURATION)) {
871 return toString(myTotalRideRouteLength[index] / MAX2(1, myRideCount[index]));
872 } else if (key == "bus") {
873 return toString(myRideBusCount[index]);
874 } else if (key == "train") {
875 return toString(myRideRailCount[index]);
876 } else if (key == "taxi") {
877 return toString(myRideTaxiCount[index]);
878 } else if (key == "bike") {
879 return toString(myRideBikeCount[index]);
880 } else if (key == "aborted") {
881 return toString(myRideAbortCount[index]);
882 }
883 throw InvalidArgument(err);
884 }
885 // vehicleTripStatistics
886 if (key == toString(SUMO_ATTR_COUNT)) {
887 return toString(myVehicleCount);
888 } else if (key == "routeLength") {
889 return toString(getAvgRouteLength());
890 } else if (key == toString(SUMO_ATTR_SPEED)) {
891 return toString(getAvgTripSpeed());
892 } else if (key == toString(SUMO_ATTR_DURATION)) {
893 return toString(getAvgDuration());
894 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
895 return toString(getAvgWaitingTime());
896 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
897 return toString(getAvgTimeLoss());
898 } else if (key == "departDelay") {
899 return toString(getAvgDepartDelay());
900 } else if (key == "departDelayWaiting") {
902 } else if (key == "totalTravelTime") {
903 // avoid human readable output
905 } else if (key == "totalDepartDelay") {
907 }
908 throw InvalidArgument(err);
909}
910
911
912void
914 if (myHolder.hasDeparted()) {
917 std::ostringstream internals;
918 internals << myDepartLane << " ";
920 internals << myDepartPosLat << " ";
921 }
922 std::string state_arrivalLane = myArrivalLane == "" ? STATE_EMPTY_ARRIVALLANE : myArrivalLane;
923 internals << myDepartSpeed << " " << myRouteLength << " " << myWaitingTime << " " << myAmWaiting << " " << myWaitingCount << " ";
924 internals << myStoppingTime << " " << myParkingStarted << " ";
925 internals << myArrivalTime << " " << state_arrivalLane << " " << myArrivalPos << " " << myArrivalPosLat << " " << myArrivalSpeed;
926 out.writeAttr(SUMO_ATTR_STATE, internals.str());
927 out.closeTag();
928 }
929}
930
931
932void
946
947
948/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define NOT_ARRIVED
#define STATE_EMPTY_ARRIVALLANE
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:69
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define SIMSTEP
Definition SUMOTime.h:61
#define TIME2STEPS(x)
Definition SUMOTime.h:57
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a railway edge.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_TAXI
vehicle is a taxi
@ GIVEN
The time is given.
@ SUMO_TAG_DEVICE
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_ARRIVALSPEED
@ SUMO_ATTR_ARRIVALLANE
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_ARRIVALTIME
@ SUMO_ATTR_WAITINGTIME
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_STOPTIME
@ SUMO_ATTR_TIMELOSS
@ SUMO_ATTR_WAITINGCOUNT
@ SUMO_ATTR_ID
@ SUMO_ATTR_ARRIVALPOS_LAT
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_COUNT
@ SUMO_ATTR_STATE
The state of a link.
int gPrecision
the precision for floating point outputs
Definition StdDefs.cpp:26
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition StdDefs.h:58
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
A device which collects info on the vehicle trip (mainly on departure and arrival)
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves departure info on insertion.
static SUMOTime myTotalDepartDelay
const std::string deviceName() const
return the name for this type of device
double myDepartSpeed
The speed on departure.
static std::vector< int > myRideAbortCount
static double getAvgBikeTripSpeed()
static std::vector< SUMOTime > myTotalRideWaitingTime
static void writeStatistics(OutputDevice &od)
write statistic output to (xml) file
void saveState(OutputDevice &out) const
Saves the state of the device.
SUMOTime myArrivalTime
The vehicle's arrival time.
SUMOTime myWaitingTime
The overall waiting time.
void loadState(const SUMOSAXAttributes &attrs)
Loads the state of the device from the given description.
static std::set< const MSDevice_Tripinfo *, ComparatorNumericalIdLess > myPendingOutput
devices which may still need to produce output
static SUMOTime myTotalBikeDuration
static SUMOTime myTotalWalkTimeLoss
static double getAvgRideWaitingTime()
SUMOTime myParkingStarted
The time when parking started.
static double getAvgBikeDuration()
static double getAvgWalkRouteLength()
std::string myArrivalLane
The lane the vehicle arrived at.
static double getAvgDepartDelayWaiting()
MSDevice_Tripinfo(SUMOVehicle &holder, const std::string &id)
Constructor.
static double getAvgTimeLoss()
static void printRideStatistics(std::ostringstream &msg, const std::string &category, const std::string &modeName, const int index)
double myArrivalSpeed
The speed when arriving.
static double getAvgRideRouteLength()
static double getAvgBikeTimeLoss()
~MSDevice_Tripinfo()
Destructor.
static SUMOTime myTotalTimeLoss
static double getTotalDepartDelay()
static double getAvgRideDuration()
static std::vector< int > myRideRailCount
static double getAvgDepartDelay()
static double myTotalBikeRouteLength
static double myTotalSpeed
static double getAvgBikeRouteLength()
static std::vector< SUMOTime > myTotalRideDuration
static SUMOTime myTotalBikeTimeLoss
static double getAvgTripSpeed()
static std::string getGlobalParameter(const std::string &prefixedKey)
try to retrieve the given parameter from the global statistics. Throw exception for unsupported key
static double getAvgRouteLength()
accessors for GUINet-Parameters
void updateParkingStopTime()
update stopping time after parking
static SUMOTime myTotalBikeDepartDelay
static SUMOTime myTotalDuration
static SUMOTime myTotalWalkDuration
static std::string printStatistics()
get statistics for printing to stdout
static void generateOutputForUnfinished()
generate output for vehicles which are still in the network
static double myTotalBikeSpeed
static double getAvgWaitingTime()
static double getTotalBikeDepartDelay()
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 meanLengthOnLane)
Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal()
static void addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss)
record tripinfo data for pedestrians
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks for waiting steps when the vehicle moves.
std::string myDepartLane
The lane the vehicle departed at.
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
static void writeRideStatistics(OutputDevice &od, const std::string &category, const int index)
double myRouteLength
The route length.
static SUMOTime myTotalWaitingTime
static double myTotalRouteLength
static double getAvgBikeWaitingTime()
double myArrivalPosLat
The lateral position on the lane the vehicle arrived at.
static double getAvgDuration()
static SUMOTime myTotalBikeWaitingTime
static bool lowAcceleration(const SUMOTrafficObject &veh)
static void cleanup()
resets counters
int myWaitingCount
The overall number of unintended stops.
SUMOTime myStoppingTime
The overall intentional stopping time.
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves arrival info.
void generateOutput(OutputDevice *tripinfoOut) const
Called on writing tripinfo output.
static void addRideTransportData(const bool isPerson, const double distance, const SUMOTime duration, const SUMOVehicleClass vClass, const std::string &line, const SUMOTime waitingTime)
record tripinfo data for rides and transports
static std::vector< int > myRideCount
bool notifyIdle(SUMOTrafficObject &veh)
record idling as waiting time - cf issue 2233
static double getAvgWalkDuration()
SUMOTime myMesoTimeLoss
The time loss when compared to the desired and allowed speed.
static std::vector< int > myRideBusCount
double myDepartPosLat
The lateral depart position.
bool myAmWaiting
Whether the vehicle is currently waiting.
static int myUndepartedVehicleCount
static int myVehicleCount
global tripinfo statistics
double myArrivalPos
The position on the lane the vehicle arrived at.
static std::vector< int > myRideTaxiCount
static std::vector< int > myRideBikeCount
static int myBikeCount
separate values for bicycles
MSMoveReminder::Notification myArrivalReason
The reason for vehicle arrival.
static double getAvgWalkTimeLoss()
static double myTotalWalkRouteLength
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_Tripinfo-options.
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
static SUMOTime myWaitingDepartDelay
static std::vector< double > myTotalRideRouteLength
static double getAvgBikeDepartDelay()
A device which collects info on the vehicle trip (mainly on departure and arrival)
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc, const bool isPerson=false)
Adds common command options that allow to assign devices to vehicles.
Definition MSDevice.cpp:155
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, DEVICEHOLDER &v, bool outputOptionSet, const bool isPerson=false)
Determines whether a vehicle should get a certain device.
Definition MSDevice.h:195
double getLength() const
return the length of the edge
Definition MSEdge.h:685
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition MSEdge.cpp:1170
MSLane * getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst=false) const
Definition MSEdge.cpp:726
static bool gUseMesoSim
Definition MSGlobals.h:106
static double gLateralResolution
Definition MSGlobals.h:100
Representation of a lane in the micro simulation.
Definition MSLane.h:84
double getLength() const
Returns the lane's length.
Definition MSLane.h:606
Something on a lane to be noticed about vehicle movement.
Notification
Definition of a vehicle state.
@ NOTIFICATION_VAPORIZED_TRACI
The vehicle got removed via TraCI.
@ NOTIFICATION_ARRIVED
The vehicle arrived at its destination (is deleted)
@ NOTIFICATION_TELEPORT_ARRIVED
The vehicle was teleported out of the net.
@ NOTIFICATION_VAPORIZED_CALIBRATOR
The vehicle got removed by a calibrator.
@ NOTIFICATION_VAPORIZED_GUI
The vehicle got removed via the GUI.
@ NOTIFICATION_DEPARTED
The vehicle has departed (was inserted into the network)
@ NOTIFICATION_VAPORIZED_VAPORIZER
The vehicle got vaporized with a vaporizer.
@ NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
@ NOTIFICATION_PARKING
The vehicle starts or ends parking.
@ NOTIFICATION_VAPORIZED_COLLISION
The vehicle got removed by a collision.
@ NOTIFICATION_TELEPORT
The vehicle is being teleported.
@ NOTIFICATION_TELEPORT_CONTINUATION
The vehicle continues being teleported past an edge.
const MSLane * getLane() const
Returns the lane the reminder works on.
The simulated network and simulation perfomer.
Definition MSNet.h:89
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:320
bool hasPersons() const
Returns whether persons are simulated.
Definition MSNet.h:395
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1190
const MSEdge * getLastEdge() const
returns the destination edge
Definition MSRoute.cpp:91
constVehIt loadedBegin() const
Returns the begin of the internal transportables map.
constVehIt loadedEnd() const
Returns the end of the internal transportables map.
virtual void erase(MSTransportable *transportable)
removes a single transportable
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
double accelThresholdForWaiting() const
maximum acceleration to consider a vehicle as 'waiting' at low speed
Definition MSVehicle.h:2064
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
Definition MSVehicle.h:514
const std::string & getID() const
Returns the name of the vehicle type.
const std::string & getID() const
Returns the id.
Definition Named.h:74
A storage for options typed value containers)
Definition OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
void setPrecision(int precision=gPrecision)
Sets the precision or resets it to default.
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
Representation of a vehicle, person, or container.
virtual bool isVehicle() const
Whether it is a vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual double getChosenSpeedFactor() const =0
virtual double getSpeed() const =0
Returns the object's current speed.
virtual SUMOTime getWaitingTime(const bool accumulated=false) const =0
virtual bool isStopped() const =0
Returns whether the object is at a stop.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
virtual int getRoutePosition() const =0
return index of edge within route
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition SUMOVehicle.h:62
virtual SUMOTime getDeparture() const =0
Returns this vehicle's real departure time.
virtual const std::vector< MSVehicleDevice * > & getDevices() const =0
Returns this vehicle's devices.
virtual bool hasDeparted() const =0
Returns whether this vehicle has departed.
virtual int getNumberReroutes() const =0
Returns the number of new routes this vehicle got.
virtual double getArrivalPos() const =0
Returns this vehicle's desired arrivalPos for its current route (may change on reroute)
virtual double getDepartPos() const =0
Returns this vehicle's real departure position.
virtual SUMOTime getDepartDelay() const =0
virtual const MSRoute & getRoute() const =0
Returns the current route.
Structure representing possible vehicle parameter.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
int arrivalEdge
(optional) The final edge within the route of the vehicle
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.