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-2026 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 if (veh.getWaitingTime() >= TIME2STEPS(1)) {
230 // waiting counts the time spent waiting to enter the next link (when it's occupied).
232 }
233}
234
235
236void
238 myMesoTimeLoss += waitingTime;
239 myWaitingTime += waitingTime;
241}
242
243void
250
251bool
255 myDepartLane = static_cast<MSVehicle&>(veh).getLane()->getID();
256 myDepartPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
257 } else {
258 myDepartLane = veh.getEdge()->getFirstAllowed(veh.getVClass(), true)->getID();
259 }
260 myDepartSpeed = veh.getSpeed();
262 } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
263 // notifyMove is not called while parking
264 // @note insertion delay when resuming after parking is included
266 }
267 return true;
268}
269
270
271bool
273 MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
276 myArrivalReason = reason;
278 myArrivalLane = static_cast<MSVehicle&>(veh).getLane()->getID();
279 myArrivalPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
280 } else {
281 myArrivalLane = veh.getEdge()->getFirstAllowed(veh.getVClass(), true)->getID();
282 }
283 // @note vehicle may have moved past its arrivalPos during the last step
284 // due to non-zero arrivalspeed but we consider it as arrived at the desired position
285 // However, vaporization may happen anywhere (via TraCI)
287 // vaporized
289 } else {
291 }
292 myArrivalSpeed = veh.getSpeed();
294 } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
296 } else if (reason == NOTIFICATION_JUNCTION
297 || reason == NOTIFICATION_TELEPORT
301 } else {
302 const MSLane* lane = static_cast<MSVehicle&>(veh).getLane();
303 if (lane != nullptr) {
304 myRouteLength += lane->getLength();
305 }
306 }
307 }
308 return true;
309}
310
311
312void
314 const SUMOTime timeLoss = MSGlobals::gUseMesoSim ? myMesoTimeLoss : static_cast<MSVehicle&>(myHolder).getTimeLoss();
315 const double routeLength = myRouteLength + (myArrivalTime == NOT_ARRIVED ? myHolder.getPositionOnLane() : myArrivalPos);
316 SUMOTime duration = 0;
317 if (myHolder.hasDeparted()) {
319 if (myHolder.getVClass() == SVC_BICYCLE) {
320 myBikeCount++;
321 myTotalBikeRouteLength += routeLength;
322 myTotalBikeSpeed += routeLength / STEPS2TIME(duration);
323 myTotalBikeDuration += duration;
325 myTotalBikeTimeLoss += timeLoss;
327 } else {
329 myTotalRouteLength += routeLength;
330 myTotalSpeed += routeLength / STEPS2TIME(duration);
331 myTotalDuration += duration;
333 myTotalTimeLoss += timeLoss;
335 }
336 }
337
338 myPendingOutput.erase(this);
339 if (tripinfoOut == nullptr) {
340 return;
341 }
342 // write
343 OutputDevice& os = *tripinfoOut;
344 os.openTag("tripinfo").writeAttr("id", myHolder.getID());
346 os.writeAttr("departLane", myDepartLane);
347 os.writeAttr("departPos", myHolder.getDepartPos());
349 os.writeAttr("departPosLat", myDepartPosLat);
350 }
351 os.writeAttr("departSpeed", myDepartSpeed);
352 SUMOTime departDelay = myHolder.getDepartDelay();
354 if (!myHolder.hasDeparted()) {
355 assert(param.depart <= SIMSTEP || param.departProcedure != DepartDefinition::GIVEN);
356 departDelay = SIMSTEP - param.depart;
357 }
358 os.writeAttr("departDelay", time2string(departDelay));
359 os.writeAttr("arrival", time2string(myArrivalTime));
360 os.writeAttr("arrivalLane", myArrivalLane);
361 os.writeAttr("arrivalPos", myArrivalPos);
363 os.writeAttr("arrivalPosLat", myArrivalPosLat);
364 }
365 os.writeAttr("arrivalSpeed", myArrivalSpeed);
366 os.writeAttr("duration", time2string(duration));
367 os.writeAttr("routeLength", routeLength);
372 os.writeAttr("rerouteNo", myHolder.getNumberReroutes());
373 os.writeAttr("devices", toString(myHolder.getDevices()));
374 os.writeAttr("vType", myHolder.getVehicleType().getID());
375 os.writeAttr("speedFactor", myHolder.getChosenSpeedFactor());
376 std::string vaporized;
377 switch (myArrivalReason) {
379 vaporized = "calibrator";
380 break;
382 vaporized = "gui";
383 break;
385 vaporized = "collision";
386 break;
388 vaporized = "vaporizer";
389 break;
391 vaporized = "traci";
392 break;
394 vaporized = "teleport";
395 break;
396 default:
398 (param.arrivalEdge >= 0 && myHolder.getRoutePosition() >= param.arrivalEdge)) {
399 vaporized = "";
400 } else {
401 vaporized = "end";
402 }
403 break;
404 }
405 os.writeAttr("vaporized", vaporized);
406 // cannot close tag because emission device output might follow
407}
408
409
410void
412 MSNet* net = MSNet::getInstance();
413 OutputDevice* tripinfoOut = (OptionsCont::getOptions().isSet("tripinfo-output") ?
414 &OutputDevice::getDeviceByOption("tripinfo-output") : nullptr);
417 const bool writeUndeparted = OptionsCont::getOptions().getBool("tripinfo-output.write-undeparted");
418 const SUMOTime t = net->getCurrentTimeStep();
419 while (myPendingOutput.size() > 0) {
420 const MSDevice_Tripinfo* d = *myPendingOutput.begin();
421 const bool departed = d->myHolder.hasDeparted();
422 const bool departDelayed = d->myHolder.getParameter().depart <= t;
423 if (!departed && departDelayed) {
426 }
427 if (departed || (writeUndeparted && departDelayed)) {
428 const_cast<MSDevice_Tripinfo*>(d)->updateParkingStopTime();
429 d->generateOutput(tripinfoOut);
430 if (tripinfoOut != nullptr) {
431 for (MSVehicleDevice* const dev : d->myHolder.getDevices()) {
432 if (typeid(*dev) == typeid(MSDevice_Tripinfo) || typeid(*dev) == typeid(MSDevice_Vehroutes)) {
433 // tripinfo is special and vehroute has its own write-unfinished option
434 continue;
435 }
436 dev->generateOutput(tripinfoOut);
437 }
438 OutputDevice::getDeviceByOption("tripinfo-output").closeTag();
439 }
440 } else {
441 myPendingOutput.erase(d);
442 }
443 }
444 // unfinished persons
445 if (net->hasPersons()) {
446 net->getPersonControl().eraseAll();
447 }
448
449}
450
451
452void
453MSDevice_Tripinfo::addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss) {
454 myWalkCount++;
455 myTotalWalkRouteLength += walkLength;
456 myTotalWalkDuration += walkDuration;
457 myTotalWalkTimeLoss += walkTimeLoss;
458}
459
460
461void
462MSDevice_Tripinfo::addRideTransportData(const bool isPerson, const double distance, const SUMOTime duration,
463 const SUMOVehicleClass vClass, const std::string& line, const SUMOTime waitingTime) {
464 const int index = isPerson ? 0 : 1;
465 myRideCount[index]++;
466 if (duration > 0) {
467 myTotalRideWaitingTime[index] += waitingTime;
468 myTotalRideRouteLength[index] += distance;
469 myTotalRideDuration[index] += duration;
470 if (vClass == SVC_BICYCLE) {
471 myRideBikeCount[index]++;
472 } else if (!line.empty()) {
473 if (isRailway(vClass)) {
474 myRideRailCount[index]++;
475 } else if (vClass == SVC_TAXI) {
476 myRideTaxiCount[index]++;
477 } else {
478 // some kind of road vehicle
479 myRideBusCount[index]++;
480 }
481 }
482 } else {
483 myRideAbortCount[index]++;
484 }
485}
486
487
488std::string
490 std::ostringstream msg;
491 msg.setf(msg.fixed);
492 msg.precision(gPrecision);
493 if (myBikeCount == 0 || myVehicleCount > 0) {
494 msg << "Statistics (avg of " << myVehicleCount << "):\n";
495 msg << " RouteLength: " << getAvgRouteLength() << "\n"
496 << " Speed: " << getAvgTripSpeed() << "\n"
497 << " Duration: " << getAvgDuration() << "\n"
498 << " WaitingTime: " << getAvgWaitingTime() << "\n"
499 << " TimeLoss: " << getAvgTimeLoss() << "\n"
500 << " DepartDelay: " << getAvgDepartDelay() << "\n";
501 }
502 if (myBikeCount > 0) {
503 msg << "Bike Statistics (avg of " << myBikeCount << "):\n"
504 << " RouteLength: " << getAvgBikeRouteLength() << "\n"
505 << " Speed: " << getAvgBikeTripSpeed() << "\n"
506 << " Duration: " << getAvgBikeDuration() << "\n"
507 << " WaitingTime: " << getAvgBikeWaitingTime() << "\n"
508 << " TimeLoss: " << getAvgBikeTimeLoss() << "\n"
509 << " DepartDelay: " << getAvgBikeDepartDelay() << "\n";
510 if (myVehicleCount > 0 && myWaitingDepartDelay >= 0) {
511 msg << "Statistics (avg of " << (myVehicleCount + myBikeCount) << "):\n";
512 }
513 }
514 if (myWaitingDepartDelay >= 0) {
515 msg << " DepartDelayWaiting: " << getAvgDepartDelayWaiting() << "\n";
516 }
517 if (myWalkCount > 0) {
518 msg << "Pedestrian Statistics (avg of " << myWalkCount << " walks):\n"
519 << " RouteLength: " << getAvgWalkRouteLength() << "\n"
520 << " Duration: " << getAvgWalkDuration() << "\n"
521 << " TimeLoss: " << getAvgWalkTimeLoss() << "\n";
522 }
523 printRideStatistics(msg, "Ride", "rides", 0);
524 printRideStatistics(msg, "Transport", "transports", 1);
525 return msg.str();
526}
527
528void
529MSDevice_Tripinfo::printRideStatistics(std::ostringstream& msg, const std::string& category, const std::string& modeName, const int index) {
530 if (myRideCount[index] > 0) {
531 msg << category << " Statistics (avg of " << myRideCount[index] << " " << modeName << "):\n";
532 msg << " WaitingTime: " << STEPS2TIME(myTotalRideWaitingTime[index] / myRideCount[index]) << "\n";
533 msg << " RouteLength: " << myTotalRideRouteLength[index] / myRideCount[index] << "\n";
534 msg << " Duration: " << STEPS2TIME(myTotalRideDuration[index] / myRideCount[index]) << "\n";
535 if (myRideBusCount[index] > 0) {
536 msg << " Bus: " << myRideBusCount[index] << "\n";
537 }
538 if (myRideRailCount[index] > 0) {
539 msg << " Train: " << myRideRailCount[index] << "\n";
540 }
541 if (myRideTaxiCount[index] > 0) {
542 msg << " Taxi: " << myRideTaxiCount[index] << "\n";
543 }
544 if (myRideBikeCount[index] > 0) {
545 msg << " Bike: " << myRideBikeCount[index] << "\n";
546 }
547 if (myRideAbortCount[index] > 0) {
548 msg << " Aborted: " << myRideAbortCount[index] << "\n";
549 }
550 }
551
552}
553
554
555void
558 od.openTag("vehicleTripStatistics");
559 od.writeAttr("count", myVehicleCount);
560 od.writeAttr("routeLength", getAvgRouteLength());
561 od.writeAttr("speed", getAvgTripSpeed());
562 od.writeAttr("duration", getAvgDuration());
563 od.writeAttr("waitingTime", getAvgWaitingTime());
564 od.writeAttr("timeLoss", getAvgTimeLoss());
565 od.writeAttr("departDelay", getAvgDepartDelay());
566 od.writeAttr("departDelayWaiting", getAvgDepartDelayWaiting());
567 od.writeAttr("totalTravelTime", time2string(myTotalDuration));
569 od.closeTag();
570 if (myBikeCount > 0) {
571 od.openTag("bikeTripStatistics");
572 od.writeAttr("count", myBikeCount);
573 od.writeAttr("routeLength", getAvgBikeRouteLength());
574 od.writeAttr("speed", getAvgBikeTripSpeed());
575 od.writeAttr("duration", getAvgBikeDuration());
576 od.writeAttr("waitingTime", getAvgBikeWaitingTime());
577 od.writeAttr("timeLoss", getAvgBikeTimeLoss());
578 od.writeAttr("departDelay", getAvgBikeDepartDelay());
579 od.writeAttr("totalTravelTime", time2string(myTotalBikeDuration));
580 od.closeTag();
581 }
582 od.openTag("pedestrianStatistics");
583 od.writeAttr("number", myWalkCount);
584 od.writeAttr("routeLength", getAvgWalkRouteLength());
585 od.writeAttr("duration", getAvgWalkDuration());
586 od.writeAttr("timeLoss", getAvgWalkTimeLoss());
587 od.closeTag();
588 writeRideStatistics(od, "rideStatistics", 0);
589 writeRideStatistics(od, "transportStatistics", 1);
590}
591
592void
593MSDevice_Tripinfo::writeRideStatistics(OutputDevice& od, const std::string& category, const int index) {
594 od.openTag(category);
595 od.writeAttr("number", myRideCount[index]);
596 if (myRideCount[index] > 0) {
597 od.writeAttr("waitingTime", STEPS2TIME(myTotalRideWaitingTime[index] / myRideCount[index]));
598 od.writeAttr("routeLength", myTotalRideRouteLength[index] / myRideCount[index]);
599 od.writeAttr("duration", STEPS2TIME(myTotalRideDuration[index] / myRideCount[index]));
600 od.writeAttr("bus", myRideBusCount[index]);
601 od.writeAttr("train", myRideRailCount[index]);
602 od.writeAttr("taxi", myRideTaxiCount[index]);
603 od.writeAttr("bike", myRideBikeCount[index]);
604 od.writeAttr("aborted", myRideAbortCount[index]);
605 }
606 od.closeTag();
607}
608
609
610double
612 if (myVehicleCount > 0) {
614 } else {
615 return 0;
616 }
617}
618
619double
621 if (myVehicleCount > 0) {
623 } else {
624 return 0;
625 }
626}
627
628double
630 if (myVehicleCount > 0) {
632 } else {
633 return 0;
634 }
635}
636
637double
639 if (myVehicleCount > 0) {
641 } else {
642 return 0;
643 }
644}
645
646
647double
649 if (myVehicleCount > 0) {
651 } else {
652 return 0;
653 }
654}
655
656
657double
659 if (myVehicleCount > 0) {
661 } else {
662 return 0;
663 }
664}
665
666double
668 if (myWaitingDepartDelay >= 0) {
670 } else {
671 return -1;
672 }
673}
674
675
676double
680
681double
683 if (myBikeCount > 0) {
685 } else {
686 return 0;
687 }
688}
689
690double
692 if (myBikeCount > 0) {
694 } else {
695 return 0;
696 }
697}
698
699double
701 if (myBikeCount > 0) {
703 } else {
704 return 0;
705 }
706}
707
708double
710 if (myBikeCount > 0) {
712 } else {
713 return 0;
714 }
715}
716
717
718double
720 if (myBikeCount > 0) {
722 } else {
723 return 0;
724 }
725}
726
727double
729 if (myBikeCount > 0) {
731 } else {
732 return 0;
733 }
734}
735
736
737double
741
742double
744 if (myWalkCount > 0) {
746 } else {
747 return 0;
748 }
749}
750
751double
753 if (myWalkCount > 0) {
755 } else {
756 return 0;
757 }
758}
759
760
761double
763 if (myWalkCount > 0) {
765 } else {
766 return 0;
767 }
768}
769
770
771double
773 if (myRideCount[0] > 0) {
775 } else {
776 return 0;
777 }
778}
779
780double
782 if (myRideCount[0] > 0) {
784 } else {
785 return 0;
786 }
787}
788
789double
791 if (myRideCount[0] > 0) {
792 return myTotalRideRouteLength[0] / myRideCount[0];
793 } else {
794 return 0;
795 }
796}
797
798
799std::string
800MSDevice_Tripinfo::getParameter(const std::string& key) const {
801 if (key == toString(SUMO_ATTR_WAITINGTIME)) {
803 } else if (key == toString(SUMO_ATTR_WAITINGCOUNT)) {
804 return toString(myWaitingCount);
805 } else if (key == toString(SUMO_ATTR_STOPTIME)) {
807 } else if (key == toString(SUMO_ATTR_ARRIVALTIME)) {
809 } else if (key == toString(SUMO_ATTR_ARRIVALLANE)) {
810 return toString(myArrivalLane);
811 } else if (key == toString(SUMO_ATTR_ARRIVALPOS)) {
812 return toString(myArrivalPos);
813 } else if (key == toString(SUMO_ATTR_ARRIVALPOS_LAT)) {
815 } else if (key == toString(SUMO_ATTR_ARRIVALSPEED)) {
816 return toString(myArrivalSpeed);
817 }
818 throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
819}
820
821
822std::string
823MSDevice_Tripinfo::getGlobalParameter(const std::string& prefixedKey) {
824 std::string key = prefixedKey; // by default, assume vehicleTripStatistics;
825 const std::string err = "Parameter '" + prefixedKey + "' is not supported for device of type 'tripinfo'";
826 if (StringUtils::startsWith(key, "vehicleTripStatistics.")) {
827 key = prefixedKey.substr(22);
828 } else if (StringUtils::startsWith(key, "bikeTripStatistics.")) {
829 key = prefixedKey.substr(19);
830 if (key == toString(SUMO_ATTR_COUNT)) {
831 return toString(myBikeCount);
832 } else if (key == "routeLength") {
834 } else if (key == toString(SUMO_ATTR_SPEED)) {
836 } else if (key == toString(SUMO_ATTR_DURATION)) {
838 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
840 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
842 } else if (key == "departDelay") {
844 } else if (key == "totalTravelTime") {
845 // avoid human readable output
847 }
848 throw InvalidArgument(err);
849
850 } else if (StringUtils::startsWith(key, "pedestrianStatistics.")) {
851 key = prefixedKey.substr(21);
852 if (key == toString(SUMO_ATTR_NUMBER) || key == toString(SUMO_ATTR_COUNT)) {
853 return toString(myWalkCount);
854 } else if (key == "routeLength") {
856 } else if (key == toString(SUMO_ATTR_DURATION)) {
858 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
860 }
861 throw InvalidArgument(err);
862
863 } else if (StringUtils::startsWith(key, "rideStatistics.") ||
864 StringUtils::startsWith(key, "transportStatistics.")) {
865 int index = 0;
866 if (StringUtils::startsWith(key, "rideStatistics.")) {
867 key = prefixedKey.substr(15);
868 } else {
869 index = 1;
870 key = prefixedKey.substr(20);
871 }
872 if (key == toString(SUMO_ATTR_NUMBER) || key == toString(SUMO_ATTR_COUNT)) {
873 return toString(myRideCount[index]);
874 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
875 return toString(STEPS2TIME(myTotalRideWaitingTime[index] / MAX2(1, myRideCount[index])));
876 } else if (key == "routeLength") {
877 return toString(myTotalRideRouteLength[index] / MAX2(1, myRideCount[index]));
878 } else if (key == toString(SUMO_ATTR_DURATION)) {
879 return toString(myTotalRideRouteLength[index] / MAX2(1, myRideCount[index]));
880 } else if (key == "bus") {
881 return toString(myRideBusCount[index]);
882 } else if (key == "train") {
883 return toString(myRideRailCount[index]);
884 } else if (key == "taxi") {
885 return toString(myRideTaxiCount[index]);
886 } else if (key == "bike") {
887 return toString(myRideBikeCount[index]);
888 } else if (key == "aborted") {
889 return toString(myRideAbortCount[index]);
890 }
891 throw InvalidArgument(err);
892 }
893 // vehicleTripStatistics
894 if (key == toString(SUMO_ATTR_COUNT)) {
895 return toString(myVehicleCount);
896 } else if (key == "routeLength") {
897 return toString(getAvgRouteLength());
898 } else if (key == toString(SUMO_ATTR_SPEED)) {
899 return toString(getAvgTripSpeed());
900 } else if (key == toString(SUMO_ATTR_DURATION)) {
901 return toString(getAvgDuration());
902 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
903 return toString(getAvgWaitingTime());
904 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
905 return toString(getAvgTimeLoss());
906 } else if (key == "departDelay") {
907 return toString(getAvgDepartDelay());
908 } else if (key == "departDelayWaiting") {
910 } else if (key == "totalTravelTime") {
911 // avoid human readable output
913 } else if (key == "totalDepartDelay") {
915 }
916 throw InvalidArgument(err);
917}
918
919
920void
922 // always write device id to replicate stochastic assignment
925 if (myHolder.hasDeparted()) {
926 std::ostringstream internals;
927 internals << myDepartLane << " ";
929 internals << myDepartPosLat << " ";
930 }
931 std::string state_arrivalLane = myArrivalLane == "" ? STATE_EMPTY_ARRIVALLANE : myArrivalLane;
932 internals << myDepartSpeed << " " << myRouteLength << " " << myWaitingTime << " " << myAmWaiting << " " << myWaitingCount << " ";
933 internals << myStoppingTime << " " << myParkingStarted << " ";
934 internals << myArrivalTime << " " << state_arrivalLane << " " << myArrivalPos << " " << myArrivalPosLat << " " << myArrivalSpeed;
935 out.writeAttr(SUMO_ATTR_STATE, internals.str());
936 }
937 out.closeTag();
938}
939
940
941void
943 if (attrs.hasAttribute(SUMO_ATTR_STATE)) {
944 std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
945 bis >> myDepartLane;
947 bis >> myDepartPosLat;
948 }
953 myArrivalLane = "";
954 }
955 }
956}
957
958
959/****************************************************************************/
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:91
#define STEPS2TIME(x)
Definition SUMOTime.h:58
#define SIMSTEP
Definition SUMOTime.h:64
#define TIME2STEPS(x)
Definition SUMOTime.h:60
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a (exclusive) 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:27
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition StdDefs.h:62
T MAX2(T a, T b)
Definition StdDefs.h:86
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
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
void recordMesoParkingTimeLoss(SUMOTime waitingTime)
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:157
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:200
double getLength() const
return the length of the edge
Definition MSEdge.h:694
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition MSEdge.cpp:1198
MSLane * getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst=false, int routingMode=0) const
Definition MSEdge.cpp:753
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:617
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:187
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
bool hasPersons() const
Returns whether persons are simulated.
Definition MSNet.h:409
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1265
const MSEdge * getLastEdge() const
returns the destination edge
Definition MSRoute.cpp:91
void eraseAll()
@removes all transportables
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:2089
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 & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
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.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
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:63
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.