Eclipse SUMO - Simulation of Urban MObility
MSPModel_NonInteracting.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2014-2022 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>
25 #include <utils/geom/GeomHelper.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>
35 
36 
37 // ===========================================================================
38 // DEBUGGING HELPERS
39 // ===========================================================================
40 #define DEBUG1 "disabled"
41 #define DEBUG2 "disabled"
42 #define DEBUGCOND(PEDID) (PEDID == DEBUG1 || PEDID == DEBUG2)
43 
44 
45 // ===========================================================================
46 // static members
47 // ===========================================================================
49 
50 // ===========================================================================
51 // MSPModel_NonInteracting method definitions
52 // ===========================================================================
54  myNet(net),
55  myNumActivePedestrians(0) {
56  assert(myNet != 0);
57  UNUSED_PARAMETER(oc);
58 }
59 
60 
62 }
63 
64 
68  MoveToNextEdge* const cmd = new MoveToNextEdge(transportable, *stage, this);
69  PState* const state = transportable->isPerson() ? new PState(cmd) : new CState(cmd);
70  myNet->getBeginOfTimestepEvents()->addEvent(cmd, now + state->computeDuration(nullptr, *stage, now));
71  return state;
72 }
73 
74 
76 MSPModel_NonInteracting::loadState(MSTransportable* transportable, MSStageMoving* stage, std::istringstream& in) {
78  MoveToNextEdge* const cmd = new MoveToNextEdge(transportable, *stage, this);
79  PState* const state = transportable->isPerson() ? new PState(cmd, &in) : new CState(cmd, &in);
81  return state;
82 }
83 
84 void
87 }
88 
89 void
92  dynamic_cast<PState*>(state)->getCommand()->abortWalk();
93 }
94 
95 
96 // ---------------------------------------------------------------------------
97 // MSPModel_NonInteracting::MoveToNextEdge method definitions
98 // ---------------------------------------------------------------------------
101  if (myTransportable == nullptr) {
102  return 0; // descheduled
103  }
104  const MSEdge* old = myParent.getEdge();
105  const bool arrived = myParent.moveToNextEdge(myTransportable, currentTime, myParent.getState()->getDirection(myParent, currentTime));
106  if (arrived) {
108  return 0;
109  }
110  return static_cast<PState*>(myParent.getState())->computeDuration(old, myParent, currentTime);
111 }
112 
113 
114 // ---------------------------------------------------------------------------
115 // MSPModel_NonInteracting::PState method definitions
116 // ---------------------------------------------------------------------------
117 MSPModel_NonInteracting::PState::PState(MoveToNextEdge* cmd, std::istringstream* in) : myCommand(cmd) {
118  if (in != nullptr) {
120  }
121 }
122 
123 
124 SUMOTime
126  myLastEntryTime = currentTime;
127  const MSEdge* edge = stage.getEdge();
128  const MSEdge* next = stage.getNextRouteEdge();
129  int dir = UNDEFINED_DIRECTION;
130  if (prev == nullptr) {
131  myCurrentBeginPos = stage.getDepartPos();
132  } else {
133  // default to FORWARD if not connected
134  dir = (edge->getToJunction() == prev->getToJunction() || edge->getToJunction() == prev->getFromJunction()) ? BACKWARD : FORWARD;
135  myCurrentBeginPos = dir == FORWARD ? 0 : edge->getLength();
136  }
137  if (next == nullptr) {
138  myCurrentEndPos = stage.getArrivalPos();
139  } else {
140  if (dir == UNDEFINED_DIRECTION) {
141  // default to FORWARD if not connected
142  dir = (edge->getFromJunction() == next->getFromJunction() || edge->getFromJunction() == next->getToJunction()) ? BACKWARD : FORWARD;
143  }
144  myCurrentEndPos = dir == FORWARD ? edge->getLength() : 0;
145  }
146  // ensure that a result > 0 is returned even if the walk ends immediately
147  // adding 0.5ms is done to ensure proper rounding
148  myCurrentDuration = MAX2((SUMOTime)1, TIME2STEPS(fabs(myCurrentEndPos - myCurrentBeginPos) / stage.getMaxSpeed(myCommand->getTransportable())));
149  //std::cout << std::setprecision(8) << SIMTIME << " curBeg=" << myCurrentBeginPos << " curEnd=" << myCurrentEndPos << " speed=" << stage.getMaxSpeed(myCommand->getTransportable()) << " dur=" << myCurrentDuration << "\n";
150  // round to the next timestep to avoid systematic higher walking speed
151  if ((myCurrentDuration % DELTA_T) > 0) {
152  myCurrentDuration += DELTA_T;
153  }
154  return myCurrentDuration;
155 }
156 
157 
158 double
160  //std::cout << SIMTIME << " lastEntryTime=" << myLastEntryTime << " pos=" << (myCurrentBeginPos + (myCurrentEndPos - myCurrentBeginPos) / myCurrentDuration * (now - myLastEntryTime)) << "\n";
161  return myCurrentBeginPos + (myCurrentEndPos - myCurrentBeginPos) / myCurrentDuration * (now - myLastEntryTime);
162 }
163 
164 int
166  if (myCurrentBeginPos == myCurrentEndPos) {
167  return UNDEFINED_DIRECTION;
168  } else {
169  return myCurrentBeginPos < myCurrentEndPos ? FORWARD : BACKWARD;
170  }
171 }
172 
173 
174 Position
176  const MSLane* lane = getSidewalk<MSEdge, MSLane>(stage.getEdge());
177  if (lane == nullptr) {
178  //std::string error = "Pedestrian '" + myCommand->myPerson->getID() + "' could not find sidewalk on edge '" + state.getEdge()->getID() + "', time="
179  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".";
180  //if (!OptionsCont::getOptions().getBool("ignore-route-errors")) {
181  // throw ProcessError(error);
182  //}
183  lane = stage.getEdge()->getLanes().front();
184  }
185  const double lateral_offset = (lane->allowsVehicleClass(SVC_PEDESTRIAN) ? 0 : SIDEWALK_OFFSET
186  * (MSGlobals::gLefthand ? -1 : 1));
187  return stage.getLanePosition(lane, getEdgePos(stage, now), lateral_offset);
188 }
189 
190 
191 double
193  //std::cout << SIMTIME << " rawAngle=" << stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) << " angle=" << stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) + (myCurrentEndPos < myCurrentBeginPos ? 180 : 0) << "\n";
194  double angle = stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) + (myCurrentEndPos < myCurrentBeginPos ? M_PI : 0);
195  if (angle > M_PI) {
196  angle -= 2 * M_PI;
197  }
198  return angle;
199 }
200 
201 
202 SUMOTime
204  return 0;
205 }
206 
207 
208 double
210  return stage.getMaxSpeed(myCommand->getTransportable());
211 }
212 
213 
214 const MSEdge*
216  return stage.getNextRouteEdge();
217 }
218 
219 
220 void
222  out << " " << myLastEntryTime << " " << myCurrentDuration;
223 }
224 
225 
226 // ---------------------------------------------------------------------------
227 // MSPModel_NonInteracting::CState method definitions
228 // ---------------------------------------------------------------------------
229 MSPModel_NonInteracting::CState::CState(MoveToNextEdge* cmd, std::istringstream* in) : PState(cmd, in) {
230 }
231 
232 
233 Position
235  const double dist = myCurrentBeginPosition.distanceTo2D(myCurrentEndPosition); //distance between begin and end position of this tranship stage
236  double pos = MIN2(STEPS2TIME(now - myLastEntryTime) * stage.getMaxSpeed(), dist); //the container shall not go beyond its end position
237  return PositionVector::positionAtOffset2D(myCurrentBeginPosition, myCurrentEndPosition, pos, 0);
238 }
239 
240 
241 double
243  double angle = stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) + (myCurrentEndPos < myCurrentBeginPos ? 1.5 * M_PI : 0.5 * M_PI);
244  if (angle > M_PI) {
245  angle -= 2 * M_PI;
246  }
247  return angle;
248 }
249 
250 
251 SUMOTime
252 MSPModel_NonInteracting::CState::computeDuration(const MSEdge* /* prev */, const MSStageMoving& stage, SUMOTime currentTime) {
253  myLastEntryTime = currentTime;
254 
255  myCurrentBeginPos = stage.getDepartPos();
256  myCurrentEndPos = stage.getArrivalPos();
257 
258  const MSLane* fromLane = stage.getFromEdge()->getLanes().front(); //the lane the container starts from during its tranship stage
259  myCurrentBeginPosition = stage.getLanePosition(fromLane, myCurrentBeginPos, LATERAL_OFFSET);
260  const MSLane* toLane = stage.getEdges().back()->getLanes().front(); //the lane the container ends during its tranship stage
261  myCurrentEndPosition = stage.getLanePosition(toLane, myCurrentEndPos, LATERAL_OFFSET);
262 
263  myCurrentDuration = MAX2((SUMOTime)1, TIME2STEPS(fabs(myCurrentEndPosition.distanceTo(myCurrentBeginPosition)) / stage.getMaxSpeed()));
264  return myCurrentDuration;
265 }
266 
267 
268 /****************************************************************************/
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:32
@ SVC_PEDESTRIAN
pedestrian
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
T MIN2(T a, T b)
Definition: StdDefs.h:74
T MAX2(T a, T b)
Definition: StdDefs.h:80
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 * getFromJunction() const
Definition: MSEdge.h:397
double getLength() const
return the length of the edge
Definition: MSEdge.h:641
const MSJunction * getToJunction() const
Definition: MSEdge.h:401
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition: MSGlobals.h:157
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:814
The simulated network and simulation perfomer.
Definition: MSNet.h:88
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:469
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
SUMOTime getWaitingTime(const MSStageMoving &stage, SUMOTime now) const
return the time the transportable spent standing
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
double getEdgePos(const MSStageMoving &stage, SUMOTime now) const
abstract methods inherited from PedestrianState
PState(MoveToNextEdge *cmd, std::istringstream *in=nullptr)
void saveState(std::ostringstream &out)
Saves the current state into the given stream.
int getDirection(const MSStageMoving &stage, SUMOTime now) const
return the walking direction (FORWARD, BACKWARD)
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:109
static const int FORWARD
Definition: MSPModel.h:108
static const double SIDEWALK_OFFSET
the offset for computing person positions when walking on edges without a sidewalk
Definition: MSPModel.h:116
static const int UNDEFINED_DIRECTION
Definition: MSPModel.h:110
virtual double getArrivalPos() const
Definition: MSStage.h:89
Position getLanePosition(const MSLane *lane, double at, double offset) const
get position on lane at length at with orthogonal offset
Definition: MSStage.cpp:152
double getEdgeAngle(const MSEdge *e, double at) const
get angle of the edge at a certain position
Definition: MSStage.cpp:158
virtual bool moveToNextEdge(MSTransportable *transportable, SUMOTime currentTime, int prevDir, MSEdge *nextInternal=0)=0
move forward and return whether the transportable arrived
ConstMSEdgeVector getEdges() const
the edges of the current stage
Definition: MSStage.cpp:613
virtual MSTransportableStateAdapter * getState() const
Definition: MSStage.h:478
const MSEdge * getEdge() const
Returns the current edge.
Definition: MSStage.cpp:599
virtual const MSEdge * getNextRouteEdge() const =0
double getDepartPos() const
Definition: MSStage.h:531
const MSEdge * getFromEdge() const
Returns first edge of the containers route.
Definition: MSStage.cpp:608
virtual double getMaxSpeed(const MSTransportable *const transportable=nullptr) const =0
the maximum speed of the transportable
bool isPerson() const
Whether it is a person.
abstract base class for managing callbacks to retrieve various state information from the model
Definition: MSPModel.h:133
virtual int getDirection(const MSStageMoving &stage, SUMOTime now) const =0
return the walking direction (FORWARD, BACKWARD)
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:252
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
#define M_PI
Definition: odrSpiral.cpp:40