1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file MSStopOut.cpp
11 /// @author Jakob Erdmann
12 /// @date Wed, 21.12.2016
13 /// @version $Id$
14 ///
15 // Ouput information about planned vehicle stop
16 /****************************************************************************/
17
18
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include <config.h>
23
24 #include <utils/vehicle/SUMOVehicle.h>
25 #include <utils/options/OptionsCont.h>
26 #include <utils/common/MsgHandler.h>
27 #include <microsim/MSNet.h>
28 #include <microsim/MSEdge.h>
29 #include <microsim/MSParkingArea.h>
30 #include <microsim/MSStoppingPlace.h>
31 #include <microsim/trigger/MSChargingStation.h>
32 #include "MSStopOut.h"
33
34
35 // ---------------------------------------------------------------------------
36 // static initialisation methods
37 // ---------------------------------------------------------------------------
38 MSStopOut* MSStopOut::myInstance = nullptr;
39
40 void
init()41 MSStopOut::init() {
42 if (OptionsCont::getOptions().isSet("stop-output")) {
43 myInstance = new MSStopOut(OutputDevice::getDeviceByOption("stop-output"));
44 }
45 }
46
47 void
cleanup()48 MSStopOut::cleanup() {
49 delete myInstance;
50 myInstance = nullptr;
51 }
52
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
MSStopOut(OutputDevice & dev)56 MSStopOut::MSStopOut(OutputDevice& dev) :
57 myDevice(dev) {
58 }
59
~MSStopOut()60 MSStopOut::~MSStopOut() {}
61
62
63 void
stopStarted(const SUMOVehicle * veh,int numPersons,int numContainers,SUMOTime time)64 MSStopOut::stopStarted(const SUMOVehicle* veh, int numPersons, int numContainers, SUMOTime time) {
65 assert(veh != 0);
66 if (myStopped.count(veh) != 0) {
67 WRITE_WARNING("Vehicle '" + veh->getID() + "' stops on edge '" + veh->getEdge()->getID()
68 + "', time " + time2string(time)
69 + " without ending the previous stop entered at time " + time2string(myStopped[veh].started));
70 }
71 StopInfo stopInfo(MSNet::getInstance()->getCurrentTimeStep(), numPersons, numContainers);
72 myStopped[veh] = stopInfo;
73 }
74
75 void
loadedPersons(const SUMOVehicle * veh,int n)76 MSStopOut::loadedPersons(const SUMOVehicle* veh, int n) {
77 // ignore triggered vehicles
78 if (veh->hasDeparted()) {
79 myStopped[veh].loadedPersons += n;
80 }
81 }
82
83 void
unloadedPersons(const SUMOVehicle * veh,int n)84 MSStopOut::unloadedPersons(const SUMOVehicle* veh, int n) {
85 myStopped[veh].unloadedPersons += n;
86 }
87
88 void
loadedContainers(const SUMOVehicle * veh,int n)89 MSStopOut::loadedContainers(const SUMOVehicle* veh, int n) {
90 myStopped[veh].loadedContainers += n;
91 }
92
93 void
unloadedContainers(const SUMOVehicle * veh,int n)94 MSStopOut::unloadedContainers(const SUMOVehicle* veh, int n) {
95 myStopped[veh].unloadedContainers += n;
96 }
97
98 void
stopEnded(const SUMOVehicle * veh,const SUMOVehicleParameter::Stop & stop,const std::string & laneOrEdgeID)99 MSStopOut::stopEnded(const SUMOVehicle* veh, const SUMOVehicleParameter::Stop& stop, const std::string& laneOrEdgeID) {
100 assert(veh != 0);
101 if (myStopped.count(veh) == 0) {
102 WRITE_WARNING("Vehicle '" + veh->getID() + "' ends stop on edge '" + veh->getEdge()->getID()
103 + "', time " + time2string(MSNet::getInstance()->getCurrentTimeStep()) + " without entering the stop");
104 return;
105 }
106 double delay = -1;
107 if (stop.until >= 0) {
108 delay = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - stop.until);
109 }
110 StopInfo& si = myStopped[veh];
111 myDevice.openTag("stopinfo");
112 myDevice.writeAttr(SUMO_ATTR_ID, veh->getID());
113 myDevice.writeAttr(SUMO_ATTR_TYPE, veh->getVehicleType().getID());
114 if (MSGlobals::gUseMesoSim) {
115 myDevice.writeAttr(SUMO_ATTR_EDGE, laneOrEdgeID);
116 } else {
117 myDevice.writeAttr(SUMO_ATTR_LANE, laneOrEdgeID);
118 }
119 myDevice.writeAttr(SUMO_ATTR_POSITION, veh->getPositionOnLane());
120 myDevice.writeAttr(SUMO_ATTR_PARKING, stop.parking);
121 myDevice.writeAttr("started", time2string(si.started));
122 myDevice.writeAttr("ended", time2string(MSNet::getInstance()->getCurrentTimeStep()));
123 myDevice.writeAttr("delay", delay);
124 myDevice.writeAttr("initialPersons", si.initialNumPersons);
125 myDevice.writeAttr("loadedPersons", si.loadedPersons);
126 myDevice.writeAttr("unloadedPersons", si.unloadedPersons);
127 myDevice.writeAttr("initialContainers", si.initialNumContainers);
128 myDevice.writeAttr("loadedContainers", si.loadedContainers);
129 myDevice.writeAttr("unloadedContainers", si.unloadedContainers);
130 if (stop.busstop != "") {
131 myDevice.writeAttr(SUMO_ATTR_BUS_STOP, stop.busstop);
132 }
133 if (stop.containerstop != "") {
134 myDevice.writeAttr(SUMO_ATTR_CONTAINER_STOP, stop.containerstop);
135 }
136 if (stop.parkingarea != "") {
137 myDevice.writeAttr(SUMO_ATTR_PARKING_AREA, stop.parkingarea);
138 }
139 if (stop.chargingStation != "") {
140 myDevice.writeAttr(SUMO_ATTR_CHARGING_STATION, stop.chargingStation);
141 }
142 myDevice.closeTag();
143 myStopped.erase(veh);
144 }
145
146 /****************************************************************************/
147