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 MSStageWaiting.cpp
15 : /// @author Melanie Weber
16 : /// @author Andreas Kendziorra
17 : /// @author Michael Behrisch
18 : /// @author Jakob Erdmann
19 : /// @date Wed, 1 Jun 2022
20 : ///
21 : // An stage for planned waiting (stopping)
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <utils/vehicle/SUMOVehicleParameter.h>
26 : #include <utils/geom/GeomHelper.h>
27 : #include <microsim/MSEdge.h>
28 : #include <microsim/MSLane.h>
29 : #include <microsim/MSNet.h>
30 : #include <microsim/MSStoppingPlace.h>
31 : #include <microsim/transportables/MSTransportable.h>
32 : #include <microsim/transportables/MSTransportableControl.h>
33 : #include <microsim/transportables/MSStageWaiting.h>
34 :
35 : /* -------------------------------------------------------------------------
36 : * MSStageWaiting - methods
37 : * ----------------------------------------------------------------------- */
38 573547 : MSStageWaiting::MSStageWaiting(const MSEdge* destination, MSStoppingPlace* toStop,
39 : SUMOTime duration, SUMOTime until, double pos, const std::string& actType,
40 573547 : const bool initial) :
41 : MSStage(initial ? MSStageType::WAITING_FOR_DEPART : MSStageType::WAITING,
42 : destination,
43 : toStop,
44 1147094 : SUMOVehicleParameter::interpretEdgePos(pos, destination->getLength(), SUMO_ATTR_DEPARTPOS, "stopping at " + destination->getID())),
45 573547 : myWaitingDuration(duration),
46 573547 : myWaitingUntil(until),
47 573547 : myStopWaitPos(Position::INVALID),
48 573547 : myActType(actType),
49 1786321 : myStopEndTime(-1) {
50 573547 : }
51 :
52 :
53 1146862 : MSStageWaiting::~MSStageWaiting() {}
54 :
55 : MSStage*
56 528934 : MSStageWaiting::clone() const {
57 528934 : MSStage* const clon = new MSStageWaiting(myDestination, myDestinationStop, myWaitingDuration, myWaitingUntil, myArrivalPos,
58 528934 : myActType, myType == MSStageType::WAITING_FOR_DEPART);
59 528934 : clon->setParameters(*this);
60 528934 : return clon;
61 : }
62 :
63 : SUMOTime
64 0 : MSStageWaiting::getUntil() const {
65 0 : return myWaitingUntil;
66 : }
67 :
68 : SUMOTime
69 31 : MSStageWaiting::getPlannedDuration() const {
70 31 : return myWaitingDuration;
71 : }
72 :
73 : SUMOTime
74 58398 : MSStageWaiting::getDuration() const {
75 58398 : return myType == MSStageType::WAITING_FOR_DEPART ? 0 : MSStage::getDuration();
76 : }
77 :
78 : Position
79 85707 : MSStageWaiting::getPosition(SUMOTime /* now */) const {
80 : if (myStopWaitPos != Position::INVALID) {
81 454 : return myStopWaitPos;
82 : }
83 85253 : return getEdgePosition(myDestination, myArrivalPos,
84 170426 : ROADSIDE_OFFSET * (MSGlobals::gLefthand ? -1 : 1));
85 : }
86 :
87 :
88 : double
89 3143 : MSStageWaiting::getAngle(SUMOTime /* now */) const {
90 3143 : return getEdgeAngle(myDestination, myArrivalPos) + M_PI / 2 * (MSGlobals::gLefthand ? -1 : 1);
91 : }
92 :
93 :
94 : void
95 65595 : MSStageWaiting::proceed(MSNet* net, MSTransportable* transportable, SUMOTime now, MSStage* previous) {
96 65595 : myDeparted = now;
97 65595 : myStopEndTime = MAX3(now, now + myWaitingDuration, myWaitingUntil);
98 65595 : if (myDestinationStop != nullptr) {
99 64658 : myDestinationStop->addTransportable(transportable);
100 64658 : myStopWaitPos = myDestinationStop->getWaitPosition(transportable);
101 : }
102 :
103 65595 : previous->getEdge()->addTransportable(transportable);
104 65595 : if (transportable->isPerson()) {
105 38096 : net->getPersonControl().setWaitEnd(myStopEndTime, transportable);
106 : } else {
107 27499 : net->getContainerControl().setWaitEnd(myStopEndTime, transportable);
108 : }
109 65595 : }
110 :
111 :
112 : void
113 56492 : MSStageWaiting::tripInfoOutput(OutputDevice& os, const MSTransportable* const) const {
114 56492 : if (myType != MSStageType::WAITING_FOR_DEPART) {
115 954 : os.openTag(SUMO_TAG_STOP);
116 1908 : os.writeAttr("duration", getDuration() != SUMOTime_MAX ? time2string(getDuration()) : "-1");
117 1908 : os.writeAttr("arrival", time2string(myArrived));
118 1908 : os.writeAttr("arrivalPos", toString(myArrivalPos));
119 2054 : os.writeAttr("actType", myActType == "" ? "waiting" : myActType);
120 1908 : os.closeTag();
121 : }
122 56492 : }
123 :
124 :
125 : void
126 3048 : MSStageWaiting::routeOutput(const bool /* isPerson */, OutputDevice& os, const bool, const MSStage* const /* previous */) const {
127 3048 : if (myType != MSStageType::WAITING_FOR_DEPART) {
128 314 : os.openTag(SUMO_TAG_STOP);
129 314 : std::string comment = "";
130 314 : if (myDestinationStop != nullptr) {
131 121 : os.writeAttr(toString(myDestinationStop->getElement()), myDestinationStop->getID());
132 121 : if (myDestinationStop->getMyName() != "") {
133 90 : comment = " <!-- " + StringUtils::escapeXML(myDestinationStop->getMyName(), true) + " -->";
134 : }
135 : } else {
136 : // lane index is arbitrary
137 193 : os.writeAttr(SUMO_ATTR_LANE, getDestination()->getID() + "_0");
138 386 : os.writeAttr(SUMO_ATTR_ENDPOS, getArrivalPos());
139 : }
140 314 : if (myWaitingDuration >= 0) {
141 568 : os.writeAttr(SUMO_ATTR_DURATION, time2string(myWaitingDuration));
142 : }
143 314 : if (myWaitingUntil >= 0) {
144 70 : os.writeAttr(SUMO_ATTR_UNTIL, time2string(myWaitingUntil));
145 : }
146 628 : if (OptionsCont::getOptions().getBool("vehroute-output.exit-times")) {
147 30 : os.writeAttr(SUMO_ATTR_STARTED, myDeparted >= 0 ? time2string(myDeparted) : "-1");
148 60 : os.writeAttr(SUMO_ATTR_ENDED, myArrived >= 0 ? time2string(myArrived) : "-1");
149 : }
150 314 : if (myActType != "") {
151 : os.writeAttr(SUMO_ATTR_ACTTYPE, myActType);
152 : }
153 : // Write rest of parameters
154 314 : writeParams(os);
155 314 : os.closeTag(comment);
156 : }
157 3048 : }
158 :
159 :
160 : void
161 43 : MSStageWaiting::abort(MSTransportable* t) {
162 43 : MSTransportableControl& tc = (t->isPerson() ?
163 43 : MSNet::getInstance()->getPersonControl() :
164 0 : MSNet::getInstance()->getContainerControl());
165 43 : tc.abortWaiting(t);
166 43 : if (myType == MSStageType::WAITING_FOR_DEPART) {
167 43 : tc.forceDeparture();
168 : }
169 43 : }
170 :
171 : std::string
172 1674 : MSStageWaiting::getStageDescription(const bool isPerson) const {
173 : UNUSED_PARAMETER(isPerson);
174 1674 : if (myActType != "") {
175 148 : return "waiting (" + myActType + ")";
176 : } else {
177 1600 : return "waiting";
178 : }
179 : }
180 :
181 : std::string
182 0 : MSStageWaiting::getStageSummary(const bool /* isPerson */) const {
183 : std::string timeInfo;
184 0 : if (myWaitingUntil >= 0) {
185 0 : timeInfo += " until " + time2string(myWaitingUntil);
186 : }
187 0 : if (myWaitingDuration >= 0) {
188 0 : timeInfo += " duration " + time2string(myWaitingDuration);
189 : }
190 0 : if (getDestinationStop() != nullptr) {
191 0 : std::string nameMsg = "";
192 0 : if (getDestinationStop()->getMyName() != "") {
193 0 : nameMsg = "(" + getDestinationStop()->getMyName() + ") ";
194 : }
195 0 : return "stopping at stop '" + getDestinationStop()->getID() + "' " + nameMsg + timeInfo + " (" + myActType + ")";
196 : }
197 0 : return "stopping at edge '" + getDestination()->getID() + "' " + timeInfo + " (" + myActType + ")";
198 : }
199 :
200 : void
201 8 : MSStageWaiting::saveState(std::ostringstream& out) {
202 8 : out << " " << myDeparted;
203 8 : }
204 :
205 : void
206 8 : MSStageWaiting::loadState(MSTransportable* transportable, std::istringstream& state) {
207 8 : state >> myDeparted;
208 8 : const SUMOTime until = MAX3(myDeparted, myDeparted + myWaitingDuration, myWaitingUntil);
209 8 : if (myDestinationStop != nullptr) {
210 0 : myDestinationStop->addTransportable(transportable);
211 0 : myStopWaitPos = myDestinationStop->getWaitPosition(transportable);
212 : }
213 8 : if (myDeparted >= 0) {
214 2 : myDestination->addTransportable(transportable);
215 2 : MSNet* net = MSNet::getInstance();
216 2 : if (transportable->isPerson()) {
217 2 : net->getPersonControl().setWaitEnd(until, transportable);
218 : } else {
219 0 : net->getContainerControl().setWaitEnd(until, transportable);
220 : }
221 : }
222 8 : }
|