Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-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/****************************************************************************/
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
148void
149MSPerson::MSPersonStage_Access::saveState(std::ostringstream& out, MSTransportable* /*transportable*/) {
150 out << " " << myDeparted << " " << myEstimatedArrival;
151}
152
153
154void
156 state >> myDeparted;
157 state >> myEstimatedArrival;
158 MSNet* net = MSNet::getInstance();
159 MSEdge* edge = myDestinationStop != nullptr ? &myDestinationStop->getLane().getEdge() : const_cast<MSEdge*>(myDestination);
160 net->getBeginOfTimestepEvents()->addEvent(new ProceedCmd(person, edge), myEstimatedArrival);
162 edge->addTransportable(person);
163}
164
165/* -------------------------------------------------------------------------
166 * MSPerson - methods
167 * ----------------------------------------------------------------------- */
169 MSTransportable(pars, vtype, plan, true),
170 myInfluencer(nullptr),
171 myChosenSpeedFactor(pars->speedFactor < 0 ? speedFactor : pars->speedFactor),
172 myTimegapCrossing(getFloatParam("pedestrian.timegap-crossing"))
173{ }
174
175
179
180
181bool
182MSPerson::checkAccess(const MSStage* const prior, const bool waitAtStop) {
183 MSStoppingPlace* prevStop = prior->getDestinationStop();
184 if (!waitAtStop && prior->getStageType() == MSStageType::TRIP) {
185 prevStop = prior->getOriginStop();
186 }
187 if (prevStop != nullptr) {
188 const MSEdge* const accessEdge = waitAtStop ? prior->getDestination() : (*myStep)->getFromEdge();
189 const MSStoppingPlace::Access* const access = prevStop->getAccess(accessEdge);
190 if (access != nullptr) {
191 const MSLane* const lane = accessEdge->getLanes()[0];
192 MSStage* newStage = nullptr;
193 if (waitAtStop) {
194 const MSEdge* const stopEdge = &prevStop->getLane().getEdge();
195 const double arrivalAtBs = (prevStop->getBeginLanePosition() + prevStop->getEndLanePosition()) / 2;
196 newStage = new MSPersonStage_Access(stopEdge, prevStop, arrivalAtBs, 0.0, access->length, false,
197 lane->geometryPositionAtOffset(access->endPos),
198 prevStop->getLane().geometryPositionAtOffset(arrivalAtBs));
199 } else {
200 const bool useDoors = access->exit == MSStoppingPlace::AccessExit::DOORS ||
201 (OptionsCont::getOptions().getString("pedestrian.model") != "jupedsim" && access->exit == MSStoppingPlace::AccessExit::CARRIAGE);
203 const double startPos = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePos(0) : prior->getArrivalPos();
204 const double startPosLat = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePosLat(0) : prior->getArrivalPosLat();
205 // The start and end attributes of the access stage are equal in this case, but we need to compute the arrival position relatively
206 // to the current lane and not the lane of the previous stage.
207 const Position start = prevStop->getLane().geometryPositionAtOffset(startPos, startPosLat);
208 const Position end = lane->getShape().transformToVectorCoordinates(start);
209 newStage = new MSPersonStage_Access(accessEdge, prevStop, end.x(), -end.y(), access->length, true, start, start);
210 } else {
211 const double startPos = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePos(0) : prior->getArrivalPos();
212 const Position& trainExit = prevStop->getLane().geometryPositionAtOffset(startPos);
213 const double arrivalPos = useDoors ? lane->getShape().nearest_offset_to_point2D(trainExit) : access->endPos;
214 Position platformEntry = lane->geometryPositionAtOffset(arrivalPos);
215 if (useDoors) {
216 // find the closer side of the platform to enter
217 const double halfWidth = lane->getWidth() / 2. - MAX2(getVehicleType().getLength(), getVehicleType().getWidth()) / 2. - POSITION_EPS;
218 platformEntry = lane->geometryPositionAtOffset(arrivalPos, halfWidth);
219 const Position& plat2 = lane->geometryPositionAtOffset(arrivalPos, -halfWidth);
220 if (trainExit.distanceSquaredTo2D(plat2) < trainExit.distanceSquaredTo2D(platformEntry)) {
221 platformEntry = plat2;
222 }
223 }
224 newStage = new MSPersonStage_Access(accessEdge, prevStop, arrivalPos, 0.0, access->length, true,
225 trainExit, platformEntry);
226 }
227 }
228 newStage->setTrip(prior->getTrip());
229 myStep = myPlan->insert(myStep, newStage);
230 return true;
231 }
232 }
233 if (prior->getJumpDuration() > 0) {
234 // negative distance indicates jump
235 MSStage* newStage = new MSPersonStage_Access(getDestination(), nullptr, getArrivalPos(), 0.0, -1, true,
236 prior->getPosition(SIMSTEP), (*myStep)->getPosition(SIMSTEP));
237 myStep = myPlan->insert(myStep, newStage);
238 return true;
239 }
240 return false;
241}
242
243
244double
246 return MAX2(0., MIN2(1., getVehicleType().getImpatience()
247 + STEPS2TIME((*myStep)->getWaitingTime()) / MSPModel_Striping::MAX_WAIT_TOLERANCE));
248}
249
250const std::string&
252// if (getCurrentStageType() == WALKING) {
253// MSStageWalking* walkingStage = dynamic_cast<MSStageWalking*>(*myStep);
254// assert(walkingStage != 0);
255// const MSEdge* nextEdge = walkingStage->getPedestrianState()->getNextEdge(*walkingStage);
256// if (nextEdge != 0) {
257// return nextEdge->getID();
258// }
259// }
260// return StringUtils::emptyString;
261 const MSEdge* nextEdge = getNextEdgePtr();
262 if (nextEdge != nullptr) {
263 return nextEdge->getID();
264 }
266}
267
268
269const MSEdge*
272 MSStageWalking* walkingStage = dynamic_cast<MSStageWalking*>(*myStep);
273 assert(walkingStage != nullptr);
274 return walkingStage->getPState()->getNextEdge(*walkingStage);
275 }
276 return nullptr;
277}
278
279
280
281void
282MSPerson::replaceWalk(const ConstMSEdgeVector& newEdges, double departPos, int firstIndex, int nextIndex) {
283 assert(nextIndex > firstIndex);
284 //std::cout << SIMTIME << " reroute person " << getID()
285 // << " newEdges=" << toString(newEdges)
286 // << " firstIndex=" << firstIndex
287 // << " nextIndex=" << nextIndex
288 // << " departPos=" << getEdgePos()
289 // << " arrivalPos=" << getNextStage(nextIndex - 1)->getArrivalPos()
290 // << "\n";
291 MSStage* const toBeReplaced = getNextStage(nextIndex - 1);
292 MSStageWalking* newStage = new MSStageWalking(getID(), newEdges,
293 toBeReplaced->getDestinationStop(), -1,
294 -1,
295 departPos,
296 toBeReplaced->getArrivalPos(),
298 appendStage(newStage, nextIndex);
299 // remove stages in reverse order so that proceed will only be called at the last removal
300 for (int i = nextIndex - 1; i >= firstIndex; i--) {
301 //std::cout << " removeStage=" << i << "\n";
302 removeStage(i);
303 }
304}
305
306
309 if (myInfluencer == nullptr) {
310 myInfluencer = new Influencer();
311 }
312 return *myInfluencer;
313}
314
315
318 return myInfluencer;
319}
320
321
322
323/* -------------------------------------------------------------------------
324 * methods of MSPerson::Influencer
325 * ----------------------------------------------------------------------- */
327
328
330
331
332void
333MSPerson::Influencer::setRemoteControlled(Position xyPos, MSLane* l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t) {
334 myRemoteXYPos = xyPos;
335 myRemoteLane = l;
336 myRemotePos = pos;
337 myRemotePosLat = posLat;
338 myRemoteAngle = angle;
339 myRemoteEdgeOffset = edgeOffset;
340 myRemoteRoute = route;
341 myLastRemoteAccess = t;
342}
343
344
345bool
347 return myLastRemoteAccess == MSNet::getInstance()->getCurrentTimeStep();
348}
349
350
351bool
353 return myLastRemoteAccess >= t - TIME2STEPS(10);
354}
355
356
357void
359 /*
360 std::cout << SIMTIME << " moveToXY person=" << p->getID()
361 << " xyPos=" << myRemoteXYPos
362 << " lane=" << Named::getIDSecure(myRemoteLane)
363 << " pos=" << myRemotePos
364 << " posLat=" << myRemotePosLat
365 << " angle=" << myRemoteAngle
366 << " eOf=" << myRemoteEdgeOffset
367 << " route=" << toString(myRemoteRoute)
368 << " aTime=" << time2string(myLastRemoteAccess)
369 << "\n";
370 */
371 switch (p->getStageType(0)) {
373 MSStageWalking* s = dynamic_cast<MSStageWalking*>(p->getCurrentStage());
374 assert(s != nullptr);
375 s->getPState()->moveToXY(p, myRemoteXYPos, myRemoteLane, myRemotePos, myRemotePosLat,
376 myRemoteAngle, myRemoteEdgeOffset, myRemoteRoute,
377 MSNet::getInstance()->getCurrentTimeStep());
378 }
379 break;
380 default:
381 break;
382 }
383}
384
385
386/****************************************************************************/
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:58
#define SIMSTEP
Definition SUMOTime.h:64
#define TIME2STEPS(x)
Definition SUMOTime.h:60
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
virtual void addTransportable(MSTransportable *t) const
Definition MSEdge.cpp:1222
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:775
double getWidth() const
Returns the lane's width.
Definition MSLane.h:646
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition MSLane.h:561
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:199
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition MSNet.h:495
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1286
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:187
void postProcessRemoteControl(MSPerson *p)
Definition MSPerson.cpp:358
Influencer()
Constructor.
Definition MSPerson.cpp:326
void setRemoteControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition MSPerson.cpp:333
~Influencer()
Destructor.
Definition MSPerson.cpp:329
bool isRemoteAffected(SUMOTime t) const
Definition MSPerson.cpp:352
bool isRemoteControlled() const
Definition MSPerson.cpp:346
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
void loadState(MSTransportable *person, std::istringstream &state)
Reconstructs the current state.
Definition MSPerson.cpp:155
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
void saveState(std::ostringstream &out, MSTransportable *transportable)
Saves the current state into the given stream.
Definition MSPerson.cpp:149
bool checkAccess(const MSStage *const prior, const bool waitAtStop=true)
Definition MSPerson.cpp:182
Influencer * myInfluencer
An instance of a speed/position influencing instance; built in "getInfluencer".
Definition MSPerson.h:239
const MSEdge * getNextEdgePtr() const
returns the next edge ptr if this person is walking and the pedestrian model allows it
Definition MSPerson.cpp:270
double getImpatience() const
Definition MSPerson.cpp:245
double myChosenSpeedFactor
Definition MSPerson.h:241
double myTimegapCrossing
value may be sampled from distribution and therefore must be cached
Definition MSPerson.h:244
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:282
virtual ~MSPerson()
destructor
Definition MSPerson.cpp:176
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition MSPerson.cpp:308
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:251
MSPerson(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan, const double speedFactor)
constructor
Definition MSPerson.cpp:168
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:287
virtual double getArrivalPos() const
Definition MSStage.h:97
void setTrip(MSStageTrip *trip)
Definition MSStage.h:291
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.
double getMaxSpeed() const override
Returns the maximum speed (the minimum of desired and physical maximum speed)
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
MSStageType getCurrentStageType() const
the current stage type of the transportable
const MSVehicleType & getVehicleType() const override
Returns the object's "vehicle" type.
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
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 & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
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:97