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_LANE "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 const SUMOTime drivingDuration = duration - myStoppingTime;
320 const double speed = drivingDuration > 0 ? routeLength / STEPS2TIME(drivingDuration) : 0;
321 if (myHolder.getVClass() == SVC_BICYCLE) {
322 myBikeCount++;
323 myTotalBikeRouteLength += routeLength;
324 myTotalBikeSpeed += speed;
325 myTotalBikeDuration += duration;
327 myTotalBikeTimeLoss += timeLoss;
329 } else {
331 myTotalRouteLength += routeLength;
332 myTotalSpeed += speed;
333 myTotalDuration += duration;
335 myTotalTimeLoss += timeLoss;
337 }
338 }
339
340 myPendingOutput.erase(this);
341 if (tripinfoOut == nullptr) {
342 return;
343 }
344 // write
345 OutputDevice& os = *tripinfoOut;
346 os.openTag("tripinfo").writeAttr("id", myHolder.getID());
348 os.writeAttr("departLane", myDepartLane);
349 os.writeAttr("departPos", myHolder.getDepartPos());
351 os.writeAttr("departPosLat", myDepartPosLat);
352 }
353 os.writeAttr("departSpeed", myDepartSpeed);
354 SUMOTime departDelay = myHolder.getDepartDelay();
356 if (!myHolder.hasDeparted()) {
357 assert(param.depart <= SIMSTEP || param.departProcedure != DepartDefinition::GIVEN);
358 departDelay = SIMSTEP - param.depart;
359 }
360 os.writeAttr("departDelay", time2string(departDelay));
361 os.writeAttr("arrival", time2string(myArrivalTime));
362 os.writeAttr("arrivalLane", myArrivalLane);
363 os.writeAttr("arrivalPos", myArrivalPos);
365 os.writeAttr("arrivalPosLat", myArrivalPosLat);
366 }
367 os.writeAttr("arrivalSpeed", myArrivalSpeed);
368 os.writeAttr("duration", time2string(duration));
369 os.writeAttr("routeLength", routeLength);
374 os.writeAttr("rerouteNo", myHolder.getNumberReroutes());
375 os.writeAttr("devices", toString(myHolder.getDevices()));
376 os.writeAttr("vType", myHolder.getVehicleType().getID());
377 os.writeAttr("speedFactor", myHolder.getChosenSpeedFactor());
378 std::string vaporized;
379 switch (myArrivalReason) {
381 vaporized = "calibrator";
382 break;
384 vaporized = "gui";
385 break;
387 vaporized = "collision";
388 break;
390 vaporized = "vaporizer";
391 break;
393 vaporized = "traci";
394 break;
397 vaporized = "teleport";
398 break;
399 default:
401 (param.arrivalEdge >= 0 && myHolder.getRoutePosition() >= param.arrivalEdge)) {
402 vaporized = "";
403 } else {
404 vaporized = "end";
405 }
406 break;
407 }
408 os.writeAttr("vaporized", vaporized);
409 // cannot close tag because emission device output might follow
410}
411
412
413void
415 MSNet* net = MSNet::getInstance();
416 OutputDevice* tripinfoOut = (OptionsCont::getOptions().isSet("tripinfo-output") ?
417 &OutputDevice::getDeviceByOption("tripinfo-output") : nullptr);
420 const bool writeUndeparted = OptionsCont::getOptions().getBool("tripinfo-output.write-undeparted");
421 const SUMOTime t = net->getCurrentTimeStep();
422 while (myPendingOutput.size() > 0) {
423 const MSDevice_Tripinfo* d = *myPendingOutput.begin();
424 const bool departed = d->myHolder.hasDeparted();
425 const bool departDelayed = d->myHolder.getParameter().depart <= t;
426 if (!departed && departDelayed) {
429 }
430 if (departed || (writeUndeparted && departDelayed)) {
431 const_cast<MSDevice_Tripinfo*>(d)->updateParkingStopTime();
432 d->generateOutput(tripinfoOut);
433 if (tripinfoOut != nullptr) {
434 for (MSVehicleDevice* const dev : d->myHolder.getDevices()) {
435 if (typeid(*dev) == typeid(MSDevice_Tripinfo) || typeid(*dev) == typeid(MSDevice_Vehroutes)) {
436 // tripinfo is special and vehroute has its own write-unfinished option
437 continue;
438 }
439 dev->generateOutput(tripinfoOut);
440 }
441 OutputDevice::getDeviceByOption("tripinfo-output").closeTag();
442 }
443 } else {
444 myPendingOutput.erase(d);
445 }
446 }
447 // unfinished persons
448 if (net->hasPersons()) {
449 net->getPersonControl().eraseAll();
450 }
451
452}
453
454
455void
456MSDevice_Tripinfo::addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss) {
457 myWalkCount++;
458 myTotalWalkRouteLength += walkLength;
459 myTotalWalkDuration += walkDuration;
460 myTotalWalkTimeLoss += walkTimeLoss;
461}
462
463
464void
465MSDevice_Tripinfo::addRideTransportData(const bool isPerson, const double distance, const SUMOTime duration,
466 const SUMOVehicleClass vClass, const std::string& line, const SUMOTime waitingTime) {
467 const int index = isPerson ? 0 : 1;
468 myRideCount[index]++;
469 if (duration > 0) {
470 myTotalRideWaitingTime[index] += waitingTime;
471 myTotalRideRouteLength[index] += distance;
472 myTotalRideDuration[index] += duration;
473 if (vClass == SVC_BICYCLE) {
474 myRideBikeCount[index]++;
475 } else if (!line.empty()) {
476 if (isRailway(vClass)) {
477 myRideRailCount[index]++;
478 } else if (vClass == SVC_TAXI) {
479 myRideTaxiCount[index]++;
480 } else {
481 // some kind of road vehicle
482 myRideBusCount[index]++;
483 }
484 }
485 } else {
486 myRideAbortCount[index]++;
487 }
488}
489
490
491std::string
493 std::ostringstream msg;
494 msg.setf(msg.fixed);
495 msg.precision(gPrecision);
496 if (myBikeCount == 0 || myVehicleCount > 0) {
497 msg << "Statistics (avg of " << myVehicleCount << "):\n";
498 msg << " RouteLength: " << getAvgRouteLength() << "\n"
499 << " Speed: " << getAvgTripSpeed() << "\n"
500 << " Duration: " << getAvgDuration() << "\n"
501 << " WaitingTime: " << getAvgWaitingTime() << "\n"
502 << " TimeLoss: " << getAvgTimeLoss() << "\n"
503 << " DepartDelay: " << getAvgDepartDelay() << "\n";
504 }
505 if (myBikeCount > 0) {
506 msg << "Bike Statistics (avg of " << myBikeCount << "):\n"
507 << " RouteLength: " << getAvgBikeRouteLength() << "\n"
508 << " Speed: " << getAvgBikeTripSpeed() << "\n"
509 << " Duration: " << getAvgBikeDuration() << "\n"
510 << " WaitingTime: " << getAvgBikeWaitingTime() << "\n"
511 << " TimeLoss: " << getAvgBikeTimeLoss() << "\n"
512 << " DepartDelay: " << getAvgBikeDepartDelay() << "\n";
513 if (myVehicleCount > 0 && myWaitingDepartDelay >= 0) {
514 msg << "Statistics (avg of " << (myVehicleCount + myBikeCount) << "):\n";
515 }
516 }
517 if (myWaitingDepartDelay >= 0) {
518 msg << " DepartDelayWaiting: " << getAvgDepartDelayWaiting() << "\n";
519 }
520 if (myWalkCount > 0) {
521 msg << "Pedestrian Statistics (avg of " << myWalkCount << " walks):\n"
522 << " RouteLength: " << getAvgWalkRouteLength() << "\n"
523 << " Duration: " << getAvgWalkDuration() << "\n"
524 << " TimeLoss: " << getAvgWalkTimeLoss() << "\n";
525 }
526 printRideStatistics(msg, "Ride", "rides", 0);
527 printRideStatistics(msg, "Transport", "transports", 1);
528 return msg.str();
529}
530
531void
532MSDevice_Tripinfo::printRideStatistics(std::ostringstream& msg, const std::string& category, const std::string& modeName, const int index) {
533 if (myRideCount[index] > 0) {
534 msg << category << " Statistics (avg of " << myRideCount[index] << " " << modeName << "):\n";
535 msg << " WaitingTime: " << STEPS2TIME(myTotalRideWaitingTime[index] / myRideCount[index]) << "\n";
536 msg << " RouteLength: " << myTotalRideRouteLength[index] / myRideCount[index] << "\n";
537 msg << " Duration: " << STEPS2TIME(myTotalRideDuration[index] / myRideCount[index]) << "\n";
538 if (myRideBusCount[index] > 0) {
539 msg << " Bus: " << myRideBusCount[index] << "\n";
540 }
541 if (myRideRailCount[index] > 0) {
542 msg << " Train: " << myRideRailCount[index] << "\n";
543 }
544 if (myRideTaxiCount[index] > 0) {
545 msg << " Taxi: " << myRideTaxiCount[index] << "\n";
546 }
547 if (myRideBikeCount[index] > 0) {
548 msg << " Bike: " << myRideBikeCount[index] << "\n";
549 }
550 if (myRideAbortCount[index] > 0) {
551 msg << " Aborted: " << myRideAbortCount[index] << "\n";
552 }
553 }
554
555}
556
557
558void
561 od.openTag("vehicleTripStatistics");
562 od.writeAttr("count", myVehicleCount);
563 od.writeAttr("routeLength", getAvgRouteLength());
564 od.writeAttr("speed", getAvgTripSpeed());
565 od.writeAttr("duration", getAvgDuration());
566 od.writeAttr("waitingTime", getAvgWaitingTime());
567 od.writeAttr("timeLoss", getAvgTimeLoss());
568 od.writeAttr("departDelay", getAvgDepartDelay());
569 od.writeAttr("departDelayWaiting", getAvgDepartDelayWaiting());
570 od.writeAttr("totalTravelTime", time2string(myTotalDuration));
572 od.closeTag();
573 if (myBikeCount > 0) {
574 od.openTag("bikeTripStatistics");
575 od.writeAttr("count", myBikeCount);
576 od.writeAttr("routeLength", getAvgBikeRouteLength());
577 od.writeAttr("speed", getAvgBikeTripSpeed());
578 od.writeAttr("duration", getAvgBikeDuration());
579 od.writeAttr("waitingTime", getAvgBikeWaitingTime());
580 od.writeAttr("timeLoss", getAvgBikeTimeLoss());
581 od.writeAttr("departDelay", getAvgBikeDepartDelay());
582 od.writeAttr("totalTravelTime", time2string(myTotalBikeDuration));
583 od.closeTag();
584 }
585 od.openTag("pedestrianStatistics");
586 od.writeAttr("number", myWalkCount);
587 od.writeAttr("routeLength", getAvgWalkRouteLength());
588 od.writeAttr("duration", getAvgWalkDuration());
589 od.writeAttr("timeLoss", getAvgWalkTimeLoss());
590 od.closeTag();
591 writeRideStatistics(od, "rideStatistics", 0);
592 writeRideStatistics(od, "transportStatistics", 1);
593}
594
595void
596MSDevice_Tripinfo::writeRideStatistics(OutputDevice& od, const std::string& category, const int index) {
597 od.openTag(category);
598 od.writeAttr("number", myRideCount[index]);
599 if (myRideCount[index] > 0) {
600 od.writeAttr("waitingTime", STEPS2TIME(myTotalRideWaitingTime[index] / myRideCount[index]));
601 od.writeAttr("routeLength", myTotalRideRouteLength[index] / myRideCount[index]);
602 od.writeAttr("duration", STEPS2TIME(myTotalRideDuration[index] / myRideCount[index]));
603 od.writeAttr("bus", myRideBusCount[index]);
604 od.writeAttr("train", myRideRailCount[index]);
605 od.writeAttr("taxi", myRideTaxiCount[index]);
606 od.writeAttr("bike", myRideBikeCount[index]);
607 od.writeAttr("aborted", myRideAbortCount[index]);
608 }
609 od.closeTag();
610}
611
612
613double
615 if (myVehicleCount > 0) {
617 } else {
618 return 0;
619 }
620}
621
622double
624 if (myVehicleCount > 0) {
626 } else {
627 return 0;
628 }
629}
630
631double
633 if (myVehicleCount > 0) {
635 } else {
636 return 0;
637 }
638}
639
640double
642 if (myVehicleCount > 0) {
644 } else {
645 return 0;
646 }
647}
648
649
650double
652 if (myVehicleCount > 0) {
654 } else {
655 return 0;
656 }
657}
658
659
660double
662 if (myVehicleCount > 0) {
664 } else {
665 return 0;
666 }
667}
668
669double
671 if (myWaitingDepartDelay >= 0) {
673 } else {
674 return -1;
675 }
676}
677
678
679double
683
684double
686 if (myBikeCount > 0) {
688 } else {
689 return 0;
690 }
691}
692
693double
695 if (myBikeCount > 0) {
697 } else {
698 return 0;
699 }
700}
701
702double
704 if (myBikeCount > 0) {
706 } else {
707 return 0;
708 }
709}
710
711double
713 if (myBikeCount > 0) {
715 } else {
716 return 0;
717 }
718}
719
720
721double
723 if (myBikeCount > 0) {
725 } else {
726 return 0;
727 }
728}
729
730double
732 if (myBikeCount > 0) {
734 } else {
735 return 0;
736 }
737}
738
739
740double
744
745double
747 if (myWalkCount > 0) {
749 } else {
750 return 0;
751 }
752}
753
754double
756 if (myWalkCount > 0) {
758 } else {
759 return 0;
760 }
761}
762
763
764double
766 if (myWalkCount > 0) {
768 } else {
769 return 0;
770 }
771}
772
773
774double
776 if (myRideCount[0] > 0) {
778 } else {
779 return 0;
780 }
781}
782
783double
785 if (myRideCount[0] > 0) {
787 } else {
788 return 0;
789 }
790}
791
792double
794 if (myRideCount[0] > 0) {
795 return myTotalRideRouteLength[0] / myRideCount[0];
796 } else {
797 return 0;
798 }
799}
800
801
802std::string
803MSDevice_Tripinfo::getParameter(const std::string& key) const {
804 if (key == toString(SUMO_ATTR_WAITINGTIME)) {
806 } else if (key == toString(SUMO_ATTR_WAITINGCOUNT)) {
807 return toString(myWaitingCount);
808 } else if (key == toString(SUMO_ATTR_STOPTIME)) {
810 } else if (key == toString(SUMO_ATTR_ARRIVALTIME)) {
812 } else if (key == toString(SUMO_ATTR_ARRIVALLANE)) {
813 return toString(myArrivalLane);
814 } else if (key == toString(SUMO_ATTR_ARRIVALPOS)) {
815 return toString(myArrivalPos);
816 } else if (key == toString(SUMO_ATTR_ARRIVALPOS_LAT)) {
818 } else if (key == toString(SUMO_ATTR_ARRIVALSPEED)) {
819 return toString(myArrivalSpeed);
820 }
821 throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
822}
823
824
825std::string
826MSDevice_Tripinfo::getGlobalParameter(const std::string& prefixedKey) {
827 std::string key = prefixedKey; // by default, assume vehicleTripStatistics;
828 const std::string err = "Parameter '" + prefixedKey + "' is not supported for device of type 'tripinfo'";
829 if (StringUtils::startsWith(key, "vehicleTripStatistics.")) {
830 key = prefixedKey.substr(22);
831 } else if (StringUtils::startsWith(key, "bikeTripStatistics.")) {
832 key = prefixedKey.substr(19);
833 if (key == toString(SUMO_ATTR_COUNT)) {
834 return toString(myBikeCount);
835 } else if (key == "routeLength") {
837 } else if (key == toString(SUMO_ATTR_SPEED)) {
839 } else if (key == toString(SUMO_ATTR_DURATION)) {
841 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
843 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
845 } else if (key == "departDelay") {
847 } else if (key == "totalTravelTime") {
848 // avoid human readable output
850 }
851 throw InvalidArgument(err);
852
853 } else if (StringUtils::startsWith(key, "pedestrianStatistics.")) {
854 key = prefixedKey.substr(21);
855 if (key == toString(SUMO_ATTR_NUMBER) || key == toString(SUMO_ATTR_COUNT)) {
856 return toString(myWalkCount);
857 } else if (key == "routeLength") {
859 } else if (key == toString(SUMO_ATTR_DURATION)) {
861 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
863 }
864 throw InvalidArgument(err);
865
866 } else if (StringUtils::startsWith(key, "rideStatistics.") ||
867 StringUtils::startsWith(key, "transportStatistics.")) {
868 int index = 0;
869 if (StringUtils::startsWith(key, "rideStatistics.")) {
870 key = prefixedKey.substr(15);
871 } else {
872 index = 1;
873 key = prefixedKey.substr(20);
874 }
875 if (key == toString(SUMO_ATTR_NUMBER) || key == toString(SUMO_ATTR_COUNT)) {
876 return toString(myRideCount[index]);
877 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
878 return toString(STEPS2TIME(myTotalRideWaitingTime[index] / MAX2(1, myRideCount[index])));
879 } else if (key == "routeLength") {
880 return toString(myTotalRideRouteLength[index] / MAX2(1, myRideCount[index]));
881 } else if (key == toString(SUMO_ATTR_DURATION)) {
882 return toString(myTotalRideRouteLength[index] / MAX2(1, myRideCount[index]));
883 } else if (key == "bus") {
884 return toString(myRideBusCount[index]);
885 } else if (key == "train") {
886 return toString(myRideRailCount[index]);
887 } else if (key == "taxi") {
888 return toString(myRideTaxiCount[index]);
889 } else if (key == "bike") {
890 return toString(myRideBikeCount[index]);
891 } else if (key == "aborted") {
892 return toString(myRideAbortCount[index]);
893 }
894 throw InvalidArgument(err);
895 }
896 // vehicleTripStatistics
897 if (key == toString(SUMO_ATTR_COUNT)) {
898 return toString(myVehicleCount);
899 } else if (key == "routeLength") {
900 return toString(getAvgRouteLength());
901 } else if (key == toString(SUMO_ATTR_SPEED)) {
902 return toString(getAvgTripSpeed());
903 } else if (key == toString(SUMO_ATTR_DURATION)) {
904 return toString(getAvgDuration());
905 } else if (key == toString(SUMO_ATTR_WAITINGTIME)) {
906 return toString(getAvgWaitingTime());
907 } else if (key == toString(SUMO_ATTR_TIMELOSS)) {
908 return toString(getAvgTimeLoss());
909 } else if (key == "departDelay") {
910 return toString(getAvgDepartDelay());
911 } else if (key == "departDelayWaiting") {
913 } else if (key == "totalTravelTime") {
914 // avoid human readable output
916 } else if (key == "totalDepartDelay") {
918 }
919 throw InvalidArgument(err);
920}
921
922
923void
925 // always write device id to replicate stochastic assignment
928 if (myHolder.hasDeparted()) {
929 std::ostringstream internals;
930 // the depart lane is empty if the device was added when loading state
931 internals << (myDepartLane == "" ? STATE_EMPTY_LANE : myDepartLane) << " ";
933 internals << myDepartPosLat << " ";
934 }
935 std::string state_arrivalLane = myArrivalLane == "" ? STATE_EMPTY_LANE : myArrivalLane;
936 internals << myDepartSpeed << " " << myRouteLength << " " << myWaitingTime << " " << myAmWaiting << " " << myWaitingCount << " ";
937 internals << myStoppingTime << " " << myParkingStarted << " ";
938 internals << myArrivalTime << " " << state_arrivalLane << " " << myArrivalPos << " " << myArrivalPosLat << " " << myArrivalSpeed;
940 internals << " " << myMesoTimeLoss;
941 }
942 out.writeAttr(SUMO_ATTR_STATE, internals.str());
943 }
944 out.closeTag();
945}
946
947
948void
950 if (attrs.hasAttribute(SUMO_ATTR_STATE)) {
951 std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
952 bis >> myDepartLane;
954 bis >> myDepartPosLat;
955 }
960 bis >> myMesoTimeLoss;
961 }
963 myDepartLane = "";
964 }
966 myArrivalLane = "";
967 }
968 }
969}
970
971
972/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define NOT_ARRIVED
#define STATE_EMPTY_LANE
SUMOTime DELTA_T
Definition SUMOTime.cpp:39
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:107
#define STEPS2TIME(x)
Definition SUMOTime.h:58
#define SIMSTEP
Definition SUMOTime.h:69
constexpr SUMOTime TIME2STEPS(double 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:57
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:181
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:213
double getLength() const
return the length of the edge
Definition MSEdge.h:695
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition MSEdge.cpp:1254
MSLane * getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst=false, int routingMode=0) const
Definition MSEdge.cpp:791
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:632
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_CONTINUATION_ARRIVED
The vehicle entered this edge during teleport and was teleported out of the net.
@ 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:201
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
bool hasPersons() const
Returns whether persons are simulated.
Definition MSNet.h:419
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1317
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:2100
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:73
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, const bool escape=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 const MSEdge * getEdge() const =0
Returns the (normal) route 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 MSEdge * getCurrentEdge() const =0
virtual int getRoutePosition() const =0
return index of edge within route
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.