LCOV - code coverage report
Current view: top level - src/microsim/transportables - MSStageTrip.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 90.4 % 239 216
Test Date: 2026-09-20 15:45:03 Functions: 82.4 % 17 14

            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    MSStageTrip.cpp
      15              : /// @author  Melanie Weber
      16              : /// @author  Andreas Kendziorra
      17              : /// @author  Michael Behrisch
      18              : /// @author  Jakob Erdmann
      19              : /// @date    Wed, 1 Jun 2022
      20              : ///
      21              : // An intermodal routing request (to be transformed into a sequence of walks and rides)
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <utils/common/StringTokenizer.h>
      26              : #include <utils/geom/GeomHelper.h>
      27              : #include <utils/options/OptionsCont.h>
      28              : #include <utils/vehicle/SUMOVehicleParameter.h>
      29              : #include <utils/router/PedestrianRouter.h>
      30              : #include <utils/router/IntermodalRouter.h>
      31              : #include <microsim/MSEdge.h>
      32              : #include <microsim/MSEdgeControl.h>
      33              : #include <microsim/devices/MSRoutingEngine.h>
      34              : #include <microsim/MSLane.h>
      35              : #include <microsim/MSNet.h>
      36              : #include <microsim/MSStoppingPlace.h>
      37              : #include <microsim/MSVehicleControl.h>
      38              : #include <microsim/devices/MSDevice_Taxi.h>
      39              : #include <microsim/transportables/MSStageDriving.h>
      40              : #include <microsim/transportables/MSStageWaiting.h>
      41              : #include <microsim/transportables/MSStageWalking.h>
      42              : #include <microsim/transportables/MSTransportable.h>
      43              : #include <microsim/transportables/MSTransportableControl.h>
      44              : #include <microsim/transportables/MSPerson.h>
      45              : #include <microsim/transportables/MSStageTrip.h>
      46              : 
      47              : 
      48              : // ===========================================================================
      49              : // static members
      50              : // ===========================================================================
      51              : #ifndef THREAD_POOL
      52              : #ifdef HAVE_FOX
      53              : FXMutex MSStageTrip::myVehCtrlMutex;
      54              : #endif
      55              : #endif
      56              : 
      57              : 
      58              : // ===========================================================================
      59              : // method definitions
      60              : // ===========================================================================
      61              : 
      62              : /* -------------------------------------------------------------------------
      63              : * MSStageTrip - methods
      64              : * ----------------------------------------------------------------------- */
      65       187292 : MSStageTrip::MSStageTrip(const MSEdge* origin, MSStoppingPlace* fromStop,
      66              :                          const MSEdge* destination, MSStoppingPlace* toStop,
      67              :                          const SUMOTime duration, const SVCPermissions modeSet,
      68              :                          const std::string& vTypes, const double speed, const double walkFactor,
      69              :                          const std::string& group,
      70       187292 :                          const double departPosLat, const bool hasArrivalPos, const double arrivalPos):
      71              :     MSStage(MSStageType::TRIP, destination, toStop, arrivalPos, 0.0, group),
      72       187292 :     myOrigin(origin),
      73       187292 :     myOriginStop(fromStop),
      74       187292 :     myDuration(duration),
      75       187292 :     myModeSet(modeSet),
      76       187292 :     myVTypes(vTypes),
      77       187292 :     mySpeed(speed),
      78       187292 :     myWalkFactor(walkFactor),
      79       187292 :     myDepartPosLat(departPosLat),
      80       374584 :     myHaveArrivalPos(hasArrivalPos) {
      81       187292 : }
      82              : 
      83              : 
      84       374574 : MSStageTrip::~MSStageTrip() {}
      85              : 
      86              : MSStage*
      87       178451 : MSStageTrip::clone() const {
      88       178451 :     MSStage* const clon = new MSStageTrip(myOrigin, const_cast<MSStoppingPlace*>(myOriginStop),
      89       178451 :                                           myDestination, myDestinationStop, myDuration,
      90       178451 :                                           myModeSet, myVTypes, mySpeed, myWalkFactor, myGroup,
      91       178451 :                                           myDepartPosLat, myHaveArrivalPos, myArrivalPos);
      92       178451 :     clon->setParameters(*this);
      93       178451 :     return clon;
      94              : }
      95              : 
      96              : 
      97              : Position
      98            0 : MSStageTrip::getPosition(SUMOTime /* now */) const {
      99              :     // may be called concurrently while the trip is still being routed
     100            0 :     return getEdgePosition(myOrigin, myDepartPos, ROADSIDE_OFFSET * (MSGlobals::gLefthand ? -1 : 1));
     101              : }
     102              : 
     103              : 
     104              : double
     105            0 : MSStageTrip::getAngle(SUMOTime /* now */) const {
     106              :     // may be called concurrently while the trip is still being routed
     107            0 :     return getEdgeAngle(myOrigin, myDepartPos) + M_PI / 2 * (MSGlobals::gLefthand ? -1 : 1);
     108              : }
     109              : 
     110              : 
     111              : const MSEdge*
     112       343429 : MSStageTrip::getEdge() const {
     113       343429 :     return myOrigin;
     114              : }
     115              : 
     116              : 
     117              : double
     118       330030 : MSStageTrip::getEdgePos(SUMOTime /* now */) const {
     119       330030 :     return myDepartPos;
     120              : }
     121              : 
     122              : 
     123              : std::vector<SUMOVehicle*>
     124       166578 : MSStageTrip::getVehicles(MSVehicleControl& vehControl, MSTransportable* transportable, const MSEdge* origin) {
     125              :     std::vector<SUMOVehicleParameter*> pars;
     126       333282 :     for (StringTokenizer st(myVTypes); st.hasNext();) {
     127          126 :         pars.push_back(new SUMOVehicleParameter());
     128          252 :         pars.back()->vtypeid = st.next();
     129          126 :         pars.back()->parametersSet |= VEHPARS_VTYPE_SET;
     130          126 :         pars.back()->departProcedure = DepartDefinition::TRIGGERED;
     131          252 :         pars.back()->id = transportable->getID() + "_" + toString(pars.size() - 1);
     132       166578 :     }
     133       166578 :     if (pars.empty()) {
     134       166457 :         if ((myModeSet & SVC_PASSENGER) != 0) {
     135         1852 :             pars.push_back(new SUMOVehicleParameter());
     136         3704 :             pars.back()->id = transportable->getID() + "_0";
     137         1852 :             pars.back()->departProcedure = DepartDefinition::TRIGGERED;
     138              :         }
     139       166457 :         if ((myModeSet & SVC_TAXI) != 0) {
     140          502 :             for (const auto& item : MSDevice_Taxi::getTaxiTypes()) {
     141          277 :                 pars.push_back(new SUMOVehicleParameter());
     142          277 :                 pars.back()->vtypeid = item.second;
     143          831 :                 pars.back()->id = transportable->getID() + "_taxi_" + item.second;
     144          277 :                 pars.back()->line = "taxi";
     145              :             }
     146              :         }
     147       166457 :         if ((myModeSet & SVC_BICYCLE) != 0) {
     148           37 :             pars.push_back(new SUMOVehicleParameter());
     149           37 :             pars.back()->vtypeid = DEFAULT_BIKETYPE_ID;
     150           74 :             pars.back()->id = transportable->getID() + "_b0";
     151           37 :             pars.back()->departProcedure = DepartDefinition::TRIGGERED;
     152              :         }
     153              :     }
     154       333156 :     ConstMSRoutePtr const routeDummy = std::make_shared<MSRoute>(transportable->getID() + "_0", ConstMSEdgeVector({ origin }), false, nullptr, StopParVector());
     155              :     std::vector<SUMOVehicle*> result;
     156       168870 :     for (SUMOVehicleParameter* vehPar : pars) {
     157         2292 :         const bool isTaxi = vehPar->line == "taxi" && (myModeSet & SVC_TAXI) != 0;
     158         2292 :         if (myDepartPos != 0) {
     159          156 :             vehPar->departPosProcedure = DepartPosDefinition::GIVEN;
     160          156 :             vehPar->departPos = myDepartPos;
     161          156 :             vehPar->parametersSet |= VEHPARS_DEPARTPOS_SET;
     162              :         }
     163         2292 :         vehPar->parametersSet |= VEHPARS_ARRIVALPOS_SET;
     164         2292 :         vehPar->arrivalPosProcedure = ArrivalPosDefinition::GIVEN;
     165         2292 :         vehPar->parametersSet |= VEHPARS_ARRIVALSPEED_SET;
     166         2292 :         vehPar->arrivalSpeedProcedure = ArrivalSpeedDefinition::GIVEN;
     167         2292 :         vehPar->arrivalSpeed = 0;
     168         2292 :         MSVehicleType* type = vehControl.getVType(vehPar->vtypeid);
     169         2292 :         if (type->getVehicleClass() != SVC_IGNORING && (origin->getPermissions() & type->getVehicleClass()) == 0 && !isTaxi) {
     170          120 :             WRITE_WARNINGF(TL("Ignoring vehicle type '%' when routing person '%' because it is not allowed on the start edge."), type->getID(), transportable->getID());
     171           40 :             delete vehPar;
     172              :         } else {
     173         4504 :             result.push_back(vehControl.buildVehicle(vehPar, routeDummy, type, !MSGlobals::gCheckRoutes));
     174              :         }
     175              :     }
     176       166578 :     if (result.empty()) {
     177              :         // walking only but may use access infrastructure
     178       164413 :         result.push_back(nullptr);
     179              :     }
     180       166578 :     return result;
     181       166578 : }
     182              : 
     183              : 
     184              : const std::string
     185       166578 : MSStageTrip::reroute(const SUMOTime time, MSTransportableRouter& router, MSTransportable* const transportable,
     186              :                      MSStage* previous, const MSEdge* origin, const MSEdge* destination, std::vector<MSStage*>& stages) {
     187       166578 :     if (origin->isTazConnector() && origin->getSuccessors().size() == 0) {
     188              :         // previous stage ended at a taz sink-edge
     189          296 :         origin = transportable->getNextStage(-1)->getDestination();
     190              :     }
     191       166578 :     MSVehicleControl& vehControl = MSNet::getInstance()->getVehicleControl();
     192              :     double minCost = std::numeric_limits<double>::max();
     193              :     std::vector<MSTransportableRouter::TripItem> minResult;
     194              :     SUMOVehicle* minVehicle = nullptr;
     195              :     // pre-collect candidate vehicles under lock (buildVehicle touches shared counters)
     196              : #ifndef THREAD_POOL
     197              : #ifdef HAVE_FOX
     198       166578 :     myVehCtrlMutex.lock();
     199              : #endif
     200              : #endif
     201       166578 :     std::vector<SUMOVehicle*> vehicles = getVehicles(vehControl, transportable, origin);
     202              : #ifndef THREAD_POOL
     203              : #ifdef HAVE_FOX
     204       166578 :     myVehCtrlMutex.unlock();
     205              : #endif
     206              : #endif
     207       333243 :     for (SUMOVehicle* vehicle : vehicles) {
     208              :         std::vector<MSTransportableRouter::TripItem> result;
     209       166665 :         double departPos = previous->getArrivalPos();
     210              :         MSStoppingPlace* const prevStop = previous->getDestinationStop();
     211       166665 :         if (MSGlobals::gUseMesoSim && prevStop != nullptr) {
     212          207 :             departPos = (prevStop->getBeginLanePosition() + prevStop->getEndLanePosition()) / 2.;
     213              :         }
     214       352951 :         if (router.compute(origin, destination, departPos, prevStop == nullptr ? "" : prevStop->getID(),
     215       302730 :                            myArrivalPos, myDestinationStop == nullptr ? "" : myDestinationStop->getID(),
     216       166665 :                            transportable->getMaxSpeed() * myWalkFactor, vehicle, transportable->getVTypeParameter(), myModeSet, time, result)) {
     217              :             double totalCost = 0;
     218       358789 :             for (const MSTransportableRouter::TripItem& item : result) {
     219       192215 :                 totalCost += item.cost;
     220              :             }
     221       166574 :             if (totalCost < minCost) {
     222              :                 minCost = totalCost;
     223              :                 minResult.swap(result);
     224              :                 std::swap(minVehicle, vehicle);
     225              :             }
     226              :         }
     227       166665 :         if (vehicle != nullptr) {
     228              : #ifndef THREAD_POOL
     229              : #ifdef HAVE_FOX
     230           94 :             myVehCtrlMutex.lock();
     231              : #endif
     232              : #endif
     233           94 :             vehControl.deleteVehicle(vehicle, true);
     234              :             vehControl.discountRoutingVehicle();
     235              : #ifndef THREAD_POOL
     236              : #ifdef HAVE_FOX
     237           94 :             myVehCtrlMutex.unlock();
     238              : #endif
     239              : #endif
     240              :         }
     241       166665 :     }
     242       166578 :     if (minCost != std::numeric_limits<double>::max()) {
     243       166499 :         const bool isTaxi = minVehicle != nullptr && (myModeSet & SVC_TAXI) != 0 && minVehicle->getParameter().line == "taxi";
     244              :         bool carUsed = false;
     245       358590 :         for (std::vector<MSTransportableRouter::TripItem>::iterator it = minResult.begin(); it != minResult.end(); ++it) {
     246       192091 :             if (!it->edges.empty()) {
     247       172495 :                 MSStoppingPlace* bs = MSNet::getInstance()->getStoppingPlace(it->destStop);
     248       172495 :                 double localArrivalPos = bs != nullptr ? bs->getAccessPos(it->edges.back()) : it->arrivalPos;
     249       172495 :                 const MSEdge* const first = it->edges.front();
     250       172495 :                 const MSEdge* const rideOrigin = origin->isTazConnector() && stages.empty() ? first : nullptr;
     251       172495 :                 if (it + 1 == minResult.end() && myHaveArrivalPos) {
     252         5569 :                     localArrivalPos = myArrivalPos;
     253              :                 }
     254       172495 :                 if (it->line == "") {
     255              :                     // determine walk departPos
     256       167488 :                     double depPos = previous->getArrivalPos();
     257       167488 :                     if (previous->getDestinationStop() != nullptr) {
     258        22413 :                         depPos = previous->getDestinationStop()->getAccessPos(first, first->getLanes()[0]->getRNG());
     259       145075 :                     } else if (origin->isTazConnector()) {
     260              :                         // walk the whole length of the first edge
     261           90 :                         if (std::find(first->getPredecessors().begin(), first->getPredecessors().end(), origin) != first->getPredecessors().end()) {
     262              :                             depPos = 0;
     263              :                         } else {
     264              :                             depPos = first->getLength();
     265              :                         }
     266       144985 :                     } else if (previous->getDestination() != first) {
     267           54 :                         if ((previous->getDestination()->getToJunction() == first->getToJunction())
     268           54 :                                 || (previous->getDestination()->getFromJunction() == first->getToJunction())) {
     269              :                             depPos = first->getLength();
     270              :                         } else {
     271              :                             depPos = 0.;
     272              :                         }
     273              :                     }
     274       167488 :                     if (destination->isTazConnector()) {
     275              :                         // walk the whole length of the last edge
     276          897 :                         const MSEdge* last = it->edges.back();
     277          897 :                         if (std::find(last->getSuccessors().begin(), last->getSuccessors().end(), destination) != last->getSuccessors().end()) {
     278              :                             localArrivalPos = last->getLength();
     279              :                         } else {
     280              :                             localArrivalPos = 0;
     281              :                         }
     282              :                     }
     283       167488 :                     previous = new MSStageWalking(transportable->getID(), it->edges, bs, myDuration, mySpeed, depPos, localArrivalPos, myDepartPosLat);
     284       167488 :                     previous->setParameters(*this);
     285       167488 :                     previous->setCosts(it->cost);
     286              :                     previous->setTrip(this);
     287       167488 :                     stages.push_back(previous);
     288         5007 :                 } else if (isTaxi && it->line == minVehicle->getID()) {
     289          228 :                     const ConstMSEdgeVector& prevEdges = previous->getEdges();
     290          228 :                     if (prevEdges.size() >= 2 && previous->getDestinationStop() == nullptr) {
     291              :                         // determine walking direction and let the previous
     292              :                         // stage end after entering its final edge
     293            6 :                         const MSEdge* last = prevEdges.back();
     294            6 :                         const MSEdge* prev = prevEdges[prevEdges.size() - 2];
     295            6 :                         if (last->getFromJunction() == prev->getToJunction() || prev->getFromJunction() == last->getFromJunction()) {
     296              :                             previous->setArrivalPos(MIN2(last->getLength(), 10.0));
     297              :                         } else {
     298            6 :                             previous->setArrivalPos(MAX2(0.0, last->getLength() - 10));
     299              :                         }
     300              :                     }
     301          684 :                     previous = new MSStageDriving(rideOrigin, it->edges.back(), bs, localArrivalPos, 0.0, std::vector<std::string>({ "taxi" }), myGroup);
     302          228 :                     previous->setParameters(*this);
     303          228 :                     previous->setCosts(it->cost);
     304              :                     previous->setTrip(this);
     305          228 :                     stages.push_back(previous);
     306         5007 :                 } else if (minVehicle != nullptr && it->line == minVehicle->getID()) {
     307         5415 :                     previous = new MSStageDriving(rideOrigin, it->edges.back(), bs, localArrivalPos, 0.0, std::vector<std::string>({ it->line }));
     308         1805 :                     previous->setParameters(*this);
     309         1805 :                     previous->setCosts(it->cost);
     310              :                     previous->setTrip(this);
     311         1805 :                     stages.push_back(previous);
     312         1805 :                     minVehicle->replaceRouteEdges(it->edges, -1, 0, "person:" + transportable->getID(), true);
     313         1805 :                     minVehicle->setArrivalPos(localArrivalPos);
     314         1805 :                     const_cast<SUMOVehicleParameter&>(minVehicle->getParameter()).arrivalPos = localArrivalPos;
     315              :                     // defer addVehicle to main thread (called from setArrived after parallel routing completes)
     316         1805 :                     myVehicleToAdd = minVehicle;
     317              :                     carUsed = true;
     318              :                 } else {
     319         2974 :                     const std::string line = OptionsCont::getOptions().getBool("persontrip.ride-public-line") ? it->line : LINE_ANY;
     320         8922 :                     previous = new MSStageDriving(rideOrigin, it->edges.back(), bs, localArrivalPos, 0.0, std::vector<std::string>({ line }), myGroup, it->intended, TIME2STEPS(it->depart));
     321         2974 :                     previous->setParameters(*this);
     322         2974 :                     previous->setCosts(it->cost);
     323              :                     previous->setTrip(this);
     324         2974 :                     stages.push_back(previous);
     325              :                 }
     326              :             }
     327              :         }
     328       166499 :         if (wasSet(VEHPARS_ARRIVALPOS_SET) && !stages.empty()) {
     329              :             // mark the last stage
     330         1181 :             stages.back()->markSet(VEHPARS_ARRIVALPOS_SET);
     331              :         }
     332              :         setCosts(minCost);
     333       166499 :         if (minVehicle != nullptr && (isTaxi || !carUsed)) {
     334              : #ifndef THREAD_POOL
     335              : #ifdef HAVE_FOX
     336          353 :             myVehCtrlMutex.lock();
     337              : #endif
     338              : #endif
     339          353 :             vehControl.deleteVehicle(minVehicle, true);
     340              :             vehControl.discountRoutingVehicle();
     341              : #ifndef THREAD_POOL
     342              : #ifdef HAVE_FOX
     343          353 :             myVehCtrlMutex.unlock();
     344              : #endif
     345              : #endif
     346              :         }
     347              :     } else {
     348              :         // append stage so the GUI won't crash due to inconsistent state
     349           79 :         previous = new MSStageWalking(transportable->getID(), ConstMSEdgeVector({ origin, destination }), myDestinationStop, myDuration, mySpeed, previous->getArrivalPos(), myArrivalPos, myDepartPosLat);
     350           79 :         previous->setParameters(*this);
     351           79 :         stages.push_back(previous);
     352           79 :         if (MSGlobals::gCheckRoutes) {  // if not pedestrians will teleport
     353          159 :             return "No connection found between " + getOriginDescription() + " and " + getDestinationDescription() + " for person '" + transportable->getID() + "'.";
     354              :         }
     355              :     }
     356       166525 :     if (stages.empty()) {
     357              :         // append stage so the GUI won't crash due to inconsistent state
     358           14 :         if (myOriginStop != nullptr && myOriginStop == myDestinationStop) {
     359           28 :             stages.push_back(new MSStageWaiting(destination, myDestinationStop, 0, -1, previous->getArrivalPos(), "sameStop", false));
     360              :         } else {
     361            0 :             stages.push_back(new MSStageWalking(transportable->getID(), ConstMSEdgeVector({ origin, destination }), myDestinationStop, myDuration, mySpeed, previous->getArrivalPos(), myArrivalPos, myDepartPosLat));
     362            0 :             if (MSGlobals::gCheckRoutes) {  // if not pedestrians will teleport
     363            0 :                 return "Empty route between " + getOriginDescription() + " and " + getDestinationDescription() + " for person '" + transportable->getID() + "'.";
     364              :             }
     365              :         }
     366              :     }
     367       166525 :     return "";
     368       167034 : }
     369              : 
     370              : 
     371              : const std::string
     372       166497 : MSStageTrip::setArrived(MSNet* net, MSTransportable* transportable, SUMOTime now, const bool vehicleArrived) {
     373       332994 :     MSStage::setArrived(net, transportable, now, vehicleArrived);
     374              :     std::vector<MSStage*> stages;
     375              :     std::string result;
     376       166497 :     if (!myComputedStages.empty()) {
     377              :         // routing was done in proceed() (serial or parallel)
     378              :         stages.swap(myComputedStages);
     379       166497 :         result = myRoutingError;
     380              :         myRoutingError = "";
     381              :     } else {
     382              :         // TRIP is at index 0 with no preceding stage, so proceed() was never called
     383            0 :         myDepartPos = transportable->getParameter().departPos;
     384            0 :         if (transportable->getParameter().departPosProcedure == DepartPosDefinition::RANDOM) {
     385              :             // TODO we should probably use the rng of the lane here
     386            0 :             myDepartPos = RandHelper::rand(myOrigin->getLength());
     387              :         }
     388            0 :         MSStageWaiting start(myOrigin, myOriginStop, -1, transportable->getParameter().depart, myDepartPos, "start", true);
     389            0 :         result = reroute(transportable->getParameter().depart, net->getIntermodalRouter(0), transportable, &start, myOrigin, myDestination, stages);
     390            0 :     }
     391       166497 :     if (myVehicleToAdd != nullptr) {
     392         1805 :         net->getVehicleControl().addVehicle(myVehicleToAdd->getID(), myVehicleToAdd);
     393         1805 :         myVehicleToAdd = nullptr;
     394              :     }
     395              :     int idx = 1;
     396       338960 :     for (MSStage* stage : stages) {
     397       172463 :         transportable->appendStage(stage, idx++);
     398              :     }
     399       166497 :     return result;
     400       166497 : }
     401              : 
     402              : 
     403              : void
     404       166498 : MSStageTrip::proceed(MSNet* net, MSTransportable* transportable, SUMOTime now, MSStage* previous) {
     405       166498 :     myDepartPos = previous->getArrivalPos();
     406              : #ifndef THREAD_POOL
     407              : #ifdef HAVE_FOX
     408       166498 :     MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
     409       166498 :     if (threadPool.size() > 0) {
     410         4512 :         MSRoutingEngine::getIntermodalRouterTT(transportable->getRNGIndex());
     411         4512 :         threadPool.add(new TripRoutingTask(*this, transportable, now, previous));
     412         4512 :         net->getPersonControl().addPendingRouting(transportable);
     413         4512 :         return;
     414              :     }
     415              : #endif
     416              : #endif
     417       161986 :     myRoutingError = reroute(now, net->getIntermodalRouter(0), transportable, previous, myOrigin, myDestination, myComputedStages);
     418       161986 :     transportable->proceed(net, now);
     419              : }
     420              : 
     421              : 
     422              : std::string
     423           53 : MSStageTrip::getOriginDescription() const {
     424           53 :     return (myOriginStop != nullptr
     425          113 :             ? toString(myOriginStop->getElement()) + " '" + myOriginStop->getID()
     426           99 :             : "edge '" + myOrigin->getID()) + "'";
     427              : }
     428              : 
     429              : std::string
     430           53 : MSStageTrip::getDestinationDescription() const {
     431           53 :     return (myDestinationStop != nullptr
     432          121 :             ? toString(myDestinationStop->getElement()) + " '" + myDestinationStop->getID()
     433           91 :             : "edge '" + myDestination->getID()) + "'";
     434              : }
     435              : 
     436              : std::string
     437            0 : MSStageTrip::getStageSummary(const bool) const {
     438            0 :     return "trip from " + getOriginDescription() + " to " + getDestinationDescription();
     439              : }
     440              : 
     441              : void
     442         1623 : MSStageTrip::routeOutput(const bool /*isPerson*/, OutputDevice& os, const bool /*withRouteLength*/, const MSStage* const previous, const bool /*withTiming*/, const bool /*saveState*/) const {
     443         1623 :     if (myArrived < 0) {
     444           10 :         const bool walkFactorSet = myWalkFactor != OptionsCont::getOptions().getFloat("persontrip.walkfactor");
     445           10 :         const bool groupSet = myGroup != OptionsCont::getOptions().getString("persontrip.default.group");
     446              :         // could still be a persontrip but most likely it was a walk in the input
     447           10 :         SumoXMLTag tag = myModeSet == 0 && !walkFactorSet && !groupSet ? SUMO_TAG_WALK : SUMO_TAG_PERSONTRIP;
     448           10 :         os.openTag(tag);
     449           10 :         if (previous == nullptr || previous->getStageType() == MSStageType::WAITING_FOR_DEPART) {
     450            4 :             os.writeAttr(SUMO_ATTR_FROM, myOrigin->getID());
     451              :         }
     452           10 :         if (myDestinationStop == nullptr) {
     453           10 :             os.writeAttr(SUMO_ATTR_TO, myDestination->getID());
     454           10 :             if (wasSet(VEHPARS_ARRIVALPOS_SET)) {
     455            6 :                 os.writeAttr(SUMO_ATTR_ARRIVALPOS, myArrivalPos);
     456              :             }
     457              :         } else {
     458            0 :             os.writeAttr(toString(myDestinationStop->getElement()), myDestinationStop->getID());
     459              :         }
     460              :         std::vector<std::string> modes;
     461           10 :         if ((myModeSet & SVC_PASSENGER) != 0) {
     462            4 :             modes.push_back("car");
     463              :         }
     464           10 :         if ((myModeSet & SVC_BICYCLE) != 0) {
     465            0 :             modes.push_back("bicycle");
     466              :         }
     467           10 :         if ((myModeSet & SVC_TAXI) != 0) {
     468            0 :             modes.push_back("taxi");
     469              :         }
     470           10 :         if ((myModeSet & SVC_BUS) != 0) {
     471            0 :             modes.push_back("public");
     472              :         }
     473           10 :         if (modes.size() > 0) {
     474            2 :             os.writeAttr(SUMO_ATTR_MODES, modes);
     475              :         }
     476           10 :         if (myVTypes.size() > 0) {
     477            0 :             os.writeAttr(SUMO_ATTR_VTYPES, myVTypes);
     478              :         }
     479           10 :         if (groupSet) {
     480            0 :             os.writeAttr(SUMO_ATTR_GROUP, myGroup);
     481              :         }
     482           10 :         if (walkFactorSet) {
     483            0 :             os.writeAttr(SUMO_ATTR_WALKFACTOR, myWalkFactor);
     484              :         }
     485           20 :         if (OptionsCont::getOptions().getBool("vehroute-output.cost")) {
     486            0 :             os.writeAttr(SUMO_ATTR_COST, getCosts());
     487              :         }
     488           10 :         os.closeTag();
     489           10 :     }
     490         1623 : }
     491              : 
     492              : 
     493              : /* -------------------------------------------------------------------------
     494              : * MSStageTrip::TripRoutingTask - methods
     495              : * ----------------------------------------------------------------------- */
     496              : #ifndef THREAD_POOL
     497              : #ifdef HAVE_FOX
     498              : void
     499         4512 : MSStageTrip::TripRoutingTask::run(MFXWorkerThread* context) {
     500              :     MSTransportableRouter& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getIntermodalRouter();
     501         4512 :     myStage.myRoutingError = myStage.reroute(myTime, router, myTransportable, myPrevious, myStage.myOrigin, myStage.myDestination, myStage.myComputedStages);
     502         4512 : }
     503              : #endif
     504              : #endif
     505              : 
     506              : 
     507              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1