LCOV - code coverage report
Current view: top level - src/microsim/output - MSStopOut.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 92.8 % 97 90
Test Date: 2025-11-13 15:38:19 Functions: 100.0 % 14 14

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 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    MSStopOut.cpp
      15              : /// @author  Jakob Erdmann
      16              : /// @date    Wed, 21.12.2016
      17              : ///
      18              : // Ouput information about planned vehicle stop
      19              : /****************************************************************************/
      20              : #include <config.h>
      21              : 
      22              : #include <utils/vehicle/SUMOVehicle.h>
      23              : #include <utils/options/OptionsCont.h>
      24              : #include <utils/common/MsgHandler.h>
      25              : #include <microsim/MSNet.h>
      26              : #include <microsim/MSEdge.h>
      27              : #include <microsim/MSLane.h>
      28              : #include <microsim/MSGlobals.h>
      29              : #include <microsim/MSParkingArea.h>
      30              : #include <microsim/MSStoppingPlace.h>
      31              : #include <microsim/MSVehicleType.h>
      32              : #include <microsim/trigger/MSChargingStation.h>
      33              : #include <microsim/trigger/MSOverheadWire.h>
      34              : #include "MSStopOut.h"
      35              : 
      36              : 
      37              : // ---------------------------------------------------------------------------
      38              : // static initialisation methods
      39              : // ---------------------------------------------------------------------------
      40              : MSStopOut* MSStopOut::myInstance = nullptr;
      41              : 
      42              : void
      43        38596 : MSStopOut::init() {
      44        77192 :     if (OptionsCont::getOptions().isSet("stop-output")) {
      45         1353 :         myInstance = new MSStopOut(OutputDevice::getDeviceByOption("stop-output"));
      46              :     }
      47        38596 : }
      48              : 
      49              : void
      50        38670 : MSStopOut::cleanup() {
      51        38670 :     delete myInstance;
      52        38670 :     myInstance = nullptr;
      53        38670 : }
      54              : 
      55              : // ===========================================================================
      56              : // method definitions
      57              : // ===========================================================================
      58         1353 : MSStopOut::MSStopOut(OutputDevice& dev) :
      59         1353 :     myDevice(dev) {
      60         1353 : }
      61              : 
      62         2698 : MSStopOut::~MSStopOut() {}
      63              : 
      64              : 
      65              : void
      66         4505 : MSStopOut::stopBlocked(const SUMOVehicle* veh, SUMOTime time) {
      67              :     assert(veh != nullptr);
      68              :     if (myStopped.count(veh) == 0) {
      69          152 :         myStopped.emplace(veh, StopInfo(-time, -1, -1));
      70              :     }
      71         4505 : }
      72              : 
      73              : 
      74              : void
      75            6 : MSStopOut::stopNotStarted(const SUMOVehicle* veh) {
      76              :     assert(veh != nullptr);
      77              :     myStopped.erase(veh);
      78            6 : }
      79              : 
      80              : 
      81              : void
      82         5893 : MSStopOut::stopStarted(const SUMOVehicle* veh, int numPersons, int numContainers, SUMOTime time) {
      83              :     assert(veh != nullptr);
      84              :     if (myStopped.count(veh) == 0) {
      85         5745 :         myStopped.emplace(veh, StopInfo(0, numPersons, numContainers));
      86              :     } else {
      87              :         MSStopOut::StopInfo& info = myStopped.find(veh)->second;
      88          148 :         info.blockTime += time;
      89          148 :         info.initialNumPersons = numPersons;
      90          148 :         info.initialNumContainers = numContainers;
      91              :     }
      92         5893 : }
      93              : 
      94              : 
      95              : void
      96         2702 : MSStopOut::loadedPersons(const SUMOVehicle* veh, int n) {
      97              :     // ignore triggered vehicles
      98         2702 :     if (veh->hasDeparted()) {
      99              :         if (myStopped.count(veh) == 0) {
     100            0 :             WRITE_WARNINGF(TL("Vehicle '%' loads persons on edge '%', time=% without starting the stop."),
     101              :                            veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     102              :         } else {
     103         2641 :             myStopped.find(veh)->second.loadedPersons += n;
     104              :         }
     105              :     }
     106         2702 : }
     107              : 
     108              : 
     109              : void
     110         1804 : MSStopOut::unloadedPersons(const SUMOVehicle* veh, int n) {
     111              :     if (myStopped.count(veh) == 0) {
     112            0 :         WRITE_WARNINGF(TL("Vehicle '%' unloads persons on edge '%', time=% without starting the stop."),
     113              :                        veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     114              :     } else {
     115         1804 :         myStopped.find(veh)->second.unloadedPersons += n;
     116              :     }
     117         1804 : }
     118              : 
     119              : 
     120              : void
     121          187 : MSStopOut::loadedContainers(const SUMOVehicle* veh, int n) {
     122              :     // ignore triggered vehicles
     123          187 :     if (veh->hasDeparted()) {
     124              :         if (myStopped.count(veh) == 0) {
     125            0 :             WRITE_WARNINGF(TL("Vehicle '%' loads container on edge '%', time=% without starting the stop."),
     126              :                            veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     127              :         } else {
     128          173 :             myStopped.find(veh)->second.loadedContainers += n;
     129              :         }
     130              :     }
     131          187 : }
     132              : 
     133              : 
     134              : void
     135          138 : MSStopOut::unloadedContainers(const SUMOVehicle* veh, int n) {
     136              :     if (myStopped.count(veh) == 0) {
     137            0 :         WRITE_WARNINGF(TL("Vehicle '%' unloads container on edge '%', time=% without starting the stop."),
     138              :                        veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     139              :     } else {
     140          138 :         myStopped.find(veh)->second.unloadedContainers += n;
     141              :     }
     142          138 : }
     143              : 
     144              : 
     145              : void
     146         5727 : MSStopOut::stopEnded(const SUMOVehicle* veh, const SUMOVehicleParameter::Stop& stop, const std::string& laneOrEdgeID, bool simEnd) {
     147              :     assert(veh != nullptr);
     148              :     if (myStopped.count(veh) == 0) {
     149            0 :         WRITE_WARNINGF(TL("Vehicle '%' ends stop on edge '%', time=% without entering the stop."),
     150              :                        veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     151            0 :         return;
     152              :     }
     153              :     const StopInfo& si = myStopped.find(veh)->second;
     154         5727 :     double delay = -1;
     155         5727 :     double arrivalDelay = -1;
     156         5727 :     if (stop.until >= 0 && !simEnd) {
     157         1640 :         delay = STEPS2TIME(SIMSTEP - stop.until);
     158              :     }
     159         5727 :     if (stop.arrival >= 0) {
     160          246 :         arrivalDelay = STEPS2TIME(stop.started - stop.arrival);
     161              :     }
     162         5727 :     myDevice.openTag("stopinfo");
     163         5727 :     myDevice.writeAttr(SUMO_ATTR_ID, veh->getID());
     164         5727 :     myDevice.writeAttr(SUMO_ATTR_TYPE, veh->getVehicleType().getID());
     165         5727 :     if (MSGlobals::gUseMesoSim) {
     166          897 :         myDevice.writeAttr(SUMO_ATTR_EDGE, laneOrEdgeID);
     167              :     } else {
     168         4830 :         myDevice.writeAttr(SUMO_ATTR_LANE, laneOrEdgeID);
     169              :     }
     170         5727 :     myDevice.writeAttr(SUMO_ATTR_POSITION, veh->getPositionOnLane());
     171         5727 :     myDevice.writeAttr(SUMO_ATTR_PARKING, stop.parking);
     172         5727 :     myDevice.writeAttr(SUMO_ATTR_STARTED, time2string(stop.started));
     173         5727 :     myDevice.writeAttr(SUMO_ATTR_ENDED, simEnd ? "-1" : time2string(SIMSTEP));
     174         5727 :     if (stop.until >= 0) {
     175         3280 :         myDevice.writeAttr("delay", delay);
     176              :     }
     177         5727 :     if (stop.arrival >= 0) {
     178          246 :         myDevice.writeAttr(SUMO_ATTR_ARRIVALDELAY, arrivalDelay);
     179              :     }
     180         5727 :     if (stop.busstop != "") {
     181         2508 :         myDevice.writeAttr(SUMO_ATTR_BUS_STOP, stop.busstop);
     182              :     }
     183         5727 :     if (stop.containerstop != "") {
     184           16 :         myDevice.writeAttr(SUMO_ATTR_CONTAINER_STOP, stop.containerstop);
     185              :     }
     186         5727 :     if (stop.parkingarea != "") {
     187         1805 :         myDevice.writeAttr(SUMO_ATTR_PARKING_AREA, stop.parkingarea);
     188              :     }
     189         5727 :     if (stop.chargingStation != "") {
     190           67 :         myDevice.writeAttr(SUMO_ATTR_CHARGING_STATION, stop.chargingStation);
     191              :     }
     192         5727 :     if (stop.overheadWireSegment != "") {
     193            0 :         myDevice.writeAttr(SUMO_ATTR_OVERHEAD_WIRE_SEGMENT, stop.overheadWireSegment);
     194              :     }
     195         5727 :     if (stop.tripId != "") {
     196           31 :         myDevice.writeAttr(SUMO_ATTR_TRIP_ID, stop.tripId);
     197              :     }
     198         5727 :     if (stop.line != "") {
     199           11 :         myDevice.writeAttr(SUMO_ATTR_LINE, stop.line);
     200              :     }
     201         5727 :     if (stop.split != "") {
     202           44 :         myDevice.writeAttr(SUMO_ATTR_SPLIT, stop.split);
     203              :     }
     204         5727 :     if (MSGlobals::gUseStopEnded) {
     205           30 :         myDevice.writeAttr(SUMO_ATTR_USED_ENDED, stop.ended >= 0);
     206              :     }
     207         5727 :     myDevice.writeAttr("initialPersons", si.initialNumPersons);
     208         5727 :     myDevice.writeAttr("loadedPersons", si.loadedPersons);
     209         5727 :     myDevice.writeAttr("unloadedPersons", si.unloadedPersons);
     210         5727 :     myDevice.writeAttr("initialContainers", si.initialNumContainers);
     211         5727 :     myDevice.writeAttr("loadedContainers", si.loadedContainers);
     212         5727 :     myDevice.writeAttr("unloadedContainers", si.unloadedContainers);
     213        11454 :     myDevice.writeAttr("blockedDuration", time2string(si.blockTime));
     214        11454 :     myDevice.closeTag();
     215              :     myStopped.erase(veh);
     216              : }
     217              : 
     218              : 
     219              : void
     220          120 : MSStopOut::generateOutputForUnfinished() {
     221         1330 :     while (!myStopped.empty()) {
     222              :         const auto& item = *myStopped.begin();
     223         1210 :         const SUMOVehicle* veh = item.first;
     224         1210 :         const SUMOVehicleParameter::Stop* stop = veh->getNextStopParameter();
     225              :         assert(stop != nullptr);
     226         1210 :         const std::string laneOrEdgeID = MSGlobals::gUseMesoSim ? veh->getEdge()->getID() : Named::getIDSecure(veh->getLane());
     227              :         // erases item from myStopped
     228         1210 :         stopEnded(veh, *stop, laneOrEdgeID, true);
     229              :     }
     230          120 : }
     231              : 
     232              : 
     233              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1