Line data Source code
1 : /****************************************************************************/ 2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 3 : // Copyright (C) 2001-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 : /****************************************************************************/ 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 34681 : MSStopOut::init() { 44 69362 : if (OptionsCont::getOptions().isSet("stop-output")) { 45 1166 : myInstance = new MSStopOut(OutputDevice::getDeviceByOption("stop-output")); 46 : } 47 34681 : } 48 : 49 : void 50 35190 : MSStopOut::cleanup() { 51 35190 : delete myInstance; 52 35190 : myInstance = nullptr; 53 35190 : } 54 : 55 : // =========================================================================== 56 : // method definitions 57 : // =========================================================================== 58 1166 : MSStopOut::MSStopOut(OutputDevice& dev) : 59 1166 : myDevice(dev) { 60 1166 : } 61 : 62 2320 : MSStopOut::~MSStopOut() {} 63 : 64 : 65 : void 66 5428 : MSStopOut::stopStarted(const SUMOVehicle* veh, int numPersons, int numContainers, SUMOTime time) { 67 : assert(veh != nullptr); 68 : if (myStopped.count(veh) != 0) { 69 0 : WRITE_WARNINGF(TL("Vehicle '%' stops on edge '%', time=% without ending the previous stop."), 70 : veh->getID(), veh->getEdge()->getID(), time2string(time)); 71 : } 72 5428 : myStopped.emplace(veh, StopInfo(numPersons, numContainers)); 73 5428 : } 74 : 75 : void 76 3156 : MSStopOut::loadedPersons(const SUMOVehicle* veh, int n) { 77 : // ignore triggered vehicles 78 3156 : if (veh->hasDeparted()) { 79 3095 : myStopped.find(veh)->second.loadedPersons += n; 80 : } 81 3156 : } 82 : 83 : void 84 2256 : MSStopOut::unloadedPersons(const SUMOVehicle* veh, int n) { 85 2256 : myStopped.find(veh)->second.unloadedPersons += n; 86 2256 : } 87 : 88 : void 89 187 : MSStopOut::loadedContainers(const SUMOVehicle* veh, int n) { 90 : // ignore triggered vehicles 91 187 : if (veh->hasDeparted()) { 92 173 : myStopped.find(veh)->second.loadedContainers += n; 93 : } 94 187 : } 95 : 96 : void 97 138 : MSStopOut::unloadedContainers(const SUMOVehicle* veh, int n) { 98 138 : myStopped.find(veh)->second.unloadedContainers += n; 99 138 : } 100 : 101 : void 102 5297 : MSStopOut::stopEnded(const SUMOVehicle* veh, const SUMOVehicleParameter::Stop& stop, const std::string& laneOrEdgeID, bool simEnd) { 103 : assert(veh != nullptr); 104 : if (myStopped.count(veh) == 0) { 105 0 : WRITE_WARNINGF(TL("Vehicle '%' ends stop on edge '%', time=% without entering the stop."), 106 : veh->getID(), veh->getEdge()->getID(), time2string(SIMSTEP)); 107 0 : return; 108 : } 109 : const StopInfo& si = myStopped.find(veh)->second; 110 5297 : double delay = -1; 111 5297 : double arrivalDelay = -1; 112 5297 : if (stop.until >= 0 && !simEnd) { 113 1011 : delay = STEPS2TIME(SIMSTEP - stop.until); 114 : } 115 5297 : if (stop.arrival >= 0) { 116 241 : arrivalDelay = STEPS2TIME(stop.started - stop.arrival); 117 : } 118 5297 : myDevice.openTag("stopinfo"); 119 5297 : myDevice.writeAttr(SUMO_ATTR_ID, veh->getID()); 120 5297 : myDevice.writeAttr(SUMO_ATTR_TYPE, veh->getVehicleType().getID()); 121 5297 : if (MSGlobals::gUseMesoSim) { 122 791 : myDevice.writeAttr(SUMO_ATTR_EDGE, laneOrEdgeID); 123 : } else { 124 4506 : myDevice.writeAttr(SUMO_ATTR_LANE, laneOrEdgeID); 125 : } 126 5297 : myDevice.writeAttr(SUMO_ATTR_POSITION, veh->getPositionOnLane()); 127 5297 : myDevice.writeAttr(SUMO_ATTR_PARKING, stop.parking); 128 5297 : myDevice.writeAttr(SUMO_ATTR_STARTED, time2string(stop.started)); 129 5297 : myDevice.writeAttr(SUMO_ATTR_ENDED, simEnd ? "-1" : time2string(SIMSTEP)); 130 5297 : if (stop.until >= 0) { 131 2022 : myDevice.writeAttr("delay", delay); 132 : } 133 5297 : if (stop.arrival >= 0) { 134 241 : myDevice.writeAttr(SUMO_ATTR_ARRIVALDELAY, arrivalDelay); 135 : } 136 5297 : if (stop.busstop != "") { 137 2268 : myDevice.writeAttr(SUMO_ATTR_BUS_STOP, stop.busstop); 138 : } 139 5297 : if (stop.containerstop != "") { 140 16 : myDevice.writeAttr(SUMO_ATTR_CONTAINER_STOP, stop.containerstop); 141 : } 142 5297 : if (stop.parkingarea != "") { 143 1772 : myDevice.writeAttr(SUMO_ATTR_PARKING_AREA, stop.parkingarea); 144 : } 145 5297 : if (stop.chargingStation != "") { 146 52 : myDevice.writeAttr(SUMO_ATTR_CHARGING_STATION, stop.chargingStation); 147 : } 148 5297 : if (stop.overheadWireSegment != "") { 149 0 : myDevice.writeAttr(SUMO_ATTR_OVERHEAD_WIRE_SEGMENT, stop.overheadWireSegment); 150 : } 151 5297 : if (stop.tripId != "") { 152 32 : myDevice.writeAttr(SUMO_ATTR_TRIP_ID, stop.tripId); 153 : } 154 5297 : if (stop.line != "") { 155 12 : myDevice.writeAttr(SUMO_ATTR_LINE, stop.line); 156 : } 157 5297 : if (stop.split != "") { 158 40 : myDevice.writeAttr(SUMO_ATTR_SPLIT, stop.split); 159 : } 160 5297 : if (MSGlobals::gUseStopEnded) { 161 60 : myDevice.writeAttr(SUMO_ATTR_USED_ENDED, stop.ended >= 0); 162 : } 163 5297 : myDevice.writeAttr("initialPersons", si.initialNumPersons); 164 5297 : myDevice.writeAttr("loadedPersons", si.loadedPersons); 165 5297 : myDevice.writeAttr("unloadedPersons", si.unloadedPersons); 166 5297 : myDevice.writeAttr("initialContainers", si.initialNumContainers); 167 5297 : myDevice.writeAttr("loadedContainers", si.loadedContainers); 168 5297 : myDevice.writeAttr("unloadedContainers", si.unloadedContainers); 169 10594 : myDevice.closeTag(); 170 : myStopped.erase(veh); 171 : } 172 : 173 : void 174 112 : MSStopOut::generateOutputForUnfinished() { 175 1340 : while (!myStopped.empty()) { 176 : const auto& item = *myStopped.begin(); 177 1228 : const SUMOVehicle* veh = item.first; 178 1228 : const SUMOVehicleParameter::Stop* stop = veh->getNextStopParameter(); 179 : assert(stop != nullptr); 180 1228 : const std::string laneOrEdgeID = MSGlobals::gUseMesoSim ? veh->getEdge()->getID() : Named::getIDSecure(veh->getLane()); 181 : // erases item from myStopped 182 1228 : stopEnded(veh, *stop, laneOrEdgeID, true); 183 : } 184 112 : } 185 : 186 : /****************************************************************************/