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 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 579528 : MSStageWaiting::MSStageWaiting(const MSEdge* destination, MSStoppingPlace* toStop,
39 : SUMOTime duration, SUMOTime until, double pos, const std::string& actType,
40 579528 : const bool initial, SUMOTime jumpDuration) :
41 : MSStage(initial ? MSStageType::WAITING_FOR_DEPART : MSStageType::WAITING,
42 : destination,
43 : toStop,
44 1159056 : SUMOVehicleParameter::interpretEdgePos(pos, destination->getLength(), SUMO_ATTR_DEPARTPOS, "stopping at " + destination->getID())),
45 579528 : myWaitingDuration(duration),
46 579528 : myWaitingUntil(until),
47 579528 : myStopWaitPos(Position::INVALID),
48 579528 : myActType(actType),
49 579528 : myJumpDuration(jumpDuration),
50 1804472 : myStopEndTime(-1) {
51 579528 : }
52 :
53 :
54 1158824 : MSStageWaiting::~MSStageWaiting() {}
55 :
56 : MSStage*
57 533925 : MSStageWaiting::clone() const {
58 533925 : MSStage* const clon = new MSStageWaiting(myDestination, myDestinationStop, myWaitingDuration, myWaitingUntil, myArrivalPos,
59 533925 : myActType, myType == MSStageType::WAITING_FOR_DEPART);
60 533925 : clon->setParameters(*this);
61 533925 : return clon;
62 : }
63 :
64 : SUMOTime
65 0 : MSStageWaiting::getUntil() const {
66 0 : return myWaitingUntil;
67 : }
68 :
69 : SUMOTime
70 31 : MSStageWaiting::getPlannedDuration() const {
71 31 : return myWaitingDuration;
72 : }
73 :
74 : SUMOTime
75 59727 : MSStageWaiting::getDuration() const {
76 59727 : return myType == MSStageType::WAITING_FOR_DEPART ? 0 : MSStage::getDuration();
77 : }
78 :
79 : Position
80 85850 : MSStageWaiting::getPosition(SUMOTime /* now */) const {
81 : if (myStopWaitPos != Position::INVALID) {
82 496 : return myStopWaitPos;
83 : }
84 85354 : return getEdgePosition(myDestination, myArrivalPos,
85 85354 : ROADSIDE_OFFSET * (MSGlobals::gLefthand ? -1 : 1));
86 : }
87 :
88 :
89 : double
90 3278 : MSStageWaiting::getAngle(SUMOTime /* now */) const {
91 3278 : const double offset = myDestinationStop == nullptr ? M_PI / 2 : myDestinationStop->getAngle();
92 3278 : return getEdgeAngle(myDestination, myArrivalPos) + offset * (MSGlobals::gLefthand ? -1 : 1);
93 : }
94 :
95 :
96 : void
97 65804 : MSStageWaiting::proceed(MSNet* net, MSTransportable* transportable, SUMOTime now, MSStage* previous) {
98 65804 : myDeparted = now;
99 65804 : myStopEndTime = MAX3(now, now + myWaitingDuration, myWaitingUntil);
100 65804 : if (unspecifiedArrivalPos()) {
101 20 : myArrivalPos = previous->getArrivalPos();
102 : }
103 65804 : if (myDestinationStop != nullptr) {
104 64814 : myDestinationStop->addTransportable(transportable);
105 64814 : myStopWaitPos = myDestinationStop->getWaitPosition(transportable);
106 : }
107 :
108 65804 : previous->getEdge()->addTransportable(transportable);
109 65804 : if (transportable->isPerson()) {
110 38173 : net->getPersonControl().setWaitEnd(myStopEndTime, transportable);
111 : } else {
112 27631 : net->getContainerControl().setWaitEnd(myStopEndTime, transportable);
113 : }
114 65804 : }
115 :
116 :
117 : void
118 57693 : MSStageWaiting::tripInfoOutput(OutputDevice& os, const MSTransportable* const) const {
119 57693 : if (myType != MSStageType::WAITING_FOR_DEPART) {
120 1018 : os.openTag(SUMO_TAG_STOP);
121 2036 : os.writeAttr("duration", getDuration() != SUMOTime_MAX ? time2string(getDuration()) : "-1");
122 2036 : os.writeAttr("arrival", time2string(myArrived));
123 2036 : os.writeAttr("arrivalPos", toString(myArrivalPos));
124 2182 : os.writeAttr("actType", myActType == "" ? "waiting" : myActType);
125 2036 : os.closeTag();
126 : }
127 57693 : }
128 :
129 :
130 : void
131 3412 : MSStageWaiting::routeOutput(const bool /* isPerson */, OutputDevice& os, const bool, const MSStage* const /* previous */) const {
132 3412 : if (myType != MSStageType::WAITING_FOR_DEPART) {
133 354 : os.openTag(SUMO_TAG_STOP);
134 354 : std::string comment = "";
135 354 : if (myDestinationStop != nullptr) {
136 129 : os.writeAttr(toString(myDestinationStop->getElement()), myDestinationStop->getID());
137 129 : if (myDestinationStop->getMyName() != "") {
138 90 : comment = " <!-- " + StringUtils::escapeXML(myDestinationStop->getMyName(), true) + " -->";
139 : }
140 : } else {
141 : // lane index is arbitrary
142 225 : os.writeAttr(SUMO_ATTR_LANE, getDestination()->getID() + "_0");
143 225 : os.writeAttr(SUMO_ATTR_ENDPOS, getArrivalPos());
144 : }
145 354 : if (myWaitingDuration >= 0) {
146 648 : os.writeAttr(SUMO_ATTR_DURATION, time2string(myWaitingDuration));
147 : }
148 354 : if (myWaitingUntil >= 0) {
149 70 : os.writeAttr(SUMO_ATTR_UNTIL, time2string(myWaitingUntil));
150 : }
151 708 : if (OptionsCont::getOptions().getBool("vehroute-output.exit-times")) {
152 30 : os.writeAttr(SUMO_ATTR_STARTED, myDeparted >= 0 ? time2string(myDeparted) : "-1");
153 60 : os.writeAttr(SUMO_ATTR_ENDED, myArrived >= 0 ? time2string(myArrived) : "-1");
154 : }
155 354 : if (myJumpDuration >= 0) {
156 32 : os.writeAttr(SUMO_ATTR_JUMP, time2string(myJumpDuration));
157 : }
158 354 : if (myActType != "") {
159 29 : os.writeAttr(SUMO_ATTR_ACTTYPE, myActType);
160 : }
161 : // Write rest of parameters
162 354 : writeParams(os);
163 354 : os.closeTag(comment);
164 : }
165 3412 : }
166 :
167 :
168 : void
169 44 : MSStageWaiting::abort(MSTransportable* t) {
170 44 : MSTransportableControl& tc = (t->isPerson() ?
171 44 : MSNet::getInstance()->getPersonControl() :
172 0 : MSNet::getInstance()->getContainerControl());
173 44 : tc.abortWaiting(t);
174 44 : if (myType == MSStageType::WAITING_FOR_DEPART) {
175 44 : tc.forceDeparture();
176 : }
177 44 : }
178 :
179 : std::string
180 1674 : MSStageWaiting::getStageDescription(const bool isPerson) const {
181 : UNUSED_PARAMETER(isPerson);
182 1674 : if (myActType != "") {
183 148 : return "waiting (" + myActType + ")";
184 : } else {
185 1600 : return "waiting";
186 : }
187 : }
188 :
189 : std::string
190 0 : MSStageWaiting::getStageSummary(const bool /* isPerson */) const {
191 : std::string timeInfo;
192 0 : if (myWaitingUntil >= 0) {
193 0 : timeInfo += " until " + time2string(myWaitingUntil);
194 : }
195 0 : if (myWaitingDuration >= 0) {
196 0 : timeInfo += " duration " + time2string(myWaitingDuration);
197 : }
198 0 : if (getDestinationStop() != nullptr) {
199 0 : std::string nameMsg = "";
200 0 : if (getDestinationStop()->getMyName() != "") {
201 0 : nameMsg = "(" + getDestinationStop()->getMyName() + ") ";
202 : }
203 0 : return "stopping at stop '" + getDestinationStop()->getID() + "' " + nameMsg + timeInfo + " (" + myActType + ")";
204 : }
205 0 : return "stopping at edge '" + getDestination()->getID() + "' " + timeInfo + " (" + myActType + ")";
206 : }
207 :
208 : void
209 8 : MSStageWaiting::saveState(std::ostringstream& out) {
210 8 : out << " " << myDeparted;
211 8 : }
212 :
213 : void
214 8 : MSStageWaiting::loadState(MSTransportable* transportable, std::istringstream& state) {
215 8 : state >> myDeparted;
216 8 : const SUMOTime until = MAX3(myDeparted, myDeparted + myWaitingDuration, myWaitingUntil);
217 8 : if (myDestinationStop != nullptr) {
218 0 : myDestinationStop->addTransportable(transportable);
219 0 : myStopWaitPos = myDestinationStop->getWaitPosition(transportable);
220 : }
221 8 : if (myDeparted >= 0) {
222 2 : myDestination->addTransportable(transportable);
223 2 : MSNet* net = MSNet::getInstance();
224 2 : if (transportable->isPerson()) {
225 2 : net->getPersonControl().setWaitEnd(until, transportable);
226 : } else {
227 0 : net->getContainerControl().setWaitEnd(until, transportable);
228 : }
229 : }
230 8 : }
|