Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2005-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 MSStop.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Michael Behrisch
17 : /// @date Mon, 13.12.2005
18 : ///
19 : // A lane area vehicles can halt at
20 : /****************************************************************************/
21 : #include <config.h>
22 :
23 : #include <mesosim/MESegment.h>
24 : #include <mesosim/MELoop.h>
25 : #include "MSLane.h"
26 : #include "MSEdge.h"
27 : #include "MSNet.h"
28 : #include "MSParkingArea.h"
29 : #include "MSStoppingPlace.h"
30 : #include "MSStop.h"
31 :
32 : // ===========================================================================
33 : // method definitions
34 : // ===========================================================================
35 : double
36 14108723 : MSStop::getEndPos(const SUMOVehicle& veh) const {
37 14108723 : const double brakePos = veh.getEdge() == getEdge() ? veh.getPositionOnLane() + veh.getBrakeGap() : 0;
38 14108723 : if ((pars.parametersSet & STOP_END_SET) != 0) {
39 4106793 : return pars.endPos;
40 10001930 : } else if (busstop != nullptr) {
41 3351719 : return busstop->getLastFreePos(veh, brakePos);
42 6650211 : } else if (containerstop != nullptr) {
43 2569379 : return containerstop->getLastFreePos(veh, brakePos);
44 4080832 : } else if (parkingarea != nullptr) {
45 1751705 : return parkingarea->getLastFreePos(veh, brakePos);
46 2329127 : } else if (chargingStation != nullptr) {
47 1040237 : return chargingStation->getLastFreePos(veh);
48 1288890 : } else if (overheadWireSegment != nullptr) {
49 0 : return overheadWireSegment->getLastFreePos(veh);
50 : }
51 1288890 : return pars.endPos;
52 : }
53 :
54 : const MSEdge*
55 14212231 : MSStop::getEdge() const {
56 14212231 : if (lane != nullptr) {
57 14212231 : return &lane->getEdge();
58 0 : } else if (segment != nullptr) {
59 0 : return &segment->getEdge();
60 : }
61 : return nullptr;
62 : }
63 :
64 : double
65 3089133 : MSStop::getReachedThreshold() const {
66 3089133 : return isOpposite ? lane->getOppositePos(pars.endPos) - (pars.endPos - pars.startPos) : pars.startPos;
67 : }
68 :
69 : std::string
70 42 : MSStop::getDescription(bool nameOnly) const {
71 : std::string result;
72 42 : if (parkingarea != nullptr) {
73 1 : if (nameOnly) {
74 : return parkingarea->getID();
75 : }
76 2 : result = "parkingArea:" + parkingarea->getID();
77 41 : } else if (containerstop != nullptr) {
78 0 : if (nameOnly) {
79 : return containerstop->getID();
80 : }
81 0 : result = "containerStop:" + containerstop->getID();
82 41 : } else if (busstop != nullptr) {
83 41 : if (nameOnly) {
84 : return busstop->getID();
85 : }
86 0 : result = "busStop:" + busstop->getID();
87 0 : } else if (chargingStation != nullptr) {
88 0 : if (nameOnly) {
89 : return chargingStation->getID();
90 : }
91 0 : result = "chargingStation:" + chargingStation->getID();
92 0 : } else if (overheadWireSegment != nullptr) {
93 0 : if (nameOnly) {
94 : return overheadWireSegment->getID();
95 : }
96 0 : result = "overheadWireSegment:" + overheadWireSegment->getID();
97 : } else {
98 0 : if (nameOnly) {
99 0 : return "";
100 : }
101 0 : result = "lane:" + lane->getID() + " pos:" + toString(pars.endPos);
102 : }
103 1 : if (pars.actType != "") {
104 0 : result += " actType:" + pars.actType;
105 : }
106 1 : return result;
107 : }
108 :
109 :
110 : std::pair<std::string, SumoXMLTag>
111 66115 : MSStop::getStoppingPlaceName() const {
112 66115 : if (busstop != nullptr && !busstop->getMyName().empty()) {
113 1403 : return std::make_pair(busstop->getMyName(), SUMO_TAG_BUS_STOP);
114 64712 : } else if (containerstop != nullptr && !containerstop->getMyName().empty()) {
115 48 : return std::make_pair(containerstop->getMyName(), SUMO_TAG_CONTAINER_STOP);
116 64664 : } else if (parkingarea != nullptr && !parkingarea->getMyName().empty()) {
117 0 : return std::make_pair(parkingarea->getMyName(), SUMO_TAG_PARKING_AREA);
118 64664 : } else if (chargingStation != nullptr && !chargingStation->getMyName().empty()) {
119 0 : return std::make_pair(chargingStation->getMyName(), SUMO_TAG_CHARGING_STATION);
120 64664 : } else if (overheadWireSegment != nullptr && !overheadWireSegment->getMyName().empty()) {
121 0 : return std::make_pair(overheadWireSegment->getMyName(), SUMO_TAG_OVERHEAD_WIRE_SEGMENT);
122 : }
123 : return std::make_pair("", SUMO_TAG_NOTHING);
124 : }
125 :
126 :
127 : void
128 879 : MSStop::write(OutputDevice& dev) const {
129 879 : SUMOVehicleParameter::Stop tmp = pars;
130 879 : tmp.duration = duration;
131 879 : if (!triggered && !containerTriggered) {
132 : // we are writing in the context of saveState. All required
133 : // transportables have entered and we must prevent the trigger condition
134 : // to be renewed on loading
135 862 : tmp.triggered = false;
136 862 : tmp.containerTriggered = false;
137 : }
138 879 : tmp.write(dev, false);
139 : // if the stop has already started but hasn't ended yet we are writing it in
140 : // the context of saveState (but we do not want to write the attribute twice
141 879 : if (pars.started >= 0 && (pars.parametersSet & STOP_STARTED_SET) == 0) {
142 507 : dev.writeAttr(SUMO_ATTR_STARTED, time2string(pars.started));
143 : }
144 879 : pars.writeParams(dev);
145 879 : dev.closeTag();
146 879 : }
147 :
148 : void
149 141768 : MSStop::initPars(const SUMOVehicleParameter::Stop& stopPar) {
150 141768 : busstop = MSNet::getInstance()->getStoppingPlace(stopPar.busstop, SUMO_TAG_BUS_STOP);
151 141768 : containerstop = MSNet::getInstance()->getStoppingPlace(stopPar.containerstop, SUMO_TAG_CONTAINER_STOP);
152 141768 : parkingarea = static_cast<MSParkingArea*>(MSNet::getInstance()->getStoppingPlace(stopPar.parkingarea, SUMO_TAG_PARKING_AREA));
153 141768 : chargingStation = MSNet::getInstance()->getStoppingPlace(stopPar.chargingStation, SUMO_TAG_CHARGING_STATION);
154 141768 : overheadWireSegment = MSNet::getInstance()->getStoppingPlace(stopPar.overheadWireSegment, SUMO_TAG_OVERHEAD_WIRE_SEGMENT);
155 141768 : duration = stopPar.duration;
156 141768 : triggered = stopPar.triggered;
157 141768 : containerTriggered = stopPar.containerTriggered;
158 141768 : joinTriggered = stopPar.joinTriggered || stopPar.join != "";
159 141768 : numExpectedPerson = (int)stopPar.awaitedPersons.size();
160 141768 : numExpectedContainer = (int)stopPar.awaitedContainers.size();
161 141768 : }
162 :
163 :
164 : int
165 238 : MSStop::getStateFlagsOld() const {
166 238 : return ((reached ? 1 : 0) + 2 * pars.getFlags());
167 : }
168 :
169 :
170 : SUMOTime
171 121737 : MSStop::getMinDuration(SUMOTime time) const {
172 121737 : if (MSGlobals::gUseStopEnded && pars.ended >= 0) {
173 53 : return pars.ended - time;
174 : }
175 121684 : if (pars.until >= 0) {
176 51713 : if (duration == -1) {
177 36910 : return pars.until - time;
178 : } else {
179 14803 : return MAX2(duration, pars.until - time);
180 : }
181 : } else {
182 69971 : return duration;
183 : }
184 : }
185 :
186 :
187 : SUMOTime
188 636894 : MSStop::getUntil() const {
189 636894 : return MSGlobals::gUseStopEnded && pars.ended >= 0 ? pars.ended : pars.until;
190 : }
191 :
192 :
193 : SUMOTime
194 135134 : MSStop::getArrival() const {
195 135134 : return MSGlobals::gUseStopStarted && pars.started >= 0 ? pars.started : pars.arrival;
196 : }
197 :
198 :
199 : SUMOTime
200 81503 : MSStop::getArrivalFallback() const {
201 81503 : SUMOTime result = getArrival();
202 81503 : if (result < 0) {
203 81421 : result = getUntil();
204 81421 : if (result >= 0 && pars.duration >= 0) {
205 14832 : result -= pars.duration;
206 : }
207 : }
208 81503 : return result;
209 : }
210 :
211 :
212 : double
213 131305486 : MSStop::getSpeed() const {
214 131305486 : return skipOnDemand ? std::numeric_limits<double>::max() : pars.speed;
215 : }
216 :
217 :
218 : bool
219 28951 : MSStop::isInRange(const double pos, const double tolerance) const {
220 28951 : return pars.startPos - tolerance <= pos && pars.endPos + tolerance >= pos;
221 : }
222 :
223 :
224 : std::vector<MSStoppingPlace*>
225 15 : MSStop::getPlaces() const {
226 : std::vector<MSStoppingPlace*> result;
227 15 : if (busstop != nullptr) {
228 15 : result.push_back(busstop);
229 : }
230 15 : if (containerstop != nullptr) {
231 0 : result.push_back(containerstop);
232 : }
233 15 : if (parkingarea != nullptr) {
234 0 : result.push_back(parkingarea);
235 : }
236 15 : if (chargingStation != nullptr) {
237 0 : result.push_back(chargingStation);
238 : }
239 15 : if (overheadWireSegment != nullptr) {
240 0 : result.push_back(overheadWireSegment);
241 : }
242 15 : return result;
243 0 : }
244 :
245 :
246 : void
247 41 : MSStop::replaceStoppingPlace(MSStoppingPlace* sp) {
248 : // @note: assume iterator edge is handled elsewhere
249 : assert(*edge == &sp->getLane().getEdge());
250 41 : lane = &sp->getLane();
251 : SUMOVehicleParameter::Stop& ncPars = const_cast<SUMOVehicleParameter::Stop&>(pars);
252 41 : ncPars.edge = lane->getEdge().getID();
253 41 : ncPars.lane = lane->getID();
254 41 : ncPars.startPos = sp->getBeginLanePosition();
255 41 : ncPars.endPos = sp->getEndLanePosition();
256 41 : if (MSGlobals::gUseMesoSim) {
257 12 : segment = MSGlobals::gMesoNet->getSegmentForEdge(lane->getEdge(), sp->getEndLanePosition());
258 : }
259 41 : switch (sp->getElement()) {
260 41 : case SUMO_TAG_BUS_STOP:
261 : case SUMO_TAG_TRAIN_STOP:
262 41 : busstop = sp;
263 41 : ncPars.busstop = sp->getID();
264 : break;
265 0 : case SUMO_TAG_CONTAINER_STOP:
266 0 : containerstop = sp;
267 0 : ncPars.containerstop = sp->getID();
268 : break;
269 : case SUMO_TAG_PARKING_AREA:
270 0 : parkingarea = dynamic_cast<MSParkingArea*>(sp);
271 0 : ncPars.parkingarea = sp->getID();
272 : break;
273 0 : case SUMO_TAG_CHARGING_STATION:
274 0 : chargingStation = sp;
275 0 : ncPars.chargingStation = sp->getID();
276 : break;
277 0 : case SUMO_TAG_OVERHEAD_WIRE_SEGMENT:
278 0 : overheadWireSegment = sp;
279 0 : ncPars.overheadWireSegment = sp->getID();
280 : break;
281 41 : default:
282 : // should not happen
283 : assert(false);
284 : }
285 41 : }
286 :
287 : /****************************************************************************/
|