LCOV - code coverage report
Current view: top level - src/microsim/output - MSMeanData_Net.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 72.8 % 257 187
Test Date: 2026-07-05 15:55:58 Functions: 83.3 % 18 15

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2004-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              : /****************************************************************************/
      14              : /// @file    MSMeanData_Net.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Michael Behrisch
      17              : /// @author  Jakob Erdmann
      18              : /// @date    Mon, 10.05.2004
      19              : ///
      20              : // Network state mean data collector for edges/lanes
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #ifdef HAVE_FOX
      25              : #include <utils/common/ScopedLocker.h>
      26              : #endif
      27              : #include <utils/common/SUMOTime.h>
      28              : #include <utils/common/ToString.h>
      29              : #include <utils/iodevices/OutputDevice.h>
      30              : #include <microsim/MSEdgeControl.h>
      31              : #include <microsim/MSEdge.h>
      32              : #include <microsim/MSLane.h>
      33              : #include <microsim/MSVehicle.h>
      34              : #include <microsim/MSGlobals.h>
      35              : #include <mesosim/MELoop.h>
      36              : #include <mesosim/MESegment.h>
      37              : #include "MSMeanData_Net.h"
      38              : 
      39              : 
      40              : // ===========================================================================
      41              : // debug constants
      42              : // ===========================================================================
      43              : //#define DEBUG_OCCUPANCY
      44              : //#define DEBUG_OCCUPANCY2
      45              : //#define DEBUG_NOTIFY_ENTER
      46              : //#define DEBUG_COND (veh.getLane()->getID() == "")
      47              : //#define DEBUG_COND (false)
      48              : //#define DEBUG_COND2 (veh.getEdge()->getID() == "")
      49              : 
      50              : 
      51              : // ===========================================================================
      52              : // method definitions
      53              : // ===========================================================================
      54              : // ---------------------------------------------------------------------------
      55              : // MSMeanData_Net::MSLaneMeanDataValues - methods
      56              : // ---------------------------------------------------------------------------
      57      8324585 : MSMeanData_Net::MSLaneMeanDataValues::MSLaneMeanDataValues(MSLane* const lane,
      58              :         const double length,
      59              :         const bool doAdd,
      60      8324585 :         const MSMeanData_Net* parent)
      61              :     : MSMeanData::MeanDataValues(lane, length, doAdd, parent),
      62      8324585 :       nVehDeparted(0), nVehArrived(0), nVehEntered(0), nVehLeft(0),
      63      8324585 :       nVehVaporized(0), nVehTeleported(0), waitSeconds(0), timeLoss(0),
      64      8324585 :       nVehLaneChangeFrom(0), nVehLaneChangeTo(0),
      65      8324585 :       frontSampleSeconds(0), frontTravelledDistance(0),
      66      8324585 :       vehLengthSum(0), occupationSum(0),
      67      8324585 :       minimalVehicleLength(INVALID_DOUBLE),
      68      8324585 :       myParent(parent) {}
      69              : 
      70              : 
      71     16645538 : MSMeanData_Net::MSLaneMeanDataValues::~MSLaneMeanDataValues() {
      72     16645538 : }
      73              : 
      74              : 
      75              : void
      76     16946522 : MSMeanData_Net::MSLaneMeanDataValues::reset(bool) {
      77     16946522 :     nVehDeparted = 0;
      78     16946522 :     nVehArrived = 0;
      79     16946522 :     nVehEntered = 0;
      80     16946522 :     nVehLeft = 0;
      81     16946522 :     nVehVaporized = 0;
      82     16946522 :     nVehTeleported = 0;
      83     16946522 :     nVehLaneChangeFrom = 0;
      84     16946522 :     nVehLaneChangeTo = 0;
      85     16946522 :     sampleSeconds = 0.;
      86     16946522 :     travelledDistance = 0;
      87     16946522 :     waitSeconds = 0;
      88     16946522 :     timeLoss = 0;
      89     16946522 :     frontSampleSeconds = 0;
      90     16946522 :     frontTravelledDistance = 0;
      91     16946522 :     vehLengthSum = 0;
      92     16946522 :     occupationSum = 0;
      93     16946522 :     minimalVehicleLength = INVALID_DOUBLE;
      94     16946522 :     resetTime = SIMSTEP;
      95     16946522 : }
      96              : 
      97              : 
      98              : void
      99      8656874 : MSMeanData_Net::MSLaneMeanDataValues::addTo(MSMeanData::MeanDataValues& val) const {
     100              :     MSLaneMeanDataValues& v = (MSLaneMeanDataValues&) val;
     101      8656874 :     v.nVehDeparted += nVehDeparted;
     102      8656874 :     v.nVehArrived += nVehArrived;
     103      8656874 :     v.nVehEntered += nVehEntered;
     104      8656874 :     v.nVehLeft += nVehLeft;
     105      8656874 :     v.nVehVaporized += nVehVaporized;
     106      8656874 :     v.nVehTeleported += nVehTeleported;
     107      8656874 :     v.nVehLaneChangeFrom += nVehLaneChangeFrom;
     108      8656874 :     v.nVehLaneChangeTo += nVehLaneChangeTo;
     109      8656874 :     v.sampleSeconds += sampleSeconds;
     110      8656874 :     v.travelledDistance += travelledDistance;
     111      8656874 :     v.waitSeconds += waitSeconds;
     112      8656874 :     v.timeLoss += timeLoss;
     113      8656874 :     v.frontSampleSeconds += frontSampleSeconds;
     114      8656874 :     v.frontTravelledDistance += frontTravelledDistance;
     115      8656874 :     v.vehLengthSum += vehLengthSum;
     116      8656874 :     v.occupationSum += occupationSum;
     117      8656874 :     if (v.minimalVehicleLength == INVALID_DOUBLE) {
     118      8564795 :         v.minimalVehicleLength = minimalVehicleLength;
     119              :     } else {
     120       177816 :         v.minimalVehicleLength = MIN2(minimalVehicleLength, v.minimalVehicleLength);
     121              :     }
     122      8656874 : }
     123              : 
     124              : 
     125              : void
     126    410521635 : MSMeanData_Net::MSLaneMeanDataValues::notifyMoveInternal(
     127              :     const SUMOTrafficObject& veh, const double frontOnLane,
     128              :     const double timeOnLane, const double /* meanSpeedFrontOnLane */,
     129              :     const double meanSpeedVehicleOnLane,
     130              :     const double travelledDistanceFrontOnLane,
     131              :     const double travelledDistanceVehicleOnLane,
     132              :     const double meanLengthOnLane) {
     133              : #ifdef DEBUG_OCCUPANCY
     134              :     if (DEBUG_COND2) {
     135              :         std::cout << SIMTIME << "\n  MSMeanData_Net::MSLaneMeanDataValues::notifyMoveInternal()\n"
     136              :                   << "  veh '" << veh.getID() << "' on edge '" << veh.getEdge()->getID() << "'"
     137              :                   << ", timeOnLane=" << timeOnLane
     138              :                   << ", meanSpeedVehicleOnLane=" << meanSpeedVehicleOnLane
     139              :                   << ",\ntravelledDistanceFrontOnLane=" << travelledDistanceFrontOnLane
     140              :                   << ", travelledDistanceVehicleOnLane=" << travelledDistanceVehicleOnLane
     141              :                   << ", meanLengthOnLane=" << meanLengthOnLane
     142              :                   << std::endl;
     143              :     }
     144              : #endif
     145    410521635 :     if (myParent != nullptr && !myParent->vehicleApplies(veh)) {
     146              :         return;
     147              :     }
     148    410479315 :     sampleSeconds += timeOnLane;
     149    410479315 :     travelledDistance += travelledDistanceVehicleOnLane;
     150    410479315 :     vehLengthSum += veh.getVehicleType().getLength() * timeOnLane;
     151    410479315 :     if (MSGlobals::gUseMesoSim) {
     152              :         // For the mesosim case no information on whether the vehicle was occupying
     153              :         // the lane with its whole length is available. We assume the whole length
     154              :         // Therefore this increment is taken out with more information on the vehicle movement.
     155     10353565 :         occupationSum += veh.getVehicleType().getLength() * timeOnLane;
     156              :     } else {
     157              :         // for the microsim case more elaborate calculation of the average length on the lane,
     158              :         // is taken out in notifyMove(), refs #153
     159    400125750 :         occupationSum += meanLengthOnLane * TS;
     160              :     }
     161    410479315 :     if (!veh.isStopped()) {
     162    394431933 :         if (myParent != nullptr && (meanSpeedVehicleOnLane < myParent->myHaltSpeed
     163    338225512 :                     || (myParent->myHaltSpeedRel > 0 && meanSpeedVehicleOnLane / veh.getCurrentEdge()->getSpeedLimit(veh.getVClass()) < myParent->myHaltSpeedRel))) {
     164     56149579 :             waitSeconds += timeOnLane;
     165    338282354 :         } else if (MSGlobals::gUseMesoSim) {
     166     10303436 :             waitSeconds += STEPS2TIME(veh.getWaitingTime());
     167              :         }
     168    394431933 :         const double vmax = veh.getLane() == nullptr ? veh.getEdge()->getVehicleMaxSpeed(&veh) : veh.getLane()->getVehicleMaxSpeed(&veh);
     169    394431933 :         if (vmax > 0) {
     170    787081015 :             timeLoss += timeOnLane * MAX2(0.0, vmax - meanSpeedVehicleOnLane) / vmax;
     171              :         }
     172              :     }
     173    410479315 :     frontSampleSeconds += frontOnLane;
     174    410479315 :     frontTravelledDistance += travelledDistanceFrontOnLane;
     175    410479315 :     if (minimalVehicleLength == INVALID_DOUBLE) {
     176       695249 :         minimalVehicleLength = veh.getVehicleType().getLengthWithGap();
     177              :     } else {
     178    818159928 :         minimalVehicleLength = MIN2(minimalVehicleLength, veh.getVehicleType().getLengthWithGap());
     179              :     }
     180              : #ifdef DEBUG_OCCUPANCY2
     181              :     // refs #3265
     182              :     std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength << std::endl;
     183              : #endif
     184              : }
     185              : 
     186              : 
     187              : bool
     188     27362461 : MSMeanData_Net::MSLaneMeanDataValues::notifyLeave(SUMOTrafficObject& veh, double /*lastPos*/, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
     189     27362461 :     if ((myParent == nullptr || myParent->vehicleApplies(veh)) && (
     190     18223608 :                 getLane() == nullptr || !veh.isVehicle() || getLane() == static_cast<MSVehicle&>(veh).getLane())) {
     191              : #ifdef HAVE_FOX
     192     22972009 :         ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
     193              : #endif
     194     22972009 :         if (MSGlobals::gUseMesoSim) {
     195      9138691 :             removeFromVehicleUpdateValues(veh);
     196              :         }
     197     22972009 :         if (reason == MSMoveReminder::NOTIFICATION_ARRIVED) {
     198      2981552 :             ++nVehArrived;
     199     19990457 :         } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
     200       130311 :             ++nVehLaneChangeFrom;
     201     19860146 :         } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
     202     11967818 :             ++nVehLeft;
     203     11967818 :             if (reason == MSMoveReminder::NOTIFICATION_TELEPORT || reason == MSMoveReminder::NOTIFICATION_TELEPORT_ARRIVED) {
     204         6597 :                 ++nVehTeleported;
     205     11961221 :             } else if (reason >= MSMoveReminder::NOTIFICATION_VAPORIZED_CALIBRATOR) {
     206        70303 :                 ++nVehVaporized;
     207              :             }
     208              :         }
     209              :     }
     210     27362461 :     if (MSGlobals::gUseMesoSim) {
     211              :         return false;
     212              :     }
     213     18214930 :     return reason == MSMoveReminder::NOTIFICATION_JUNCTION;
     214              : }
     215              : 
     216              : 
     217              : bool
     218     23996586 : MSMeanData_Net::MSLaneMeanDataValues::notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane) {
     219              : #ifdef DEBUG_NOTIFY_ENTER
     220              :     std::cout << "\n" << SIMTIME << " MSMeanData_Net::MSLaneMeanDataValues: veh '" << veh.getID() << "' enters lane '" << enteredLane->getID() << "'" << std::endl;
     221              : #else
     222              :     UNUSED_PARAMETER(enteredLane);
     223              : #endif
     224     23996586 :     if (myParent == nullptr || myParent->vehicleApplies(veh)) {
     225     23078685 :         if (getLane() == nullptr || !veh.isVehicle() || getLane() == static_cast<MSVehicle&>(veh).getLane()) {
     226              : #ifdef HAVE_FOX
     227     23069845 :             ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
     228              : #endif
     229     23069845 :             if (reason == MSMoveReminder::NOTIFICATION_DEPARTED) {
     230      3157008 :                 ++nVehDeparted;
     231     19912837 :             } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
     232       129970 :                 ++nVehLaneChangeTo;
     233     19782867 :             } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
     234     11920714 :                 ++nVehEntered;
     235              :             }
     236              :         }
     237     23078685 :         return true;
     238              :     }
     239              :     return false;
     240              : }
     241              : 
     242              : 
     243              : bool
     244     22483689 : MSMeanData_Net::MSLaneMeanDataValues::isEmpty() const {
     245     21824807 :     return sampleSeconds == 0 && nVehDeparted == 0 && nVehArrived == 0 && nVehEntered == 0
     246     44308048 :            && nVehLeft == 0 && nVehVaporized == 0 && nVehTeleported == 0 && nVehLaneChangeFrom == 0 && nVehLaneChangeTo == 0;
     247              : }
     248              : 
     249              : double
     250       960598 : MSMeanData_Net::MSLaneMeanDataValues::getOccupancy(SUMOTime period, int numLanes) const {
     251       960598 :     return occupationSum / STEPS2TIME(period) / myLaneLength / (double)numLanes * 100.;
     252              : }
     253              : 
     254              : void
     255       960476 : MSMeanData_Net::MSLaneMeanDataValues::write(OutputDevice& dev, const SumoXMLAttrMask& attributeMask, const SUMOTime period,
     256              :         const int numLanes, const double speedLimit, const double defaultTravelTime, const int numVehicles) const {
     257              : 
     258       960476 :     double density = frontSampleSeconds / STEPS2TIME(period) * 1000. / myLaneLength;
     259       960476 :     double overlapDensity = sampleSeconds / STEPS2TIME(period) * 1000. / myLaneLength;
     260       960476 :     if (MSGlobals::gLateralResolution < 0) {
     261              :         // avoid exceeding upper bound
     262       906606 :         density = MIN2(density, 1000 * (double)numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     263       905395 :         overlapDensity = MIN2(overlapDensity, 1000 * (double)numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     264              :     }
     265       960476 :     const double laneDensity = density / (double)numLanes;
     266       960476 :     const double occupancy = getOccupancy(period, numLanes);
     267              : #ifdef DEBUG_OCCUPANCY2
     268              :     // tests #3264
     269              :     if (occupancy > 100) {
     270              :         std::cout << SIMTIME << " Encountered bad occupancy: " << occupancy
     271              :                   << ", myLaneLength=" << myLaneLength << ", period=" << STEPS2TIME(period) << ", occupationSum=" << occupationSum
     272              :                   << std::endl;
     273              :     }
     274              :     // refs #3265
     275              :     std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength
     276              :               << "\ndensity=" << density << "\n";
     277              : #endif
     278              : 
     279       960476 :     if (myParent == nullptr) {
     280        10065 :         const double speed = sampleSeconds == 0 ? 0. : travelledDistance / sampleSeconds;
     281        10065 :         const double frontSpeed = frontSampleSeconds == 0 ? 0. : frontTravelledDistance / frontSampleSeconds;
     282        10065 :         dev.writeOptionalAttr(SUMO_ATTR_DENSITY, density, attributeMask, sampleSeconds == 0);
     283        10065 :         dev.writeOptionalAttr(SUMO_ATTR_LANEDENSITY, laneDensity, attributeMask, sampleSeconds == 0);
     284        10065 :         dev.writeOptionalAttr(SUMO_ATTR_OCCUPANCY, occupancy, attributeMask, sampleSeconds == 0);
     285        10065 :         dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask, sampleSeconds == 0);
     286        10065 :         dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask, sampleSeconds == 0);
     287        10065 :         dev.writeOptionalAttr(SUMO_ATTR_SPEED, speed, attributeMask, sampleSeconds == 0);
     288        10065 :         dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. || sampleSeconds == 0 ? 0. : travelledDistance / sampleSeconds / speedLimit,
     289        10065 :                               attributeMask, sampleSeconds == 0);
     290        10065 :         dev.writeOptionalAttr(SUMO_ATTR_DEPARTED, nVehDeparted, attributeMask);
     291        10065 :         dev.writeOptionalAttr(SUMO_ATTR_ARRIVED, nVehArrived, attributeMask);
     292        10065 :         dev.writeOptionalAttr(SUMO_ATTR_ENTERED, nVehEntered, attributeMask);
     293        10065 :         dev.writeOptionalAttr(SUMO_ATTR_LEFT, nVehLeft, attributeMask);
     294        10065 :         dev.writeOptionalAttr(SUMO_ATTR_VAPORIZED, nVehVaporized, attributeMask, nVehVaporized == 0);
     295        10065 :         dev.writeOptionalAttr(SUMO_ATTR_TELEPORTED, nVehTeleported, attributeMask, nVehTeleported == 0);
     296        10065 :         dev.writeOptionalAttr(SUMO_ATTR_FLOW, density * frontSpeed * 3.6, attributeMask, frontSampleSeconds == 0);
     297        20130 :         dev.closeTag();
     298              :         return;
     299              :     }
     300       950411 :     const bool haveSamples = sampleSeconds > myParent->myMinSamples;
     301       950411 :     const bool haveFrontSamples = frontSampleSeconds > myParent->myMinSamples;
     302       950411 :     const bool haveSamplesOrDefault = haveSamples || defaultTravelTime >= 0.;
     303              :     bool haveTravelTime = haveSamplesOrDefault;
     304       950411 :     double traveltime = myParent->myMaxTravelTime;
     305       950411 :     if (haveSamples) {
     306       619650 :         if (numVehicles > 0) {
     307          241 :             traveltime = sampleSeconds / numVehicles;
     308              :         } else {
     309              :             traveltime = myParent->myMaxTravelTime;
     310       619409 :             if (frontTravelledDistance > NUMERICAL_EPS) {
     311       845932 :                 traveltime = MIN2(traveltime, myLaneLength * frontSampleSeconds / frontTravelledDistance);
     312       196341 :             } else if (defaultTravelTime >= 0.) {
     313            0 :                 traveltime = defaultTravelTime;
     314              :             } else {
     315              :                 haveTravelTime = false;
     316              :             }
     317              :         }
     318       330761 :     } else if (defaultTravelTime >= 0.) {
     319         2638 :         traveltime = defaultTravelTime;
     320              :     }
     321       950411 :     dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, traveltime, attributeMask, !haveTravelTime);
     322       950411 :     double overlapTraveltime = myParent->myMaxTravelTime;
     323       950411 :     if (travelledDistance > 0.) {
     324              :         // one vehicle has to drive lane length + vehicle length before it has left the lane
     325              :         // thus we need to scale with an extended length, approximated by lane length + average vehicle length
     326       850831 :         overlapTraveltime = MIN2(overlapTraveltime, (myLaneLength + vehLengthSum / sampleSeconds) * sampleSeconds / travelledDistance);
     327              :     }
     328       950411 :     dev.writeOptionalAttr(SUMO_ATTR_OVERLAPTRAVELTIME, overlapTraveltime, attributeMask, !haveSamples || numVehicles > 0);
     329       950411 :     dev.writeOptionalAttr(SUMO_ATTR_DENSITY, density, attributeMask, !haveSamples || numVehicles > 0);
     330       950411 :     dev.writeOptionalAttr(SUMO_ATTR_OVERLAPDENSITY, overlapDensity, attributeMask, sampleSeconds == 0);
     331       950411 :     dev.writeOptionalAttr(SUMO_ATTR_LANEDENSITY, laneDensity, attributeMask, !haveSamples || numVehicles > 0);
     332       950411 :     dev.writeOptionalAttr(SUMO_ATTR_OCCUPANCY, occupancy, attributeMask, !haveSamples || numVehicles > 0);
     333       950411 :     dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask, !haveSamples);
     334       950411 :     dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask, !haveSamples);
     335       950411 :     double speed = 0.;
     336              :     double frontSpeed = 0.;
     337       950411 :     if (haveSamples) {
     338       619650 :         speed = travelledDistance / sampleSeconds;
     339       330761 :     } else if (defaultTravelTime > 0.) {
     340         2638 :         speed = myLaneLength / defaultTravelTime;
     341              :     }
     342       950411 :     if (haveFrontSamples) {
     343       578977 :         frontSpeed = frontTravelledDistance / frontSampleSeconds;
     344       371434 :     } else if (defaultTravelTime > 0.) {
     345         2638 :         frontSpeed = myLaneLength / defaultTravelTime;
     346              :     }
     347       950411 :     dev.writeOptionalAttr(SUMO_ATTR_SPEED, speed, attributeMask, !haveSamplesOrDefault);
     348       950411 :     dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : speed / speedLimit, attributeMask, !haveSamplesOrDefault);
     349       950411 :     dev.writeOptionalAttr(SUMO_ATTR_DEPARTED, nVehDeparted, attributeMask);
     350       950411 :     dev.writeOptionalAttr(SUMO_ATTR_ARRIVED, nVehArrived, attributeMask);
     351       950411 :     dev.writeOptionalAttr(SUMO_ATTR_ENTERED, nVehEntered, attributeMask);
     352       950411 :     dev.writeOptionalAttr(SUMO_ATTR_LEFT, nVehLeft, attributeMask);
     353       950411 :     dev.writeOptionalAttr(SUMO_ATTR_LANECHANGEDFROM, nVehLaneChangeFrom, attributeMask);
     354       950411 :     dev.writeOptionalAttr(SUMO_ATTR_LANECHANGEDTO, nVehLaneChangeTo, attributeMask);
     355       950411 :     dev.writeOptionalAttr(SUMO_ATTR_VAPORIZED, nVehVaporized, attributeMask, nVehVaporized == 0);
     356       950411 :     dev.writeOptionalAttr(SUMO_ATTR_TELEPORTED, nVehTeleported, attributeMask, nVehTeleported == 0);
     357       950411 :     dev.writeOptionalAttr(SUMO_ATTR_FLOW, density * frontSpeed * 3.6, attributeMask, !haveSamples || numVehicles == 0);
     358      1900822 :     dev.closeTag();
     359              : }
     360              : 
     361              : 
     362              : double
     363            0 : MSMeanData_Net::MSLaneMeanDataValues::getAttributeValue(SumoXMLAttr a,
     364              :         const SUMOTime period, const double numLanes, const double speedLimit) const {
     365              :     /// @todo: remove redundancy in derived values (density, laneDensity)
     366            0 :     switch (a) {
     367            0 :         case SUMO_ATTR_DENSITY:
     368            0 :             return MIN2(frontSampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
     369            0 :                         1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     370            0 :         case SUMO_ATTR_LANEDENSITY: {
     371            0 :             const double density = MIN2(frontSampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
     372            0 :                                         1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     373            0 :             return density / numLanes;
     374              :         }
     375            0 :         case SUMO_ATTR_OVERLAPDENSITY: {
     376            0 :             const double overlapDensity = MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
     377            0 :                                                1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     378            0 :             return overlapDensity / numLanes;
     379              :         }
     380            0 :         case SUMO_ATTR_OCCUPANCY:
     381            0 :             return occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 1000;
     382            0 :         case SUMO_ATTR_WAITINGTIME:
     383            0 :             return waitSeconds;
     384            0 :         case SUMO_ATTR_TIMELOSS:
     385            0 :             return timeLoss;
     386            0 :         case SUMO_ATTR_SPEED:
     387            0 :             return travelledDistance / sampleSeconds;
     388            0 :         case SUMO_ATTR_SPEEDREL:
     389            0 :             return speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit;
     390            0 :         case SUMO_ATTR_DEPARTED:
     391            0 :             return nVehDeparted;
     392            0 :         case SUMO_ATTR_ARRIVED:
     393            0 :             return nVehArrived;
     394            0 :         case SUMO_ATTR_ENTERED:
     395            0 :             return nVehEntered;
     396            0 :         case SUMO_ATTR_LEFT:
     397            0 :             return nVehLeft;
     398            0 :         case SUMO_ATTR_VAPORIZED:
     399            0 :             return nVehVaporized;
     400            0 :         case SUMO_ATTR_TELEPORTED:
     401            0 :             return nVehTeleported;
     402            0 :         case SUMO_ATTR_FLOW: {
     403            0 :             const double density = MIN2(frontSampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
     404            0 :                                         1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     405            0 :             const double speed = frontTravelledDistance / frontSampleSeconds;
     406            0 :             return density * speed * 3.6;
     407              :         }
     408              :         default:
     409              :             return 0;
     410              :     }
     411              : }
     412              : 
     413              : // ---------------------------------------------------------------------------
     414              : // MSMeanData_Net - methods
     415              : // ---------------------------------------------------------------------------
     416        22902 : MSMeanData_Net::MSMeanData_Net(const std::string& id,
     417              :                                const SUMOTime dumpBegin,
     418              :                                const SUMOTime dumpEnd, const bool useLanes,
     419              :                                const std::string& excludeEmpty,
     420              :                                const bool withInternal,
     421              :                                const bool trackVehicles,
     422              :                                const int detectPersons,
     423              :                                const double maxTravelTime,
     424              :                                const double minSamples,
     425              :                                const double haltSpeed,
     426              :                                const double haltSpeedRel,
     427              :                                const std::string& vTypes,
     428              :                                const std::string& writeAttributes,
     429              :                                const std::vector<MSEdge*>& edges,
     430        22902 :                                AggregateType aggregate) :
     431              :     MSMeanData(id, dumpBegin, dumpEnd, useLanes, excludeEmpty,
     432              :                withInternal, trackVehicles, detectPersons, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate),
     433        22902 :     myHaltSpeed(haltSpeed),
     434        22902 :     myHaltSpeedRel(haltSpeedRel)
     435        22902 : { }
     436              : 
     437              : 
     438        44773 : MSMeanData_Net::~MSMeanData_Net() {}
     439              : 
     440              : 
     441              : MSMeanData::MeanDataValues*
     442      8322308 : MSMeanData_Net::createValues(MSLane* const lane, const double length, const bool doAdd) const {
     443      8322308 :     return new MSLaneMeanDataValues(lane, length, doAdd, this);
     444              : }
     445              : 
     446              : 
     447              : std::vector<std::string>
     448            0 : MSMeanData_Net::getAttributeNames() const {
     449              :     std::vector<std::string> result;
     450            0 :     result.push_back(toString(SUMO_ATTR_DENSITY));
     451            0 :     result.push_back(toString(SUMO_ATTR_LANEDENSITY));
     452            0 :     result.push_back(toString(SUMO_ATTR_OCCUPANCY));
     453            0 :     result.push_back(toString(SUMO_ATTR_WAITINGTIME));
     454            0 :     result.push_back(toString(SUMO_ATTR_TIMELOSS));
     455            0 :     result.push_back(toString(SUMO_ATTR_SPEED));
     456            0 :     result.push_back(toString(SUMO_ATTR_SPEEDREL));
     457            0 :     result.push_back(toString(SUMO_ATTR_DEPARTED));
     458            0 :     result.push_back(toString(SUMO_ATTR_ARRIVED));
     459            0 :     result.push_back(toString(SUMO_ATTR_ENTERED));
     460            0 :     result.push_back(toString(SUMO_ATTR_LEFT));
     461            0 :     result.push_back(toString(SUMO_ATTR_VAPORIZED));
     462            0 :     result.push_back(toString(SUMO_ATTR_TELEPORTED));
     463            0 :     result.push_back(toString(SUMO_ATTR_FLOW));
     464            0 :     return result;
     465            0 : }
     466              : 
     467              : 
     468              : double
     469            0 : MSMeanData_Net::getAttributeValue(const MSLane* lane, SumoXMLAttr a, double defaultValue) const {
     470              :     double result = defaultValue;
     471            0 :     const std::vector<MeanDataValues*>* edgeValues = getEdgeValues(&lane->getEdge());
     472            0 :     if (edgeValues == nullptr) {
     473              :         return result;
     474              :     }
     475              :     MeanDataValues* values = nullptr;
     476            0 :     if (!myAmEdgeBased) {
     477            0 :         values = (*edgeValues)[lane->getIndex()];
     478              :     } else {
     479            0 :         MeanDataValues* sumData = createValues(nullptr, lane->getLength(), false);
     480            0 :         for (MeanDataValues* meanData : (*edgeValues)) {
     481            0 :             meanData->addTo(*sumData);
     482              :         }
     483              :         values = sumData;
     484              :     }
     485              :     const SUMOTime myLastResetTime = 0; // XXX store last reset time
     486            0 :     const SUMOTime period = SIMSTEP - myLastResetTime;
     487            0 :     result = values->getAttributeValue(a, period, lane->getEdge().getNumLanes(), lane->getSpeedLimit());
     488            0 :     if (myAmEdgeBased) {
     489            0 :         delete values;
     490              :     }
     491              :     return result;
     492              : }
     493              : 
     494              : 
     495              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1