LCOV - code coverage report
Current view: top level - src/microsim/devices - MSDevice_Battery.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 75.8 % 289 219
Test Date: 2026-03-26 16:31:35 Functions: 87.5 % 40 35

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2013-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    MSDevice_Battery.cpp
      15              : /// @author  Tamas Kurczveil
      16              : /// @author  Pablo Alvarez Lopez
      17              : /// @author  Mirko Barthauer
      18              : /// @date    20.12.2013
      19              : ///
      20              : // The Battery parameters for the vehicle
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <algorithm>
      25              : #include <utils/common/StringUtils.h>
      26              : #include <utils/options/OptionsCont.h>
      27              : #include <utils/iodevices/OutputDevice.h>
      28              : #include <utils/common/SUMOTime.h>
      29              : #include <utils/geom/GeomHelper.h>
      30              : #include <utils/emissions/HelpersEnergy.h>
      31              : #include <utils/xml/SUMOSAXAttributes.h>
      32              : #include <microsim/MSNet.h>
      33              : #include <microsim/MSLane.h>
      34              : #include <microsim/MSEdge.h>
      35              : #include <microsim/MSVehicle.h>
      36              : #include "MSDevice_StationFinder.h"
      37              : #include "MSDevice_Emissions.h"
      38              : #include "MSDevice_Battery.h"
      39              : 
      40              : #define DEFAULT_MAX_CAPACITY 35000
      41              : #define DEFAULT_CHARGE_RATIO 0.5
      42              : 
      43              : 
      44              : // ===========================================================================
      45              : // method definitions
      46              : // ===========================================================================
      47              : // ---------------------------------------------------------------------------
      48              : // static initialisation methods
      49              : // ---------------------------------------------------------------------------
      50              : void
      51        44303 : MSDevice_Battery::insertOptions(OptionsCont& oc) {
      52        88606 :     insertDefaultAssignmentOptions("battery", "Battery", oc);
      53              :     // custom options
      54        44303 :     oc.doRegister("device.battery.track-fuel", new Option_Bool(false));
      55        88606 :     oc.addDescription("device.battery.track-fuel", "Battery", TL("Track fuel consumption for non-electric vehicles"));
      56        44303 : }
      57              : 
      58              : 
      59              : void
      60      5554740 : MSDevice_Battery::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into, MSDevice_StationFinder* sf) {
      61              :     // Check if vehicle should get a battery
      62     11109374 :     if (sf != nullptr || equippedByDefaultAssignmentOptions(OptionsCont::getOptions(), "battery", v, false)) {
      63              :         // obtain parameter values
      64         1723 :         const double maximumBatteryCapacity = readParameterValue(v, SUMO_ATTR_MAXIMUMBATTERYCAPACITY, "battery.capacity", DEFAULT_MAX_CAPACITY);
      65         1723 :         const double actualBatteryCapacity = readParameterValue(v, SUMO_ATTR_ACTUALBATTERYCAPACITY, "battery.chargeLevel", maximumBatteryCapacity * DEFAULT_CHARGE_RATIO);
      66         1723 :         const double stoppingThreshold = readParameterValue(v, SUMO_ATTR_STOPPINGTHRESHOLD, "battery.stoppingThreshold", 0.1);
      67         1723 :         const double maximumChargeRate = readParameterValue(v, SUMO_ATTR_MAXIMUMCHARGERATE, "battery.maximumChargeRate", 150000.);
      68         3446 :         const std::string chargeLevelTable = v.getStringParam("device.battery.chargeLevelTable");
      69         3446 :         const std::string chargeCurveTable = v.getStringParam("device.battery.chargeCurveTable");
      70              : 
      71              :         // battery constructor
      72         1723 :         MSDevice_Battery* device = new MSDevice_Battery(v, "battery_" + v.getID(),
      73         3446 :                 actualBatteryCapacity, maximumBatteryCapacity, stoppingThreshold, maximumChargeRate, chargeLevelTable, chargeCurveTable);
      74              : 
      75              :         // Add device to vehicle
      76         1723 :         into.push_back(device);
      77              : 
      78         1723 :         if (sf != nullptr) {
      79              :             sf->setBattery(device);
      80              :         }
      81              :         // ensure that parameters are initialized
      82         1723 :         v.getEmissionParameters();
      83              :     }
      84      5554740 : }
      85              : 
      86              : 
      87              : double
      88         6892 : MSDevice_Battery::readParameterValue(SUMOVehicle& v, const SumoXMLAttr& attr, const std::string& paramName, double defaultVal) {
      89         6892 :     const std::string& oldParam = toString(attr);
      90         6892 :     const SUMOVTypeParameter& typeParams = v.getVehicleType().getParameter();
      91         6892 :     if (v.getParameter().hasParameter(oldParam) || typeParams.hasParameter(oldParam)) {
      92            0 :         WRITE_WARNINGF(TL("Battery device in vehicle '%' still uses old parameter '%'. Please update to 'device.%'."), v.getID(), oldParam, paramName);
      93            0 :         if (v.getParameter().getParameter(oldParam, "-") == "-") {
      94            0 :             return typeParams.getDouble(oldParam, defaultVal);
      95              :         }
      96            0 :         return StringUtils::toDouble(v.getParameter().getParameter(oldParam, "0"));
      97              :     }
      98        13784 :     return v.getFloatParam("device." + paramName, false, defaultVal);
      99              : }
     100              : 
     101              : 
     102              : // ---------------------------------------------------------------------------
     103              : // MSDevice_Battery-methods
     104              : // ---------------------------------------------------------------------------
     105         1723 : MSDevice_Battery::MSDevice_Battery(SUMOVehicle& holder, const std::string& id, const double actualBatteryCapacity, const double maximumBatteryCapacity,
     106         1723 :                                    const double stoppingThreshold, const double maximumChargeRate, const std::string& chargeLevelTable, const std::string& chargeCurveTable) :
     107              :     MSVehicleDevice(holder, id),
     108         1723 :     myActualBatteryCapacity(0),         // [actualBatteryCapacity <= maximumBatteryCapacity]
     109         1723 :     myMaximumBatteryCapacity(0),        // [maximumBatteryCapacity >= 0]
     110         1723 :     myStoppingThreshold(0),             // [stoppingThreshold >= 0]
     111         1723 :     myMaximumChargeRate(0),
     112         1723 :     myChargeLimit(-1),
     113         1723 :     myLastAngle(std::numeric_limits<double>::infinity()),
     114         1723 :     myChargingStopped(false),           // Initially vehicle don't charge stopped
     115         1723 :     myChargingInTransit(false),         // Initially vehicle don't charge in transit
     116         1723 :     myChargingStartTime(0),             // Initially charging start time (must be if the vehicle was launched at the charging station)
     117         1723 :     myConsum(0),                        // Initially the vehicle is stopped and therefore the consum is zero.
     118         1723 :     myTotalConsumption(0.0),
     119         1723 :     myTotalRegenerated(0.0),
     120         1723 :     myActChargingStation(nullptr),         // Initially the vehicle isn't over a Charging Station
     121         1723 :     myPreviousNeighbouringChargingStation(nullptr),    // Initially the vehicle wasn't over a Charging Station
     122         1723 :     myEnergyCharged(0),                 // Initially the energy charged is zero
     123         1723 :     myVehicleStopped(0),
     124         1723 :     myDepletedCount(0) {
     125              :     // Initially the vehicle is stopped and the corresponding variable is 0
     126              : 
     127         1723 :     if (maximumBatteryCapacity < 0) {
     128            0 :         WRITE_WARNINGF(TL("Battery builder: Vehicle '%' doesn't have a valid value for parameter % (%)."), getID(), toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY), toString(maximumBatteryCapacity));
     129              :     } else {
     130         1723 :         myMaximumBatteryCapacity = maximumBatteryCapacity;
     131              :     }
     132              : 
     133         1723 :     if (actualBatteryCapacity > maximumBatteryCapacity) {
     134            0 :         WRITE_WARNINGF(TL("Battery builder: Vehicle '%' has a % (%) greater than its % (%). A max battery capacity value will be assigned."),
     135              :                        getID(), toString(SUMO_ATTR_ACTUALBATTERYCAPACITY), toString(actualBatteryCapacity), toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY), toString(maximumBatteryCapacity));
     136            0 :         myActualBatteryCapacity = myMaximumBatteryCapacity;
     137              :     } else {
     138         1723 :         myActualBatteryCapacity = actualBatteryCapacity;
     139              :     }
     140              : 
     141         1723 :     if (stoppingThreshold < 0) {
     142            0 :         WRITE_WARNINGF(TL("Battery builder: Vehicle '%' doesn't have a valid value for parameter % (%)."), getID(), toString(SUMO_ATTR_STOPPINGTHRESHOLD), toString(stoppingThreshold));
     143              :     } else {
     144         1723 :         myStoppingThreshold = stoppingThreshold;
     145              :     }
     146              : 
     147         1763 :     myTrackFuel = PollutantsInterface::getFuel(holder.getVehicleType().getEmissionClass()) != "Electricity" && OptionsCont::getOptions().getBool("device.battery.track-fuel");
     148         1723 :     if (!myTrackFuel && !holder.getVehicleType().getParameter().wasSet(VTYPEPARS_EMISSIONCLASS_SET)) {
     149           72 :         WRITE_WARNINGF(TL("The battery device is active for vehicle '%' but no emission class is set. "
     150              :                           "Please consider setting an explicit emission class or battery outputs might be inconsistent with emission outputs!"),
     151              :                        holder.getID());
     152              :     }
     153         1723 :     myChargeType = (myTrackFuel) ? MSChargingStation::ChargeType::CHARGETYPE_FUEL : MSChargingStation::ChargeType::CHARGETYPE_NORMAL;
     154              : 
     155         1723 :     if (maximumChargeRate < 0) {
     156            0 :         WRITE_WARNINGF(TL("Battery builder: Vehicle '%' doesn't have a valid value for parameter % (%)."), getID(), toString(SUMO_ATTR_MAXIMUMCHARGERATE), toString(maximumChargeRate));
     157              :     } else {
     158         1723 :         if (!chargeLevelTable.empty() && !chargeCurveTable.empty()) {
     159            0 :             LinearApproxHelpers::setPoints(myChargeCurve, chargeLevelTable, chargeCurveTable);
     160            0 :             myMaximumChargeRate = LinearApproxHelpers::getMaximumValue(myChargeCurve);
     161              :         } else {
     162         1723 :             myMaximumChargeRate = maximumChargeRate;
     163              :         }
     164              :     }
     165         1723 : }
     166              : 
     167              : 
     168         3446 : MSDevice_Battery::~MSDevice_Battery() {
     169         3446 : }
     170              : 
     171              : 
     172       446724 : bool MSDevice_Battery::notifyMove(SUMOTrafficObject& tObject, double /* oldPos */, double /* newPos */, double newSpeed) {
     173       446724 :     if (!tObject.isVehicle()) {
     174              :         return false;
     175              :     }
     176       446724 :     notifyMoveInternal(tObject, 0., TS, 0., newSpeed, 0., 0., 0.);
     177       446724 :     return true;
     178              : }
     179              : 
     180              : 
     181              : void
     182       455596 : MSDevice_Battery::notifyMoveInternal(const SUMOTrafficObject& tObject,
     183              :                                      const double /* frontOnLane */,
     184              :                                      const double timeOnLane,
     185              :                                      const double /* meanSpeedFrontOnLane */,
     186              :                                      const double meanSpeedVehicleOnLane,
     187              :                                      const double /* travelledDistanceFrontOnLane */,
     188              :                                      const double /* travelledDistanceVehicleOnLane */,
     189              :                                      const double /* meanLengthOnLane */) {
     190              :     const SUMOVehicle& veh = static_cast<const SUMOVehicle&>(tObject);
     191              :     // Start vehicleStoppedTimer if the vehicle is stopped. In other case reset timer
     192       455596 :     if (meanSpeedVehicleOnLane < myStoppingThreshold) {
     193              :         // Increase vehicle stopped timer
     194       205618 :         increaseVehicleStoppedTimer();
     195              :     } else {
     196              :         // Reset vehicle Stopped
     197       249978 :         resetVehicleStoppedTimer();
     198              :     }
     199              : 
     200              :     // Update Energy from the battery
     201       455596 :     EnergyParams* const params = myHolder.getEmissionParameters();
     202       455596 :     if (getMaximumBatteryCapacity() != 0) {
     203       455596 :         if (!myTrackFuel && !veh.getVehicleType().getParameter().wasSet(VTYPEPARS_EMISSIONCLASS_SET)) {
     204              :             // no explicit emission class, we fall back to the energy model; a warning has been issued on creation
     205         1066 :             myConsum = PollutantsInterface::getEnergyHelper().compute(0, PollutantsInterface::ELEC, meanSpeedVehicleOnLane, veh.getAcceleration(),
     206         1066 :                        veh.getSlope(), params) * timeOnLane;
     207              :         } else {
     208       455063 :             myConsum = PollutantsInterface::compute(veh.getVehicleType().getEmissionClass(),
     209       455063 :                                                     myTrackFuel ? PollutantsInterface::FUEL : PollutantsInterface::ELEC,
     210       455063 :                                                     meanSpeedVehicleOnLane, veh.getAcceleration(),
     211       910126 :                                                     veh.getSlope(), params) * timeOnLane;
     212              :         }
     213       455596 :         if (veh.isParking()) {
     214              :             // recuperation from last braking step is ok but further consumption should cease
     215         1184 :             myConsum = MIN2(myConsum, 0.0);
     216              :         }
     217              : 
     218              :         // saturate between 0 and myMaximumBatteryCapacity [Wh]
     219       455596 :         if (myConsum > getActualBatteryCapacity() && getActualBatteryCapacity() > 0 && getMaximumBatteryCapacity() > 0) {
     220           32 :             myDepletedCount++;
     221           32 :             if (myDepletedCount == 1) {
     222           48 :                 WRITE_WARNINGF(TL("Battery of vehicle '%' is depleted, time=%."), veh.getID(), time2string(SIMSTEP));
     223              :             }
     224              :         }
     225              : 
     226              :         // Energy lost/gained from vehicle movement (via vehicle energy model) [Wh]
     227       455596 :         setActualBatteryCapacity(getActualBatteryCapacity() - myConsum);
     228              : 
     229              :         // Track total energy consumption and regeneration
     230       455596 :         if (myConsum > 0.0) {
     231       332893 :             myTotalConsumption += myConsum;
     232              :         } else {
     233       122703 :             myTotalRegenerated -= myConsum;
     234              :         }
     235              : 
     236       455596 :         myLastAngle = veh.getAngle();
     237              :     }
     238              : 
     239              :     // Check if vehicle has under their position one charge Station
     240       455596 :     const std::string chargingStationID = MSNet::getInstance()->getStoppingPlaceID(veh.getLane(), veh.getPositionOnLane(), SUMO_TAG_CHARGING_STATION);
     241              : 
     242              :     // If vehicle is over a charging station
     243       455596 :     if (chargingStationID != "") {
     244              :         // if the vehicle is almost stopped, or charge in transit is enabled, then charge vehicle
     245       102664 :         MSChargingStation* const cs = static_cast<MSChargingStation*>(MSNet::getInstance()->getStoppingPlace(chargingStationID, SUMO_TAG_CHARGING_STATION));
     246       102664 :         const MSParkingArea* pa = cs->getParkingArea();
     247       102664 :         if (((meanSpeedVehicleOnLane < myStoppingThreshold) || cs->getChargeInTransit()) && (pa == nullptr || veh.isParking()) && cs->getChargeType() == myChargeType) {
     248              :             // Set Flags Stopped/intransit to
     249       100460 :             if (meanSpeedVehicleOnLane < myStoppingThreshold) {
     250              :                 // vehicle ist almost stopped, then is charging stopped
     251        99132 :                 myChargingStopped = true;
     252              : 
     253              :                 // therefore isn't charging in transit
     254        99132 :                 myChargingInTransit = false;
     255              :             } else {
     256              :                 // vehicle is moving, and the Charging station allow charge in transit
     257         1328 :                 myChargingStopped = false;
     258              : 
     259              :                 // Therefore charge in transit
     260         1328 :                 myChargingInTransit = true;
     261              :             }
     262              : 
     263              :             // get pointer to charging station
     264       100460 :             myActChargingStation = cs;
     265              : 
     266              :             // Only update charging start time if vehicle allow charge in transit, or in other case
     267              :             // if the vehicle not allow charge in transit but it's stopped.
     268       100460 :             if ((myActChargingStation->getChargeInTransit()) || (meanSpeedVehicleOnLane < myStoppingThreshold)) {
     269              :                 // Update Charging start time
     270       100460 :                 increaseChargingStartTime();
     271              :             }
     272              : 
     273              :             // time it takes the vehicle at the station < charging station time delay?
     274       100460 :             if (getChargingStartTime() > myActChargingStation->getChargeDelay()) {
     275              :                 // Enable charging vehicle
     276        99505 :                 myActChargingStation->setChargingVehicle(true);
     277              : 
     278              :                 // Calulate energy charged
     279       201882 :                 myEnergyCharged = MIN2(MIN2(myActChargingStation->getChargingPower(myTrackFuel) * myActChargingStation->getEfficency(), getMaximumChargeRate() * (myTrackFuel ? 1 : 1. / 3600.)) * timeOnLane, getMaximumBatteryCapacity() - getActualBatteryCapacity());
     280              : 
     281              :                 // Update Battery charge
     282        99505 :                 setActualBatteryCapacity(getActualBatteryCapacity() + myEnergyCharged);
     283              :             }
     284              :             // add charge value for output to myActChargingStation
     285       100460 :             myActChargingStation->addChargeValueForOutput(myEnergyCharged, this);
     286              :         }
     287              :         // else disable charging vehicle
     288              :         else {
     289         2204 :             cs->setChargingVehicle(false);
     290              :         }
     291              :         // disable charging vehicle from previous (not current) ChargingStation (reason: if there is no gap between two different chargingStations = the vehicle switches from used charging station to other one in a single timestap)
     292       102664 :         if (myPreviousNeighbouringChargingStation != nullptr && myPreviousNeighbouringChargingStation != cs) {
     293          481 :             myPreviousNeighbouringChargingStation->setChargingVehicle(false);
     294              :         }
     295       102664 :         myPreviousNeighbouringChargingStation = cs;
     296              :     }
     297              :     // In other case, vehicle will be not charged
     298              :     else {
     299              :         // Disable flags
     300       352932 :         myChargingInTransit = false;
     301       352932 :         myChargingStopped = false;
     302              : 
     303              :         // Disable charging vehicle
     304       352932 :         if (myActChargingStation != nullptr) {
     305          554 :             myActChargingStation->setChargingVehicle(false);
     306              :         }
     307              : 
     308              :         // Set charging station pointer to NULL
     309       352932 :         myActChargingStation = nullptr;
     310              : 
     311              :         // Set energy charged to 0
     312       352932 :         myEnergyCharged = 0;
     313              : 
     314              :         // Reset timer
     315       352932 :         resetChargingStartTime();
     316              :     }
     317       455596 : }
     318              : 
     319              : 
     320              : void
     321            0 : MSDevice_Battery::saveState(OutputDevice& out) const {
     322            0 :     out.openTag(SUMO_TAG_DEVICE);
     323            0 :     out.writeAttr(SUMO_ATTR_ID, getID());
     324              :     std::vector<std::string> internals;
     325            0 :     internals.push_back(toString(myActualBatteryCapacity));
     326            0 :     internals.push_back(toString(myLastAngle));
     327            0 :     internals.push_back(toString(myChargingStopped));
     328            0 :     internals.push_back(toString(myChargingInTransit));
     329            0 :     internals.push_back(toString(myChargingStartTime));
     330            0 :     internals.push_back(toString(myTotalConsumption));
     331            0 :     internals.push_back(toString(myTotalRegenerated));
     332            0 :     internals.push_back(toString(myEnergyCharged));
     333            0 :     internals.push_back(toString(myVehicleStopped));
     334            0 :     internals.push_back(getChargingStationID());
     335            0 :     std::string prevChargingID = (myPreviousNeighbouringChargingStation == nullptr) ? "NULL" : myPreviousNeighbouringChargingStation->getID();
     336            0 :     internals.push_back(prevChargingID);
     337            0 :     internals.push_back(toString(myMaximumChargeRate));
     338            0 :     out.writeAttr(SUMO_ATTR_STATE, toString(internals));
     339            0 :     out.closeTag();
     340            0 : }
     341              : 
     342              : 
     343              : void
     344            0 : MSDevice_Battery::loadState(const SUMOSAXAttributes& attrs) {
     345            0 :     std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
     346            0 :     bis >> myActualBatteryCapacity;
     347            0 :     bis >> myLastAngle;
     348            0 :     bis >> myChargingStopped;
     349            0 :     bis >> myChargingInTransit;
     350            0 :     bis >> myChargingStartTime;
     351            0 :     bis >> myTotalConsumption;
     352            0 :     bis >> myTotalRegenerated;
     353            0 :     bis >> myEnergyCharged;
     354            0 :     bis >> myVehicleStopped;
     355              :     std::string chargingID;
     356            0 :     bis >> chargingID;
     357            0 :     if (chargingID != "NULL") {
     358            0 :         myActChargingStation = dynamic_cast<MSChargingStation*>(MSNet::getInstance()->getStoppingPlace(chargingID, SUMO_TAG_CHARGING_STATION));
     359              :     }
     360              :     std::string prevChargingID;
     361            0 :     bis >> prevChargingID;
     362            0 :     if (prevChargingID != "NULL") {
     363            0 :         myPreviousNeighbouringChargingStation = dynamic_cast<MSChargingStation*>(MSNet::getInstance()->getStoppingPlace(prevChargingID, SUMO_TAG_CHARGING_STATION));
     364              :     }
     365            0 :     bis >> myMaximumChargeRate;
     366            0 : }
     367              : 
     368              : 
     369              : void
     370       555301 : MSDevice_Battery::setActualBatteryCapacity(const double actualBatteryCapacity) {
     371       555301 :     if (actualBatteryCapacity < 0) {
     372         1340 :         myActualBatteryCapacity = 0;
     373       553961 :     } else if (actualBatteryCapacity > myMaximumBatteryCapacity) {
     374            4 :         myActualBatteryCapacity = myMaximumBatteryCapacity;
     375              :     } else {
     376       553957 :         myActualBatteryCapacity = actualBatteryCapacity;
     377              :     }
     378       555301 : }
     379              : 
     380              : 
     381              : void
     382            9 : MSDevice_Battery::setMaximumBatteryCapacity(const double maximumBatteryCapacity) {
     383            9 :     if (myMaximumBatteryCapacity < 0) {
     384            0 :         WRITE_WARNINGF(TL("Trying to set into the battery device of vehicle '%' an invalid % (%)."), getID(), toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY), toString(maximumBatteryCapacity));
     385              :     } else {
     386            9 :         myMaximumBatteryCapacity = maximumBatteryCapacity;
     387              :     }
     388            9 : }
     389              : 
     390              : 
     391              : void
     392            0 : MSDevice_Battery::setStoppingThreshold(const double stoppingThreshold) {
     393            0 :     if (stoppingThreshold < 0) {
     394            0 :         WRITE_WARNINGF(TL("Trying to set into the battery device of vehicle '%' an invalid % (%)."), getID(), toString(SUMO_ATTR_STOPPINGTHRESHOLD), toString(stoppingThreshold));
     395              :     } else {
     396            0 :         myStoppingThreshold = stoppingThreshold;
     397              :     }
     398            0 : }
     399              : 
     400              : 
     401              : void
     402            0 : MSDevice_Battery::setMaximumChargeRate(const double chargeRate) {
     403            0 :     if (chargeRate < 0) {
     404            0 :         WRITE_WARNINGF(TL("Trying to set into the battery device of vehicle '%' an invalid % (%)."), getID(), toString(SUMO_ATTR_MAXIMUMCHARGERATE), toString(chargeRate));
     405              :     } else {
     406            0 :         myMaximumChargeRate = chargeRate;
     407              :     }
     408            0 : }
     409              : 
     410              : 
     411              : void
     412            8 : MSDevice_Battery::setChargeLimit(const double limit) {
     413            8 :     myChargeLimit = limit;
     414            8 : }
     415              : 
     416              : 
     417              : void
     418       352932 : MSDevice_Battery::resetChargingStartTime() {
     419       352932 :     myChargingStartTime = 0;
     420       352932 : }
     421              : 
     422              : 
     423              : void
     424       100460 : MSDevice_Battery::increaseChargingStartTime() {
     425       100460 :     myChargingStartTime += DELTA_T;
     426       100460 : }
     427              : 
     428              : 
     429              : void
     430       249978 : MSDevice_Battery::resetVehicleStoppedTimer() {
     431       249978 :     myVehicleStopped = 0;
     432       249978 : }
     433              : 
     434              : 
     435              : void
     436       205618 : MSDevice_Battery::increaseVehicleStoppedTimer() {
     437       205618 :     myVehicleStopped++;
     438       205618 : }
     439              : 
     440              : 
     441              : void
     442          200 : MSDevice_Battery::setEnergyCharged(const double energyCharged) {
     443          200 :     myEnergyCharged = energyCharged;
     444          200 : }
     445              : 
     446              : 
     447              : double
     448      1380400 : MSDevice_Battery::getActualBatteryCapacity() const {
     449      1380400 :     return myActualBatteryCapacity;
     450              : }
     451              : 
     452              : 
     453              : double
     454       944419 : MSDevice_Battery::getMaximumBatteryCapacity() const {
     455       944419 :     return myMaximumBatteryCapacity;
     456              : }
     457              : 
     458              : 
     459              : double
     460       119758 : MSDevice_Battery::getConsum() const {
     461       119758 :     return myConsum;
     462              : }
     463              : 
     464              : double
     465       120813 : MSDevice_Battery::getTotalConsumption() const {
     466       120813 :     return myTotalConsumption;
     467              : }
     468              : 
     469              : 
     470              : double
     471       119758 : MSDevice_Battery::getTotalRegenerated() const {
     472       119758 :     return myTotalRegenerated;
     473              : }
     474              : 
     475              : 
     476              : bool
     477       119668 : MSDevice_Battery::isChargingStopped() const {
     478       119668 :     return myChargingStopped;
     479              : }
     480              : 
     481              : 
     482              : bool
     483       119668 : MSDevice_Battery::isChargingInTransit() const {
     484       119668 :     return myChargingInTransit;
     485              : }
     486              : 
     487              : 
     488              : SUMOTime
     489       199193 : MSDevice_Battery::getChargingStartTime() const {
     490       199193 :     return myChargingStartTime;
     491              : }
     492              : 
     493              : 
     494              : SUMOTime
     495            0 : MSDevice_Battery::estimateChargingDuration(const double toCharge, const double csPower) const {
     496              :     //if (!myChargeCurve.empty()) {
     497              :     //    // TODO: integrate charge curve
     498              :     //}
     499            0 :     return TIME2STEPS(toCharge / MIN2(csPower, myMaximumChargeRate));
     500              : }
     501              : 
     502              : 
     503              : std::string
     504       119758 : MSDevice_Battery::getChargingStationID() const {
     505       119758 :     if (myActChargingStation != nullptr) {
     506              :         return myActChargingStation->getID();
     507              :     } else {
     508        90922 :         return "NULL";
     509              :     }
     510              : }
     511              : 
     512              : double
     513       286435 : MSDevice_Battery::getEnergyCharged() const {
     514       286435 :     return myEnergyCharged;
     515              : }
     516              : 
     517              : 
     518              : int
     519       119668 : MSDevice_Battery::getVehicleStopped() const {
     520       119668 :     return myVehicleStopped;
     521              : }
     522              : 
     523              : 
     524              : double
     525        98365 : MSDevice_Battery::getStoppingThreshold() const {
     526        98365 :     return myStoppingThreshold;
     527              : }
     528              : 
     529              : 
     530              : double
     531        99505 : MSDevice_Battery::getMaximumChargeRate() const {
     532        99505 :     double baseVal = (myChargeCurve.empty()) ? myMaximumChargeRate : LinearApproxHelpers::getInterpolatedValue(myChargeCurve, myActualBatteryCapacity / myMaximumBatteryCapacity);
     533        99505 :     return (myChargeLimit < 0) ? baseVal : MIN2(myChargeLimit, baseVal);
     534              : }
     535              : 
     536              : 
     537              : bool
     538          106 : MSDevice_Battery::tracksFuel() const {
     539          106 :     return myTrackFuel;
     540              : }
     541              : 
     542              : 
     543              : MSChargingStation::ChargeType
     544          496 : MSDevice_Battery::getChargeType() const {
     545          496 :     return myChargeType;
     546              : }
     547              : 
     548              : 
     549              : std::string
     550          768 : MSDevice_Battery::getParameter(const std::string& key) const {
     551         1536 :     if (key == toString(SUMO_ATTR_ACTUALBATTERYCAPACITY)
     552         1536 :             || key == toString(SUMO_ATTR_CHARGELEVEL)) {
     553           90 :         return toString(getActualBatteryCapacity());
     554          678 :     } else if (key == toString(SUMO_ATTR_ENERGYCONSUMED)) {
     555           90 :         return toString(getConsum());
     556          588 :     } else if (key == "chargePower") {
     557           60 :         return toString(getEnergyCharged() * 3600.);
     558          528 :     } else if (key == "usedAverage") {
     559           60 :         return toString(getTotalConsumption() * 3600 / STEPS2TIME(SIMSTEP - myHolder.getDeparture()));
     560          468 :     } else if (key == toString(SUMO_ATTR_TOTALENERGYCONSUMED)) {
     561           90 :         return toString(getTotalConsumption());
     562          378 :     } else if (key == toString(SUMO_ATTR_TOTALENERGYREGENERATED)) {
     563           90 :         return toString(getTotalRegenerated());
     564          288 :     } else if (key == toString(SUMO_ATTR_ENERGYCHARGED)) {
     565           90 :         return toString(getEnergyCharged());
     566          396 :     } else if (key == toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY) || key == "capacity") {
     567           99 :         return toString(getMaximumBatteryCapacity());
     568           99 :     } else if (key == toString(SUMO_ATTR_MAXIMUMCHARGERATE)) {
     569            0 :         return toString(getMaximumChargeRate());
     570           99 :     } else if (key == toString(SUMO_ATTR_CHARGINGSTATIONID)) {
     571           90 :         return getChargingStationID();
     572              :     }
     573           27 :     throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
     574              : }
     575              : 
     576              : 
     577              : void
     578            9 : MSDevice_Battery::setParameter(const std::string& key, const std::string& value) {
     579              :     double doubleValue;
     580              :     try {
     581            9 :         doubleValue = StringUtils::toDouble(value);
     582            0 :     } catch (NumberFormatException&) {
     583            0 :         throw InvalidArgument("Setting parameter '" + key + "' requires a number for device of type '" + deviceName() + "'");
     584            0 :     }
     585           18 :     if (key == toString(SUMO_ATTR_ACTUALBATTERYCAPACITY) || key == toString(SUMO_ATTR_CHARGELEVEL)) {
     586            0 :         setActualBatteryCapacity(doubleValue);
     587           18 :     } else if (key == toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY) || key == "capacity") {
     588            9 :         setMaximumBatteryCapacity(doubleValue);
     589            0 :     } else if (key == toString(SUMO_ATTR_MAXIMUMCHARGERATE)) {
     590            0 :         setMaximumChargeRate(doubleValue);
     591              :     } else {
     592            0 :         throw InvalidArgument("Setting parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
     593              :     }
     594            9 : }
     595              : 
     596              : 
     597              : void
     598          560 : MSDevice_Battery::notifyParking() {
     599              :     // @note: only charing is performed but no energy is consumed
     600          560 :     notifyMove(myHolder, myHolder.getPositionOnLane(), myHolder.getPositionOnLane(), myHolder.getSpeed());
     601          560 :     myConsum = 0;
     602          560 : }
     603              : 
     604              : 
     605              : void
     606         1617 : MSDevice_Battery::generateOutput(OutputDevice* tripinfoOut) const {
     607         1617 :     if (tripinfoOut != nullptr) {
     608          207 :         tripinfoOut->openTag("battery");
     609          207 :         tripinfoOut->writeAttr("depleted", toString(myDepletedCount));
     610          207 :         tripinfoOut->writeAttr("actualBatteryCapacity", toString(myActualBatteryCapacity));
     611          207 :         tripinfoOut->writeAttr("totalEnergyConsumed", toString(myTotalConsumption));
     612          207 :         tripinfoOut->writeAttr("totalEnergyRegenerated", toString(myTotalRegenerated));
     613          414 :         tripinfoOut->closeTag();
     614              :     }
     615         1617 : }
     616              : 
     617              : 
     618              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1