LCOV - code coverage report
Current view: top level - src/microsim/transportables - MSPerson.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 114 132 86.4 %
Date: 2024-05-07 15:28:01 Functions: 22 28 78.6 %

          Line data    Source code
       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             : /****************************************************************************/
      14             : /// @file    MSPerson.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             : // The class for modelling person-movements
      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 "MSStageWalking.h"
      49             : #include "MSPerson.h"
      50             : 
      51             : 
      52             : // ===========================================================================
      53             : // method definitions
      54             : // ===========================================================================
      55             : /* -------------------------------------------------------------------------
      56             : * MSPerson::MSPersonStage_Access - methods
      57             : * ----------------------------------------------------------------------- */
      58        5024 : MSPerson::MSPersonStage_Access::MSPersonStage_Access(const MSEdge* destination, MSStoppingPlace* toStop,
      59             :         const double arrivalPos, const double arrivalPosLat, const double dist, const bool isExit,
      60        5024 :         const Position& startPos, const Position& endPos) :
      61             :     MSStage(MSStageType::ACCESS, destination, toStop, arrivalPos, arrivalPosLat),
      62       10048 :     myDist(dist), myAmExit(isExit) {
      63        5024 :     myPath.push_back(startPos);
      64        5024 :     myPath.push_back(endPos);
      65        5024 : }
      66             : 
      67             : 
      68       10048 : MSPerson::MSPersonStage_Access::~MSPersonStage_Access() {}
      69             : 
      70             : MSStage*
      71           0 : MSPerson::MSPersonStage_Access::clone() const {
      72           0 :     return new MSPersonStage_Access(myDestination, myDestinationStop, myArrivalPos, myArrivalPosLat, myDist, myAmExit, myPath.front(), myPath.back());
      73             : }
      74             : 
      75             : void
      76        5024 : MSPerson::MSPersonStage_Access::proceed(MSNet* net, MSTransportable* person, SUMOTime now, MSStage* /* previous */) {
      77        5024 :     myDeparted = now;
      78        5024 :     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        5024 :     net->getBeginOfTimestepEvents()->addEvent(new ProceedCmd(person, &myDestinationStop->getLane().getEdge()), myEstimatedArrival);
      81        5024 :     net->getPersonControl().startedAccess();
      82        5024 :     myDestinationStop->getLane().getEdge().addTransportable(person);
      83        5024 : }
      84             : 
      85             : 
      86             : std::string
      87           0 : MSPerson::MSPersonStage_Access::getStageDescription(const bool /* isPerson */) const {
      88           0 :     return "access";
      89             : }
      90             : 
      91             : 
      92             : std::string
      93           0 : MSPerson::MSPersonStage_Access::getStageSummary(const bool /* isPerson */) const {
      94           0 :     return (myAmExit ? "access from stop '" : "access to stop '") + getDestinationStop()->getID() + "'";
      95             : }
      96             : 
      97             : 
      98             : Position
      99       20874 : MSPerson::MSPersonStage_Access::getPosition(SUMOTime now) const {
     100       20874 :     return myPath.positionAtOffset(myPath.length() * (double)(now - myDeparted) / (double)(myEstimatedArrival - myDeparted));
     101             : }
     102             : 
     103             : 
     104             : double
     105       18518 : MSPerson::MSPersonStage_Access::getAngle(SUMOTime /* now */) const {
     106       18518 :     return myPath.angleAt2D(0);
     107             : }
     108             : 
     109             : 
     110             : double
     111       17822 : MSPerson::MSPersonStage_Access::getSpeed() const {
     112       17822 :     return myDist / STEPS2TIME(MAX2((SUMOTime)1, myEstimatedArrival - myDeparted));
     113             : }
     114             : 
     115             : void
     116        4048 : MSPerson::MSPersonStage_Access::tripInfoOutput(OutputDevice& os, const MSTransportable* const) const {
     117        8096 :     os.openTag("access");
     118        4048 :     os.writeAttr("stop", getDestinationStop()->getID());
     119        8096 :     os.writeAttr("depart", time2string(myDeparted));
     120        8096 :     os.writeAttr("arrival", myArrived >= 0 ? time2string(myArrived) : "-1");
     121        8096 :     os.writeAttr("duration", myArrived > 0 ? time2string(getDuration()) : "-1");
     122        4048 :     os.writeAttr("routeLength", myDist);
     123        4048 :     os.closeTag();
     124        4048 : }
     125             : 
     126             : 
     127             : SUMOTime
     128        4992 : MSPerson::MSPersonStage_Access::ProceedCmd::execute(SUMOTime currentTime) {
     129        4992 :     MSNet::getInstance()->getPersonControl().endedAccess();
     130        4992 :     myStopEdge->removeTransportable(myPerson);
     131        4992 :     if (!myPerson->proceed(MSNet::getInstance(), currentTime)) {
     132          49 :         MSNet::getInstance()->getPersonControl().erase(myPerson);
     133             :     }
     134        4992 :     return 0;
     135             : }
     136             : 
     137             : 
     138             : /* -------------------------------------------------------------------------
     139             :  * MSPerson - methods
     140             :  * ----------------------------------------------------------------------- */
     141      318296 : MSPerson::MSPerson(const SUMOVehicleParameter* pars, MSVehicleType* vtype, MSTransportable::MSTransportablePlan* plan, const double speedFactor) :
     142             :     MSTransportable(pars, vtype, plan, true),
     143      318296 :     myInfluencer(nullptr),
     144      318296 :     myChosenSpeedFactor(pars->speedFactor < 0 ? speedFactor : pars->speedFactor)
     145      318296 : { }
     146             : 
     147             : 
     148      611169 : MSPerson::~MSPerson() {
     149      318251 :     delete myInfluencer;
     150      611169 : }
     151             : 
     152             : 
     153             : bool
     154      596894 : MSPerson::checkAccess(const MSStage* const prior, const bool waitAtStop) {
     155             :     MSStoppingPlace* prevStop = prior->getDestinationStop();
     156      596894 :     if (!waitAtStop && prior->getStageType() == MSStageType::TRIP) {
     157      233328 :         prevStop = prior->getOriginStop();
     158             :     }
     159      596894 :     if (prevStop != nullptr) {
     160       45479 :         const MSEdge* const accessEdge = waitAtStop ? prior->getDestination() : (*myStep)->getFromEdge();
     161       45479 :         const MSStoppingPlace::Access* const access = prevStop->getAccess(accessEdge);
     162       45479 :         if (access != nullptr) {
     163        5024 :             const MSLane* const lane = accessEdge->getLanes()[0];
     164        5024 :             MSStage* newStage = nullptr;
     165        5024 :             if (waitAtStop) {
     166        2574 :                 const MSEdge* const stopEdge = &prevStop->getLane().getEdge();
     167        2574 :                 const double arrivalAtBs = (prevStop->getBeginLanePosition() + prevStop->getEndLanePosition()) / 2;
     168        2574 :                 newStage = new MSPersonStage_Access(stopEdge, prevStop, arrivalAtBs, 0.0, access->length, false,
     169        2574 :                                                     lane->geometryPositionAtOffset(access->endPos),
     170        5148 :                                                     prevStop->getLane().geometryPositionAtOffset(arrivalAtBs));
     171             :             } else {
     172        2450 :                 const OptionsCont& oc = OptionsCont::getOptions();
     173        4900 :                 const std::string model = oc.getString("pedestrian.model");
     174        2450 :                 if (model != "jupedsim") {
     175        2450 :                     const double startPos = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePos(0) : prior->getArrivalPos();
     176        2450 :                     const Position& trainExit = prevStop->getLane().geometryPositionAtOffset(startPos);
     177        2450 :                     const double arrivalPos = access->useDoors ? lane->getShape().nearest_offset_to_point2D(trainExit) : access->endPos;
     178             :                     Position platformEntry = lane->geometryPositionAtOffset(arrivalPos);
     179        2450 :                     if (access->useDoors) {
     180             :                         // find the closer side of the platform to enter
     181         900 :                         const double halfWidth = lane->getWidth() / 2. - MAX2(getVehicleType().getLength(), getVehicleType().getWidth()) / 2. - POSITION_EPS;
     182         450 :                         platformEntry = lane->geometryPositionAtOffset(arrivalPos, halfWidth);
     183         450 :                         const Position& plat2 = lane->geometryPositionAtOffset(arrivalPos, -halfWidth);
     184         450 :                         if (trainExit.distanceSquaredTo2D(plat2) < trainExit.distanceSquaredTo2D(platformEntry)) {
     185         356 :                             platformEntry = plat2;
     186             :                         }
     187             :                     }
     188        2450 :                     newStage = new MSPersonStage_Access(accessEdge, prevStop, arrivalPos, 0.0, access->length, true,
     189        2450 :                                                         trainExit, platformEntry);
     190             :                 } else {
     191           0 :                     const double startPos = prior->getStageType() == MSStageType::TRIP ? prior->getEdgePos(0) : prior->getArrivalPos();
     192           0 :                     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           0 :                     const Position start = prevStop->getLane().geometryPositionAtOffset(startPos, startPosLat);
     196           0 :                     const Position end = lane->getShape().transformToVectorCoordinates(start);
     197           0 :                     newStage = new MSPersonStage_Access(accessEdge, prevStop, end.x(), -end.y(), access->length, true, start, start);
     198             :                 }
     199             :             }
     200        5024 :             myStep = myPlan->insert(myStep, newStage);
     201             :             return true;
     202             :         }
     203             :     }
     204             :     return false;
     205             : }
     206             : 
     207             : 
     208             : double
     209           0 : MSPerson::getImpatience() const {
     210           0 :     return MAX2(0., MIN2(1., getVehicleType().getImpatience()
     211           0 :                          + STEPS2TIME((*myStep)->getWaitingTime(SIMSTEP)) / MSPModel_Striping::MAX_WAIT_TOLERANCE));
     212             : }
     213             : 
     214             : const std::string&
     215         315 : MSPerson::getNextEdge() const {
     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         315 :     const MSEdge* nextEdge = getNextEdgePtr();
     226         315 :     if (nextEdge != nullptr) {
     227         313 :         return nextEdge->getID();
     228             :     }
     229             :     return StringUtils::emptyString;
     230             : }
     231             : 
     232             : 
     233             : const MSEdge*
     234      164053 : MSPerson::getNextEdgePtr() const {
     235      164053 :     if (getCurrentStageType() == MSStageType::WALKING) {
     236      164053 :         MSStageWalking* walkingStage =  dynamic_cast<MSStageWalking*>(*myStep);
     237             :         assert(walkingStage != nullptr);
     238      164053 :         return walkingStage->getPState()->getNextEdge(*walkingStage);
     239             :     }
     240             :     return nullptr;
     241             : }
     242             : 
     243             : 
     244             : 
     245             : void
     246        1514 : 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        1514 :     MSStage* toBeReplaced = getNextStage(nextIndex - 1);
     256        1514 :     if (newEdges.back() != toBeReplaced->getDestination()) {
     257             : 
     258             :     }
     259             :     MSStageWalking* newStage = new MSStageWalking(getID(), newEdges,
     260             :             toBeReplaced->getDestinationStop(), -1,
     261             :             -1,
     262             :             departPos,
     263        1514 :             toBeReplaced->getArrivalPos(),
     264        1514 :             MSPModel::UNSPECIFIED_POS_LAT);
     265        1514 :     appendStage(newStage, nextIndex);
     266             :     // remove stages in reverse order so that proceed will only be called at the last removal
     267        3034 :     for (int i = nextIndex - 1; i >= firstIndex; i--) {
     268             :         //std::cout << " removeStage=" << i << "\n";
     269        1520 :         removeStage(i);
     270             :     }
     271        1514 : }
     272             : 
     273             : 
     274             : MSPerson::Influencer&
     275       67981 : MSPerson::getInfluencer() {
     276       67981 :     if (myInfluencer == nullptr) {
     277         242 :         myInfluencer = new Influencer();
     278             :     }
     279       67981 :     return *myInfluencer;
     280             : }
     281             : 
     282             : 
     283             : const MSPerson::Influencer*
     284           0 : MSPerson::getInfluencer() const {
     285           0 :     return myInfluencer;
     286             : }
     287             : 
     288             : 
     289             : 
     290             : /* -------------------------------------------------------------------------
     291             :  * methods of MSPerson::Influencer
     292             :  * ----------------------------------------------------------------------- */
     293         121 : MSPerson::Influencer::Influencer() {}
     294             : 
     295             : 
     296         121 : MSPerson::Influencer::~Influencer() {}
     297             : 
     298             : 
     299             : void
     300       16339 : MSPerson::Influencer::setRemoteControlled(Position xyPos, MSLane* l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t) {
     301       16339 :     myRemoteXYPos = xyPos;
     302       16339 :     myRemoteLane = l;
     303       16339 :     myRemotePos = pos;
     304       16339 :     myRemotePosLat = posLat;
     305       16339 :     myRemoteAngle = angle;
     306       16339 :     myRemoteEdgeOffset = edgeOffset;
     307       16339 :     myRemoteRoute = route;
     308       16339 :     myLastRemoteAccess = t;
     309       16339 : }
     310             : 
     311             : 
     312             : bool
     313       35303 : MSPerson::Influencer::isRemoteControlled() const {
     314       35303 :     return myLastRemoteAccess == MSNet::getInstance()->getCurrentTimeStep();
     315             : }
     316             : 
     317             : 
     318             : bool
     319           0 : MSPerson::Influencer::isRemoteAffected(SUMOTime t) const {
     320           0 :     return myLastRemoteAccess >= t - TIME2STEPS(10);
     321             : }
     322             : 
     323             : 
     324             : void
     325       16339 : MSPerson::Influencer::postProcessRemoteControl(MSPerson* p) {
     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       16339 :     switch (p->getStageType(0)) {
     339             :         case MSStageType::WALKING: {
     340       16339 :             MSStageWalking* s = dynamic_cast<MSStageWalking*>(p->getCurrentStage());
     341             :             assert(s != nullptr);
     342       16339 :             s->getPState()->moveToXY(p, myRemoteXYPos, myRemoteLane, myRemotePos, myRemotePosLat,
     343       16339 :                                      myRemoteAngle, myRemoteEdgeOffset, myRemoteRoute,
     344             :                                      MSNet::getInstance()->getCurrentTimeStep());
     345             :         }
     346       16339 :         break;
     347             :         default:
     348             :             break;
     349             :     }
     350       16339 : }
     351             : 
     352             : 
     353             : /****************************************************************************/

Generated by: LCOV version 1.14