LCOV - code coverage report
Current view: top level - src/microsim/devices - MSIdling.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 77 87 88.5 %
Date: 2024-04-29 15:38:36 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2007-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    MSIdling.cpp
      15             : /// @author  Jakob Erdmann
      16             : /// @author  Mirko Barthauer
      17             : /// @date    17.08.2020
      18             : ///
      19             : // An algorithm that performs Idling for the taxi device
      20             : /****************************************************************************/
      21             : #include <config.h>
      22             : 
      23             : #include <limits>
      24             : #include <microsim/MSNet.h>
      25             : #include <microsim/MSEdge.h>
      26             : #include <microsim/MSLane.h>
      27             : #include <microsim/MSStop.h>
      28             : #include <microsim/MSParkingArea.h>
      29             : #include <microsim/transportables/MSTransportable.h>
      30             : #include <microsim/trigger/MSTriggeredRerouter.h>
      31             : #include <mesosim/MELoop.h>
      32             : #include "MSRoutingEngine.h"
      33             : #include "MSIdling.h"
      34             : 
      35             : //#define DEBUG_IDLING
      36             : //#define DEBUG_COND(obj) (obj->getHolder().getID() == "p0")
      37             : //#define DEBUG_COND(obj) (obj->getHolder().isSelected())
      38             : #define DEBUG_COND(obj) (true)
      39             : 
      40             : 
      41             : // ===========================================================================
      42             : // MSIdling_stop methods
      43             : // ===========================================================================
      44             : 
      45             : void
      46        9005 : MSIdling_Stop::idle(MSDevice_Taxi* taxi) {
      47        9005 :     if (!taxi->getHolder().hasStops()) {
      48             : #ifdef DEBUG_IDLING
      49             :         if (DEBUG_COND(taxi)) {
      50             :             std::cout << SIMTIME << " taxi=" << taxi->getHolder().getID() << " MSIdling_Stop add stop\n";
      51             :         }
      52             : #endif
      53             :         std::string errorOut;
      54         150 :         double brakeGap = 0;
      55             :         std::pair<const MSLane*, double> stopPos;
      56         150 :         if (MSGlobals::gUseMesoSim) {
      57             :             // stops are only checked in MESegment::receive so we need to put this onto the next segment
      58          44 :             MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(taxi->getHolder());
      59          44 :             MSRouteIterator ri = veh.getCurrentRouteEdge();
      60          44 :             MESegment* curSeg = MSGlobals::gMesoNet->getSegmentForEdge(**ri, veh.getPositionOnLane());
      61             :             MESegment* stopSeg = curSeg->getNextSegment();
      62          44 :             if (stopSeg == nullptr) {
      63           2 :                 if ((ri + 1) != veh.getRoute().end()) {
      64           0 :                     stopSeg = MSGlobals::gMesoNet->getSegmentForEdge(**(ri + 1), 0);
      65             :                 } else {
      66           6 :                     WRITE_WARNINGF(TL("Idle taxi '%' has no next segment to stop. time=%."), taxi->getHolder().getID(), time2string(SIMSTEP));
      67             :                     return;
      68             :                 }
      69             :             }
      70             :             // determine offset of stopSeg
      71             :             double stopOffset = 0;
      72             :             const MSEdge& stopEdge = stopSeg->getEdge();
      73          42 :             MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(stopEdge);
      74          84 :             while (seg != stopSeg) {
      75          42 :                 stopOffset += seg->getLength();
      76             :                 seg = seg->getNextSegment();
      77             :             }
      78             :             stopPos = std::make_pair(stopEdge.getLanes()[0], stopOffset);
      79             :         } else {
      80         106 :             MSVehicle& veh = dynamic_cast<MSVehicle&>(taxi->getHolder());
      81         106 :             brakeGap = veh.getCarFollowModel().brakeGap(veh.getSpeed());
      82         106 :             stopPos = veh.getLanePosAfterDist(brakeGap);
      83             :         }
      84         148 :         if (stopPos.first != nullptr) {
      85         148 :             SUMOVehicleParameter::Stop stop;
      86         148 :             if (MSGlobals::gUseMesoSim) {
      87             :                 stop.edge = stopPos.first->getEdge().getID();
      88             :             } else {
      89             :                 stop.lane = stopPos.first->getID();
      90             :             }
      91         148 :             stop.startPos = stopPos.second;
      92         148 :             stop.endPos = stopPos.second + POSITION_EPS;
      93         148 :             if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
      94          12 :                 stop.containerTriggered = true;
      95             :             } else {
      96         136 :                 stop.triggered = true;
      97             :             }
      98             :             stop.actType = "idling";
      99         148 :             stop.parking = ParkingType::OFFROAD;
     100         148 :             taxi->getHolder().addTraciStop(stop, errorOut);
     101         148 :             if (errorOut != "") {
     102           0 :                 WRITE_WARNING(errorOut);
     103             :             }
     104         148 :         } else {
     105           0 :             WRITE_WARNINGF(TL("Idle taxi '%' could not stop within %m"), taxi->getHolder().getID(), toString(brakeGap));
     106             :         }
     107             :     } else {
     108        8855 :         MSStop& stop = taxi->getHolder().getNextStop();
     109             : #ifdef DEBUG_IDLING
     110             :         if (DEBUG_COND(taxi)) {
     111             :             std::cout << SIMTIME << " taxi=" << taxi->getHolder().getID() << " MSIdling_Stop reusing stop with duration " << time2string(stop.duration) << "\n";
     112             :         }
     113             : #endif
     114        8855 :         if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
     115         366 :             stop.containerTriggered = true;
     116             :         } else {
     117        8489 :             stop.triggered = true;
     118             :         }
     119             :     }
     120             : }
     121             : 
     122             : 
     123             : // ===========================================================================
     124             : // MSIdling_RandomCircling methods
     125             : // ===========================================================================
     126             : 
     127             : void
     128      111644 : MSIdling_RandomCircling::idle(MSDevice_Taxi* taxi) {
     129             :     SUMOVehicle& veh = taxi->getHolder();
     130      111644 :     ConstMSEdgeVector edges = veh.getRoute().getEdges();
     131             :     ConstMSEdgeVector newEdges;
     132      111644 :     double remainingDist = -veh.getPositionOnLane();
     133             :     int remainingEdges = 0;
     134      111644 :     int routePos = veh.getRoutePosition();
     135      111644 :     const int routeLength = (int)edges.size();
     136      363292 :     while (routePos + 1 < routeLength && (remainingEdges < 2 || remainingDist < 200)) {
     137      251648 :         const MSEdge* edge = edges[routePos];
     138      251648 :         remainingDist += edge->getLength();
     139      251648 :         remainingEdges++;
     140             :         routePos++;
     141      251648 :         newEdges.push_back(edge);
     142             :     }
     143      111644 :     const MSEdge* lastEdge = edges.back();
     144      111644 :     newEdges.push_back(lastEdge);
     145             :     int added = 0;
     146      119954 :     while (remainingEdges < 2 || remainingDist < 200) {
     147        8310 :         remainingDist += lastEdge->getLength();
     148        8310 :         remainingEdges++;
     149        8310 :         MSEdgeVector successors = lastEdge->getSuccessors(veh.getVClass());
     150       28338 :         for (auto it = successors.begin(); it != successors.end();) {
     151       20028 :             if ((*it)->getFunction() == SumoXMLEdgeFunc::CONNECTOR) {
     152             :                 it = successors.erase(it);
     153             :             } else {
     154             :                 it++;
     155             :             }
     156             :         }
     157        8310 :         if (successors.size() == 0) {
     158           0 :             WRITE_WARNINGF(TL("Vehicle '%' ends idling in a cul-de-sac"), veh.getID());
     159             :             break;
     160             :         } else {
     161        8310 :             int nextIndex = RandHelper::rand((int)successors.size(), veh.getRNG());
     162        8310 :             newEdges.push_back(successors[nextIndex]);
     163        8310 :             lastEdge = newEdges.back();
     164        8310 :             added++;
     165             :         }
     166             :     }
     167      111644 :     if (added > 0) {
     168             :         //std::cout << SIMTIME << " circleVeh=" << veh.getID() << "  newEdges=" << toString(newEdges) << "\n";
     169       15864 :         veh.replaceRouteEdges(newEdges, -1, 0, "taxi:idling:randomCircling", false, false, false);
     170             :     }
     171      111644 : }
     172             : 
     173             : // ===========================================================================
     174             : // MSIdling_TaxiStand methods
     175             : // ===========================================================================
     176             : 
     177             : void
     178        4512 : MSIdling_TaxiStand::idle(MSDevice_Taxi* taxi) {
     179        4512 :     MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(taxi->getHolder());
     180             : 
     181        4512 :     const MSTriggeredRerouter::RerouteInterval* rerouteDef = myRerouter->getCurrentReroute(SIMSTEP);
     182        4512 :     if (rerouteDef == nullptr || rerouteDef->parkProbs.getVals().size() == 0) {
     183           0 :         if (!myHaveWarned) {
     184           0 :             WRITE_WARNINGF(TL("Could not determine taxi stand for vehicle '%' at time=%"), veh.getID(), time2string(SIMSTEP));
     185           0 :             myHaveWarned = true;
     186             :         }
     187           0 :         return;
     188             :     }
     189             :     MSStop* lastStop = nullptr;
     190        4512 :     if (veh.hasStops()) {
     191        4458 :         lastStop = &veh.getStop((int)veh.getStops().size() - 1);
     192             :     }
     193        4458 :     if (lastStop == nullptr || lastStop->parkingarea == nullptr) {
     194         132 :         const MSParkingArea* pa = rerouteDef->parkProbs.getVals().front().first;
     195         132 :         SUMOVehicleParameter::Stop stop;
     196         132 :         stop.lane = pa->getLane().getID();
     197         132 :         stop.startPos = pa->getBeginLanePosition();
     198         132 :         stop.endPos = pa->getEndLanePosition();
     199             : 
     200         132 :         if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
     201           0 :             stop.containerTriggered = true;
     202             :         } else {
     203         132 :             stop.triggered = true;
     204             :         }
     205             :         stop.actType = "idling";
     206             :         stop.parkingarea = pa->getID();
     207         132 :         stop.parking = ParkingType::OFFROAD;
     208         132 :         const int nextStopIndex = (int)veh.getStops().size();
     209             :         std::string error;
     210         132 :         if (!veh.insertStop(nextStopIndex, stop, "taxi:taxistand", false, error)) {
     211           0 :             WRITE_WARNING("Stop insertion failed for idling taxi '" + veh.getID() + "' (" + error + ").");
     212             :         } else {
     213             :             //std::cout << SIMTIME << " taxistandsVeh=" << veh.getID() << "  driving to parkingArea " << pa->getID() << "\n";
     214         132 :             veh.activateReminders(MSMoveReminder::NOTIFICATION_PARKING_REROUTE, &pa->getLane());
     215             :         }
     216         132 :     } else {
     217             :         //std::cout << SIMTIME << " taxistandsVeh=" << veh.getID() << "  already driving to parkingArea\n";
     218             :     }
     219             : }
     220             : 
     221             : 
     222             : 
     223             : /****************************************************************************/

Generated by: LCOV version 1.14