LCOV - code coverage report
Current view: top level - src/microsim/transportables - MSPModel_NonInteracting.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 103 103 100.0 %
Date: 2024-05-06 15:32:35 Functions: 22 22 100.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2014-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    MSPModel_NonInteracting.cpp
      15             : /// @author  Jakob Erdmann
      16             : /// @date    Mon, 13 Jan 2014
      17             : ///
      18             : // The pedestrian following model (prototype)
      19             : /****************************************************************************/
      20             : #include <config.h>
      21             : 
      22             : #include <cmath>
      23             : #include <algorithm>
      24             : #include <utils/common/RandHelper.h>
      25             : #include <utils/geom/GeomHelper.h>
      26             : #include <utils/options/OptionsCont.h>
      27             : #include <utils/router/IntermodalNetwork.h>
      28             : #include <microsim/MSGlobals.h>
      29             : #include <microsim/MSNet.h>
      30             : #include <microsim/MSEdge.h>
      31             : #include <microsim/MSLane.h>
      32             : #include <microsim/MSJunction.h>
      33             : #include <microsim/MSEventControl.h>
      34             : #include "MSPModel_NonInteracting.h"
      35             : 
      36             : 
      37             : // ===========================================================================
      38             : // DEBUGGING HELPERS
      39             : // ===========================================================================
      40             : #define DEBUG1 "disabled"
      41             : #define DEBUG2 "disabled"
      42             : #define DEBUGCOND(PEDID) (PEDID == DEBUG1 || PEDID == DEBUG2)
      43             : 
      44             : 
      45             : // ===========================================================================
      46             : // static members
      47             : // ===========================================================================
      48             : const double MSPModel_NonInteracting::CState::LATERAL_OFFSET(0);
      49             : 
      50             : // ===========================================================================
      51             : // MSPModel_NonInteracting method definitions
      52             : // ===========================================================================
      53        5601 : MSPModel_NonInteracting::MSPModel_NonInteracting(const OptionsCont& oc, MSNet* net) :
      54        5601 :     myNet(net),
      55        5601 :     myNumActivePedestrians(0) {
      56             :     assert(myNet != 0);
      57             :     UNUSED_PARAMETER(oc);
      58        5601 : }
      59             : 
      60             : 
      61       11166 : MSPModel_NonInteracting::~MSPModel_NonInteracting() {
      62       11166 : }
      63             : 
      64             : 
      65             : MSTransportableStateAdapter*
      66      132561 : MSPModel_NonInteracting::add(MSTransportable* transportable, MSStageMoving* stage, SUMOTime now) {
      67      132561 :     myNumActivePedestrians++;
      68      132561 :     MoveToNextEdge* const cmd = new MoveToNextEdge(transportable, *stage, this);
      69      132561 :     PState* const state = transportable->isPerson() ? new PState(cmd) : new CState(cmd);
      70      132561 :     myNet->getBeginOfTimestepEvents()->addEvent(cmd, now + state->computeDuration(nullptr, *stage, now));
      71      132561 :     return state;
      72             : }
      73             : 
      74             : 
      75             : MSTransportableStateAdapter*
      76          13 : MSPModel_NonInteracting::loadState(MSTransportable* transportable, MSStageMoving* stage, std::istringstream& in) {
      77          13 :     myNumActivePedestrians++;
      78          13 :     MoveToNextEdge* const cmd = new MoveToNextEdge(transportable, *stage, this);
      79          13 :     PState* const state = transportable->isPerson() ? new PState(cmd, &in) : new CState(cmd, &in);
      80          13 :     myNet->getBeginOfTimestepEvents()->addEvent(cmd, state->getEventTime());
      81          13 :     return state;
      82             : }
      83             : 
      84             : void
      85        5599 : MSPModel_NonInteracting::clearState() {
      86        5599 :     myNumActivePedestrians = 0;
      87        5599 : }
      88             : 
      89             : void
      90         429 : MSPModel_NonInteracting::remove(MSTransportableStateAdapter* state) {
      91         429 :     myNumActivePedestrians--;
      92         429 :     dynamic_cast<PState*>(state)->getCommand()->abortWalk();
      93         429 : }
      94             : 
      95             : 
      96             : // ---------------------------------------------------------------------------
      97             : // MSPModel_NonInteracting::MoveToNextEdge method definitions
      98             : // ---------------------------------------------------------------------------
      99             : SUMOTime
     100      143854 : MSPModel_NonInteracting::MoveToNextEdge::execute(SUMOTime currentTime) {
     101      143854 :     if (myTransportable == nullptr) {
     102             :         return 0; // descheduled
     103             :     }
     104      143428 :     const MSEdge* old = myParent.getEdge();
     105      143428 :     const bool arrived = myParent.moveToNextEdge(myTransportable, currentTime, myParent.getPState()->getDirection(myParent, currentTime));
     106      143428 :     if (arrived) {
     107      131901 :         myModel->registerArrived();
     108      131901 :         return 0;
     109             :     }
     110       11527 :     myParent.activateEntryReminders(myTransportable);
     111       11527 :     return static_cast<PState*>(myParent.getPState())->computeDuration(old, myParent, currentTime);
     112             : }
     113             : 
     114             : 
     115             : // ---------------------------------------------------------------------------
     116             : // MSPModel_NonInteracting::PState method definitions
     117             : // ---------------------------------------------------------------------------
     118      132574 : MSPModel_NonInteracting::PState::PState(MoveToNextEdge* cmd, std::istringstream* in) : myCommand(cmd) {
     119      132574 :     if (in != nullptr) {
     120          13 :         (*in) >> myLastEntryTime >> myCurrentDuration;
     121             :     }
     122      132574 : }
     123             : 
     124             : 
     125             : SUMOTime
     126       34540 : MSPModel_NonInteracting::PState::computeDuration(const MSEdge* prev, const MSStageMoving& stage, SUMOTime currentTime) {
     127       34540 :     myLastEntryTime = currentTime;
     128       34540 :     const MSEdge* edge = stage.getEdge();
     129       34540 :     const MSEdge* next = stage.getNextRouteEdge();
     130       34540 :     int dir = UNDEFINED_DIRECTION;
     131       34540 :     if (prev == nullptr) {
     132       23013 :         myCurrentBeginPos = stage.getDepartPos();
     133             :     } else {
     134             :         // default to FORWARD if not connected
     135       11527 :         dir = (edge->getToJunction() == prev->getToJunction() || edge->getToJunction() == prev->getFromJunction()) ? BACKWARD : FORWARD;
     136       14074 :         myCurrentBeginPos = dir == FORWARD ? 0 : edge->getLength();
     137             :     }
     138       34540 :     if (next == nullptr) {
     139       22487 :         myCurrentEndPos = stage.getArrivalPos();
     140             :     } else {
     141       12053 :         if (dir == UNDEFINED_DIRECTION) {
     142             :             // default to FORWARD if not connected
     143        7995 :             dir = (edge->getFromJunction() == next->getFromJunction() || edge->getFromJunction() == next->getToJunction()) ? BACKWARD : FORWARD;
     144             :         }
     145       21616 :         myCurrentEndPos = dir == FORWARD ? edge->getLength() : 0;
     146             :     }
     147             :     // ensure that a result > 0 is returned even if the walk ends immediately
     148             :     // adding 0.5ms is done to ensure proper rounding
     149       34540 :     myCurrentDuration = MAX2((SUMOTime)1, TIME2STEPS(fabs(myCurrentEndPos - myCurrentBeginPos) / stage.getMaxSpeed(myCommand->getTransportable())));
     150             :     //std::cout << std::setprecision(8) << SIMTIME << " curBeg=" << myCurrentBeginPos << " curEnd=" << myCurrentEndPos << " speed=" << stage.getMaxSpeed(myCommand->getTransportable()) << " dur=" << myCurrentDuration << "\n";
     151             :     // round to the next timestep to avoid systematic higher walking speed
     152       34540 :     if ((myCurrentDuration % DELTA_T) > 0) {
     153       28563 :         myCurrentDuration += DELTA_T;
     154             :     }
     155       34540 :     return myCurrentDuration;
     156             : }
     157             : 
     158             : 
     159             : double
     160      946382 : MSPModel_NonInteracting::PState::getEdgePos(const MSStageMoving&, SUMOTime now) const {
     161             :     //std::cout << SIMTIME << " lastEntryTime=" << myLastEntryTime << " pos=" << (myCurrentBeginPos + (myCurrentEndPos - myCurrentBeginPos) / myCurrentDuration * (now - myLastEntryTime)) << "\n";
     162      946382 :     return myCurrentBeginPos + (myCurrentEndPos - myCurrentBeginPos) / (double)myCurrentDuration * (double)(now - myLastEntryTime);
     163             : }
     164             : 
     165             : int
     166      143428 : MSPModel_NonInteracting::PState::getDirection(const MSStageMoving& /*stage*/, SUMOTime /*now*/) const {
     167      143428 :     if (myCurrentBeginPos == myCurrentEndPos) {
     168        2284 :         return UNDEFINED_DIRECTION;
     169             :     } else {
     170      141144 :         return myCurrentBeginPos < myCurrentEndPos ? FORWARD : BACKWARD;
     171             :     }
     172             : }
     173             : 
     174             : 
     175             : Position
     176      190918 : MSPModel_NonInteracting::PState::getPosition(const MSStageMoving& stage, SUMOTime now) const {
     177      190918 :     const MSLane* lane = getSidewalk<MSEdge, MSLane>(stage.getEdge());
     178      190918 :     if (lane == nullptr) {
     179             :         //std::string error = "Pedestrian '" + myCommand->myPerson->getID() + "' could not find sidewalk on edge '" + state.getEdge()->getID() + "', time="
     180             :         //    + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".";
     181             :         //if (!OptionsCont::getOptions().getBool("ignore-route-errors")) {
     182             :         //    throw ProcessError(error);
     183             :         //}
     184         172 :         lane = stage.getEdge()->getLanes().front();
     185             :     }
     186      191090 :     const double lateral_offset = (lane->allowsVehicleClass(SVC_PEDESTRIAN) ? 0 : SIDEWALK_OFFSET
     187         172 :                                    * (MSGlobals::gLefthand ? -1 : 1));
     188      190918 :     return stage.getLanePosition(lane, getEdgePos(stage, now), lateral_offset);
     189             : }
     190             : 
     191             : 
     192             : double
     193      117336 : MSPModel_NonInteracting::PState::getAngle(const MSStageMoving& stage, SUMOTime now) const {
     194             :     //std::cout << SIMTIME << " rawAngle=" << stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) << " angle=" << stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) + (myCurrentEndPos < myCurrentBeginPos ? 180 : 0) << "\n";
     195      117336 :     double angle = stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) + (myCurrentEndPos < myCurrentBeginPos ? M_PI : 0);
     196      117336 :     if (angle > M_PI) {
     197        3463 :         angle -= 2 * M_PI;
     198             :     }
     199      117336 :     return angle;
     200             : }
     201             : 
     202             : 
     203             : SUMOTime
     204           2 : MSPModel_NonInteracting::PState::getWaitingTime(const MSStageMoving&, SUMOTime) const {
     205           2 :     return 0;
     206             : }
     207             : 
     208             : 
     209             : double
     210      184586 : MSPModel_NonInteracting::PState::getSpeed(const MSStageMoving& stage) const {
     211      184586 :     return stage.getMaxSpeed(myCommand->getTransportable());
     212             : }
     213             : 
     214             : 
     215             : const MSEdge*
     216           1 : MSPModel_NonInteracting::PState::getNextEdge(const MSStageMoving& stage) const {
     217           1 :     return stage.getNextRouteEdge();
     218             : }
     219             : 
     220             : 
     221             : void
     222          13 : MSPModel_NonInteracting::PState::saveState(std::ostringstream& out) {
     223          26 :     out << " " << myLastEntryTime << " " << myCurrentDuration;
     224          13 : }
     225             : 
     226             : 
     227             : // ---------------------------------------------------------------------------
     228             : // MSPModel_NonInteracting::CState method definitions
     229             : // ---------------------------------------------------------------------------
     230      109548 : MSPModel_NonInteracting::CState::CState(MoveToNextEdge* cmd, std::istringstream* in) : PState(cmd, in) {
     231      109548 : }
     232             : 
     233             : 
     234             : Position
     235          67 : MSPModel_NonInteracting::CState::getPosition(const MSStageMoving& stage, SUMOTime now) const {
     236             :     const double dist = myCurrentBeginPosition.distanceTo2D(myCurrentEndPosition);    //distance between begin and end position of this tranship stage
     237          67 :     double pos = MIN2(STEPS2TIME(now - myLastEntryTime) * stage.getMaxSpeed(), dist);    //the container shall not go beyond its end position
     238          67 :     return PositionVector::positionAtOffset2D(myCurrentBeginPosition, myCurrentEndPosition, pos, 0);
     239             : }
     240             : 
     241             : 
     242             : double
     243          67 : MSPModel_NonInteracting::CState::getAngle(const MSStageMoving& stage, SUMOTime now) const {
     244          67 :     double angle = stage.getEdgeAngle(stage.getEdge(), getEdgePos(stage, now)) + (myCurrentEndPos < myCurrentBeginPos ? 1.5 * M_PI : 0.5 * M_PI);
     245          67 :     if (angle > M_PI) {
     246          19 :         angle -= 2 * M_PI;
     247             :     }
     248          67 :     return angle;
     249             : }
     250             : 
     251             : 
     252             : SUMOTime
     253      109548 : MSPModel_NonInteracting::CState::computeDuration(const MSEdge* /* prev */, const MSStageMoving& stage, SUMOTime currentTime) {
     254      109548 :     myLastEntryTime = currentTime;
     255             : 
     256      109548 :     myCurrentBeginPos = stage.getDepartPos();
     257      109548 :     myCurrentEndPos = stage.getArrivalPos();
     258             : 
     259      109548 :     const MSLane* fromLane = stage.getFromEdge()->getLanes().front(); //the lane the container starts from during its tranship stage
     260      109548 :     myCurrentBeginPosition = stage.getLanePosition(fromLane, myCurrentBeginPos, LATERAL_OFFSET);
     261      109548 :     const MSLane* toLane = stage.getEdges().back()->getLanes().front(); //the lane the container ends during its tranship stage
     262      109548 :     myCurrentEndPosition = stage.getLanePosition(toLane, myCurrentEndPos, LATERAL_OFFSET);
     263             : 
     264      109548 :     myCurrentDuration = MAX2((SUMOTime)1, TIME2STEPS(fabs(myCurrentEndPosition.distanceTo(myCurrentBeginPosition)) / stage.getMaxSpeed()));
     265      109548 :     return myCurrentDuration;
     266             : }
     267             : 
     268             : 
     269             : /****************************************************************************/

Generated by: LCOV version 1.14