LCOV - code coverage report
Current view: top level - src/microsim/transportables - MSStageWalking.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 89.8 % 265 238
Test Date: 2026-07-26 16:30:20 Functions: 90.5 % 21 19

            Line data    Source code
       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              : /****************************************************************************/
      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       229682 : 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       229682 :                                const std::string& routeID) :
      67              :     MSStageMoving(MSStageType::WALKING, route, routeID, toStop, speed, departPos, arrivalPos, departPosLat, departLane),
      68       229682 :     myWalkingTime(walkingTime),
      69       229682 :     myExitTimes(nullptr),
      70       229682 :     myInternalDistance(0) {
      71       229682 :     myDepartPos = SUMOVehicleParameter::interpretEdgePos(departPos, route.front()->getLength(), SUMO_ATTR_DEPARTPOS,
      72       459364 :                   "person '" + personID + "' walking from edge '" + route.front()->getID() + "'");
      73       229682 :     myArrivalPos = SUMOVehicleParameter::interpretEdgePos(arrivalPos, route.back()->getLength(), SUMO_ATTR_ARRIVALPOS,
      74       229682 :                    "person '" + personID + "' walking to edge '" + route.back()->getID() + "'");
      75       229682 :     if (walkingTime > 0) {
      76          111 :         mySpeed = computeAverageSpeed();
      77              :     }
      78       229682 : }
      79              : 
      80              : 
      81       459278 : MSStageWalking::~MSStageWalking() {
      82       229639 :     delete myExitTimes;
      83       459278 : }
      84              : 
      85              : 
      86              : MSStage*
      87        26644 : MSStageWalking::clone() const {
      88        26644 :     std::vector<const MSEdge*> route = myRoute;
      89        26644 :     double departPos = myDepartPos;
      90        26644 :     double arrivalPos = myArrivalPos;
      91        26644 :     int departLane = myDepartLane;
      92        26644 :     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        26644 :     MSStage* clon = new MSStageWalking("dummyID", route, myDestinationStop, myWalkingTime, mySpeed, departPos, arrivalPos, myDepartPosLat, departLane, myRouteID);
     108        26644 :     clon->setParameters(*this);
     109        26644 :     return clon;
     110        26644 : }
     111              : 
     112              : 
     113              : void
     114       228747 : MSStageWalking::proceed(MSNet* net, MSTransportable* person, SUMOTime now, MSStage* previous) {
     115       228747 :     myDeparted = now;
     116       228747 :     myRouteStep = myRoute.begin();
     117       228747 :     myLastEdgeEntryTime = now;
     118       228747 :     if (myWalkingTime == 0) {
     119            0 :         if (!person->proceed(net, now)) {
     120            0 :             MSNet::getInstance()->getPersonControl().erase(person);
     121              :         }
     122            0 :         return;
     123              :     }
     124       228747 :     const OptionsCont& oc = OptionsCont::getOptions();
     125       228747 :     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       228049 :         myDepartPos = previous->getEdgePos(now);
     128       456098 :         if (oc.getString("pedestrian.model") == "jupedsim") {
     129            0 :             myDepartPosLat = previous->getEdgePosLat(now);
     130              :         }
     131       228049 :         if (myWalkingTime > 0) {
     132           93 :             mySpeed = computeAverageSpeed();
     133              :         }
     134              :     }
     135       228747 :     MSTransportableControl& pControl = net->getPersonControl();
     136       228747 :     myPState = pControl.getMovementModel()->add(person, this, now);
     137       228743 :     if (myPState == nullptr) {
     138            8 :         pControl.erase(person);
     139            8 :         return;
     140              :     }
     141       228735 :     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       227224 :         activateEntryReminders(person, true);
     144              :     }
     145       457470 :     if (oc.getBool("vehroute-output.exit-times")) {
     146          144 :         myExitTimes = new std::vector<SUMOTime>();
     147              :     }
     148       228735 :     (*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           18 : MSStageWalking::setSpeed(double speed) {
     160           18 :     mySpeed = speed;
     161           18 : }
     162              : 
     163              : 
     164              : double
     165          204 : MSStageWalking::computeAverageSpeed() const {
     166          204 :     return walkDistance() / STEPS2TIME(myWalkingTime + 1); // avoid systematic rounding errors
     167              : }
     168              : 
     169              : 
     170              : double
     171       276455 : MSStageWalking::walkDistance(bool partial) const {
     172              :     double length = 0;
     173       276455 :     auto endIt = partial && myArrived < 0 ? myRouteStep + 1 : myRoute.end();
     174       751229 :     for (ConstMSEdgeVector::const_iterator i = myRoute.begin(); i != endIt; ++i) {
     175       474774 :         length += (*i)->getLength();
     176              :     }
     177       276455 :     if (myRoute.size() > 1 && MSNet::getInstance()->getPersonControl().getMovementModel()->usingInternalLanes()) {
     178       121451 :         if (myInternalDistance > 0) {
     179       109360 :             length += myInternalDistance;
     180              :         } else {
     181              :             // use lower bound for distance to pass the intersection
     182        48194 :             for (ConstMSEdgeVector::const_iterator i = myRoute.begin(); i != endIt - 1; ++i) {
     183        36103 :                 const MSEdge* fromEdge = *i;
     184        36103 :                 const MSEdge* toEdge = *(i + 1);
     185        36103 :                 const MSLane* from = getSidewalk<MSEdge, MSLane>(fromEdge);
     186        36103 :                 const MSLane* to = getSidewalk<MSEdge, MSLane>(toEdge);
     187              :                 Position fromPos;
     188              :                 Position toPos;
     189        36103 :                 if (from != nullptr && to != nullptr) {
     190        36103 :                     if (fromEdge->getToJunction() == toEdge->getFromJunction()) {
     191        36055 :                         fromPos = from->getShape().back();
     192        36055 :                         toPos = to->getShape().front();
     193           48 :                     } else if (fromEdge->getToJunction() == toEdge->getToJunction()) {
     194           26 :                         fromPos = from->getShape().back();
     195           26 :                         toPos = to->getShape().back();
     196           22 :                     } else if (fromEdge->getFromJunction() == toEdge->getFromJunction()) {
     197           10 :                         fromPos = from->getShape().front();
     198           10 :                         toPos = to->getShape().front();
     199           12 :                     } else if (fromEdge->getFromJunction() == toEdge->getToJunction()) {
     200           12 :                         fromPos = from->getShape().front();
     201           12 :                         toPos = to->getShape().back();
     202              :                     }
     203              :                     //std::cout << " from=" << from->getID() << " to=" << to->getID() << " junctionLength=" << fromPos.distanceTo2D(toPos) << "\n";
     204        36103 :                     length += fromPos.distanceTo2D(toPos);
     205              :                 }
     206              :             }
     207              :         }
     208              :     }
     209              :     // determine walking direction for depart and arrival
     210       276455 :     int dummy = 0;
     211       276455 :     const int departFwdArrivalDir = MSPModel::canTraverse(MSPModel::FORWARD, myRoute, dummy);
     212       276455 :     const int departBwdArrivalDir = MSPModel::canTraverse(MSPModel::BACKWARD, myRoute, dummy);
     213       276455 :     const bool mayStartForward = departFwdArrivalDir != MSPModel::UNDEFINED_DIRECTION;
     214       276455 :     const bool mayStartBackward = departBwdArrivalDir != MSPModel::UNDEFINED_DIRECTION;
     215       276455 :     const double arrivalPos = partial && myArrived < 0 ? getEdgePos(SIMSTEP) : myArrivalPos;
     216       276455 :     const double lengthFwd = (length - myDepartPos - (
     217              :                                   departFwdArrivalDir == MSPModel::BACKWARD
     218       276455 :                                   ? arrivalPos
     219       276455 :                                   : myRoute.back()->getLength() - arrivalPos));
     220       276455 :     const double lengthBwd = (length - (myRoute.front()->getLength() - myDepartPos) - (
     221              :                                   departBwdArrivalDir == MSPModel::BACKWARD
     222       276455 :                                   ? arrivalPos
     223       276455 :                                   : myRoute.back()->getLength() - arrivalPos));
     224              :     //std::cout << " length=" << length << " lengthFwd=" << lengthFwd << " lengthBwd=" << lengthBwd << " mayStartForward=" << mayStartForward << " mayStartBackward=" << mayStartBackward << "\n";
     225              : 
     226       276455 :     if (myRoute.size() == 1) {
     227       134393 :         if (myDepartPos > myArrivalPos) {
     228              :             length = lengthBwd;
     229              :         } else {
     230              :             length = lengthFwd;
     231              :         }
     232              :     } else {
     233       142062 :         if (mayStartForward && mayStartBackward) {
     234        11035 :             length = lengthFwd < lengthBwd ? lengthFwd : lengthBwd;
     235       131027 :         } else if (mayStartForward) {
     236              :             length = lengthFwd;
     237        49204 :         } else if (mayStartBackward) {
     238              :             length = lengthBwd;
     239              :         } else {
     240              :             length = lengthFwd;
     241              :         }
     242              :     }
     243              :     //std::cout << SIMTIME << " route=" << toString(myRoute)
     244              :     //    << " depPos=" << myDepartPos << " arPos=" << myArrivalPos
     245              :     //    << " dFwdADir=" << departFwdArrivalDir
     246              :     //    << " dBwdADir=" << departBwdArrivalDir
     247              :     //    << " lengthFwd=" << lengthFwd
     248              :     //    << " lengthBwd=" << lengthBwd
     249              :     //    << "\n";
     250              : 
     251       276455 :     return MAX2(POSITION_EPS, length);
     252              : }
     253              : 
     254              : 
     255              : SUMOTime
     256       111040 : MSStageWalking::getTimeLoss(const MSTransportable* transportable) const {
     257       111040 :     SUMOTime timeLoss = myArrived == -1 ? 0 : getDuration() - TIME2STEPS(walkDistance(true) / getMaxSpeed(transportable));
     258       111040 :     if (timeLoss < 0 && timeLoss > TIME2STEPS(-0.1)) {
     259              :         // avoid negative timeLoss due to rounding errors
     260              :         timeLoss = 0;
     261              :     }
     262       111040 :     return timeLoss;
     263              : }
     264              : 
     265              : 
     266              : void
     267        55520 : MSStageWalking::tripInfoOutput(OutputDevice& os, const MSTransportable* const person) const {
     268        55520 :     if (!myWarnedInvalidTripinfo && MSNet::getInstance()->getPersonControl().getMovementModel()->usingShortcuts()) {
     269            0 :         WRITE_WARNING(TL("The pedestrian model uses infrastructure which is not in the network, timeLoss and routeLength may be invalid."));
     270            0 :         myWarnedInvalidTripinfo = true;
     271              :     }
     272        55520 :     const double distance = walkDistance(true);
     273        55520 :     const double maxSpeed = getMaxSpeed(person);
     274        55520 :     const SUMOTime duration = myArrived - myDeparted;
     275        55520 :     const SUMOTime timeLoss = getTimeLoss(person);
     276        55520 :     MSDevice_Tripinfo::addPedestrianData(distance, duration, timeLoss);
     277        55520 :     os.openTag("walk");
     278        55520 :     os.writeAttr("depart", myDeparted >= 0 ? time2string(myDeparted) : "-1");
     279        55520 :     os.writeAttr("departPos", myDepartPos);
     280        55520 :     os.writeAttr("arrival", myArrived >= 0 ? time2string(myArrived) : "-1");
     281        55520 :     os.writeAttr("arrivalPos", myArrived >= 0 ? toString(myArrivalPos) : "-1");
     282       110775 :     os.writeAttr("duration", myDeparted < 0 ? "-1" :
     283        55255 :                  time2string(myArrived >= 0 ? duration : MSNet::getInstance()->getCurrentTimeStep() - myDeparted));
     284        55520 :     os.writeAttr("routeLength", myArrived >= 0 ? toString(distance) : "-1");
     285        55520 :     os.writeAttr("timeLoss", time2string(timeLoss));
     286        55520 :     os.writeAttr("maxSpeed", maxSpeed);
     287        55520 :     os.writeAttr("waitingTime", time2string(getTotalWaitingTime()));
     288        55520 :     os.closeTag();
     289        55520 : }
     290              : 
     291              : 
     292              : void
     293         2425 : MSStageWalking::routeOutput(const bool /* isPerson */, OutputDevice& os, const bool withRouteLength, const MSStage* const /* previous */, const bool withTiming, const bool saveState) const {
     294         2425 :     os.openTag("walk").writeAttr(SUMO_ATTR_EDGES, myRoute);
     295         2425 :     std::string comment = "";
     296         2425 :     if (myDestinationStop != nullptr) {
     297          453 :         os.writeAttr(toString(myDestinationStop->getElement()), myDestinationStop->getID());
     298          453 :         if (myDestinationStop->getMyName() != "") {
     299          231 :             comment =  " <!-- " + StringUtils::escapeXML(myDestinationStop->getMyName(), true) + " -->";
     300              :         }
     301         1972 :     } else if (wasSet(VEHPARS_ARRIVALPOS_SET)) {
     302          166 :         os.writeAttr(SUMO_ATTR_ARRIVALPOS, myArrivalPos);
     303              :     }
     304         2425 :     if (myWalkingTime > 0) {
     305            0 :         os.writeAttr(SUMO_ATTR_DURATION, time2string(myWalkingTime));
     306         2425 :     } else if (mySpeed > 0) {
     307           24 :         os.writeAttr(SUMO_ATTR_SPEED, mySpeed);
     308              :     }
     309         2425 :     if (withRouteLength) {
     310           36 :         if (myDeparted >= 0) {
     311           36 :             os.writeAttr("routeLength", walkDistance(true));
     312              :         } else {
     313            0 :             os.writeAttr("routeLength", "-1");
     314              :         }
     315              :     }
     316         2425 :     if (myExitTimes != nullptr) {
     317              :         std::vector<std::string> exits;
     318          562 :         for (SUMOTime t : *myExitTimes) {
     319          780 :             exits.push_back(time2string(t));
     320              :         }
     321          344 :         std::vector<std::string> missing(MAX2(0, (int)myRoute.size() - (int)myExitTimes->size()), "-1");
     322          172 :         exits.insert(exits.end(), missing.begin(), missing.end());
     323          172 :         os.writeAttr("exitTimes", exits);
     324          172 :     }
     325         2425 :     if (withTiming) {
     326          194 :         os.writeAttr(SUMO_ATTR_STARTED, myDeparted >= 0 ? time2string(myDeparted) : "-1");
     327          194 :         os.writeAttr(SUMO_ATTR_ENDED, myArrived >= 0 ? time2string(myArrived) : "-1");
     328              :     }
     329         4850 :     if (OptionsCont::getOptions().getBool("vehroute-output.cost")) {
     330          105 :         os.writeAttr(SUMO_ATTR_COST, getCosts());
     331              :     }
     332         2425 :     if (saveState && getTotalWaitingTime() > 0) {
     333            2 :         os.writeAttr("waitingTime", time2string(getTotalWaitingTime()));
     334              :     }
     335         2425 :     os.closeTag(comment);
     336         2425 : }
     337              : 
     338              : 
     339              : bool
     340      2858144 : MSStageWalking::moveToNextEdge(MSTransportable* person, SUMOTime currentTime, int prevDir, MSEdge* nextInternal, const bool isReplay) {
     341      2858144 :     ((MSEdge*)getEdge())->removeTransportable(person);
     342      2858144 :     const MSLane* lane = getSidewalk<MSEdge, MSLane>(getEdge());
     343              :     const bool arrived = myRouteStep == myRoute.end() - 1;
     344      2858144 :     if (lane != nullptr) {
     345      2836265 :         const double tl = person->getVehicleType().getLength();
     346              :         const double lastPos = (arrived
     347      2836265 :                                 ? (prevDir == MSPModel::FORWARD
     348      4144288 :                                    ? getArrivalPos() + tl
     349      1983758 :                                    : getArrivalPos() - tl)
     350       675735 :                                 : person->getPositionOnLane());
     351      2836265 :         activateLeaveReminders(person, lane, lastPos, currentTime, arrived);
     352              :     }
     353      2858144 :     if (myExitTimes != nullptr && nextInternal == nullptr) {
     354          374 :         myExitTimes->push_back(currentTime);
     355              :     }
     356              :     myMoveReminders.clear();
     357      2858144 :     myLastEdgeEntryTime = currentTime;
     358              :     //std::cout << SIMTIME << " moveToNextEdge person=" << person->getID() << "\n";
     359      2858144 :     if (myCurrentInternalEdge != nullptr) {
     360       365596 :         myInternalDistance += (myPState->getPathLength() == 0 ? myCurrentInternalEdge->getLength() : myPState->getPathLength());
     361              :     }
     362      2858144 :     if (arrived) {
     363      2160556 :         MSPerson* p = dynamic_cast<MSPerson*>(person);
     364      2160556 :         if (!isReplay && p->hasInfluencer() && p->getInfluencer().isRemoteControlled()) {
     365      1941782 :             myCurrentInternalEdge = nextInternal;
     366      1941782 :             ((MSEdge*) getEdge())->addTransportable(person);
     367      1941782 :             return false;
     368              :         }
     369       218774 :         if (myDestinationStop != nullptr) {
     370        33582 :             myDestinationStop->addTransportable(person);
     371              :         }
     372       218774 :         if (isReplay) {
     373              :             // cannot do this in the replay device because the person might get deleted below
     374           40 :             MSNet::getInstance()->getPersonControl().getMovementModel()->remove(myPState);
     375              :         }
     376       218774 :         if (!person->proceed(MSNet::getInstance(), currentTime)) {
     377       212253 :             MSNet::getInstance()->getPersonControl().erase(person);
     378              :         }
     379              :         //std::cout << " end walk. myRouteStep=" << (*myRouteStep)->getID() << "\n";
     380       218774 :         return true;
     381              :     } else {
     382       697588 :         if (nextInternal == nullptr) {
     383              :             ++myRouteStep;
     384              :         }
     385       697588 :         myCurrentInternalEdge = nextInternal;
     386       697588 :         ((MSEdge*) getEdge())->addTransportable(person);
     387       697588 :         return false;
     388              :     }
     389              : }
     390              : 
     391              : 
     392              : void
     393      2866172 : MSStageWalking::activateEntryReminders(MSTransportable* person, const bool isDepart) {
     394      2866172 :     const MSLane* const nextLane = getSidewalk<MSEdge, MSLane>(getEdge());
     395      2866172 :     if (nextLane != nullptr) {
     396      3686446 :         for (MSMoveReminder* const rem : nextLane->getMoveReminders()) {
     397      1381615 :             if (rem->notifyEnter(*person, isDepart ? MSMoveReminder::NOTIFICATION_DEPARTED : MSMoveReminder::NOTIFICATION_JUNCTION, nextLane)) {
     398        18564 :                 myMoveReminders.push_back(rem);
     399              :             }
     400              :         }
     401              :     }
     402      5732344 :     if (hasParameter("rerouter")) {
     403              :         double minDist = std::numeric_limits<double>::max();
     404              :         MSTriggeredRerouter* nearest = nullptr;
     405          190 :         for (MSMoveReminder* const rem : myMoveReminders) {
     406          120 :             MSTriggeredRerouter* rerouter = dynamic_cast<MSTriggeredRerouter*>(rem);
     407          120 :             if (rerouter != nullptr) {
     408           70 :                 const double dist2 = rerouter->getPosition().distanceSquaredTo2D(person->getPosition());
     409           70 :                 if (dist2 < minDist) {
     410              :                     nearest = rerouter;
     411              :                     minDist = dist2;
     412              :                 }
     413              :             }
     414              :         }
     415           70 :         if (nearest != nullptr) {
     416           70 :             nearest->triggerRouting(*person, MSMoveReminder::NOTIFICATION_JUNCTION);
     417              :         }
     418              :         // TODO maybe removal of the reminders? Or can we rely on movetonextedge to clean everything up?
     419              :     }
     420      2866172 : }
     421              : 
     422              : 
     423              : void
     424            0 : MSStageWalking::activateMoveReminders(MSTransportable* person, double oldPos, double newPos, double newSpeed) {
     425            0 :     for (std::vector<MSMoveReminder*>::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
     426            0 :         if ((*rem)->notifyMove(*person, oldPos, newPos, newSpeed)) {
     427              :             ++rem;
     428              :         } else {
     429            0 :             rem = myMoveReminders.erase(rem);
     430              :         }
     431              :     }
     432            0 : }
     433              : 
     434              : 
     435              : void
     436      2836265 : MSStageWalking::activateLeaveReminders(MSTransportable* person, const MSLane* lane, double lastPos, SUMOTime t, bool arrived) {
     437      2836265 :     MSMoveReminder::Notification notification = arrived ? MSMoveReminder::NOTIFICATION_ARRIVED : MSMoveReminder::NOTIFICATION_JUNCTION;
     438      2853705 :     for (MSMoveReminder* const rem : myMoveReminders) {
     439        17440 :         rem->updateDetector(*person, 0.0, lane->getLength(), myLastEdgeEntryTime, t, t, true);
     440        17440 :         rem->notifyLeave(*person, lastPos, notification);
     441              :     }
     442      2836265 : }
     443              : 
     444              : 
     445              : int
     446       449288 : MSStageWalking::getRoutePosition() const {
     447       449288 :     return (int)(myRouteStep - myRoute.begin());
     448              : }
     449              : 
     450              : 
     451              : double
     452     22605730 : MSStageWalking::getMaxSpeed(const MSTransportable* const person) const {
     453     22605730 :     return mySpeed >= 0 ? mySpeed : person->getMaxSpeed();
     454              : }
     455              : 
     456              : std::string
     457            0 : MSStageWalking::getStageSummary(const bool /* isPerson */) const {
     458            0 :     const std::string dest = (getDestinationStop() == nullptr ?
     459            0 :                               " edge '" + getDestination()->getID() + "'" :
     460            0 :                               " stop '" + getDestinationStop()->getID() + "'" + (
     461            0 :                                   getDestinationStop()->getMyName() != "" ? " (" + getDestinationStop()->getMyName() + ")" : ""));
     462            0 :     return "walking to " + dest;
     463              : }
     464              : 
     465              : 
     466              : void
     467           32 : MSStageWalking::saveState(std::ostringstream& out, MSTransportable* /*transportable*/) {
     468           64 :     out << " " << myDeparted << " " << (myRouteStep - myRoute.begin()) << " " << myLastEdgeEntryTime;
     469           32 :     if (myExitTimes != nullptr) {
     470           12 :         out << " " << myExitTimes->size();
     471           18 :         for (SUMOTime t : *myExitTimes) {
     472              :             out << " " << t;
     473              :         }
     474              :     } else {
     475           20 :         out << " " << -1;
     476              :     }
     477           32 :     myPState->saveState(out);
     478           32 : }
     479              : 
     480              : 
     481              : void
     482           36 : MSStageWalking::loadState(MSTransportable* transportable, std::istringstream& state) {
     483              :     int stepIdx;
     484           36 :     state >> myDeparted >> stepIdx >> myLastEdgeEntryTime;
     485              :     int exitTimesSize;
     486           36 :     state >> exitTimesSize;
     487           36 :     if (exitTimesSize >= 0) {
     488           12 :         myExitTimes = new std::vector<SUMOTime>();
     489              :         SUMOTime t;
     490           18 :         for (int i = 0; i < exitTimesSize; i++) {
     491              :             state >> t;
     492            6 :             myExitTimes->push_back(t);
     493              :         }
     494           24 :         if (!OptionsCont::getOptions().getBool("vehroute-output.exit-times")) {
     495            0 :             delete myExitTimes;
     496            0 :             myExitTimes = nullptr;
     497              :         }
     498              :     }
     499           36 :     myRouteStep = myRoute.begin() + stepIdx;
     500           36 :     myPState = MSNet::getInstance()->getPersonControl().getMovementModel()->loadState(transportable, this, state);
     501           36 :     if (myPState->getLane() && !myPState->getLane()->isNormal()) {
     502            1 :         myCurrentInternalEdge = &myPState->getLane()->getEdge();
     503            1 :         myCurrentInternalEdge->addTransportable(transportable);
     504              :     } else {
     505           35 :         (*myRouteStep)->addTransportable(transportable);
     506              :     }
     507           36 : }
     508              : 
     509              : 
     510              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1