LCOV - code coverage report
Current view: top level - src/microsim/devices - MSIdling.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 89.0 % 91 81
Test Date: 2024-11-22 15:46:21 Functions: 100.0 % 3 3

            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         9943 : MSIdling_Stop::idle(MSDevice_Taxi* taxi) {
      47         9943 :     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          194 :         double brakeGap = 0;
      55              :         std::pair<const MSLane*, double> stopPos;
      56          194 :         if (MSGlobals::gUseMesoSim) {
      57              :             // stops are only checked in MESegment::receive so we need to put this onto the next segment
      58           59 :             MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(taxi->getHolder());
      59           59 :             MSRouteIterator ri = veh.getCurrentRouteEdge();
      60           59 :             MESegment* curSeg = MSGlobals::gMesoNet->getSegmentForEdge(**ri, veh.getPositionOnLane());
      61              :             MESegment* stopSeg = curSeg->getNextSegment();
      62           59 :             if (stopSeg == nullptr) {
      63            3 :                 if ((ri + 1) != veh.getRoute().end()) {
      64            0 :                     stopSeg = MSGlobals::gMesoNet->getSegmentForEdge(**(ri + 1), 0);
      65              :                 } else {
      66            9 :                     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           56 :             MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(stopEdge);
      74          112 :             while (seg != stopSeg) {
      75           56 :                 stopOffset += seg->getLength();
      76              :                 seg = seg->getNextSegment();
      77              :             }
      78              :             stopPos = std::make_pair(stopEdge.getLanes()[0], stopOffset);
      79              :         } else {
      80          135 :             MSVehicle& veh = dynamic_cast<MSVehicle&>(taxi->getHolder());
      81          135 :             brakeGap = veh.getCarFollowModel().brakeGap(veh.getSpeed(), veh.getCarFollowModel().getMaxDecel(), 0.0);
      82          135 :             stopPos = veh.getLanePosAfterDist(brakeGap);
      83              :         }
      84          191 :         if (stopPos.first != nullptr) {
      85          191 :             SUMOVehicleParameter::Stop stop;
      86          191 :             if (MSGlobals::gUseMesoSim) {
      87              :                 stop.edge = stopPos.first->getEdge().getID();
      88              :             } else {
      89              :                 stop.lane = stopPos.first->getID();
      90              :             }
      91          191 :             stop.startPos = MAX2(0.0, stopPos.second - POSITION_EPS);
      92          191 :             stop.endPos = stopPos.second;
      93          191 :             if (MSGlobals::gUseMesoSim) {
      94              :                 // meso needs the stop to be on the next segment
      95           56 :                 stop.startPos += POSITION_EPS;
      96           56 :                 stop.endPos += POSITION_EPS;
      97              :             }
      98          191 :             if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
      99           24 :                 stop.containerTriggered = true;
     100              :             } else {
     101          167 :                 stop.triggered = true;
     102              :             }
     103              :             stop.actType = "idling";
     104          191 :             stop.parking = ParkingType::OFFROAD;
     105          191 :             taxi->getHolder().addTraciStop(stop, errorOut);
     106          191 :             if (errorOut != "") {
     107            0 :                 WRITE_WARNING(errorOut);
     108              :             }
     109          191 :         } else {
     110            0 :             WRITE_WARNINGF(TL("Idle taxi '%' could not stop within %m"), taxi->getHolder().getID(), toString(brakeGap));
     111              :         }
     112              :     } else {
     113         9749 :         MSStop& stop = taxi->getHolder().getNextStop();
     114              : #ifdef DEBUG_IDLING
     115              :         if (DEBUG_COND(taxi)) {
     116              :             std::cout << SIMTIME << " taxi=" << taxi->getHolder().getID() << " MSIdling_Stop reusing stop with duration " << time2string(stop.duration) << "\n";
     117              :         }
     118              : #endif
     119         9749 :         if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
     120          636 :             stop.containerTriggered = true;
     121              :         } else {
     122         9113 :             stop.triggered = true;
     123              :         }
     124              :     }
     125              : }
     126              : 
     127              : 
     128              : // ===========================================================================
     129              : // MSIdling_RandomCircling methods
     130              : // ===========================================================================
     131              : 
     132              : void
     133        90553 : MSIdling_RandomCircling::idle(MSDevice_Taxi* taxi) {
     134              :     SUMOVehicle& veh = taxi->getHolder();
     135        90553 :     ConstMSEdgeVector edges = veh.getRoute().getEdges();
     136              :     ConstMSEdgeVector newEdges;
     137        90553 :     double remainingDist = -veh.getPositionOnLane();
     138              :     int remainingEdges = 0;
     139        90553 :     int routePos = veh.getRoutePosition();
     140        90553 :     const int routeLength = (int)edges.size();
     141       298510 :     while (routePos + 1 < routeLength && (remainingEdges < 2 || remainingDist < 200)) {
     142       207957 :         const MSEdge* edge = edges[routePos];
     143       207957 :         remainingDist += edge->getLength();
     144       207957 :         remainingEdges++;
     145              :         routePos++;
     146       207957 :         newEdges.push_back(edge);
     147              :     }
     148        90553 :     const MSEdge* lastEdge = edges.back();
     149        90553 :     newEdges.push_back(lastEdge);
     150              :     int added = 0;
     151        97781 :     while (remainingEdges < 2 || remainingDist < 200) {
     152         7228 :         remainingDist += lastEdge->getLength();
     153         7228 :         remainingEdges++;
     154         7228 :         MSEdgeVector successors = lastEdge->getSuccessors(veh.getVClass());
     155        26456 :         for (auto it = successors.begin(); it != successors.end();) {
     156        19228 :             if ((*it)->getFunction() == SumoXMLEdgeFunc::CONNECTOR) {
     157              :                 it = successors.erase(it);
     158              :             } else {
     159              :                 it++;
     160              :             }
     161              :         }
     162         7228 :         if (successors.size() == 0) {
     163            0 :             WRITE_WARNINGF(TL("Vehicle '%' ends idling in a cul-de-sac"), veh.getID());
     164              :             break;
     165              :         } else {
     166         7228 :             int nextIndex = RandHelper::rand((int)successors.size(), veh.getRNG());
     167         7228 :             newEdges.push_back(successors[nextIndex]);
     168         7228 :             lastEdge = newEdges.back();
     169         7228 :             added++;
     170              :         }
     171         7228 :     }
     172        90553 :     if (added > 0) {
     173              :         //std::cout << SIMTIME << " circleVeh=" << veh.getID() << "  newEdges=" << toString(newEdges) << "\n";
     174        13686 :         veh.replaceRouteEdges(newEdges, -1, 0, "taxi:idling:randomCircling", false, false, false);
     175              :     }
     176        90553 : }
     177              : 
     178              : // ===========================================================================
     179              : // MSIdling_TaxiStand methods
     180              : // ===========================================================================
     181              : 
     182              : void
     183         6615 : MSIdling_TaxiStand::idle(MSDevice_Taxi* taxi) {
     184         6615 :     MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(taxi->getHolder());
     185              : 
     186         6615 :     const MSTriggeredRerouter::RerouteInterval* rerouteDef = myRerouter->getCurrentReroute(SIMSTEP);
     187         6615 :     if (rerouteDef == nullptr || rerouteDef->parkProbs.getVals().size() == 0) {
     188            0 :         if (!myHaveWarned) {
     189            0 :             WRITE_WARNINGF(TL("Could not determine taxi stand for vehicle '%' at time=%"), veh.getID(), time2string(SIMSTEP));
     190            0 :             myHaveWarned = true;
     191              :         }
     192            0 :         return;
     193              :     }
     194              :     MSStop* lastStop = nullptr;
     195         6615 :     if (veh.hasStops()) {
     196         6561 :         lastStop = &veh.getStop((int)veh.getStops().size() - 1);
     197              :     }
     198         6561 :     if (lastStop == nullptr || lastStop->parkingarea == nullptr) {
     199          137 :         const MSParkingArea* pa = dynamic_cast<MSParkingArea*>(rerouteDef->parkProbs.getVals().front().first);
     200          137 :         SUMOVehicleParameter::Stop stop;
     201          137 :         stop.lane = pa->getLane().getID();
     202          137 :         stop.startPos = pa->getBeginLanePosition();
     203          137 :         stop.endPos = pa->getEndLanePosition();
     204              : 
     205          137 :         if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
     206            0 :             stop.containerTriggered = true;
     207              :         } else {
     208          137 :             stop.triggered = true;
     209              :         }
     210              :         stop.actType = "idling";
     211              :         stop.parkingarea = pa->getID();
     212          137 :         stop.parking = ParkingType::OFFROAD;
     213          137 :         const int nextStopIndex = (int)veh.getStops().size();
     214              :         std::string error;
     215          137 :         if (!veh.insertStop(nextStopIndex, stop, "taxi:taxistand", false, error)) {
     216            0 :             WRITE_WARNING("Stop insertion failed for idling taxi '" + veh.getID() + "' (" + error + ").");
     217              :         } else {
     218              :             //std::cout << SIMTIME << " taxistandsVeh=" << veh.getID() << "  driving to parkingArea " << pa->getID() << "\n";
     219          137 :             veh.activateReminders(MSMoveReminder::NOTIFICATION_PARKING_REROUTE, &pa->getLane());
     220              :         }
     221          137 :     } else {
     222              :         //std::cout << SIMTIME << " taxistandsVeh=" << veh.getID() << "  already driving to parkingArea\n";
     223              :     }
     224              : }
     225              : 
     226              : 
     227              : 
     228              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1