Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSPModel_NonInteracting.cpp
Go to the documentation of this file.
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/****************************************************************************/
18// The pedestrian following model (prototype)
19/****************************************************************************/
20#include <config.h>
21
22#include <cmath>
23#include <algorithm>
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>
35
36
37// ===========================================================================
38// static members
39// ===========================================================================
41
42
43// ===========================================================================
44// MSPModel_NonInteracting method definitions
45// ===========================================================================
47 myNet(net),
48 myNumActivePedestrians(0) {
49 assert(myNet != 0);
51}
52
53
56
57
61 MoveToNextEdge* const cmd = new MoveToNextEdge(transportable, *stage, this);
62 PState* const state = transportable->isPerson() ? new PState(cmd) : new CState(cmd);
63 myNet->getBeginOfTimestepEvents()->addEvent(cmd, now + state->computeDuration(nullptr, *stage, now));
64 return state;
65}
66
67
69MSPModel_NonInteracting::loadState(MSTransportable* transportable, MSStageMoving* stage, std::istringstream& in) {
71 MoveToNextEdge* const cmd = new MoveToNextEdge(transportable, *stage, this);
72 PState* const state = transportable->isPerson() ? new PState(cmd, &in) : new CState(cmd, &in);
74 return state;
75}
76
77void
81
82void
85 dynamic_cast<PState*>(state)->getCommand()->abortWalk();
86}
87
88
89// ---------------------------------------------------------------------------
90// MSPModel_NonInteracting::MoveToNextEdge method definitions
91// ---------------------------------------------------------------------------
94 if (myTransportable == nullptr) {
95 return 0; // descheduled
96 }
97 const MSEdge* old = myParent.getEdge();
98 const bool arrived = myParent.moveToNextEdge(myTransportable, currentTime, myParent.getPState()->getDirection());
99 if (arrived) {
101 return 0;
102 }
103 SUMOTime nextDuration = static_cast<PState*>(myParent.getPState())->computeDuration(old, myParent, currentTime);
104 // first compute position on the new edge
106 if (myTransportable == nullptr) {
107 return 0; // descheduled by rerouter on new edge
108 }
109 return nextDuration;
110}
111
112
113// ---------------------------------------------------------------------------
114// MSPModel_NonInteracting::PState method definitions
115// ---------------------------------------------------------------------------
116MSPModel_NonInteracting::PState::PState(MoveToNextEdge* cmd, std::istringstream* in) : myCommand(cmd) {
117 if (in != nullptr) {
119 }
120}
121
122
125 myLastEntryTime = currentTime;
126 const MSEdge* edge = stage.getEdge();
127 const MSEdge* next = stage.getNextRouteEdge();
128 int dir = UNDEFINED_DIRECTION;
129 if (prev == nullptr) {
130 myCurrentBeginPos = stage.getDepartPos();
131 } else {
132 // default to FORWARD if not connected
133 dir = (edge->getToJunction() == prev->getToJunction() || edge->getToJunction() == prev->getFromJunction()) ? BACKWARD : FORWARD;
134 myCurrentBeginPos = dir == FORWARD ? 0 : edge->getLength();
135 }
136 if (next == nullptr) {
137 myCurrentEndPos = stage.getArrivalPos();
138 } else {
139 if (dir == UNDEFINED_DIRECTION) {
140 // default to FORWARD if not connected
141 dir = (edge->getFromJunction() == next->getFromJunction() || edge->getFromJunction() == next->getToJunction()) ? BACKWARD : FORWARD;
142 }
143 myCurrentEndPos = dir == FORWARD ? edge->getLength() : 0;
144 }
145 // ensure that a result > 0 is returned even if the walk ends immediately
146 // adding 0.5ms is done to ensure proper rounding
147 myCurrentDuration = MAX2((SUMOTime)1, TIME2STEPS(fabs(myCurrentEndPos - myCurrentBeginPos) / stage.getMaxSpeed(myCommand->getTransportable())));
148 //std::cout << std::setprecision(8) << SIMTIME << " curBeg=" << myCurrentBeginPos << " curEnd=" << myCurrentEndPos << " speed=" << stage.getMaxSpeed(myCommand->getTransportable()) << " dur=" << myCurrentDuration << "\n";
149 // round to the next timestep to avoid systematic higher walking speed
150 if ((myCurrentDuration % DELTA_T) > 0) {
151 myCurrentDuration += DELTA_T;
152 }
153 return myCurrentDuration;
154}
155
156
157double
159 //std::cout << SIMTIME << " lastEntryTime=" << myLastEntryTime << " pos=" << (myCurrentBeginPos + (myCurrentEndPos - myCurrentBeginPos) / myCurrentDuration * (now - myLastEntryTime)) << "\n";
160 return myCurrentBeginPos + (myCurrentEndPos - myCurrentBeginPos) / (double)myCurrentDuration * (double)(now - myLastEntryTime);
161}
162
163int
165 if (myCurrentBeginPos == myCurrentEndPos) {
166 return UNDEFINED_DIRECTION;
167 } else {
168 return myCurrentBeginPos < myCurrentEndPos ? FORWARD : BACKWARD;
169 }
170}
171
172
175 const MSLane* lane = getSidewalk<MSEdge, MSLane>(stage.getEdge());
176 if (lane == nullptr) {
177 //std::string error = "Pedestrian '" + myCommand->myPerson->getID() + "' could not find sidewalk on edge '" + state.getEdge()->getID() + "', time="
178 // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".";
179 //if (!OptionsCont::getOptions().getBool("ignore-route-errors")) {
180 // throw ProcessError(error);
181 //}
182 lane = stage.getEdge()->getLanes().front();
183 }
184 const double lateral_offset = (lane->allowsVehicleClass(SVC_PEDESTRIAN) ? 0 : SIDEWALK_OFFSET
185 * (MSGlobals::gLefthand ? -1 : 1));
186 return stage.getLanePosition(lane, getEdgePos(now), lateral_offset);
187}
188
189
190double
192 //std::cout << SIMTIME << " rawAngle=" << stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) << " angle=" << stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) + (myCurrentEndPos < myCurrentBeginPos ? 180 : 0) << "\n";
193 double angle = stage.getEdgeAngle(stage.getEdge(), getEdgePos(now)) + (myCurrentEndPos < myCurrentBeginPos ? M_PI : 0);
194 if (angle > M_PI) {
195 angle -= 2 * M_PI;
196 }
197 return angle;
198}
199
200
201double
203 return stage.getMaxSpeed(myCommand->getTransportable());
204}
205
206
207const MSEdge*
211
212
213void
215 out << " " << myLastEntryTime << " " << myCurrentDuration;
216}
217
218
219// ---------------------------------------------------------------------------
220// MSPModel_NonInteracting::CState method definitions
221// ---------------------------------------------------------------------------
222MSPModel_NonInteracting::CState::CState(MoveToNextEdge* cmd, std::istringstream* in) : PState(cmd, in) {
223}
224
225
228 const double dist = myCurrentBeginPosition.distanceTo2D(myCurrentEndPosition); //distance between begin and end position of this tranship stage
229 double pos = MIN2(STEPS2TIME(now - myLastEntryTime) * stage.getMaxSpeed(), dist); //the container shall not go beyond its end position
230 return PositionVector::positionAtOffset2D(myCurrentBeginPosition, myCurrentEndPosition, pos, 0);
231}
232
233
234double
236 double angle = stage.getEdgeAngle(stage.getEdge(), getEdgePos(now)) + (myCurrentEndPos < myCurrentBeginPos ? 1.5 * M_PI : 0.5 * M_PI);
237 if (angle > M_PI) {
238 angle -= 2 * M_PI;
239 }
240 return angle;
241}
242
243
246 myLastEntryTime = currentTime;
247
248 myCurrentBeginPos = stage.getDepartPos();
249 myCurrentEndPos = stage.getArrivalPos();
250
251 const MSLane* fromLane = stage.getFromEdge()->getLanes().front(); //the lane the container starts from during its tranship stage
252 myCurrentBeginPosition = stage.getLanePosition(fromLane, myCurrentBeginPos, LATERAL_OFFSET);
253 const MSLane* toLane = stage.getEdges().back()->getLanes().front(); //the lane the container ends during its tranship stage
254 myCurrentEndPosition = stage.getLanePosition(toLane, myCurrentEndPos, LATERAL_OFFSET);
255
256 myCurrentDuration = MAX2((SUMOTime)1, TIME2STEPS(fabs(myCurrentEndPosition.distanceTo(myCurrentBeginPosition)) / stage.getMaxSpeed()));
257 return myCurrentDuration;
258}
259
260
261/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
#define STEPS2TIME(x)
Definition SUMOTime.h:58
constexpr SUMOTime TIME2STEPS(double x)
Definition SUMOTime.h:60
@ SVC_PEDESTRIAN
pedestrian
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
A road/street connecting two junctions.
Definition MSEdge.h:77
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:168
const MSJunction * getToJunction() const
Definition MSEdge.h:427
double getLength() const
return the length of the edge
Definition MSEdge.h:694
const MSJunction * getFromJunction() const
Definition MSEdge.h:423
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition MSGlobals.h:177
Representation of a lane in the micro simulation.
Definition MSLane.h:84
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition MSLane.h:956
The simulated network and simulation perfomer.
Definition MSNet.h:89
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition MSNet.h:495
Position getPosition(const MSStageMoving &stage, SUMOTime now) const
return the network coordinate of the container
double getAngle(const MSStageMoving &stage, SUMOTime now) const
return the direction in which the container heading to
SUMOTime computeDuration(const MSEdge *prev, const MSStageMoving &stage, SUMOTime currentTime)
compute tranship time on edge and update state members
static const double LATERAL_OFFSET
the offset for computing container positions when being transhiped
CState(MoveToNextEdge *cmd, std::istringstream *in=nullptr)
SUMOTime execute(SUMOTime currentTime)
Executes the command.
implementation of callbacks to retrieve various state information from the model
const MSEdge * getNextEdge(const MSStageMoving &stage) const
return the list of internal edges if the transportable is on an intersection
int getDirection() const
return the walking direction (FORWARD, BACKWARD, UNDEFINED_DIRECTION)
double getEdgePos(SUMOTime now) const
abstract methods inherited from PedestrianState
virtual double getAngle(const MSStageMoving &stage, SUMOTime now) const
return the direction in which the transportable faces in degrees
double getSpeed(const MSStageMoving &stage) const
return the current speed of the transportable
virtual Position getPosition(const MSStageMoving &stage, SUMOTime now) const
return the network coordinate of the transportable
virtual SUMOTime computeDuration(const MSEdge *prev, const MSStageMoving &stage, SUMOTime currentTime)
compute walking time on edge and update state members
PState(MoveToNextEdge *cmd, std::istringstream *in=nullptr)
void saveState(std::ostringstream &out)
Saves the current state into the given stream.
MSTransportableStateAdapter * add(MSTransportable *transportable, MSStageMoving *stage, SUMOTime now)
register the given transportable
MSPModel_NonInteracting(const OptionsCont &oc, MSNet *net)
Constructor (it should not be necessary to construct more than one instance)
void remove(MSTransportableStateAdapter *state)
remove the specified person from the pedestrian simulation
void clearState()
Resets pedestrians when quick-loading state.
MSTransportableStateAdapter * loadState(MSTransportable *transportable, MSStageMoving *stage, std::istringstream &in)
load the state of the given transportable
int myNumActivePedestrians
the total number of active pedestrians
MSNet * myNet
the net to which to issue moveToNextEdge commands
static const int BACKWARD
Definition MSPModel.h:55
static const int FORWARD
Definition MSPModel.h:54
static const double SIDEWALK_OFFSET
the offset for computing person positions when walking on edges without a sidewalk
Definition MSPModel.h:62
static const int UNDEFINED_DIRECTION
Definition MSPModel.h:56
virtual double getArrivalPos() const
Definition MSStage.h:97
Position getLanePosition(const MSLane *lane, double at, double offset) const
get position on lane at length at with orthogonal offset
Definition MSStage.cpp:183
double getEdgeAngle(const MSEdge *e, double at) const
get angle of the edge at a certain position
Definition MSStage.cpp:189
virtual const MSEdge * getNextRouteEdge() const =0
virtual void activateEntryReminders(MSTransportable *person, const bool isDepart=false)
add the move reminders for the current lane on entry
ConstMSEdgeVector getEdges() const
the edges of the current stage
const MSEdge * getEdge() const
Returns the current edge.
MSTransportableStateAdapter * getPState() const
double getDepartPos() const
const MSEdge * getFromEdge() const
Returns first edge of the containers route.
virtual bool moveToNextEdge(MSTransportable *transportable, SUMOTime currentTime, int prevDir, MSEdge *nextInternal=nullptr, const bool isReplay=false)=0
move forward and return whether the transportable arrived
virtual double getMaxSpeed(const MSTransportable *const transportable=nullptr) const =0
the maximum speed of the transportable
bool isPerson() const override
Whether it is a person.
abstract base class for managing callbacks to retrieve various state information from the model
Definition MSPModel.h:154
virtual int getDirection() const =0
return the walking direction (FORWARD, BACKWARD, UNDEFINED_DIRECTION)
A storage for options typed value containers)
Definition OptionsCont.h:89
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition Position.h:273
Position positionAtOffset2D(double pos, double lateralOffset=0, bool extrapolateBeyond=false) const
Returns the position at the given length.
#define UNUSED_PARAMETER(x)
#define M_PI
Definition odrSpiral.cpp:45