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-2023 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
40
41// ===========================================================================
42// static members
43// ===========================================================================
44std::set<const MSDevice_Tripinfo*, ComparatorNumericalIdLess> MSDevice_Tripinfo::myPendingOutput;
45
55
62
67std::vector<int> MSDevice_Tripinfo::myRideCount({0, 0});
68std::vector<int> MSDevice_Tripinfo::myRideBusCount({0, 0});
69std::vector<int> MSDevice_Tripinfo::myRideRailCount({0, 0});
70std::vector<int> MSDevice_Tripinfo::myRideTaxiCount({0, 0});
71std::vector<int> MSDevice_Tripinfo::myRideBikeCount({0, 0});
72std::vector<int> MSDevice_Tripinfo::myRideAbortCount({0, 0});
73std::vector<SUMOTime> MSDevice_Tripinfo::myTotalRideWaitingTime({0, 0});
74std::vector<double> MSDevice_Tripinfo::myTotalRideRouteLength({0., 0.});
75std::vector<SUMOTime> MSDevice_Tripinfo::myTotalRideDuration({0, 0});
76
77// ===========================================================================
78// method definitions
79// ===========================================================================
80// ---------------------------------------------------------------------------
81// static initialisation methods
82// ---------------------------------------------------------------------------
83void
85 oc.addOptionSubTopic("Tripinfo Device");
86 insertDefaultAssignmentOptions("tripinfo", "Tripinfo Device", oc);
87}
88
89
90void
91MSDevice_Tripinfo::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
93 const bool enableByOutputOption = oc.isSet("tripinfo-output") || oc.getBool("duration-log.statistics");
94 if (equippedByDefaultAssignmentOptions(oc, "tripinfo", v, enableByOutputOption)) {
95 MSDevice_Tripinfo* device = new MSDevice_Tripinfo(v, "tripinfo_" + v.getID());
96 into.push_back(device);
97 myPendingOutput.insert(device);
98 }
99}
100
101
102// ---------------------------------------------------------------------------
103// MSDevice_Tripinfo-methods
104// ---------------------------------------------------------------------------
105MSDevice_Tripinfo::MSDevice_Tripinfo(SUMOVehicle& holder, const std::string& id) :
106 MSVehicleDevice(holder, id),
107 myDepartLane(""),
108 myDepartSpeed(-1),
109 myDepartPosLat(0),
110 myWaitingTime(0),
111 myAmWaiting(false),
112 myWaitingCount(0),
113 myStoppingTime(0),
114 myParkingStarted(-1),
115 myArrivalTime(NOT_ARRIVED),
116 myArrivalLane(""),
117 myArrivalPos(-1),
118 myArrivalPosLat(0.),
119 myArrivalSpeed(-1),
120 myArrivalReason(MSMoveReminder::NOTIFICATION_ARRIVED),
121 myMesoTimeLoss(0),
122 myRouteLength(0.) {
123}
124
125
127 // ensure clean up for vaporized vehicles which do not generate output
128 myPendingOutput.erase(this);
129}
130
131void
133 myVehicleCount = 0;
135 myTotalSpeed = 0;
136 myTotalDuration = 0;
138 myTotalTimeLoss = 0;
141
142 myBikeCount = 0;
148
149 myWalkCount = 0;
153
154 myRideCount = {0, 0};
155 myRideBusCount = {0, 0};
156 myRideRailCount = {0, 0};
157 myRideTaxiCount = {0, 0};
158 myRideBikeCount = {0, 0};
159 myRideAbortCount = {0, 0};
160 myTotalRideWaitingTime = {0, 0};
161 myTotalRideRouteLength = {0., 0.};
162 myTotalRideDuration = {0, 0};
163}
164
165bool
167 if (veh.isVehicle()) {
169 if (!myAmWaiting) {
171 myAmWaiting = true;
172 }
173 }
174 return true;
175}
176
177
178bool
180 double /*newPos*/, double newSpeed) {
181 if (veh.isStopped()) {
182 if (newSpeed <= SUMO_const_haltingSpeed) {
184 }
185 } else if (newSpeed <= SUMO_const_haltingSpeed && lowAcceleration(veh)) {
187 if (!myAmWaiting) {
189 myAmWaiting = true;
190 }
191 } else {
192 myAmWaiting = false;
193 }
194 return true;
195}
196
197
198bool
201 // acceleration is not modelled
202 return false;
203 } else {
204 const MSVehicle& v = dynamic_cast<const MSVehicle&>(veh);
206 }
207}
208
209
210void
212 const double /* frontOnLane */,
213 const double timeOnLane,
214 const double /* meanSpeedFrontOnLane */,
215 const double meanSpeedVehicleOnLane,
216 const double /* travelledDistanceFrontOnLane */,
217 const double /* travelledDistanceVehicleOnLane */,
218 const double /* meanLengthOnLane */) {
219
220 // called by meso
221 const double vmax = veh.getEdge()->getVehicleMaxSpeed(&veh);
222 if (vmax > 0) {
223 myMesoTimeLoss += TIME2STEPS(timeOnLane * (vmax - meanSpeedVehicleOnLane) / vmax);
224 }
226}
227
228
229void
231 if (myParkingStarted >= 0) {
233 myParkingStarted = -1;
234 }
235}
236
237bool
241 myDepartLane = static_cast<MSVehicle&>(veh).getLane()->getID();
242 myDepartPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
243 }
244 myDepartSpeed = veh.getSpeed();
246 } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
247 // notifyMove is not called while parking
248 // @note insertion delay when resuming after parking is included
250 }
251 return true;
252}
253
254
255bool
257 MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
260 myArrivalReason = reason;
262 myArrivalLane = static_cast<MSVehicle&>(veh).getLane()->getID();
263 myArrivalPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
264 }
265 // @note vehicle may have moved past its arrivalPos during the last step
266 // due to non-zero arrivalspeed but we consider it as arrived at the desired position
267 // However, vaporization may happen anywhere (via TraCI)
269 // vaporized
271 } else {
273 }
274 myArrivalSpeed = veh.getSpeed();
276 } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
278 } else if (reason == NOTIFICATION_JUNCTION || reason == NOTIFICATION_TELEPORT) {
281 } else {
282 const MSLane* lane = static_cast<MSVehicle&>(veh).getLane();
283 if (lane != nullptr) {
284 myRouteLength += lane->getLength();
285 }
286 }
287 }
288 return true;
289}
290
291
292void
294 const SUMOTime timeLoss = MSGlobals::gUseMesoSim ? myMesoTimeLoss : static_cast<MSVehicle&>(myHolder).getTimeLoss();
295 const double routeLength = myRouteLength + (myArrivalTime == NOT_ARRIVED ? myHolder.getPositionOnLane() : myArrivalPos);
296 SUMOTime duration = 0;
297 if (myHolder.hasDeparted()) {
299 if (myHolder.getVClass() == SVC_BICYCLE) {
300 myBikeCount++;
301 myTotalBikeRouteLength += routeLength;
302 myTotalBikeSpeed += routeLength / STEPS2TIME(duration);
303 myTotalBikeDuration += duration;
305 myTotalBikeTimeLoss += timeLoss;
306 } else {
308 myTotalRouteLength += routeLength;
309 myTotalSpeed += routeLength / STEPS2TIME(duration);
310 myTotalDuration += duration;
312 myTotalTimeLoss += timeLoss;
313 }
315 }
316
317 myPendingOutput.erase(this);
318 if (tripinfoOut == nullptr) {
319 return;
320 }
321 // write
322 OutputDevice& os = *tripinfoOut;
323 os.openTag("tripinfo").writeAttr("id", myHolder.getID());
325 os.writeAttr("departLane", myDepartLane);
326 os.writeAttr("departPos", myHolder.getDepartPos());
328 os.writeAttr("departPosLat", myDepartPosLat);
329 }
330 os.writeAttr("departSpeed", myDepartSpeed);
331 SUMOTime departDelay = myHolder.getDepartDelay();
333 if (!myHolder.hasDeparted()) {
334 assert(param.depart <= SIMSTEP || param.departProcedure != DepartDefinition::GIVEN);
335 departDelay = SIMSTEP - param.depart;
336 }
337 os.writeAttr("departDelay", time2string(departDelay));
338 os.writeAttr("arrival", time2string(myArrivalTime));
339 os.writeAttr("arrivalLane", myArrivalLane);
340 os.writeAttr("arrivalPos", myArrivalPos);
342 os.writeAttr("arrivalPosLat", myArrivalPosLat);
343 }
344 os.writeAttr("arrivalSpeed", myArrivalSpeed);
345 os.writeAttr("duration", time2string(duration));
346 os.writeAttr("routeLength", routeLength);
351 os.writeAttr("rerouteNo", myHolder.getNumberReroutes());
352 os.writeAttr("devices", toString(myHolder.getDevices()));
353 os.writeAttr("vType", myHolder.getVehicleType().getID());
354 os.writeAttr("speedFactor", myHolder.getChosenSpeedFactor());
355 std::string vaporized;
356 switch (myArrivalReason) {
358 vaporized = "calibrator";
359 break;
361 vaporized = "gui";
362 break;
364 vaporized = "collision";
365 break;
367 vaporized = "vaporizer";
368 break;
370 vaporized = "traci";
371 break;
373 vaporized = "teleport";
374 break;
375 default:
377 (param.arrivalEdge >= 0 && myHolder.getRoutePosition() >= param.arrivalEdge)) {
378 vaporized = "";
379 } else {
380 vaporized = "end";
381 }
382 break;
383 }
384 os.writeAttr("vaporized", vaporized);
385 // cannot close tag because emission device output might follow
386}
387
388
389void
391 MSNet* net = MSNet::getInstance();
392 OutputDevice* tripinfoOut = (OptionsCont::getOptions().isSet("tripinfo-output") ?
393 &OutputDevice::getDeviceByOption("tripinfo-output") : nullptr);
396 const bool writeUndeparted = OptionsCont::getOptions().getBool("tripinfo-output.write-undeparted");
397 const SUMOTime t = net->getCurrentTimeStep();
398 while (myPendingOutput.size() > 0) {
399 const MSDevice_Tripinfo* d = *myPendingOutput.begin();
400 const bool departed = d->myHolder.hasDeparted();
401 const bool departDelayed = d->myHolder.getParameter().depart <= t;
402 if (!departed && departDelayed) {
405 }
406 if (departed || (writeUndeparted && departDelayed)) {
407 const_cast<MSDevice_Tripinfo*>(d)->updateParkingStopTime();
408 d->generateOutput(tripinfoOut);
409 if (tripinfoOut != nullptr) {
410 for (MSVehicleDevice* const dev : d->myHolder.getDevices()) {
411 if (typeid(*dev) == typeid(MSDevice_Tripinfo) || typeid(*dev) == typeid(MSDevice_Vehroutes)) {
412 // tripinfo is special and vehroute has it's own write-unfinished option
413 continue;
414 }
415 dev->generateOutput(tripinfoOut);
416 }
417 OutputDevice::getDeviceByOption("tripinfo-output").closeTag();
418 }
419 } else {
420 myPendingOutput.erase(d);
421 }
422 }
423 // unfinished persons
424 if (net->hasPersons()) {
426 while (pc.loadedBegin() != pc.loadedEnd()) {
427 pc.erase(pc.loadedBegin()->second);
428 }
429 }
430
431}
432
433
434void
435MSDevice_Tripinfo::addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss) {
436 myWalkCount++;
437 myTotalWalkRouteLength += walkLength;
438 myTotalWalkDuration += walkDuration;
439 myTotalWalkTimeLoss += walkTimeLoss;
440}
441
442
443void
444MSDevice_Tripinfo::addRideTransportData(const bool isPerson, const double distance, const SUMOTime duration,
445 const SUMOVehicleClass vClass, const std::string& line, const SUMOTime waitingTime) {
446 const int index = isPerson ? 0 : 1;
447 myRideCount[index]++;
448 if (duration > 0) {
449 myTotalRideWaitingTime[index] += waitingTime;
450 myTotalRideRouteLength[index] += distance;
451 myTotalRideDuration[index] += duration;
452 if (vClass == SVC_BICYCLE) {
453 myRideBikeCount[index]++;
454 } else if (!line.empty()) {
455 if (isRailway(vClass)) {
456 myRideRailCount[index]++;
457 } else if (vClass == SVC_TAXI) {
458 myRideTaxiCount[index]++;
459 } else {
460 // some kind of road vehicle
461 myRideBusCount[index]++;
462 }
463 }
464 } else {
465 myRideAbortCount[index]++;
466 }
467}
468
469
470std::string
472 std::ostringstream msg;
473 msg.setf(msg.fixed);
474 msg.precision(gPrecision);
475 if (myBikeCount == 0 || myVehicleCount > 0) {
476 msg << "Statistics (avg of " << myVehicleCount << "):\n";
477 msg << " RouteLength: " << getAvgRouteLength() << "\n"
478 << " Speed: " << getAvgTripSpeed() << "\n"
479 << " Duration: " << getAvgDuration() << "\n"
480 << " WaitingTime: " << getAvgWaitingTime() << "\n"
481 << " TimeLoss: " << getAvgTimeLoss() << "\n";
482 }
483 if (myBikeCount > 0) {
484 msg << "Bike Statistics (avg of " << myBikeCount << "):\n"
485 << " RouteLength: " << getAvgBikeRouteLength() << "\n"
486 << " Speed: " << getAvgBikeTripSpeed() << "\n"
487 << " Duration: " << getAvgBikeDuration() << "\n"
488 << " WaitingTime: " << getAvgBikeWaitingTime() << "\n"
489 << " TimeLoss: " << getAvgBikeTimeLoss() << "\n";
490 if (myVehicleCount > 0) {
491 msg << "Statistics (avg of " << (myVehicleCount + myBikeCount) << "):\n";
492 }
493 }
494 msg << " DepartDelay: " << getAvgDepartDelay() << "\n";
495 if (myWaitingDepartDelay >= 0) {
496 msg << " DepartDelayWaiting: " << getAvgDepartDelayWaiting() << "\n";
497 }
498 if (myWalkCount > 0) {
499 msg << "Pedestrian Statistics (avg of " << myWalkCount << " walks):\n"
500 << " RouteLength: " << getAvgWalkRouteLength() << "\n"
501 << " Duration: " << getAvgWalkDuration() << "\n"
502 << " TimeLoss: " << getAvgWalkTimeLoss() << "\n";
503 }
504 printRideStatistics(msg, "Ride", "rides", 0);
505 printRideStatistics(msg, "Transport", "transports", 1);
506 return msg.str();
507}
508
509void
510MSDevice_Tripinfo::printRideStatistics(std::ostringstream& msg, const std::string& category, const std::string& modeName, const int index) {
511 if (myRideCount[index] > 0) {
512 msg << category << " Statistics (avg of " << myRideCount[index] << " " << modeName << "):\n";
513 msg << " WaitingTime: " << STEPS2TIME(myTotalRideWaitingTime[index] / myRideCount[index]) << "\n";
514 msg << " RouteLength: " << myTotalRideRouteLength[index] / myRideCount[index] << "\n";
515 msg << " Duration: " << STEPS2TIME(myTotalRideDuration[index] / myRideCount[index]) << "\n";
516 if (myRideBusCount[index] > 0) {
517 msg << " Bus: " << myRideBusCount[index] << "\n";
518 }
519 if (myRideRailCount[index] > 0) {
520 msg << " Train: " << myRideRailCount[index] << "\n";
521 }
522 if (myRideTaxiCount[index] > 0) {
523 msg << " Taxi: " << myRideTaxiCount[index] << "\n";
524 }
525 if (myRideBikeCount[index] > 0) {
526 msg << " Bike: " << myRideBikeCount[index] << "\n";
527 }
528 if (myRideAbortCount[index] > 0) {
529 msg << " Aborted: " << myRideAbortCount[index] << "\n";
530 }
531 }
532
533}
534
535
536void
539 od.openTag("vehicleTripStatistics");
540 od.writeAttr("count", myVehicleCount);
541 od.writeAttr("routeLength", getAvgRouteLength());
542 od.writeAttr("speed", getAvgTripSpeed());
543 od.writeAttr("duration", getAvgDuration());
544 od.writeAttr("waitingTime", getAvgWaitingTime());
545 od.writeAttr("timeLoss", getAvgTimeLoss());
546 od.writeAttr("departDelay", getAvgDepartDelay());
547 od.writeAttr("departDelayWaiting", getAvgDepartDelayWaiting());
548 od.writeAttr("totalTravelTime", time2string(myTotalDuration));
549 od.writeAttr("totalDepartDelay", time2string(TIME2STEPS(getTotalDepartDelay())));
550 od.closeTag();
551 if (myBikeCount > 0) {
552 od.openTag("bikeTripStatistics");
553 od.writeAttr("count", myBikeCount);
554 od.writeAttr("routeLength", getAvgBikeRouteLength());
555 od.writeAttr("speed", getAvgBikeTripSpeed());
556 od.writeAttr("duration", getAvgBikeDuration());
557 od.writeAttr("waitingTime", getAvgBikeWaitingTime());
558 od.writeAttr("timeLoss", getAvgBikeTimeLoss());
559 od.writeAttr("totalTravelTime", time2string(myTotalBikeDuration));
560 od.closeTag();
561 }
562 od.openTag("pedestrianStatistics");
563 od.writeAttr("number", myWalkCount);
564 od.writeAttr("routeLength", getAvgWalkRouteLength());
565 od.writeAttr("duration", getAvgWalkDuration());
566 od.writeAttr("timeLoss", getAvgWalkTimeLoss());
567 od.closeTag();
568 writeRideStatistics(od, "rideStatistics", 0);
569 writeRideStatistics(od, "transportStatistics", 1);
570}
571
572void
573MSDevice_Tripinfo::writeRideStatistics(OutputDevice& od, const std::string& category, const int index) {
574 od.openTag(category);
575 od.writeAttr("number", myRideCount[index]);
576 if (myRideCount[index] > 0) {
577 od.writeAttr("waitingTime", STEPS2TIME(myTotalRideWaitingTime[index] / myRideCount[index]));
578 od.writeAttr("routeLength", myTotalRideRouteLength[index] / myRideCount[index]);
579 od.writeAttr("duration", STEPS2TIME(myTotalRideDuration[index] / myRideCount[index]));
580 od.writeAttr("bus", myRideBusCount[index]);
581 od.writeAttr("train", myRideRailCount[index]);
582 od.writeAttr("taxi", myRideTaxiCount[index]);
583 od.writeAttr("bike", myRideBikeCount[index]);
584 od.writeAttr("aborted", myRideAbortCount[index]);
585 }
586 od.closeTag();
587}
588
589
590double
592 if (myVehicleCount > 0) {
594 } else {
595 return 0;
596 }
597}
598
599double
601 if (myVehicleCount > 0) {
603 } else {
604 return 0;
605 }
606}
607
608double
610 if (myVehicleCount > 0) {
612 } else {
613 return 0;
614 }
615}
616
617double
619 if (myVehicleCount > 0) {
621 } else {
622 return 0;
623 }
624}
625
626
627double
629 if (myVehicleCount > 0) {
631 } else {
632 return 0;
633 }
634}
635
636
637double
639 if (myVehicleCount > 0) {
641 } else {
642 return 0;
643 }
644}
645
646double
648 if (myWaitingDepartDelay >= 0) {
650 } else {
651 return -1;
652 }
653}
654
655
656double
659}
660
661double
663 if (myBikeCount > 0) {
665 } else {
666 return 0;
667 }
668}
669
670double
672 if (myBikeCount > 0) {
674 } else {
675 return 0;
676 }
677}
678
679double
681 if (myBikeCount > 0) {
683 } else {
684 return 0;
685 }
686}
687
688double
690 if (myBikeCount > 0) {
692 } else {
693 return 0;
694 }
695}
696
697
698double
700 if (myBikeCount > 0) {
702 } else {
703 return 0;
704 }
705}
706
707
708
709double
711 if (myWalkCount > 0) {
713 } else {
714 return 0;
715 }
716}
717
718double
720 if (myWalkCount > 0) {
722 } else {
723 return 0;
724 }
725}
726
727
728double
730 if (myWalkCount > 0) {
732 } else {
733 return 0;
734 }
735}
736
737
738double
740 if (myRideCount[0] > 0) {
742 } else {
743 return 0;
744 }
745}
746
747double
749 if (myRideCount[0] > 0) {
751 } else {
752 return 0;
753 }
754}
755
756double
758 if (myRideCount[0] > 0) {
759 return myTotalRideRouteLength[0] / myRideCount[0];
760 } else {
761 return 0;
762 }
763}
764
765
766std::string
767MSDevice_Tripinfo::getParameter(const std::string& key) const {
768 if (key == toString(SUMO_ATTR_WAITINGTIME)) {
770 } else if (key == toString(SUMO_ATTR_WAITINGCOUNT)) {
771 return toString(myWaitingCount);
772 } else if (key == toString(SUMO_ATTR_STOPTIME)) {
774 }
775 throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
776}
777
778
779std::string
780MSDevice_Tripinfo::getGlobalParameter(const std::string& prefixedKey) {
781 std::string key = prefixedKey; // by default, assume vehicleTripStatistics;
782 const std::string err = "Parameter '" + prefixedKey + "' is not supported for device of type 'tripinfo'";
783 if (StringUtils::startsWith(key, "vehicleTripStatistics.")) {
784 key = prefixedKey.substr(22);
785 } else if (StringUtils::startsWith(key, "bikeTripStatistics.")) {
786 key = prefixedKey.substr(19);
787 if (key == toString(SUMO_ATTR_COUNT)) {
788 return toString(myBikeCount);
789 } else if (key == "routeLength") {
791 } else if (key == toString(SUMO_ATTR_SPEED)) {
793 } else if (key == toString(SUMO_ATTR_DURATION)) {
795 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
797 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
799 } else if (key == "totalTravelTime") {
800 // avoid human readable output
802 }
803 throw InvalidArgument(err);
804
805 } else if (StringUtils::startsWith(key, "pedestrianStatistics.")) {
806 key = prefixedKey.substr(21);
807 if (key == toString(SUMO_ATTR_NUMBER) || key == toString(SUMO_ATTR_COUNT)) {
808 return toString(myWalkCount);
809 } else if (key == "routeLength") {
811 } else if (key == toString(SUMO_ATTR_DURATION)) {
813 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
815 }
816 throw InvalidArgument(err);
817
818 } else if (StringUtils::startsWith(key, "rideStatistics.") ||
819 StringUtils::startsWith(key, "transportStatistics.")) {
820 int index = 0;
821 if (StringUtils::startsWith(key, "rideStatistics.")) {
822 key = prefixedKey.substr(15);
823 } else {
824 index = 1;
825 key = prefixedKey.substr(20);
826 }
827 if (key == toString(SUMO_ATTR_NUMBER) || key == toString(SUMO_ATTR_COUNT)) {
828 return toString(myRideCount[index]);
829 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
830 return toString(STEPS2TIME(myTotalRideWaitingTime[index] / MAX2(1, myRideCount[index])));
831 } else if (key == "routeLength") {
832 return toString(myTotalRideRouteLength[index] / MAX2(1, myRideCount[index]));
833 } else if (key == toString(SUMO_ATTR_DURATION)) {
834 return toString(myTotalRideRouteLength[index] / MAX2(1, myRideCount[index]));
835 } else if (key == "bus") {
836 return toString(myRideBusCount[index]);
837 } else if (key == "train") {
838 return toString(myRideRailCount[index]);
839 } else if (key == "taxi") {
840 return toString(myRideTaxiCount[index]);
841 } else if (key == "bike") {
842 return toString(myRideBikeCount[index]);
843 } else if (key == "aborted") {
844 return toString(myRideAbortCount[index]);
845 }
846 throw InvalidArgument(err);
847 }
848 // vehicleTripStatistics
849 if (key == toString(SUMO_ATTR_COUNT)) {
850 return toString(myVehicleCount);
851 } else if (key == "routeLength") {
852 return toString(getAvgRouteLength());
853 } else if (key == toString(SUMO_ATTR_SPEED)) {
854 return toString(getAvgTripSpeed());
855 } else if (key == toString(SUMO_ATTR_DURATION)) {
856 return toString(getAvgDuration());
857 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
858 return toString(getAvgWaitingTime());
859 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
860 return toString(getAvgTimeLoss());
861 } else if (key == "departDelay") {
862 return toString(getAvgDepartDelay());
863 } else if (key == "departDelayWaiting") {
865 } else if (key == "totalTravelTime") {
866 // avoid human readable output
868 } else if (key == "totalDepartDelay") {
870 }
871 throw InvalidArgument(err);
872}
873
874
875void
877 if (myHolder.hasDeparted()) {
880 std::ostringstream internals;
882 internals << myDepartLane << " " << myDepartPosLat << " ";
883 }
884 internals << myDepartSpeed << " " << myRouteLength << " " << myWaitingTime << " " << myAmWaiting << " " << myWaitingCount << " ";
885 internals << myStoppingTime << " " << myParkingStarted;
886 out.writeAttr(SUMO_ATTR_STATE, internals.str());
887 out.closeTag();
888 }
889}
890
891
892void
894 std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
897 }
900}
901
902
903/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
#define NOT_ARRIVED
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
#define STEPS2TIME(x)
Definition: SUMOTime.h:54
#define SIMSTEP
Definition: SUMOTime.h:60
#define TIME2STEPS(x)
Definition: SUMOTime.h:56
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission 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_SPEED
@ SUMO_ATTR_WAITINGTIME
@ SUMO_ATTR_STOPTIME
@ SUMO_ATTR_TIMELOSS
@ SUMO_ATTR_WAITINGCOUNT
@ SUMO_ATTR_ID
@ 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 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()
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
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:144
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:202
double getLength() const
return the length of the edge
Definition: MSEdge.h:658
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:1068
static bool gUseMesoSim
Definition: MSGlobals.h:103
static double gLateralResolution
Definition: MSGlobals.h:97
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
double getLength() const
Returns the lane's length.
Definition: MSLane.h:593
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.
const MSLane * getLane() const
Returns the lane the reminder works on.
The simulated network and simulation perfomer.
Definition: MSNet.h:88
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
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:1159
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:2054
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:517
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:91
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.
Definition: OptionsCont.cpp:59
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
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 SUMOTime getWaitingTime() const =0
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 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.