LCOV - code coverage report
Current view: top level - src/microsim/devices - MSDevice_StationFinder.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 4 4
Test Date: 2025-07-30 21:30:17 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 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    MSDevice_StationFinder.h
      15              : /// @author  Michael Behrisch
      16              : /// @author  Mirko Barthauer
      17              : /// @date    2023-05-24
      18              : ///
      19              : // A device which triggers rerouting to nearby charging stations
      20              : /****************************************************************************/
      21              : #pragma once
      22              : #include <config.h>
      23              : 
      24              : #include <utils/common/WrappingCommand.h>
      25              : #include <microsim/trigger/MSStoppingPlaceRerouter.h>
      26              : #include "MSVehicleDevice.h"
      27              : 
      28              : 
      29              : #define DEFAULT_SOC_INTERVAL 0.1
      30              : #define DEFAULT_ENERGY_PER_DISTANCE 200 // Wh/km
      31              : #define DEFAULT_AVG_WAITING_TIME 900. // s
      32              : #define DEFAULT_CHARGINGSTATION_VIEW_DIST 10 // m
      33              : #define DEFAULT_CONSUMPTION_ESTIMATE_HISTORY 10 // s
      34              : #define DEFAULT_OPPORTUNITY_INTERVAL 1800 // s
      35              : 
      36              : // ===========================================================================
      37              : // class declarations
      38              : // ===========================================================================
      39              : class MSDevice_Battery;
      40              : class MSStoppingPlace;
      41              : 
      42              : 
      43              : // ===========================================================================
      44              : // class definitions
      45              : // ===========================================================================
      46              : /**
      47              :  * @class MSDevice_StationFinder
      48              :  * @brief A device which triggers rerouting to nearby charging stations
      49              :  *
      50              :  * Each device checks the battery status by being
      51              :  *  called each time step and initiaiting the search for a compatible
      52              :  *  charging station if the battery level is too low.
      53              :  *
      54              :  * @see MSDevice
      55              :  */
      56              : class MSDevice_StationFinder : public MSVehicleDevice, MSStoppingPlaceRerouter {
      57              : public:
      58              :     enum ChargeType {
      59              :         CHARGETYPE_CHARGING,
      60              :         CHARGETYPE_BIDIRECTIONAL,
      61              :         CHARGETYPE_BATTERYEXCHANGE,
      62              :         CHARGETYPE_FUEL
      63              :     };
      64              : 
      65              :     enum ChargingStrategy {
      66              :         CHARGINGSTRATEGY_NONE,
      67              :         CHARGINGSTRATEGY_BALANCED,
      68              :         CHARGINGSTRATEGY_LATEST
      69              :     };
      70              : 
      71              :     enum RescueAction {
      72              :         RESCUEACTION_NONE,
      73              :         RESCUEACTION_REMOVE,
      74              :         RESCUEACTION_TOW
      75              :     };
      76              : 
      77              :     enum SearchState {
      78              :         SEARCHSTATE_NONE = 0,
      79              :         SEARCHSTATE_SUCCESSFUL,
      80              :         SEARCHSTATE_UNSUCCESSFUL,
      81              :         SEARCHSTATE_CHARGING,
      82              :         SEARCHSTATE_WAITING,
      83              :         SEARCHSTATE_BROKEN_DOWN
      84              :     };
      85              : 
      86              :     /** @brief Inserts MSDevice_StationFinder-options
      87              :      */
      88              :     static void insertOptions(OptionsCont& oc);
      89              : 
      90              : 
      91              :     /** @brief Build devices for the given vehicle, if needed
      92              :      *
      93              :      * The options are read and evaluated whether stationFinder-devices shall be built
      94              :      *  for the given vehicle.
      95              :      *
      96              :      * For each seen vehicle, the global vehicle index is increased.
      97              :      *
      98              :      * The built device is stored in the given vector.
      99              :      *
     100              :      * @param[in] v The vehicle for which a device may be built
     101              :      * @param[in, filled] into The vector to store the built device in
     102              :      */
     103              :     static void buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into);
     104              : 
     105              :     /** @brief Constructor
     106              :      *
     107              :      * @param[in] holder The vehicle that holds this device
     108              :      */
     109              :     MSDevice_StationFinder(SUMOVehicle& holder);
     110              : 
     111              :     /// @brief Destructor.
     112              :     ~MSDevice_StationFinder();
     113              : 
     114              :     /// @name Methods called on vehicle movement / state change, overwriting MSDevice
     115              :     /// @{
     116              : 
     117              :     /** @brief Computes current emission values and adds them to their sums
     118              :         *
     119              :         * The vehicle's current emission values
     120              :         *  are computed using the current velocity and acceleration.
     121              :         *
     122              :         * @param[in] veh The regarded vehicle
     123              :         * @param[in] oldPos Position before the move-micro-timestep.
     124              :         * @param[in] newPos Position after the move-micro-timestep.
     125              :         * @param[in] newSpeed The vehicle's current speed
     126              :         * @return false, if the vehicle is beyond the lane, true otherwise
     127              :         * @see MSMoveReminder
     128              :         * @see MSMoveReminder::notifyMove
     129              :         * @see PollutantsInterface
     130              :         */
     131              :     bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos, double newSpeed) override;
     132              : 
     133              :     /** @brief Computes idling emission values and adds them to the emission sums
     134              :         *
     135              :         * Idling implied by zero velocity, acceleration and slope
     136              :         *
     137              :         * @param[in] veh The vehicle
     138              :         *
     139              :         * @see MSMoveReminder::notifyMove
     140              :         * @see PollutantsInterface
     141              :         */
     142              :     bool notifyIdle(SUMOTrafficObject& veh) override;
     143              : 
     144              :     /// @}
     145              : 
     146              :     /** @brief Saves the state of the device
     147              :      *
     148              :      * @param[in] out The OutputDevice to write the information into
     149              :      */
     150              :     void saveState(OutputDevice& out) const override;
     151              : 
     152              :     /** @brief Loads the state of the device from the given description
     153              :      *
     154              :      * @param[in] attrs XML attributes describing the current state
     155              :      */
     156              :     void loadState(const SUMOSAXAttributes& attrs) override;
     157              : 
     158              :     /// @brief return the name for this type of device
     159          240 :     const std::string deviceName() const override {
     160          240 :         return "stationfinder";
     161              :     }
     162              : 
     163              :     /// @brief return the string representation of the chosen charging strategy
     164              :     const std::string getChargingStrategy() const {
     165              :         if (myChargingStrategy == CHARGINGSTRATEGY_NONE) {
     166              :             return "none";
     167              :         } else if (myChargingStrategy == CHARGINGSTRATEGY_BALANCED) {
     168              :             return "balanced";
     169              :         } else {
     170              :             return "latest";
     171              :         }
     172              :     }
     173              : 
     174              :     /** @brief Called on writing tripinfo output
     175              :      *
     176              :      * @param[in] os The stream to write the information into
     177              :      * @exception IOError not yet implemented
     178              :      * @see MSDevice::tripInfoOutput
     179              :      */
     180              :     void generateOutput(OutputDevice* tripinfoOut) const override;
     181              : 
     182              :     void setBattery(MSDevice_Battery* battery) {
     183           87 :         myBattery = battery;
     184           87 :     }
     185              : 
     186              :     std::string getParameter(const std::string& key) const override;
     187              : 
     188              :     /// @brief try to set the given parameter for this device. Throw exception for unsupported key
     189              :     void setParameter(const std::string& key, const std::string& value) override;
     190              : 
     191              :     /** @brief Compute some custom target function components
     192              :      *
     193              :      * @param[in] veh the concerned vehicle
     194              :      * @param[in] brakeGap the distance before which the vehicle cannot stop
     195              :      * @param[in] newDestination whether the destination changed
     196              :      * @param[in] alternative the stopping place to evaluate
     197              :      * @param[in] occupancy occupancy of the stopping place
     198              :      * @param[in] router the router to use for evaluation if needed
     199              :      * @param[in,out] stoppingPlaceValues the data structure to write the evaluation values to
     200              :      * @param[in] newRoute the complete route to the destination passing by the stopping place
     201              :      * @param[in] stoppingPlaceApproach the route to the stopping place
     202              :      * @param[in] maxValues the maximum values of the components
     203              :      * @param[in] addInput external input data
     204              :      * @return false if the stopping place cannot be used according to the custom evaluation components
     205              :      */
     206              :     bool evaluateCustomComponents(SUMOVehicle& veh, double brakeGap, bool newDestination,
     207              :                                   MSStoppingPlace* alternative, double occupancy, double prob,
     208              :                                   SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, StoppingPlaceParamMap_t& stoppingPlaceValues,
     209              :                                   ConstMSEdgeVector& newRoute,
     210              :                                   ConstMSEdgeVector& stoppingPlaceApproach,
     211              :                                   StoppingPlaceParamMap_t& maxValues,
     212              :                                   StoppingPlaceParamMap_t& addInput) override;
     213              : 
     214              :     /// @brief Whether the stopping place should be discarded due to its results from the component evaluation
     215              :     bool validComponentValues(StoppingPlaceParamMap_t& stoppingPlaceValues) override;
     216              : 
     217              :     /// @brief Whether the stopping place should be included in the search (can be used to add an additional filter)
     218              :     bool useStoppingPlace(MSStoppingPlace* stoppingPlace) override;
     219              : 
     220              :     /// @brief Provide the router to use (MSNet::getRouterTT or MSRoutingEngine)
     221              :     SUMOAbstractRouter<MSEdge, SUMOVehicle>& getRouter(SUMOVehicle& veh, const Prohibitions& prohibited) override;
     222              : 
     223              :     /// @brief Return the number of occupied places of the StoppingPlace
     224              :     double getStoppingPlaceOccupancy(MSStoppingPlace* stoppingPlace) override;
     225              : 
     226              :     /// @brief Return the number of occupied places of the StoppingPlace from the previous time step
     227              :     double getLastStepStoppingPlaceOccupancy(MSStoppingPlace* stoppingPlace) override;
     228              : 
     229              :     /// @brief Return the number of places the StoppingPlace provides
     230              :     double getStoppingPlaceCapacity(MSStoppingPlace* stoppingPlace) override;
     231              : 
     232              :     /// @brief store the blocked stopping place in the vehicle
     233              :     void rememberBlockedStoppingPlace(SUMOVehicle& veh, const MSStoppingPlace* stoppingPlace, bool blocked) override;
     234              : 
     235              :     /// @brief store the stopping place score in the vehicle
     236              :     void rememberStoppingPlaceScore(SUMOVehicle& veh, MSStoppingPlace* place, const std::string& score) override;
     237              : 
     238              :     /// @brief forget all stopping place score for this vehicle
     239              :     void resetStoppingPlaceScores(SUMOVehicle& veh) override;
     240              : 
     241              :     /// @brief ask the vehicle when it has seen the stopping place
     242              :     SUMOTime sawBlockedStoppingPlace(SUMOVehicle& veh, MSStoppingPlace* place, bool local) override;
     243              : 
     244              :     /// @brief ask how many times already the vehicle has been rerouted to another stopping place
     245              :     int getNumberStoppingPlaceReroutes(SUMOVehicle& veh) override;
     246              : 
     247              :     /// @brief update the number of reroutes for the vehicle
     248              :     void setNumberStoppingPlaceReroutes(SUMOVehicle& veh, int value) override;
     249              : 
     250              : protected:
     251              :     /** @brief Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal()
     252              :      *
     253              :      */
     254              :     void notifyMoveInternal(const SUMOTrafficObject& veh,
     255              :                             const double frontOnLane,
     256              :                             const double timeOnLane,
     257              :                             const double meanSpeedFrontOnLane,
     258              :                             const double meanSpeedVehicleOnLane,
     259              :                             const double travelledDistanceFrontOnLane,
     260              :                             const double travelledDistanceVehicleOnLane,
     261              :                             const double meanLengthOnLane) override;
     262              : 
     263              : private:
     264              :     /** @brief central search function for close charging stations
     265              :      *
     266              :      * @param[in] router
     267              :      * @param[in] expectedConsumption
     268              :      * @param[in,out] scores additional input for score computation and scores of the best charging station
     269              :      * @param[in] constrainTT whether to constrain the search radius by a maximum travel time
     270              :      * @param[in] skipVisited whether to skip charging stations which have not been available when passing by recently
     271              :      * @param[in] skipOccupied whether to skip fully occupied charging stations
     272              :      * @param[in] visible whether the charging station has to be within the visibility radius of the vehicle
     273              :      * @return The found charging station, otherwise nullptr
     274              :      */
     275              :     MSChargingStation* findChargingStation(SUMOAbstractRouter<MSEdge,
     276              :                                            SUMOVehicle>& router,
     277              :                                            double expectedConsumption,
     278              :                                            StoppingPlaceParamMap_t& scores,
     279              :                                            bool constrainTT = true, bool skipVisited = true, bool skipOccupied = false, bool visible = false);
     280              : 
     281              : 
     282              :     /** @brief reroute to a charging station
     283              :      *
     284              :      * @param[in] replace if the already planned next stop should be replaced (a new stop will be prepended if false)
     285              :      * @return true if the vehicle has been redirected to a charging station, false otherwise
     286              :      */
     287              :     bool rerouteToChargingStation(bool replace = false);
     288              : 
     289              : 
     290              :     /** @brief check which stop is suited for opportunistic charging and try to plan charging stops
     291              :      *
     292              :      * @return true if the vehicle has planned at least one opportunistic charging stop
     293              :      */
     294              :     bool planOpportunisticCharging();
     295              : 
     296              : 
     297              :     /** @brief search for a charging station and teleport the vehicle there as a rescue measure
     298              :      */
     299              :     SUMOTime teleportToChargingStation(const SUMOTime currentTime);
     300              : 
     301              :     /** @brief estimate the energy needed for the planned route / up to a target edge
     302              :      *
     303              :      * @param[in] target edge along the route up to which the consumption shall be estimated - the complete route will be used if defaulting to nullptr
     304              :      * @param[in] includeEmptySoC whether to add an additional buffer for the range up to the "empty" threshold
     305              :      * @param[in] stopDiscount duration in seconds to discount in the consumption estimation due to occurred stopping time
     306              :      * @return energy in Wh needed to complete the planned route
     307              :      */
     308              :     double estimateConsumption(const MSEdge* target = nullptr, const bool includeEmptySoC = true, const double stopDiscount = 0.) const;
     309              : 
     310              :     /** @brief compute the free space at a charging station
     311              :      *
     312              :      * @param[in] cs the charging station to compute the free space for
     313              :      * @return the free space at the charging station as a fraction of the holder vehicle
     314              :      */
     315              :     double freeSpaceAtChargingStation(MSChargingStation* cs) const;
     316              : 
     317              :     /** @brief adopt a planned charging stop outside of the device
     318              :      *
     319              :      * @return whether an already present stop was adopted to be used with the device logic
     320              :      */
     321              :     bool alreadyPlannedCharging();
     322              : 
     323              :     /** @brief create the event command for teleporting in case of brake-down
     324              :      */
     325              :     void initRescueCommand();
     326              : 
     327              :     /** @brief create the event command for changing charging rates
     328              :      */
     329              :     void initChargeLimitCommand();
     330              : 
     331              :     /** @brief update the maximum charge rate of the battery to simulate charging strategies
     332              :      */
     333              :     SUMOTime updateChargeLimit(const SUMOTime currentTime);
     334              : 
     335              :     /** @brief
     336              :      */
     337              :     void implementChargingStrategy(SUMOTime begin, SUMOTime end, const double plannedCharge, const MSChargingStation* cs);
     338              : 
     339              : private:
     340              :     /// @brief myHolder cast to needed type
     341              :     MSVehicle& myVeh;
     342              : 
     343              :     /// @brief The corresponding battery device
     344              :     MSDevice_Battery* myBattery;
     345              : 
     346              :     /// @brief To which station we are currently travelling
     347              :     MSStoppingPlace* myChargingStation;
     348              : 
     349              :     /// @brief The command responsible for rescue actions
     350              :     WrappingCommand<MSDevice_StationFinder>* myRescueCommand;
     351              : 
     352              :     /// @brief The command responsible for limiting the charging rate (~ implement charging strategies)
     353              :     WrappingCommand<MSDevice_StationFinder>* myChargeLimitCommand;
     354              : 
     355              :     /// @brief The next charging rates to set via myChargingRateCommand
     356              :     std::vector<std::pair<SUMOTime, double>> myChargeLimits;
     357              : 
     358              :     /// @brief Last time the SoC was checked
     359              :     SUMOTime myLastChargeCheck;
     360              : 
     361              :     /// @brief Time interval after which the SoC has to be checked
     362              :     SUMOTime myCheckInterval;
     363              : 
     364              :     /// @brief Arrival time in the vicinity of the target charging station (to track the waiting time before accessing it)
     365              :     SUMOTime myArrivalAtChargingStation;
     366              : 
     367              :     /// @brief Last time charging stations have been searched
     368              :     SUMOTime myLastSearch;
     369              : 
     370              :     /// @brief Last time charging stations have been searched for opportunistic charging
     371              :     SUMOTime myLastOpportunisticSearch;
     372              : 
     373              :     /// @brief The time to wait for a rescue vehicle in case the battery is empty
     374              :     double myRescueTime;
     375              : 
     376              :     /// @brief The safety buffer when calculating expected consumption
     377              :     double myReserveFactor;
     378              : 
     379              :     /// @brief The state of charge threshold below which rescue mode is activated
     380              :     double myEmptySoC;
     381              : 
     382              :     /// @brief The maximum euclidean distance between the vehicle and the charging station (-1 deactivates the condition)
     383              :     double myMaxEuclideanDistance;
     384              : 
     385              :     /// @brief The max travel time to the next charging station
     386              :     SUMOTime myRadius;
     387              : 
     388              :     /// @brief Time interval to search again for a charging station if the first attempt failed
     389              :     SUMOTime myRepeatInterval;
     390              : 
     391              :     /// @brief Accepted waiting time at the charging station before a place becomes available
     392              :     SUMOTime myWaitForCharge;
     393              : 
     394              :     /// @brief Minimal expected stop duration to allow for opportunistic charging (not needed to complete the route)
     395              :     SUMOTime myMinOpportunisticTime;
     396              : 
     397              :     /// @brief SoC the last time the station finder algorithm was run completely
     398              :     double myUpdateSoC;
     399              : 
     400              :     /// @brief The maximum charging speed of the vehicle battery in W
     401              :     double myMaxChargePower;
     402              : 
     403              :     /// @brief The target state of charge where the vehicle stops charging
     404              :     double myTargetSoC;
     405              : 
     406              :     /// @brief The state of charge at which the vehicle starts looking for charging stations
     407              :     double mySearchSoC;
     408              : 
     409              :     /// @brief The state of charge at/below which the vehicle is interested in charging although it may still be sufficient to terminate its route
     410              :     double myOpportunitySoC;
     411              : 
     412              :     /// @brief The share of stopping time a charging stop should take from the next regular (non-charging) stop under certain conditions
     413              :     double myReplacePlannedStop;
     414              : 
     415              :     /// @brief The distance in meters to the original stop replaced by the charging stop (models charging close to the activity location) - used as well for opportunistic charging
     416              :     double myDistanceToOriginalStop;
     417              : 
     418              :     /// @brief The type of charging permitted by the battery (charging, bidirectional, battery exchange)
     419              :     ChargeType myChargeType;
     420              : 
     421              :     /// @brief The chosen charging strategy
     422              :     ChargingStrategy myChargingStrategy;
     423              : 
     424              :     /// @brief What to do when the state of charge gets very low
     425              :     RescueAction myRescueAction;
     426              : 
     427              :     /// @brief The current state of the charging search (remember for decision logic)
     428              :     SearchState mySearchState = SEARCHSTATE_NONE;
     429              : 
     430              :     /// @brief Whether to skip searching charging stations if the battery charge is sufficient to complete the current route
     431              :     bool myCheckEnergyForRoute;
     432              : 
     433              : private:
     434              :     /// @brief Invalidated copy constructor.
     435              :     MSDevice_StationFinder(const MSDevice_StationFinder&);
     436              : 
     437              :     /// @brief Invalidated assignment operator.
     438              :     MSDevice_StationFinder& operator=(const MSDevice_StationFinder&);
     439              : };
        

Generated by: LCOV version 2.0-1