LCOV - code coverage report
Current view: top level - src/microsim/output - MSStopOut.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 95.1 % 102 97
Test Date: 2026-04-16 16:39:47 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-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    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/MSStop.h>
      29              : #include <microsim/MSGlobals.h>
      30              : #include <microsim/MSParkingArea.h>
      31              : #include <microsim/MSStoppingPlace.h>
      32              : #include <microsim/MSVehicleType.h>
      33              : #include <microsim/trigger/MSChargingStation.h>
      34              : #include <microsim/trigger/MSOverheadWire.h>
      35              : #include "MSStopOut.h"
      36              : 
      37              : 
      38              : // ---------------------------------------------------------------------------
      39              : // static initialisation methods
      40              : // ---------------------------------------------------------------------------
      41              : MSStopOut* MSStopOut::myInstance = nullptr;
      42              : 
      43              : void
      44        41446 : MSStopOut::init() {
      45        82892 :     if (OptionsCont::getOptions().isSet("stop-output")) {
      46         1457 :         myInstance = new MSStopOut(OutputDevice::getDeviceByOption("stop-output"));
      47              :     }
      48        41446 : }
      49              : 
      50              : void
      51        41448 : MSStopOut::cleanup() {
      52        41448 :     delete myInstance;
      53        41448 :     myInstance = nullptr;
      54        41448 : }
      55              : 
      56              : // ===========================================================================
      57              : // method definitions
      58              : // ===========================================================================
      59         1457 : MSStopOut::MSStopOut(OutputDevice& dev) :
      60         1457 :     myDevice(dev) {
      61         1457 : }
      62              : 
      63         2900 : MSStopOut::~MSStopOut() {}
      64              : 
      65              : 
      66              : void
      67         5904 : MSStopOut::stopBlocked(const SUMOVehicle* veh, SUMOTime time) {
      68              :     assert(veh != nullptr);
      69              :     if (myStopped.count(veh) == 0) {
      70          170 :         myStopped.emplace(veh, StopInfo(-time, -1, -1));
      71              :     }
      72         5904 : }
      73              : 
      74              : 
      75              : void
      76           17 : MSStopOut::stopNotStarted(const SUMOVehicle* veh) {
      77              :     assert(veh != nullptr);
      78              :     myStopped.erase(veh);
      79           17 : }
      80              : 
      81              : 
      82              : void
      83         6367 : MSStopOut::stopStarted(const SUMOVehicle* veh, int numPersons, int numContainers, SUMOTime time) {
      84              :     assert(veh != nullptr);
      85              :     if (myStopped.count(veh) == 0) {
      86         6201 :         myStopped.emplace(veh, StopInfo(0, numPersons, numContainers));
      87              :     } else {
      88              :         MSStopOut::StopInfo& info = myStopped.find(veh)->second;
      89          166 :         info.blockTime += time;
      90          166 :         info.initialNumPersons = numPersons;
      91          166 :         info.initialNumContainers = numContainers;
      92              :     }
      93         6367 : }
      94              : 
      95              : 
      96              : void
      97         2721 : MSStopOut::loadedPersons(const SUMOVehicle* veh, int n) {
      98              :     // ignore triggered vehicles
      99         2721 :     if (veh->hasDeparted()) {
     100              :         if (myStopped.count(veh) == 0) {
     101            0 :             WRITE_WARNINGF(TL("Vehicle '%' loads persons on edge '%', time=% without starting the stop."),
     102              :                            veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     103              :         } else {
     104         2660 :             myStopped.find(veh)->second.loadedPersons += n;
     105              :         }
     106              :     }
     107         2721 : }
     108              : 
     109              : 
     110              : void
     111         1823 : MSStopOut::unloadedPersons(const SUMOVehicle* veh, int n) {
     112              :     if (myStopped.count(veh) == 0) {
     113            0 :         WRITE_WARNINGF(TL("Vehicle '%' unloads persons on edge '%', time=% without starting the stop."),
     114              :                        veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     115              :     } else {
     116         1823 :         myStopped.find(veh)->second.unloadedPersons += n;
     117              :     }
     118         1823 : }
     119              : 
     120              : 
     121              : void
     122          187 : MSStopOut::loadedContainers(const SUMOVehicle* veh, int n) {
     123              :     // ignore triggered vehicles
     124          187 :     if (veh->hasDeparted()) {
     125              :         if (myStopped.count(veh) == 0) {
     126            0 :             WRITE_WARNINGF(TL("Vehicle '%' loads container on edge '%', time=% without starting the stop."),
     127              :                            veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     128              :         } else {
     129          173 :             myStopped.find(veh)->second.loadedContainers += n;
     130              :         }
     131              :     }
     132          187 : }
     133              : 
     134              : 
     135              : void
     136          138 : MSStopOut::unloadedContainers(const SUMOVehicle* veh, int n) {
     137              :     if (myStopped.count(veh) == 0) {
     138            0 :         WRITE_WARNINGF(TL("Vehicle '%' unloads container on edge '%', time=% without starting the stop."),
     139              :                        veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     140              :     } else {
     141          138 :         myStopped.find(veh)->second.unloadedContainers += n;
     142              :     }
     143          138 : }
     144              : 
     145              : 
     146              : void
     147         6187 : MSStopOut::stopEnded(const SUMOVehicle* veh, const MSStop& stop, bool simEnd) {
     148              :     assert(veh != nullptr);
     149              :     if (myStopped.count(veh) == 0) {
     150            3 :         WRITE_WARNINGF(TL("Vehicle '%' ends stop on edge '%', time=% without entering the stop."),
     151              :                        veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP));
     152            1 :         return;
     153              :     }
     154              :     const SUMOVehicleParameter::Stop& pars = stop.pars;
     155              :     const StopInfo& si = myStopped.find(veh)->second;
     156         6186 :     double delay = -1;
     157         6186 :     double arrivalDelay = -1;
     158         6186 :     if (pars.until >= 0 && !simEnd) {
     159         1680 :         delay = STEPS2TIME(SIMSTEP - pars.until);
     160              :     }
     161         6186 :     if (pars.arrival >= 0) {
     162          245 :         arrivalDelay = STEPS2TIME(pars.started - pars.arrival);
     163              :     }
     164         6186 :     myDevice.openTag("stopinfo");
     165         6186 :     myDevice.writeAttr(SUMO_ATTR_ID, veh->getID());
     166         6186 :     myDevice.writeAttr(SUMO_ATTR_TYPE, veh->getVehicleType().getID());
     167         6186 :     if (MSGlobals::gUseMesoSim) {
     168          967 :         myDevice.writeAttr(SUMO_ATTR_EDGE, veh->getEdge()->getID());
     169              :     } else {
     170         5219 :         myDevice.writeAttr(SUMO_ATTR_LANE, stop.lane->getID());
     171              :     }
     172         6186 :     myDevice.writeAttr(SUMO_ATTR_POSITION, veh->getPositionOnLane());
     173         6186 :     myDevice.writeAttr(SUMO_ATTR_PARKING, pars.parking);
     174         6186 :     myDevice.writeAttr(SUMO_ATTR_STARTED, time2string(pars.started));
     175         6186 :     myDevice.writeAttr(SUMO_ATTR_ENDED, simEnd ? "-1" : time2string(SIMSTEP));
     176         6186 :     if (pars.until >= 0) {
     177         1680 :         myDevice.writeAttr("delay", delay);
     178              :     }
     179         6186 :     if (pars.arrival >= 0) {
     180          245 :         myDevice.writeAttr(SUMO_ATTR_ARRIVALDELAY, arrivalDelay);
     181              :     }
     182         6186 :     if (pars.busstop != "") {
     183         2536 :         myDevice.writeAttr(SUMO_ATTR_BUS_STOP, pars.busstop);
     184              :     }
     185         6186 :     if (pars.containerstop != "") {
     186           16 :         myDevice.writeAttr(SUMO_ATTR_CONTAINER_STOP, pars.containerstop);
     187              :     }
     188         6186 :     if (pars.parkingarea != "") {
     189         1923 :         myDevice.writeAttr(SUMO_ATTR_PARKING_AREA, pars.parkingarea);
     190              :     }
     191         6186 :     if (pars.chargingStation != "") {
     192           82 :         myDevice.writeAttr(SUMO_ATTR_CHARGING_STATION, pars.chargingStation);
     193              :     }
     194         6186 :     if (pars.overheadWireSegment != "") {
     195            0 :         myDevice.writeAttr(SUMO_ATTR_OVERHEAD_WIRE_SEGMENT, pars.overheadWireSegment);
     196              :     }
     197         6186 :     if (pars.tripId != "") {
     198           30 :         myDevice.writeAttr(SUMO_ATTR_TRIP_ID, pars.tripId);
     199              :     }
     200         6186 :     if (pars.line != "") {
     201           10 :         myDevice.writeAttr(SUMO_ATTR_LINE, pars.line);
     202              :     }
     203         6186 :     if (pars.split != "") {
     204           43 :         myDevice.writeAttr(SUMO_ATTR_SPLIT, pars.split);
     205              :     }
     206         6186 :     if (MSGlobals::gUseStopEnded) {
     207           30 :         myDevice.writeAttr(SUMO_ATTR_USED_ENDED, pars.ended >= 0);
     208              :     }
     209         6186 :     myDevice.writeAttr("initialPersons", si.initialNumPersons);
     210         6186 :     myDevice.writeAttr("loadedPersons", si.loadedPersons);
     211         6186 :     myDevice.writeAttr("unloadedPersons", si.unloadedPersons);
     212         6186 :     myDevice.writeAttr("initialContainers", si.initialNumContainers);
     213         6186 :     myDevice.writeAttr("loadedContainers", si.loadedContainers);
     214         6186 :     myDevice.writeAttr("unloadedContainers", si.unloadedContainers);
     215         6186 :     myDevice.writeAttr("blockedDuration", time2string(si.blockTime));
     216              : 
     217         6186 :     if (stop.pars.speed > 0) {
     218           68 :         if (stop.waypointWithStop) {
     219           12 :             myDevice.writeAttr(SUMO_ATTR_STATE, "waypointStopped");
     220              :         } else {
     221           56 :             myDevice.writeAttr(SUMO_ATTR_STATE, "waypoint");
     222              :         }
     223         6118 :     } else if (stop.skipOnDemand) {
     224           38 :         myDevice.writeAttr(SUMO_ATTR_STATE, "skippedOnDemand");
     225              :     }
     226              : 
     227        12372 :     myDevice.closeTag();
     228              :     myStopped.erase(veh);
     229              : }
     230              : 
     231              : 
     232              : void
     233          121 : MSStopOut::generateOutputForUnfinished() {
     234         1380 :     while (!myStopped.empty()) {
     235              :         const auto& item = *myStopped.begin();
     236         1259 :         const SUMOVehicle* veh = item.first;
     237              :         assert(veh->isStopped());
     238         1259 :         const MSStop& stop = veh->getNextStop();
     239              :         // erases item from myStopped
     240         1259 :         stopEnded(veh, stop, true);
     241              :     }
     242          121 : }
     243              : 
     244              : 
     245              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1