Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2014-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 MSPModel_NonInteracting.cpp
15 : /// @author Jakob Erdmann
16 : /// @date Mon, 13 Jan 2014
17 : ///
18 : // The pedestrian following model (prototype)
19 : /****************************************************************************/
20 : #include <config.h>
21 :
22 : #include <cmath>
23 : #include <algorithm>
24 : #include <utils/common/RandHelper.h>
25 : #include <utils/geom/GeomHelper.h>
26 : #include <utils/options/OptionsCont.h>
27 : #include <utils/router/IntermodalNetwork.h>
28 : #include <microsim/MSGlobals.h>
29 : #include <microsim/MSNet.h>
30 : #include <microsim/MSEdge.h>
31 : #include <microsim/MSLane.h>
32 : #include <microsim/MSJunction.h>
33 : #include <microsim/MSEventControl.h>
34 : #include "MSPModel_NonInteracting.h"
35 :
36 :
37 : // ===========================================================================
38 : // static members
39 : // ===========================================================================
40 : const double MSPModel_NonInteracting::CState::LATERAL_OFFSET(0);
41 :
42 :
43 : // ===========================================================================
44 : // MSPModel_NonInteracting method definitions
45 : // ===========================================================================
46 10138 : MSPModel_NonInteracting::MSPModel_NonInteracting(const OptionsCont& oc, MSNet* net) :
47 10138 : myNet(net),
48 10138 : myNumActivePedestrians(0) {
49 : assert(myNet != 0);
50 : UNUSED_PARAMETER(oc);
51 10138 : }
52 :
53 :
54 20228 : MSPModel_NonInteracting::~MSPModel_NonInteracting() {
55 20228 : }
56 :
57 :
58 : MSTransportableStateAdapter*
59 159563 : MSPModel_NonInteracting::add(MSTransportable* transportable, MSStageMoving* stage, SUMOTime now) {
60 159563 : myNumActivePedestrians++;
61 159563 : MoveToNextEdge* const cmd = new MoveToNextEdge(transportable, *stage, this);
62 159563 : PState* const state = transportable->isPerson() ? new PState(cmd) : new CState(cmd);
63 159563 : myNet->getBeginOfTimestepEvents()->addEvent(cmd, now + state->computeDuration(nullptr, *stage, now));
64 159563 : return state;
65 : }
66 :
67 :
68 : MSTransportableStateAdapter*
69 10 : MSPModel_NonInteracting::loadState(MSTransportable* transportable, MSStageMoving* stage, std::istringstream& in) {
70 10 : myNumActivePedestrians++;
71 10 : MoveToNextEdge* const cmd = new MoveToNextEdge(transportable, *stage, this);
72 10 : PState* const state = transportable->isPerson() ? new PState(cmd, &in) : new CState(cmd, &in);
73 10 : myNet->getBeginOfTimestepEvents()->addEvent(cmd, state->getEventTime());
74 10 : return state;
75 : }
76 :
77 : void
78 10113 : MSPModel_NonInteracting::clearState() {
79 10113 : myNumActivePedestrians = 0;
80 10113 : }
81 :
82 : void
83 432 : MSPModel_NonInteracting::remove(MSTransportableStateAdapter* state) {
84 432 : myNumActivePedestrians--;
85 432 : dynamic_cast<PState*>(state)->getCommand()->abortWalk();
86 432 : }
87 :
88 :
89 : // ---------------------------------------------------------------------------
90 : // MSPModel_NonInteracting::MoveToNextEdge method definitions
91 : // ---------------------------------------------------------------------------
92 : SUMOTime
93 2089005 : MSPModel_NonInteracting::MoveToNextEdge::execute(SUMOTime currentTime) {
94 2089005 : if (myTransportable == nullptr) {
95 : return 0; // descheduled
96 : }
97 2088577 : const MSEdge* old = myParent.getEdge();
98 2088577 : const bool arrived = myParent.moveToNextEdge(myTransportable, currentTime, myParent.getPState()->getDirection());
99 2088577 : if (arrived) {
100 158780 : myModel->registerArrived();
101 158780 : return 0;
102 : }
103 1929797 : myParent.activateEntryReminders(myTransportable);
104 1929797 : return static_cast<PState*>(myParent.getPState())->computeDuration(old, myParent, currentTime);
105 : }
106 :
107 :
108 : // ---------------------------------------------------------------------------
109 : // MSPModel_NonInteracting::PState method definitions
110 : // ---------------------------------------------------------------------------
111 159573 : MSPModel_NonInteracting::PState::PState(MoveToNextEdge* cmd, std::istringstream* in) : myCommand(cmd) {
112 159573 : if (in != nullptr) {
113 10 : (*in) >> myLastEntryTime >> myCurrentDuration;
114 : }
115 159573 : }
116 :
117 :
118 : SUMOTime
119 1954036 : MSPModel_NonInteracting::PState::computeDuration(const MSEdge* prev, const MSStageMoving& stage, SUMOTime currentTime) {
120 1954036 : myLastEntryTime = currentTime;
121 1954036 : const MSEdge* edge = stage.getEdge();
122 1954036 : const MSEdge* next = stage.getNextRouteEdge();
123 1954036 : int dir = UNDEFINED_DIRECTION;
124 1954036 : if (prev == nullptr) {
125 24239 : myCurrentBeginPos = stage.getDepartPos();
126 : } else {
127 : // default to FORWARD if not connected
128 1929797 : dir = (edge->getToJunction() == prev->getToJunction() || edge->getToJunction() == prev->getFromJunction()) ? BACKWARD : FORWARD;
129 3849481 : myCurrentBeginPos = dir == FORWARD ? 0 : edge->getLength();
130 : }
131 1954036 : if (next == nullptr) {
132 1940734 : myCurrentEndPos = stage.getArrivalPos();
133 : } else {
134 13302 : if (dir == UNDEFINED_DIRECTION) {
135 : // default to FORWARD if not connected
136 9097 : dir = (edge->getFromJunction() == next->getFromJunction() || edge->getFromJunction() == next->getToJunction()) ? BACKWARD : FORWARD;
137 : }
138 24044 : myCurrentEndPos = dir == FORWARD ? edge->getLength() : 0;
139 : }
140 : // ensure that a result > 0 is returned even if the walk ends immediately
141 : // adding 0.5ms is done to ensure proper rounding
142 1954036 : myCurrentDuration = MAX2((SUMOTime)1, TIME2STEPS(fabs(myCurrentEndPos - myCurrentBeginPos) / stage.getMaxSpeed(myCommand->getTransportable())));
143 : //std::cout << std::setprecision(8) << SIMTIME << " curBeg=" << myCurrentBeginPos << " curEnd=" << myCurrentEndPos << " speed=" << stage.getMaxSpeed(myCommand->getTransportable()) << " dur=" << myCurrentDuration << "\n";
144 : // round to the next timestep to avoid systematic higher walking speed
145 1954036 : if ((myCurrentDuration % DELTA_T) > 0) {
146 1947916 : myCurrentDuration += DELTA_T;
147 : }
148 1954036 : return myCurrentDuration;
149 : }
150 :
151 :
152 : double
153 18182763 : MSPModel_NonInteracting::PState::getEdgePos(SUMOTime now) const {
154 : //std::cout << SIMTIME << " lastEntryTime=" << myLastEntryTime << " pos=" << (myCurrentBeginPos + (myCurrentEndPos - myCurrentBeginPos) / myCurrentDuration * (now - myLastEntryTime)) << "\n";
155 18182763 : return myCurrentBeginPos + (myCurrentEndPos - myCurrentBeginPos) / (double)myCurrentDuration * (double)(now - myLastEntryTime);
156 : }
157 :
158 : int
159 2088577 : MSPModel_NonInteracting::PState::getDirection() const {
160 2088577 : if (myCurrentBeginPos == myCurrentEndPos) {
161 2310 : return UNDEFINED_DIRECTION;
162 : } else {
163 2086267 : return myCurrentBeginPos < myCurrentEndPos ? FORWARD : BACKWARD;
164 : }
165 : }
166 :
167 :
168 : Position
169 7894367 : MSPModel_NonInteracting::PState::getPosition(const MSStageMoving& stage, SUMOTime now) const {
170 7894367 : const MSLane* lane = getSidewalk<MSEdge, MSLane>(stage.getEdge());
171 7894367 : if (lane == nullptr) {
172 : //std::string error = "Pedestrian '" + myCommand->myPerson->getID() + "' could not find sidewalk on edge '" + state.getEdge()->getID() + "', time="
173 : // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".";
174 : //if (!OptionsCont::getOptions().getBool("ignore-route-errors")) {
175 : // throw ProcessError(error);
176 : //}
177 170 : lane = stage.getEdge()->getLanes().front();
178 : }
179 7894537 : const double lateral_offset = (lane->allowsVehicleClass(SVC_PEDESTRIAN) ? 0 : SIDEWALK_OFFSET
180 170 : * (MSGlobals::gLefthand ? -1 : 1));
181 7894367 : return stage.getLanePosition(lane, getEdgePos(now), lateral_offset);
182 : }
183 :
184 :
185 : double
186 3941883 : MSPModel_NonInteracting::PState::getAngle(const MSStageMoving& stage, SUMOTime now) const {
187 : //std::cout << SIMTIME << " rawAngle=" << stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) << " angle=" << stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) + (myCurrentEndPos < myCurrentBeginPos ? 180 : 0) << "\n";
188 3941883 : double angle = stage.getEdgeAngle(stage.getEdge(), getEdgePos(now)) + (myCurrentEndPos < myCurrentBeginPos ? M_PI : 0);
189 3941883 : if (angle > M_PI) {
190 3646 : angle -= 2 * M_PI;
191 : }
192 3941883 : return angle;
193 : }
194 :
195 :
196 : double
197 4115401 : MSPModel_NonInteracting::PState::getSpeed(const MSStageMoving& stage) const {
198 4115401 : return stage.getMaxSpeed(myCommand->getTransportable());
199 : }
200 :
201 :
202 : const MSEdge*
203 3 : MSPModel_NonInteracting::PState::getNextEdge(const MSStageMoving& stage) const {
204 3 : return stage.getNextRouteEdge();
205 : }
206 :
207 :
208 : void
209 10 : MSPModel_NonInteracting::PState::saveState(std::ostringstream& out) {
210 20 : out << " " << myLastEntryTime << " " << myCurrentDuration;
211 10 : }
212 :
213 :
214 : // ---------------------------------------------------------------------------
215 : // MSPModel_NonInteracting::CState method definitions
216 : // ---------------------------------------------------------------------------
217 135324 : MSPModel_NonInteracting::CState::CState(MoveToNextEdge* cmd, std::istringstream* in) : PState(cmd, in) {
218 135324 : }
219 :
220 :
221 : Position
222 71 : MSPModel_NonInteracting::CState::getPosition(const MSStageMoving& stage, SUMOTime now) const {
223 : const double dist = myCurrentBeginPosition.distanceTo2D(myCurrentEndPosition); //distance between begin and end position of this tranship stage
224 71 : double pos = MIN2(STEPS2TIME(now - myLastEntryTime) * stage.getMaxSpeed(), dist); //the container shall not go beyond its end position
225 71 : return PositionVector::positionAtOffset2D(myCurrentBeginPosition, myCurrentEndPosition, pos, 0);
226 : }
227 :
228 :
229 : double
230 71 : MSPModel_NonInteracting::CState::getAngle(const MSStageMoving& stage, SUMOTime now) const {
231 71 : double angle = stage.getEdgeAngle(stage.getEdge(), getEdgePos(now)) + (myCurrentEndPos < myCurrentBeginPos ? 1.5 * M_PI : 0.5 * M_PI);
232 71 : if (angle > M_PI) {
233 20 : angle -= 2 * M_PI;
234 : }
235 71 : return angle;
236 : }
237 :
238 :
239 : SUMOTime
240 135324 : MSPModel_NonInteracting::CState::computeDuration(const MSEdge* /* prev */, const MSStageMoving& stage, SUMOTime currentTime) {
241 135324 : myLastEntryTime = currentTime;
242 :
243 135324 : myCurrentBeginPos = stage.getDepartPos();
244 135324 : myCurrentEndPos = stage.getArrivalPos();
245 :
246 135324 : const MSLane* fromLane = stage.getFromEdge()->getLanes().front(); //the lane the container starts from during its tranship stage
247 135324 : myCurrentBeginPosition = stage.getLanePosition(fromLane, myCurrentBeginPos, LATERAL_OFFSET);
248 135324 : const MSLane* toLane = stage.getEdges().back()->getLanes().front(); //the lane the container ends during its tranship stage
249 135324 : myCurrentEndPosition = stage.getLanePosition(toLane, myCurrentEndPos, LATERAL_OFFSET);
250 :
251 135324 : myCurrentDuration = MAX2((SUMOTime)1, TIME2STEPS(fabs(myCurrentEndPosition.distanceTo(myCurrentBeginPosition)) / stage.getMaxSpeed()));
252 135324 : return myCurrentDuration;
253 : }
254 :
255 :
256 : /****************************************************************************/
|