LCOV - code coverage report
Current view: top level - src/microsim/transportables - MSStageWalking.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 89.0 % 254 226
Test Date: 2025-11-13 15:38:19 Functions: 90.9 % 22 20

            Line data    Source code
       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              : /****************************************************************************/
      14              : /// @file    MSStageWalking.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @author  Laura Bieker
      19              : /// @date    Mon, 9 Jul 2001
      20              : ///
      21              : // A stage performing walking on a sequence of edges.
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <string>
      26              : #include <vector>
      27              : #include <utils/iodevices/OutputDevice.h>
      28              : #include <utils/options/OptionsCont.h>
      29              : #include <utils/common/ToString.h>
      30              : #include <utils/common/StringUtils.h>
      31              : #include <utils/geom/GeomHelper.h>
      32              : #include <utils/router/IntermodalNetwork.h>
      33              : #include <microsim/MSNet.h>
      34              : #include <microsim/MSEdge.h>
      35              : #include <microsim/MSLane.h>
      36              : #include <microsim/transportables/MSTransportableControl.h>
      37              : #include <microsim/MSInsertionControl.h>
      38              : #include <microsim/MSEventControl.h>
      39              : #include <microsim/MSVehicle.h>
      40              : #include <microsim/MSVehicleControl.h>
      41              : #include <microsim/MSStoppingPlace.h>
      42              : #include <microsim/MSRouteHandler.h>
      43              : #include <microsim/devices/MSDevice_Tripinfo.h>
      44              : #include <microsim/devices/MSDevice_Taxi.h>
      45              : #include <microsim/trigger/MSTriggeredRerouter.h>
      46              : #include "MSPModel_Striping.h"
      47              : #include "MSStageTrip.h"
      48              : #include "MSPerson.h"
      49              : #include "MSStageWalking.h"
      50              : 
      51              : 
      52              : // ===========================================================================
      53              : // static member definition
      54              : // ===========================================================================
      55              : bool MSStageWalking::myWarnedInvalidTripinfo = false;
      56              : 
      57              : 
      58              : // ===========================================================================
      59              : // method definitions
      60              : // ===========================================================================
      61       268091 : MSStageWalking::MSStageWalking(const std::string& personID,
      62              :                                const ConstMSEdgeVector& route,
      63              :                                MSStoppingPlace* toStop,
      64              :                                SUMOTime walkingTime, double speed,
      65              :                                double departPos, double arrivalPos, double departPosLat, int departLane,
      66       268091 :                                const std::string& routeID) :
      67              :     MSStageMoving(MSStageType::WALKING, route, routeID, toStop, speed, departPos, arrivalPos, departPosLat, departLane),
      68       268091 :     myWalkingTime(walkingTime),
      69       268091 :     myExitTimes(nullptr),
      70       268091 :     myInternalDistance(0) {
      71       268091 :     myDepartPos = SUMOVehicleParameter::interpretEdgePos(departPos, route.front()->getLength(), SUMO_ATTR_DEPARTPOS,
      72       536182 :                   "person '" + personID + "' walking from edge '" + route.front()->getID() + "'");
      73       268091 :     myArrivalPos = SUMOVehicleParameter::interpretEdgePos(arrivalPos, route.back()->getLength(), SUMO_ATTR_ARRIVALPOS,
      74       268091 :                    "person '" + personID + "' walking to edge '" + route.back()->getID() + "'");
      75       268091 :     if (walkingTime > 0) {
      76          111 :         mySpeed = computeAverageSpeed();
      77              :     }
      78       268091 : }
      79              : 
      80              : 
      81       536054 : MSStageWalking::~MSStageWalking() {
      82       268027 :     delete myExitTimes;
      83       536054 : }
      84              : 
      85              : 
      86              : MSStage*
      87        26254 : MSStageWalking::clone() const {
      88        26254 :     std::vector<const MSEdge*> route = myRoute;
      89        26254 :     double departPos = myDepartPos;
      90        26254 :     double arrivalPos = myArrivalPos;
      91        26254 :     int departLane = myDepartLane;
      92        26254 :     if (myRouteID != "" && MSRoute::distDictionary(myRouteID) != nullptr) {
      93          576 :         route = MSRoute::dictionary(myRouteID, MSRouteHandler::getParsingRNG())->getEdges();
      94          288 :         if (departPos > route[0]->getLength()) {
      95            0 :             WRITE_WARNINGF(TL("Adjusting departPos for cloned walk with routeDistribution '%'"), myRouteID);
      96            0 :             departPos = route[0]->getLength();
      97              :         }
      98          288 :         if (arrivalPos > route.back()->getLength()) {
      99            0 :             WRITE_WARNINGF(TL("Adjusting arrivalPos for cloned walk with routeDistribution '%'"), myRouteID);
     100            0 :             arrivalPos = route.back()->getLength();
     101              :         }
     102          288 :         if (departLane >= route[0]->getNumLanes()) {
     103            0 :             WRITE_WARNINGF(TL("Adjusting departLane for cloned walk with routeDistribution '%'"), myRouteID);
     104            0 :             departLane = route[0]->getNumLanes() - 1;
     105              :         }
     106              :     }
     107        26254 :     MSStage* clon = new MSStageWalking("dummyID", route, myDestinationStop, myWalkingTime, mySpeed, departPos, arrivalPos, myDepartPosLat, departLane, myRouteID);
     108        26254 :     clon->setParameters(*this);
     109        26254 :     return clon;
     110        26254 : }
     111              : 
     112              : 
     113              : void
     114       267190 : MSStageWalking::proceed(MSNet* net, MSTransportable* person, SUMOTime now, MSStage* previous) {
     115       267190 :     myDeparted = now;
     116       267190 :     myRouteStep = myRoute.begin();
     117       267190 :     myLastEdgeEntryTime = now;
     118       267190 :     if (myWalkingTime == 0) {
     119            0 :         if (!person->proceed(net, now)) {
     120            0 :             MSNet::getInstance()->getPersonControl().erase(person);
     121              :         }
     122            0 :         return;
     123              :     }
     124       267190 :     const OptionsCont& oc = OptionsCont::getOptions();
     125       267190 :     if (previous->getEdgePos(now) >= 0 && previous->getEdge() == *myRouteStep) {
     126              :         // we need to adapt to the arrival position of the vehicle unless we have an explicit access
     127       266493 :         myDepartPos = previous->getEdgePos(now);
     128       532986 :         if (oc.getString("pedestrian.model") == "jupedsim") {
     129            0 :             myDepartPosLat = previous->getEdgePosLat(now);
     130              :         }
     131       266493 :         if (myWalkingTime > 0) {
     132           93 :             mySpeed = computeAverageSpeed();
     133              :         }
     134              :     }
     135       267190 :     MSTransportableControl& pControl = net->getPersonControl();
     136       267190 :     myPState = pControl.getMovementModel()->add(person, this, now);
     137       267186 :     if (myPState == nullptr) {
     138            8 :         pControl.erase(person);
     139            8 :         return;
     140              :     }
     141       267178 :     if (previous->getStageType() != MSStageType::WALKING || previous->getEdge() != getEdge()) {
     142              :         // we only need new move reminders if we are walking a different edge (else it is probably a rerouting)
     143       265667 :         activateEntryReminders(person, true);
     144              :     }
     145       534356 :     if (oc.getBool("vehroute-output.exit-times")) {
     146          126 :         myExitTimes = new std::vector<SUMOTime>();
     147              :     }
     148       267178 :     (*myRouteStep)->addTransportable(person);
     149              : }
     150              : 
     151              : 
     152              : void
     153         1696 : MSStageWalking::abort(MSTransportable*) {
     154         1696 :     MSNet::getInstance()->getPersonControl().getMovementModel()->remove(myPState);
     155         1696 : }
     156              : 
     157              : 
     158              : void
     159           19 : MSStageWalking::setSpeed(double speed) {
     160           19 :     mySpeed = speed;
     161           19 : }
     162              : 
     163              : 
     164              : double
     165          204 : MSStageWalking::computeAverageSpeed() const {
     166          204 :     return walkDistance() / STEPS2TIME(myWalkingTime + 1); // avoid systematic rounding errors
     167              : }
     168              : 
     169              : 
     170              : bool
     171      1121895 : MSPerson::isJammed() const {
     172      1121895 :     MSStageWalking* stage = dynamic_cast<MSStageWalking*>(getCurrentStage());
     173      1121895 :     if (stage != nullptr) {
     174      1121895 :         return stage->getPState()->isJammed();
     175              :     }
     176              :     return false;
     177              : }
     178              : 
     179              : 
     180              : double
     181       274719 : MSStageWalking::walkDistance(bool partial) const {
     182              :     double length = 0;
     183       274719 :     auto endIt = partial && myArrived < 0 ? myRouteStep + 1 : myRoute.end();
     184       745032 :     for (ConstMSEdgeVector::const_iterator i = myRoute.begin(); i != endIt; ++i) {
     185       470313 :         length += (*i)->getLength();
     186              :     }
     187       274719 :     if (myRoute.size() > 1 && MSNet::getInstance()->getPersonControl().getMovementModel()->usingInternalLanes()) {
     188       120341 :         if (myInternalDistance > 0) {
     189       108255 :             length += myInternalDistance;
     190              :         } else {
     191              :             // use lower bound for distance to pass the intersection
     192        48189 :             for (ConstMSEdgeVector::const_iterator i = myRoute.begin(); i != endIt - 1; ++i) {
     193        36103 :                 const MSEdge* fromEdge = *i;
     194        36103 :                 const MSEdge* toEdge = *(i + 1);
     195        36103 :                 const MSLane* from = getSidewalk<MSEdge, MSLane>(fromEdge);
     196        36103 :                 const MSLane* to = getSidewalk<MSEdge, MSLane>(toEdge);
     197              :                 Position fromPos;
     198              :                 Position toPos;
     199        36103 :                 if (from != nullptr && to != nullptr) {
     200        36103 :                     if (fromEdge->getToJunction() == toEdge->getFromJunction()) {
     201        36055 :                         fromPos = from->getShape().back();
     202        36055 :                         toPos = to->getShape().front();
     203           48 :                     } else if (fromEdge->getToJunction() == toEdge->getToJunction()) {
     204           26 :                         fromPos = from->getShape().back();
     205           26 :                         toPos = to->getShape().back();
     206           22 :                     } else if (fromEdge->getFromJunction() == toEdge->getFromJunction()) {
     207           10 :                         fromPos = from->getShape().front();
     208           10 :                         toPos = to->getShape().front();
     209           12 :                     } else if (fromEdge->getFromJunction() == toEdge->getToJunction()) {
     210           12 :                         fromPos = from->getShape().front();
     211           12 :                         toPos = to->getShape().back();
     212              :                     }
     213              :                     //std::cout << " from=" << from->getID() << " to=" << to->getID() << " junctionLength=" << fromPos.distanceTo2D(toPos) << "\n";
     214        36103 :                     length += fromPos.distanceTo2D(toPos);
     215              :                 }
     216              :             }
     217              :         }
     218              :     }
     219              :     // determine walking direction for depart and arrival
     220       274719 :     int dummy = 0;
     221       274719 :     const int departFwdArrivalDir = MSPModel::canTraverse(MSPModel::FORWARD, myRoute, dummy);
     222       274719 :     const int departBwdArrivalDir = MSPModel::canTraverse(MSPModel::BACKWARD, myRoute, dummy);
     223       274719 :     const bool mayStartForward = departFwdArrivalDir != MSPModel::UNDEFINED_DIRECTION;
     224       274719 :     const bool mayStartBackward = departBwdArrivalDir != MSPModel::UNDEFINED_DIRECTION;
     225       274719 :     const double arrivalPos = partial && myArrived < 0 ? getEdgePos(SIMSTEP) : myArrivalPos;
     226       274719 :     const double lengthFwd = (length - myDepartPos - (
     227              :                                   departFwdArrivalDir == MSPModel::BACKWARD
     228       274719 :                                   ? arrivalPos
     229       274719 :                                   : myRoute.back()->getLength() - arrivalPos));
     230       274719 :     const double lengthBwd = (length - (myRoute.front()->getLength() - myDepartPos) - (
     231              :                                   departBwdArrivalDir == MSPModel::BACKWARD
     232       274719 :                                   ? arrivalPos
     233       274719 :                                   : myRoute.back()->getLength() - arrivalPos));
     234              :     //std::cout << " length=" << length << " lengthFwd=" << lengthFwd << " lengthBwd=" << lengthBwd << " mayStartForward=" << mayStartForward << " mayStartBackward=" << mayStartBackward << "\n";
     235              : 
     236       274719 :     if (myRoute.size() == 1) {
     237       134187 :         if (myDepartPos > myArrivalPos) {
     238              :             length = lengthBwd;
     239              :         } else {
     240              :             length = lengthFwd;
     241              :         }
     242              :     } else {
     243       140532 :         if (mayStartForward && mayStartBackward) {
     244        10945 :             length = lengthFwd < lengthBwd ? lengthFwd : lengthBwd;
     245       129587 :         } else if (mayStartForward) {
     246              :             length = lengthFwd;
     247        48074 :         } else if (mayStartBackward) {
     248              :             length = lengthBwd;
     249              :         } else {
     250              :             length = lengthFwd;
     251              :         }
     252              :     }
     253              :     //std::cout << SIMTIME << " route=" << toString(myRoute)
     254              :     //    << " depPos=" << myDepartPos << " arPos=" << myArrivalPos
     255              :     //    << " dFwdADir=" << departFwdArrivalDir
     256              :     //    << " dBwdADir=" << departBwdArrivalDir
     257              :     //    << " lengthFwd=" << lengthFwd
     258              :     //    << " lengthBwd=" << lengthBwd
     259              :     //    << "\n";
     260              : 
     261       274719 :     return MAX2(POSITION_EPS, length);
     262              : }
     263              : 
     264              : 
     265              : SUMOTime
     266       110336 : MSStageWalking::getTimeLoss(const MSTransportable* transportable) const {
     267       110336 :     SUMOTime timeLoss = myArrived == -1 ? 0 : getDuration() - TIME2STEPS(walkDistance(true) / getMaxSpeed(transportable));
     268       110336 :     if (timeLoss < 0 && timeLoss > TIME2STEPS(-0.1)) {
     269              :         // avoid negative timeLoss due to rounding errors
     270              :         timeLoss = 0;
     271              :     }
     272       110336 :     return timeLoss;
     273              : }
     274              : 
     275              : 
     276              : void
     277        55168 : MSStageWalking::tripInfoOutput(OutputDevice& os, const MSTransportable* const person) const {
     278        55168 :     if (!myWarnedInvalidTripinfo && MSNet::getInstance()->getPersonControl().getMovementModel()->usingShortcuts()) {
     279            0 :         WRITE_WARNING(TL("The pedestrian model uses infrastructure which is not in the network, timeLoss and routeLength may be invalid."));
     280            0 :         myWarnedInvalidTripinfo = true;
     281              :     }
     282        55168 :     const double distance = walkDistance(true);
     283        55168 :     const double maxSpeed = getMaxSpeed(person);
     284        55168 :     const SUMOTime duration = myArrived - myDeparted;
     285        55168 :     const SUMOTime timeLoss = getTimeLoss(person);
     286        55168 :     MSDevice_Tripinfo::addPedestrianData(distance, duration, timeLoss);
     287        55168 :     os.openTag("walk");
     288       110336 :     os.writeAttr("depart", myDeparted >= 0 ? time2string(myDeparted) : "-1");
     289        55168 :     os.writeAttr("departPos", myDepartPos);
     290       110336 :     os.writeAttr("arrival", myArrived >= 0 ? time2string(myArrived) : "-1");
     291       110336 :     os.writeAttr("arrivalPos", myArrived >= 0 ? toString(myArrivalPos) : "-1");
     292       165245 :     os.writeAttr("duration", myDeparted < 0 ? "-1" :
     293        54909 :                  time2string(myArrived >= 0 ? duration : MSNet::getInstance()->getCurrentTimeStep() - myDeparted));
     294       110336 :     os.writeAttr("routeLength", myArrived >= 0 ? toString(distance) : "-1");
     295       110336 :     os.writeAttr("timeLoss", time2string(timeLoss));
     296        55168 :     os.writeAttr("maxSpeed", maxSpeed);
     297       110336 :     os.writeAttr("waitingTime", time2string(getTotalWaitingTime()));
     298        55168 :     os.closeTag();
     299        55168 : }
     300              : 
     301              : 
     302              : void
     303         2361 : MSStageWalking::routeOutput(const bool /* isPerson */, OutputDevice& os, const bool withRouteLength, const MSStage* const /* previous */) const {
     304         2361 :     os.openTag("walk").writeAttr(SUMO_ATTR_EDGES, myRoute);
     305         2361 :     std::string comment = "";
     306         2361 :     if (myDestinationStop != nullptr) {
     307          431 :         os.writeAttr(toString(myDestinationStop->getElement()), myDestinationStop->getID());
     308          431 :         if (myDestinationStop->getMyName() != "") {
     309          222 :             comment =  " <!-- " + StringUtils::escapeXML(myDestinationStop->getMyName(), true) + " -->";
     310              :         }
     311         1930 :     } else if (wasSet(VEHPARS_ARRIVALPOS_SET)) {
     312          168 :         os.writeAttr(SUMO_ATTR_ARRIVALPOS, myArrivalPos);
     313              :     }
     314         2361 :     if (myWalkingTime > 0) {
     315            0 :         os.writeAttr(SUMO_ATTR_DURATION, time2string(myWalkingTime));
     316         2361 :     } else if (mySpeed > 0) {
     317           24 :         os.writeAttr(SUMO_ATTR_SPEED, mySpeed);
     318              :     }
     319         2361 :     if (withRouteLength) {
     320           36 :         if (myDeparted >= 0) {
     321           72 :             os.writeAttr("routeLength", walkDistance(true));
     322              :         } else {
     323            0 :             os.writeAttr("routeLength", "-1");
     324              :         }
     325              :     }
     326         2361 :     if (myExitTimes != nullptr) {
     327              :         std::vector<std::string> exits;
     328          444 :         for (SUMOTime t : *myExitTimes) {
     329          636 :             exits.push_back(time2string(t));
     330              :         }
     331          252 :         std::vector<std::string> missing(MAX2(0, (int)myRoute.size() - (int)myExitTimes->size()), "-1");
     332          126 :         exits.insert(exits.end(), missing.begin(), missing.end());
     333          126 :         os.writeAttr("exitTimes", exits);
     334          126 :         os.writeAttr(SUMO_ATTR_STARTED, myDeparted >= 0 ? time2string(myDeparted) : "-1");
     335          126 :         os.writeAttr(SUMO_ATTR_ENDED, myArrived >= 0 ? time2string(myArrived) : "-1");
     336          126 :     }
     337         4722 :     if (OptionsCont::getOptions().getBool("vehroute-output.cost")) {
     338          105 :         os.writeAttr(SUMO_ATTR_COST, getCosts());
     339              :     }
     340         2361 :     os.closeTag(comment);
     341         2361 : }
     342              : 
     343              : 
     344              : bool
     345       994309 : MSStageWalking::moveToNextEdge(MSTransportable* person, SUMOTime currentTime, int prevDir, MSEdge* nextInternal, const bool isReplay) {
     346       994309 :     ((MSEdge*)getEdge())->removeTransportable(person);
     347       994309 :     const MSLane* lane = getSidewalk<MSEdge, MSLane>(getEdge());
     348              :     const bool arrived = myRouteStep == myRoute.end() - 1;
     349       994309 :     if (lane != nullptr) {
     350       974334 :         const double tl = person->getVehicleType().getLength();
     351              :         const double lastPos = (arrived
     352       974334 :                                 ? (prevDir == MSPModel::FORWARD
     353       284902 :                                    ? getArrivalPos() + tl
     354        41260 :                                    : getArrivalPos() - tl)
     355       730692 :                                 : person->getPositionOnLane());
     356       974334 :         activateLeaveReminders(person, lane, lastPos, currentTime, arrived);
     357              :     }
     358       994309 :     if (myExitTimes != nullptr && nextInternal == nullptr) {
     359          318 :         myExitTimes->push_back(currentTime);
     360              :     }
     361              :     myMoveReminders.clear();
     362       994309 :     myLastEdgeEntryTime = currentTime;
     363              :     //std::cout << SIMTIME << " moveToNextEdge person=" << person->getID() << "\n";
     364       994309 :     if (myCurrentInternalEdge != nullptr) {
     365       394664 :         myInternalDistance += (myPState->getPathLength() == 0 ? myCurrentInternalEdge->getLength() : myPState->getPathLength());
     366              :     }
     367       994309 :     if (arrived) {
     368       243668 :         MSPerson* p = dynamic_cast<MSPerson*>(person);
     369       243668 :         if (!isReplay && p->hasInfluencer() && p->getInfluencer().isRemoteControlled()) {
     370            0 :             myCurrentInternalEdge = nextInternal;
     371            0 :             ((MSEdge*) getEdge())->addTransportable(person);
     372            0 :             return false;
     373              :         }
     374       243668 :         if (myDestinationStop != nullptr) {
     375        32418 :             myDestinationStop->addTransportable(person);
     376              :         }
     377       243668 :         if (isReplay) {
     378              :             // cannot do this in the replay device because the person might get deleted below
     379           40 :             MSNet::getInstance()->getPersonControl().getMovementModel()->remove(myPState);
     380              :         }
     381       243668 :         if (!person->proceed(MSNet::getInstance(), currentTime)) {
     382       237225 :             MSNet::getInstance()->getPersonControl().erase(person);
     383              :         }
     384              :         //std::cout << " end walk. myRouteStep=" << (*myRouteStep)->getID() << "\n";
     385       243668 :         return true;
     386              :     } else {
     387       750641 :         if (nextInternal == nullptr) {
     388              :             ++myRouteStep;
     389              :         }
     390       750641 :         myCurrentInternalEdge = nextInternal;
     391       750641 :         ((MSEdge*) getEdge())->addTransportable(person);
     392       750641 :         return false;
     393              :     }
     394              : }
     395              : 
     396              : 
     397              : void
     398      1015788 : MSStageWalking::activateEntryReminders(MSTransportable* person, const bool isDepart) {
     399      1015788 :     const MSLane* const nextLane = getSidewalk<MSEdge, MSLane>(getEdge());
     400      1015788 :     if (nextLane != nullptr) {
     401      1963556 :         for (MSMoveReminder* const rem : nextLane->getMoveReminders()) {
     402      1554048 :             if (rem->notifyEnter(*person, isDepart ? MSMoveReminder::NOTIFICATION_DEPARTED : MSMoveReminder::NOTIFICATION_JUNCTION, nextLane)) {
     403        19044 :                 myMoveReminders.push_back(rem);
     404              :             }
     405              :         }
     406              :     }
     407      2031576 :     if (hasParameter("rerouter")) {
     408              :         double minDist = std::numeric_limits<double>::max();
     409              :         MSTriggeredRerouter* nearest = nullptr;
     410          190 :         for (MSMoveReminder* const rem : myMoveReminders) {
     411          120 :             MSTriggeredRerouter* rerouter = dynamic_cast<MSTriggeredRerouter*>(rem);
     412          120 :             if (rerouter != nullptr) {
     413           70 :                 const double dist2 = rerouter->getPosition().distanceSquaredTo2D(person->getPosition());
     414           70 :                 if (dist2 < minDist) {
     415              :                     nearest = rerouter;
     416              :                     minDist = dist2;
     417              :                 }
     418              :             }
     419              :         }
     420           70 :         if (nearest != nullptr) {
     421           70 :             nearest->triggerRouting(*person, MSMoveReminder::NOTIFICATION_JUNCTION);
     422              :         }
     423              :         // TODO maybe removal of the reminders? Or can we rely on movetonextedge to clean everything up?
     424              :     }
     425      1015788 : }
     426              : 
     427              : 
     428              : void
     429            0 : MSStageWalking::activateMoveReminders(MSTransportable* person, double oldPos, double newPos, double newSpeed) {
     430            0 :     for (std::vector<MSMoveReminder*>::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
     431            0 :         if ((*rem)->notifyMove(*person, oldPos, newPos, newSpeed)) {
     432              :             ++rem;
     433              :         } else {
     434            0 :             rem = myMoveReminders.erase(rem);
     435              :         }
     436              :     }
     437            0 : }
     438              : 
     439              : 
     440              : void
     441       974334 : MSStageWalking::activateLeaveReminders(MSTransportable* person, const MSLane* lane, double lastPos, SUMOTime t, bool arrived) {
     442       974334 :     MSMoveReminder::Notification notification = arrived ? MSMoveReminder::NOTIFICATION_ARRIVED : MSMoveReminder::NOTIFICATION_JUNCTION;
     443       992254 :     for (MSMoveReminder* const rem : myMoveReminders) {
     444        17920 :         rem->updateDetector(*person, 0.0, lane->getLength(), myLastEdgeEntryTime, t, t, true);
     445        17920 :         rem->notifyLeave(*person, lastPos, notification);
     446              :     }
     447       974334 : }
     448              : 
     449              : 
     450              : int
     451       448840 : MSStageWalking::getRoutePosition() const {
     452       448840 :     return (int)(myRouteStep - myRoute.begin());
     453              : }
     454              : 
     455              : 
     456              : double
     457     15774480 : MSStageWalking::getMaxSpeed(const MSTransportable* const person) const {
     458     15774480 :     return mySpeed >= 0 ? mySpeed : person->getMaxSpeed();
     459              : }
     460              : 
     461              : std::string
     462            0 : MSStageWalking::getStageSummary(const bool /* isPerson */) const {
     463            0 :     const std::string dest = (getDestinationStop() == nullptr ?
     464            0 :                               " edge '" + getDestination()->getID() + "'" :
     465            0 :                               " stop '" + getDestinationStop()->getID() + "'" + (
     466            0 :                                   getDestinationStop()->getMyName() != "" ? " (" + getDestinationStop()->getMyName() + ")" : ""));
     467            0 :     return "walking to " + dest;
     468              : }
     469              : 
     470              : 
     471              : void
     472           19 : MSStageWalking::saveState(std::ostringstream& out) {
     473           38 :     out << " " << myDeparted << " " << (myRouteStep - myRoute.begin()) << " " << myLastEdgeEntryTime;
     474           19 :     myPState->saveState(out);
     475           19 : }
     476              : 
     477              : 
     478              : void
     479           24 : MSStageWalking::loadState(MSTransportable* transportable, std::istringstream& state) {
     480              :     int stepIdx;
     481           24 :     state >> myDeparted >> stepIdx >> myLastEdgeEntryTime;
     482           24 :     myRouteStep = myRoute.begin() + stepIdx;
     483           24 :     myPState = MSNet::getInstance()->getPersonControl().getMovementModel()->loadState(transportable, this, state);
     484           24 :     if (myPState->getLane() && !myPState->getLane()->isNormal()) {
     485            1 :         myCurrentInternalEdge = &myPState->getLane()->getEdge();
     486            1 :         myCurrentInternalEdge->addTransportable(transportable);
     487              :     } else {
     488           23 :         (*myRouteStep)->addTransportable(transportable);
     489              :     }
     490           24 : }
     491              : 
     492              : 
     493              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1