Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MSPerson.cpp
Go to the documentation of this file.
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/****************************************************************************/
21// The class for modelling person-movements
22/****************************************************************************/
23#include <config.h>
24
25#include <string>
26#include <vector>
33#include <microsim/MSNet.h>
34#include <microsim/MSEdge.h>
35#include <microsim/MSLane.h>
39#include <microsim/MSVehicle.h>
45#include "MSPModel_Striping.h"
46#include "MSStageTrip.h"
47#include "MSStageWalking.h"
48#include "MSPerson.h"
49
50
51// ===========================================================================
52// method definitions
53// ===========================================================================
54/* -------------------------------------------------------------------------
55* MSPerson::MSPersonStage_Access - methods
56* ----------------------------------------------------------------------- */
58 const double arrivalPos, const double arrivalPosLat, const double dist, const bool isExit,
59 const Position& startPos, const Position& endPos) :
60 MSStage(MSStageType::ACCESS, destination, toStop, arrivalPos, arrivalPosLat),
61 myDist(dist), myAmExit(isExit) {
62 myPath.push_back(startPos);
63 myPath.push_back(endPos);
64}
65
66
68
71 return new MSPersonStage_Access(myDestination, myDestinationStop, myArrivalPos, myArrivalPosLat, myDist, myAmExit, myPath.front(), myPath.back());
72}
73
74void
76 myDeparted = now;
77 if (myDist >= 0) {
78 myEstimatedArrival = now + TIME2STEPS(myDist / person->getMaxSpeed());
79 } else {
80 myEstimatedArrival = now + previous->getJumpDuration();
81 }
82 // TODO myEstimatedArrival is not a multiple of DELTA_T here. This might give a problem because the destination position will not be reached precisely
83 MSEdge* edge = myDestinationStop != nullptr ? &myDestinationStop->getLane().getEdge() : const_cast<MSEdge*>(myDestination);
84 net->getBeginOfTimestepEvents()->addEvent(new ProceedCmd(person, edge), myEstimatedArrival);
86 edge->addTransportable(person);
87}
88
89
90std::string
92 return "access";
93}
94
95
96std::string
97MSPerson::MSPersonStage_Access::getStageSummary(const bool /* isPerson */) const {
98 if (myDestination == nullptr) {
99 return ("jump to edge '") + getDestination()->getID() + "'";
100 } else {
101 return (myAmExit ? "access from stop '" : "access to stop '") + getDestinationStop()->getID() + "'";
102 }
103}
104
105
108 return myPath.positionAtOffset(myPath.length() * (double)(now - myDeparted) / (double)(myEstimatedArrival - myDeparted));
109}
110
111
112double
114 return myPath.angleAt2D(0);
115}
116
117
118double
120 return myDist / STEPS2TIME(MAX2((SUMOTime)1, myEstimatedArrival - myDeparted));
121}
122
123void
125 os.openTag("access");
126 if (getDestinationStop() != nullptr) {
127 os.writeAttr("stop", getDestinationStop()->getID());
128 }
129 os.writeAttr("depart", time2string(myDeparted));
130 os.writeAttr("arrival", myArrived >= 0 ? time2string(myArrived) : "-1");
131 os.writeAttr("duration", myArrived > 0 ? time2string(getDuration()) : "-1");
132 os.writeAttr("routeLength", myDist);
133 os.closeTag();
134}
135
136
140 myStopEdge->removeTransportable(myPerson);
141 if (!myPerson->proceed(MSNet::getInstance(), currentTime)) {
143 }
144 return 0;
145}
146
147
148/* -------------------------------------------------------------------------
149 * MSPerson - methods
150 * ----------------------------------------------------------------------- */
152 MSTransportable(pars, vtype, plan, true),
153 myInfluencer(nullptr),
154 myChosenSpeedFactor(pars->speedFactor < 0 ? speedFactor : pars->speedFactor),
155 myTimegapCrossing(getFloatParam("pedestrian.timegap-crossing"))
156{ }
157
158
162
163
164bool
165MSPerson::checkAccess(const MSStage* const prior, const bool waitAtStop) {
166 MSStoppingPlace* prevStop = prior->getDestinationStop();
167 if (!waitAtStop && prior->getStageType() == MSStageType::TRIP) {
168 prevStop = prior->getOriginStop();
169 }
170 if (prevStop != nullptr) {
171 const MSEdge* const accessEdge = waitAtStop ? prior->getDestination() : (*myStep)->getFromEdge();
172 const MSStoppingPlace::Access* const access = prevStop->getAccess(accessEdge);
173 if (access != nullptr) {
174 const MSLane* const lane = accessEdge->getLanes()[0];
175 MSStage* newStage = nullptr;
176 if (waitAtStop) {
177 const MSEdge* const stopEdge = &prevStop->getLane().getEdge();
178 const double arrivalAtBs = (prevStop->getBeginLanePosition() + prevStop->getEndLanePosition()) / 2;
179 newStage = new MSPersonStage_Access(stopEdge, prevStop, arrivalAtBs, 0.0, access->length, false,
180 lane->geometryPositionAtOffset(access->endPos),
181 prevStop->getLane().geometryPositionAtOffset(arrivalAtBs));
182 } else {
183 const bool useDoors = access->exit == MSStoppingPlace::AccessExit::DOORS ||
184 (OptionsCont::getOptions().getString("pedestrian.model") != "jupedsim" && access->exit == MSStoppingPlace::AccessExit::CARRIAGE);
186 const double startPos = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePos(0) : prior->getArrivalPos();
187 const double startPosLat = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePosLat(0) : prior->getArrivalPosLat();
188 // The start and end attributes of the access stage are equal in this case, but we need to compute the arrival position relatively
189 // to the current lane and not the lane of the previous stage.
190 const Position start = prevStop->getLane().geometryPositionAtOffset(startPos, startPosLat);
191 const Position end = lane->getShape().transformToVectorCoordinates(start);
192 newStage = new MSPersonStage_Access(accessEdge, prevStop, end.x(), -end.y(), access->length, true, start, start);
193 } else {
194 const double startPos = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePos(0) : prior->getArrivalPos();
195 const Position& trainExit = prevStop->getLane().geometryPositionAtOffset(startPos);
196 const double arrivalPos = useDoors ? lane->getShape().nearest_offset_to_point2D(trainExit) : access->endPos;
197 Position platformEntry = lane->geometryPositionAtOffset(arrivalPos);
198 if (useDoors) {
199 // find the closer side of the platform to enter
200 const double halfWidth = lane->getWidth() / 2. - MAX2(getVehicleType().getLength(), getVehicleType().getWidth()) / 2. - POSITION_EPS;
201 platformEntry = lane->geometryPositionAtOffset(arrivalPos, halfWidth);
202 const Position& plat2 = lane->geometryPositionAtOffset(arrivalPos, -halfWidth);
203 if (trainExit.distanceSquaredTo2D(plat2) < trainExit.distanceSquaredTo2D(platformEntry)) {
204 platformEntry = plat2;
205 }
206 }
207 newStage = new MSPersonStage_Access(accessEdge, prevStop, arrivalPos, 0.0, access->length, true,
208 trainExit, platformEntry);
209 }
210 }
211 newStage->setTrip(prior->getTrip());
212 myStep = myPlan->insert(myStep, newStage);
213 return true;
214 }
215 }
216 if (prior->getJumpDuration() > 0) {
217 // negative distance indicates jump
218 MSStage* newStage = new MSPersonStage_Access(getDestination(), nullptr, getArrivalPos(), 0.0, -1, true,
219 prior->getPosition(SIMSTEP) , (*myStep)->getPosition(SIMSTEP));
220 myStep = myPlan->insert(myStep, newStage);
221 return true;
222 }
223 return false;
224}
225
226
227double
229 return MAX2(0., MIN2(1., getVehicleType().getImpatience()
230 + STEPS2TIME((*myStep)->getWaitingTime()) / MSPModel_Striping::MAX_WAIT_TOLERANCE));
231}
232
233const std::string&
235// if (getCurrentStageType() == WALKING) {
236// MSStageWalking* walkingStage = dynamic_cast<MSStageWalking*>(*myStep);
237// assert(walkingStage != 0);
238// const MSEdge* nextEdge = walkingStage->getPedestrianState()->getNextEdge(*walkingStage);
239// if (nextEdge != 0) {
240// return nextEdge->getID();
241// }
242// }
243// return StringUtils::emptyString;
244 const MSEdge* nextEdge = getNextEdgePtr();
245 if (nextEdge != nullptr) {
246 return nextEdge->getID();
247 }
249}
250
251
252const MSEdge*
255 MSStageWalking* walkingStage = dynamic_cast<MSStageWalking*>(*myStep);
256 assert(walkingStage != nullptr);
257 return walkingStage->getPState()->getNextEdge(*walkingStage);
258 }
259 return nullptr;
260}
261
262
263
264void
265MSPerson::replaceWalk(const ConstMSEdgeVector& newEdges, double departPos, int firstIndex, int nextIndex) {
266 assert(nextIndex > firstIndex);
267 //std::cout << SIMTIME << " reroute person " << getID()
268 // << " newEdges=" << toString(newEdges)
269 // << " firstIndex=" << firstIndex
270 // << " nextIndex=" << nextIndex
271 // << " departPos=" << getEdgePos()
272 // << " arrivalPos=" << getNextStage(nextIndex - 1)->getArrivalPos()
273 // << "\n";
274 MSStage* const toBeReplaced = getNextStage(nextIndex - 1);
275 MSStageWalking* newStage = new MSStageWalking(getID(), newEdges,
276 toBeReplaced->getDestinationStop(), -1,
277 -1,
278 departPos,
279 toBeReplaced->getArrivalPos(),
281 appendStage(newStage, nextIndex);
282 // remove stages in reverse order so that proceed will only be called at the last removal
283 for (int i = nextIndex - 1; i >= firstIndex; i--) {
284 //std::cout << " removeStage=" << i << "\n";
285 removeStage(i);
286 }
287}
288
289
292 if (myInfluencer == nullptr) {
293 myInfluencer = new Influencer();
294 }
295 return *myInfluencer;
296}
297
298
301 return myInfluencer;
302}
303
304
305
306/* -------------------------------------------------------------------------
307 * methods of MSPerson::Influencer
308 * ----------------------------------------------------------------------- */
310
311
313
314
315void
316MSPerson::Influencer::setRemoteControlled(Position xyPos, MSLane* l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t) {
317 myRemoteXYPos = xyPos;
318 myRemoteLane = l;
319 myRemotePos = pos;
320 myRemotePosLat = posLat;
321 myRemoteAngle = angle;
322 myRemoteEdgeOffset = edgeOffset;
323 myRemoteRoute = route;
324 myLastRemoteAccess = t;
325}
326
327
328bool
330 return myLastRemoteAccess == MSNet::getInstance()->getCurrentTimeStep();
331}
332
333
334bool
336 return myLastRemoteAccess >= t - TIME2STEPS(10);
337}
338
339
340void
342 /*
343 std::cout << SIMTIME << " moveToXY person=" << p->getID()
344 << " xyPos=" << myRemoteXYPos
345 << " lane=" << Named::getIDSecure(myRemoteLane)
346 << " pos=" << myRemotePos
347 << " posLat=" << myRemotePosLat
348 << " angle=" << myRemoteAngle
349 << " eOf=" << myRemoteEdgeOffset
350 << " route=" << toString(myRemoteRoute)
351 << " aTime=" << time2string(myLastRemoteAccess)
352 << "\n";
353 */
354 switch (p->getStageType(0)) {
356 MSStageWalking* s = dynamic_cast<MSStageWalking*>(p->getCurrentStage());
357 assert(s != nullptr);
358 s->getPState()->moveToXY(p, myRemoteXYPos, myRemoteLane, myRemotePos, myRemotePosLat,
359 myRemoteAngle, myRemoteEdgeOffset, myRemoteRoute,
360 MSNet::getInstance()->getCurrentTimeStep());
361 }
362 break;
363 default:
364 break;
365 }
366}
367
368
369/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSPerson.h:51
MSStageType
Definition MSStage.h:55
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:91
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define SIMSTEP
Definition SUMOTime.h:61
#define TIME2STEPS(x)
Definition SUMOTime.h:57
T MIN2(T a, T b)
Definition StdDefs.h:76
T MAX2(T a, T b)
Definition StdDefs.h:82
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
virtual void addTransportable(MSTransportable *t) const
Definition MSEdge.cpp:1188
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
Representation of a lane in the micro simulation.
Definition MSLane.h:84
virtual const PositionVector & getShape(bool) const
Definition MSLane.h:294
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:764
double getWidth() const
Returns the lane's width.
Definition MSLane.h:635
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition MSLane.h:560
The simulated network and simulation perfomer.
Definition MSNet.h:89
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition MSNet.h:476
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:325
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1201
static const double MAX_WAIT_TOLERANCE
the time pedestrians take to reach maximum impatience
static const double UNSPECIFIED_POS_LAT
the default lateral offset for persons when starting a walk
Definition MSPModel.h:65
Changes the wished person speed and position.
Definition MSPerson.h:179
void postProcessRemoteControl(MSPerson *p)
Definition MSPerson.cpp:341
Influencer()
Constructor.
Definition MSPerson.cpp:309
void setRemoteControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition MSPerson.cpp:316
~Influencer()
Destructor.
Definition MSPerson.cpp:312
bool isRemoteAffected(SUMOTime t) const
Definition MSPerson.cpp:335
bool isRemoteControlled() const
Definition MSPerson.cpp:329
SUMOTime execute(SUMOTime currentTime)
Executes the command.
Definition MSPerson.cpp:138
Position getPosition(SUMOTime now) const
returns the position of the transportable
Definition MSPerson.cpp:107
MSPersonStage_Access(const MSEdge *destination, MSStoppingPlace *toStop, const double arrivalPos, const double arrivalPosLat, const double dist, const bool isExit, const Position &startPos, const Position &endPos)
constructor
Definition MSPerson.cpp:57
double getSpeed() const
the speed of the person in this stage
Definition MSPerson.cpp:119
void tripInfoOutput(OutputDevice &os, const MSTransportable *const transportable) const
Called on writing tripinfo output.
Definition MSPerson.cpp:124
virtual void proceed(MSNet *net, MSTransportable *person, SUMOTime now, MSStage *previous)
proceeds to the next step
Definition MSPerson.cpp:75
double getAngle(SUMOTime now) const
returns the angle of the transportable
Definition MSPerson.cpp:113
std::string getStageDescription(const bool isPerson) const
returns the stage description as a string
Definition MSPerson.cpp:91
std::string getStageSummary(const bool isPerson) const
return string summary of the current stage
Definition MSPerson.cpp:97
bool checkAccess(const MSStage *const prior, const bool waitAtStop=true)
Definition MSPerson.cpp:165
Influencer * myInfluencer
An instance of a speed/position influencing instance; built in "getInfluencer".
Definition MSPerson.h:231
const MSEdge * getNextEdgePtr() const
returns the next edge ptr if this person is walking and the pedestrian model allows it
Definition MSPerson.cpp:253
double getImpatience() const
Definition MSPerson.cpp:228
double myChosenSpeedFactor
Definition MSPerson.h:233
double myTimegapCrossing
value may be sampled from distribution and therefore must be cached
Definition MSPerson.h:236
void replaceWalk(const ConstMSEdgeVector &newEdges, double departPos, int firstIndex, int nextIndex)
set new walk and replace the stages with relative indices in the interval [firstIndex,...
Definition MSPerson.cpp:265
virtual ~MSPerson()
destructor
Definition MSPerson.cpp:159
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition MSPerson.cpp:291
const std::string & getNextEdge() const
return the list of internal edges if this person is walking and the pedestrian model allows it
Definition MSPerson.cpp:234
MSPerson(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan, const double speedFactor)
constructor
Definition MSPerson.cpp:151
const MSEdge * getDestination() const
returns the destination edge
Definition MSStage.cpp:65
virtual double getEdgePos(SUMOTime now) const
Definition MSStage.cpp:83
virtual SUMOTime getJumpDuration() const
Return the current jump duration (if applicable)
Definition MSStage.h:133
virtual double getEdgePosLat(SUMOTime now) const
Definition MSStage.cpp:89
MSStageTrip * getTrip() const
Definition MSStage.h:283
virtual double getArrivalPos() const
Definition MSStage.h:97
void setTrip(MSStageTrip *trip)
Definition MSStage.h:287
virtual MSStoppingPlace * getOriginStop() const
returns the origin stop (if any). only needed for MSStageTrip
Definition MSStage.h:93
virtual Position getPosition(SUMOTime now) const =0
returns the position of the transportable
MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
Definition MSStage.h:88
MSStageType getStageType() const
Definition MSStage.h:138
virtual double getArrivalPosLat() const
Definition MSStage.h:104
MSTransportableStateAdapter * getPState() const
A lane area vehicles can halt at.
const Access * getAccess(const MSEdge *edge) const
the access on the given edge to the stop, nullptr if there is none
double getBeginLanePosition() const
Returns the begin position of this stop.
double getEndLanePosition() const
Returns the end position of this stop.
const MSLane & getLane() const
Returns the lane this stop is located at.
virtual void erase(MSTransportable *transportable)
removes a single transportable
const MSEdge * getDestination() const
Returns the current destination.
MSStageType getStageType(int next) const
the stage type for the nth next stage
MSStage * getNextStage(int offset) const
Return the next (or previous) stage denoted by the offset.
MSStage * getCurrentStage() const
Return the current stage.
MSTransportablePlan::iterator myStep
the iterator over the route
MSTransportablePlan * myPlan
the plan of the transportable
void removeStage(int next, bool stayInSim=true)
removes the nth next stage
double getArrivalPos() const
returns the final arrival pos
const MSVehicleType & getVehicleType() const
Returns the object's "vehicle" type.
MSStageType getCurrentStageType() const
the current stage type of the transportable
void appendStage(MSStage *stage, int next=-1)
Appends the given stage to the current plan.
std::vector< MSStage * > MSTransportablePlan
the structure holding the plan of a transportable
double getMaxSpeed() const
Returns the maximum speed (the minimum of desired and physical maximum speed)
virtual void moveToXY(MSPerson *p, Position pos, MSLane *lane, double lanePos, double lanePosLat, double angle, int routeOffset, const ConstMSEdgeVector &edges, SUMOTime t)
try to move transportable to the given position
Definition MSPModel.h:194
virtual const MSEdge * getNextEdge(const MSStageMoving &stage) const =0
return the list of internal edges if the transportable is on an intersection
The car-following model and parameter.
const std::string & getID() const
Returns the id.
Definition Named.h:74
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceSquaredTo2D(const Position &p2) const
returns the square of the distance to another position (Only using x and y positions)
Definition Position.h:278
double x() const
Returns the x-position.
Definition Position.h:52
double y() const
Returns the y-position.
Definition Position.h:57
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
Position transformToVectorCoordinates(const Position &p, bool extend=false) const
return position p within the length-wise coordinate system defined by this position vector....
double getFloatParam(const std::string &paramName, const bool required=false, const double deflt=INVALID_DOUBLE, bool checkDist=true) const
Retrieve a floating point parameter for the traffic object.
Structure representing possible vehicle parameter.
static std::string emptyString
An empty string.
Definition StringUtils.h:91