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