Eclipse SUMO - Simulation of Urban MObility
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-2024 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>
29 #include <utils/common/ToString.h>
31 #include <utils/geom/GeomHelper.h>
33 #include <microsim/MSNet.h>
34 #include <microsim/MSEdge.h>
35 #include <microsim/MSLane.h>
39 #include <microsim/MSVehicle.h>
46 #include "MSPModel_Striping.h"
47 #include "MSStageTrip.h"
48 #include "MSStageWalking.h"
49 #include "MSPerson.h"
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
55 /* -------------------------------------------------------------------------
56 * MSPerson::MSPersonStage_Access - methods
57 * ----------------------------------------------------------------------- */
59  const double arrivalPos, const double arrivalPosLat, const double dist, const bool isExit,
60  const Position& startPos, const Position& endPos) :
61  MSStage(MSStageType::ACCESS, destination, toStop, arrivalPos, arrivalPosLat),
62  myDist(dist), myAmExit(isExit) {
63  myPath.push_back(startPos);
64  myPath.push_back(endPos);
65 }
66 
67 
69 
70 MSStage*
72  return new MSPersonStage_Access(myDestination, myDestinationStop, myArrivalPos, myArrivalPosLat, myDist, myAmExit, myPath.front(), myPath.back());
73 }
74 
75 void
77  myDeparted = now;
78  myEstimatedArrival = now + TIME2STEPS(myDist / person->getMaxSpeed());
79  // TODO myEstimatedArrival is not a multiple of DELTA_T here. This might give a problem because the destination position will not be reached precisely
80  net->getBeginOfTimestepEvents()->addEvent(new ProceedCmd(person, &myDestinationStop->getLane().getEdge()), myEstimatedArrival);
82  myDestinationStop->getLane().getEdge().addTransportable(person);
83 }
84 
85 
86 std::string
87 MSPerson::MSPersonStage_Access::getStageDescription(const bool /* isPerson */) const {
88  return "access";
89 }
90 
91 
92 std::string
93 MSPerson::MSPersonStage_Access::getStageSummary(const bool /* isPerson */) const {
94  return (myAmExit ? "access from stop '" : "access to stop '") + getDestinationStop()->getID() + "'";
95 }
96 
97 
100  return myPath.positionAtOffset(myPath.length() * (double)(now - myDeparted) / (double)(myEstimatedArrival - myDeparted));
101 }
102 
103 
104 double
106  return myPath.angleAt2D(0);
107 }
108 
109 
110 double
112  return myDist / STEPS2TIME(MAX2((SUMOTime)1, myEstimatedArrival - myDeparted));
113 }
114 
115 void
117  os.openTag("access");
118  os.writeAttr("stop", getDestinationStop()->getID());
119  os.writeAttr("depart", time2string(myDeparted));
120  os.writeAttr("arrival", myArrived >= 0 ? time2string(myArrived) : "-1");
121  os.writeAttr("duration", myArrived > 0 ? time2string(getDuration()) : "-1");
122  os.writeAttr("routeLength", myDist);
123  os.closeTag();
124 }
125 
126 
127 SUMOTime
130  myStopEdge->removeTransportable(myPerson);
131  if (!myPerson->proceed(MSNet::getInstance(), currentTime)) {
133  }
134  return 0;
135 }
136 
137 
138 /* -------------------------------------------------------------------------
139  * MSPerson - methods
140  * ----------------------------------------------------------------------- */
141 MSPerson::MSPerson(const SUMOVehicleParameter* pars, MSVehicleType* vtype, MSTransportable::MSTransportablePlan* plan, const double speedFactor) :
142  MSTransportable(pars, vtype, plan, true),
143  myInfluencer(nullptr),
144  myChosenSpeedFactor(pars->speedFactor < 0 ? speedFactor : pars->speedFactor)
145 { }
146 
147 
149  delete myInfluencer;
150 }
151 
152 
153 bool
154 MSPerson::checkAccess(const MSStage* const prior, const bool waitAtStop) {
155  MSStoppingPlace* prevStop = prior->getDestinationStop();
156  if (!waitAtStop && prior->getStageType() == MSStageType::TRIP) {
157  prevStop = prior->getOriginStop();
158  }
159  if (prevStop != nullptr) {
160  const MSEdge* const accessEdge = waitAtStop ? prior->getDestination() : (*myStep)->getFromEdge();
161  const MSStoppingPlace::Access* const access = prevStop->getAccess(accessEdge);
162  if (access != nullptr) {
163  const MSLane* const lane = accessEdge->getLanes()[0];
164  MSStage* newStage = nullptr;
165  if (waitAtStop) {
166  const MSEdge* const stopEdge = &prevStop->getLane().getEdge();
167  const double arrivalAtBs = (prevStop->getBeginLanePosition() + prevStop->getEndLanePosition()) / 2;
168  newStage = new MSPersonStage_Access(stopEdge, prevStop, arrivalAtBs, 0.0, access->length, false,
169  lane->geometryPositionAtOffset(access->endPos),
170  prevStop->getLane().geometryPositionAtOffset(arrivalAtBs));
171  } else {
172  const OptionsCont& oc = OptionsCont::getOptions();
173  const std::string model = oc.getString("pedestrian.model");
174  if (model != "jupedsim") {
175  const double startPos = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePos(0) : prior->getArrivalPos();
176  const Position& trainExit = prevStop->getLane().geometryPositionAtOffset(startPos);
177  const double arrivalPos = access->useDoors ? lane->getShape().nearest_offset_to_point2D(trainExit) : access->endPos;
178  Position platformEntry = lane->geometryPositionAtOffset(arrivalPos);
179  if (access->useDoors) {
180  // find the closer side of the platform to enter
181  const double halfWidth = lane->getWidth() / 2. - MAX2(getVehicleType().getLength(), getVehicleType().getWidth()) / 2. - POSITION_EPS;
182  platformEntry = lane->geometryPositionAtOffset(arrivalPos, halfWidth);
183  const Position& plat2 = lane->geometryPositionAtOffset(arrivalPos, -halfWidth);
184  if (trainExit.distanceSquaredTo2D(plat2) < trainExit.distanceSquaredTo2D(platformEntry)) {
185  platformEntry = plat2;
186  }
187  }
188  newStage = new MSPersonStage_Access(accessEdge, prevStop, arrivalPos, 0.0, access->length, true,
189  trainExit, platformEntry);
190  } else {
191  const double startPos = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePos(0) : prior->getArrivalPos();
192  const double startPosLat = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePosLat(0) : prior->getArrivalPosLat();
193  // The start and end attributes of the access stage are equal in this case, but we need to compute the arrival position relatively
194  // to the current lane and not the lane of the previous stage.
195  const Position start = prevStop->getLane().geometryPositionAtOffset(startPos, startPosLat);
196  const Position end = lane->getShape().transformToVectorCoordinates(start);
197  newStage = new MSPersonStage_Access(accessEdge, prevStop, end.x(), -end.y(), access->length, true, start, start);
198  }
199  }
200  myStep = myPlan->insert(myStep, newStage);
201  return true;
202  }
203  }
204  return false;
205 }
206 
207 
208 double
210  return MAX2(0., MIN2(1., getVehicleType().getImpatience()
211  + STEPS2TIME((*myStep)->getWaitingTime(SIMSTEP)) / MSPModel_Striping::MAX_WAIT_TOLERANCE));
212 }
213 
214 const std::string&
216 // if (getCurrentStageType() == WALKING) {
217 // MSStageWalking* walkingStage = dynamic_cast<MSStageWalking*>(*myStep);
218 // assert(walkingStage != 0);
219 // const MSEdge* nextEdge = walkingStage->getPedestrianState()->getNextEdge(*walkingStage);
220 // if (nextEdge != 0) {
221 // return nextEdge->getID();
222 // }
223 // }
224 // return StringUtils::emptyString;
225  const MSEdge* nextEdge = getNextEdgePtr();
226  if (nextEdge != nullptr) {
227  return nextEdge->getID();
228  }
230 }
231 
232 
233 const MSEdge*
236  MSStageWalking* walkingStage = dynamic_cast<MSStageWalking*>(*myStep);
237  assert(walkingStage != nullptr);
238  return walkingStage->getPState()->getNextEdge(*walkingStage);
239  }
240  return nullptr;
241 }
242 
243 
244 
245 void
246 MSPerson::reroute(const ConstMSEdgeVector& newEdges, double departPos, int firstIndex, int nextIndex) {
247  assert(nextIndex > firstIndex);
248  //std::cout << SIMTIME << " reroute person " << getID()
249  // << " newEdges=" << toString(newEdges)
250  // << " firstIndex=" << firstIndex
251  // << " nextIndex=" << nextIndex
252  // << " departPos=" << getEdgePos()
253  // << " arrivalPos=" << getNextStage(nextIndex - 1)->getArrivalPos()
254  // << "\n";
255  MSStage* toBeReplaced = getNextStage(nextIndex - 1);
256  if (newEdges.back() != toBeReplaced->getDestination()) {
257 
258  }
259  MSStageWalking* newStage = new MSStageWalking(getID(), newEdges,
260  toBeReplaced->getDestinationStop(), -1,
261  -1,
262  departPos,
263  toBeReplaced->getArrivalPos(),
265  appendStage(newStage, nextIndex);
266  // remove stages in reverse order so that proceed will only be called at the last removal
267  for (int i = nextIndex - 1; i >= firstIndex; i--) {
268  //std::cout << " removeStage=" << i << "\n";
269  removeStage(i);
270  }
271 }
272 
273 
276  if (myInfluencer == nullptr) {
277  myInfluencer = new Influencer();
278  }
279  return *myInfluencer;
280 }
281 
282 
285  return myInfluencer;
286 }
287 
288 
289 
290 /* -------------------------------------------------------------------------
291  * methods of MSPerson::Influencer
292  * ----------------------------------------------------------------------- */
294 
295 
297 
298 
299 void
300 MSPerson::Influencer::setRemoteControlled(Position xyPos, MSLane* l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t) {
301  myRemoteXYPos = xyPos;
302  myRemoteLane = l;
303  myRemotePos = pos;
304  myRemotePosLat = posLat;
305  myRemoteAngle = angle;
306  myRemoteEdgeOffset = edgeOffset;
307  myRemoteRoute = route;
308  myLastRemoteAccess = t;
309 }
310 
311 
312 bool
314  return myLastRemoteAccess == MSNet::getInstance()->getCurrentTimeStep();
315 }
316 
317 
318 bool
320  return myLastRemoteAccess >= t - TIME2STEPS(10);
321 }
322 
323 
324 void
326  /*
327  std::cout << SIMTIME << " moveToXY person=" << p->getID()
328  << " xyPos=" << myRemoteXYPos
329  << " lane=" << Named::getIDSecure(myRemoteLane)
330  << " pos=" << myRemotePos
331  << " posLat=" << myRemotePosLat
332  << " angle=" << myRemoteAngle
333  << " eOf=" << myRemoteEdgeOffset
334  << " route=" << toString(myRemoteRoute)
335  << " aTime=" << time2string(myLastRemoteAccess)
336  << "\n";
337  */
338  switch (p->getStageType(0)) {
339  case MSStageType::WALKING: {
340  MSStageWalking* s = dynamic_cast<MSStageWalking*>(p->getCurrentStage());
341  assert(s != nullptr);
342  s->getPState()->moveToXY(p, myRemoteXYPos, myRemoteLane, myRemotePos, myRemotePosLat,
343  myRemoteAngle, myRemoteEdgeOffset, myRemoteRoute,
344  MSNet::getInstance()->getCurrentTimeStep());
345  }
346  break;
347  default:
348  break;
349  }
350 }
351 
352 
353 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
MSStageType
Definition: MSStage.h:54
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition: SUMOTime.cpp:69
#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 addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:756
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:627
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:552
virtual const PositionVector & getShape(bool) const
Definition: MSLane.h:294
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:182
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:471
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:1173
static const double MAX_WAIT_TOLERANCE
static const double UNSPECIFIED_POS_LAT
the default lateral offset for persons when starting a walk
Definition: MSPModel.h:130
Changes the wished person speed and position.
Definition: MSPerson.h:176
void postProcessRemoteControl(MSPerson *p)
Definition: MSPerson.cpp:325
Influencer()
Constructor.
Definition: MSPerson.cpp:293
void setRemoteControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition: MSPerson.cpp:300
~Influencer()
Destructor.
Definition: MSPerson.cpp:296
bool isRemoteAffected(SUMOTime t) const
Definition: MSPerson.cpp:319
bool isRemoteControlled() const
Definition: MSPerson.cpp:313
SUMOTime execute(SUMOTime currentTime)
Executes the command.
Definition: MSPerson.cpp:128
Position getPosition(SUMOTime now) const
returns the position of the transportable
Definition: MSPerson.cpp:99
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:58
double getSpeed() const
the speed of the person in this stage
Definition: MSPerson.cpp:111
MSStage * clone() const
Definition: MSPerson.cpp:71
void tripInfoOutput(OutputDevice &os, const MSTransportable *const transportable) const
Called on writing tripinfo output.
Definition: MSPerson.cpp:116
virtual void proceed(MSNet *net, MSTransportable *person, SUMOTime now, MSStage *previous)
proceeds to the next step
Definition: MSPerson.cpp:76
double getAngle(SUMOTime now) const
returns the angle of the transportable
Definition: MSPerson.cpp:105
std::string getStageDescription(const bool isPerson) const
returns the stage description as a string
Definition: MSPerson.cpp:87
std::string getStageSummary(const bool isPerson) const
return string summary of the current stage
Definition: MSPerson.cpp:93
bool checkAccess(const MSStage *const prior, const bool waitAtStop=true)
Definition: MSPerson.cpp:154
Influencer * myInfluencer
An instance of a speed/position influencing instance; built in "getInfluencer".
Definition: MSPerson.h:228
const MSEdge * getNextEdgePtr() const
returns the next edge ptr if this person is walking and the pedestrian model allows it
Definition: MSPerson.cpp:234
double getImpatience() const
Definition: MSPerson.cpp:209
double myChosenSpeedFactor
Definition: MSPerson.h:230
void reroute(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:246
virtual ~MSPerson()
destructor
Definition: MSPerson.cpp:148
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSPerson.cpp:275
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:215
MSPerson(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan, const double speedFactor)
constructor
Definition: MSPerson.cpp:141
virtual MSStoppingPlace * getOriginStop() const
returns the origin stop (if any). only needed for MSStageTrip
Definition: MSStage.h:89
const MSEdge * getDestination() const
returns the destination edge
Definition: MSStage.cpp:65
virtual double getEdgePos(SUMOTime now) const
Definition: MSStage.cpp:83
virtual double getEdgePosLat(SUMOTime now) const
Definition: MSStage.cpp:89
virtual double getArrivalPos() const
Definition: MSStage.h:93
MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
Definition: MSStage.h:84
MSStageType getStageType() const
Definition: MSStage.h:126
virtual double getArrivalPosLat() const
Definition: MSStage.h:97
MSTransportableStateAdapter * getPState() const
Definition: MSStageMoving.h:49
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
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.
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
const MSVehicleType & getVehicleType() const
Returns the object's "vehicle" type.
MSStageType getCurrentStageType() const
the current stage type of the transportable
MSStage * getCurrentStage() const
Return the current stage.
void appendStage(MSStage *stage, int next=-1)
Appends the given stage to the current plan.
const MSLane * getLane() const
Returns the current lane (may be nullptr)
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:192
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.
Definition: MSVehicleType.h:63
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
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.
Definition: OptionsCont.cpp:60
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
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:276
double x() const
Returns the x-position.
Definition: Position.h:55
double y() const
Returns the y-position.
Definition: Position.h:60
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....
Structure representing possible vehicle parameter.
static std::string emptyString
An empty string.
Definition: StringUtils.h:86