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-02 16:00:03 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        42243 : MSDevice_Battery::insertOptions(OptionsCont& oc) {
      52        84486 :     insertDefaultAssignmentOptions("battery", "Battery", oc);
      53              :     // custom options
      54        42243 :     oc.doRegister("device.battery.track-fuel", new Option_Bool(false));
      55        84486 :     oc.addDescription("device.battery.track-fuel", "Battery", TL("Track fuel consumption for non-electric vehicles"));
      56        42243 : }
      57              : 
      58              : 
      59              : void
      60      5537923 : MSDevice_Battery::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into, MSDevice_StationFinder* sf) {
      61              :     // Check if vehicle should get a battery
      62     11075738 :     if (sf != nullptr || equippedByDefaultAssignmentOptions(OptionsCont::getOptions(), "battery", v, false)) {
      63              :         // obtain parameter values
      64         1701 :         const double maximumBatteryCapacity = readParameterValue(v, SUMO_ATTR_MAXIMUMBATTERYCAPACITY, "battery.capacity", DEFAULT_MAX_CAPACITY);
      65         1701 :         const double actualBatteryCapacity = readParameterValue(v, SUMO_ATTR_ACTUALBATTERYCAPACITY, "battery.chargeLevel", maximumBatteryCapacity * DEFAULT_CHARGE_RATIO);
      66         1701 :         const double stoppingThreshold = readParameterValue(v, SUMO_ATTR_STOPPINGTHRESHOLD, "battery.stoppingThreshold", 0.1);
      67         1701 :         const double maximumChargeRate = readParameterValue(v, SUMO_ATTR_MAXIMUMCHARGERATE, "battery.maximumChargeRate", 150000.);
      68         3402 :         const std::string chargeLevelTable = v.getStringParam("device.battery.chargeLevelTable");
      69         3402 :         const std::string chargeCurveTable = v.getStringParam("device.battery.chargeCurveTable");
      70              : 
      71              :         // battery constructor
      72         1701 :         MSDevice_Battery* device = new MSDevice_Battery(v, "battery_" + v.getID(),
      73         3402 :                 actualBatteryCapacity, maximumBatteryCapacity, stoppingThreshold, maximumChargeRate, chargeLevelTable, chargeCurveTable);
      74              : 
      75              :         // Add device to vehicle
      76         1701 :         into.push_back(device);
      77              : 
      78         1701 :         if (sf != nullptr) {
      79              :             sf->setBattery(device);
      80              :         }
      81              :         // ensure that parameters are initialized
      82         1701 :         v.getEmissionParameters();
      83              :     }
      84      5537923 : }
      85              : 
      86              : 
      87              : double
      88         6804 : MSDevice_Battery::readParameterValue(SUMOVehicle& v, const SumoXMLAttr& attr, const std::string& paramName, double defaultVal) {
      89         6804 :     const std::string& oldParam = toString(attr);
      90         6804 :     const SUMOVTypeParameter& typeParams = v.getVehicleType().getParameter();
      91         6804 :     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        13608 :     return v.getFloatParam("device." + paramName, false, defaultVal);
      99              : }
     100              : 
     101              : 
     102              : // ---------------------------------------------------------------------------
     103              : // MSDevice_Battery-methods
     104              : // ---------------------------------------------------------------------------
     105         1701 : MSDevice_Battery::MSDevice_Battery(SUMOVehicle& holder, const std::string& id, const double actualBatteryCapacity, const double maximumBatteryCapacity,
     106         1701 :                                    const double stoppingThreshold, const double maximumChargeRate, const std::string& chargeLevelTable, const std::string& chargeCurveTable) :
     107              :     MSVehicleDevice(holder, id),
     108         1701 :     myActualBatteryCapacity(0),         // [actualBatteryCapacity <= maximumBatteryCapacity]
     109         1701 :     myMaximumBatteryCapacity(0),        // [maximumBatteryCapacity >= 0]
     110         1701 :     myStoppingThreshold(0),             // [stoppingThreshold >= 0]
     111         1701 :     myMaximumChargeRate(0),
     112         1701 :     myChargeLimit(-1),
     113         1701 :     myLastAngle(std::numeric_limits<double>::infinity()),
     114         1701 :     myChargingStopped(false),           // Initially vehicle don't charge stopped
     115         1701 :     myChargingInTransit(false),         // Initially vehicle don't charge in transit
     116         1701 :     myChargingStartTime(0),             // Initially charging start time (must be if the vehicle was launched at the charging station)
     117         1701 :     myConsum(0),                        // Initially the vehicle is stopped and therefore the consum is zero.
     118         1701 :     myTotalConsumption(0.0),
     119         1701 :     myTotalRegenerated(0.0),
     120         1701 :     myActChargingStation(nullptr),         // Initially the vehicle isn't over a Charging Station
     121         1701 :     myPreviousNeighbouringChargingStation(nullptr),    // Initially the vehicle wasn't over a Charging Station
     122         1701 :     myEnergyCharged(0),                 // Initially the energy charged is zero
     123         1701 :     myVehicleStopped(0),
     124         1701 :     myDepletedCount(0) {
     125              :     // Initially the vehicle is stopped and the corresponding variable is 0
     126              : 
     127         1701 :     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         1701 :         myMaximumBatteryCapacity = maximumBatteryCapacity;
     131              :     }
     132              : 
     133         1701 :     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         1701 :         myActualBatteryCapacity = actualBatteryCapacity;
     139              :     }
     140              : 
     141         1701 :     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         1701 :         myStoppingThreshold = stoppingThreshold;
     145              :     }
     146              : 
     147         1741 :     myTrackFuel = PollutantsInterface::getFuel(holder.getVehicleType().getEmissionClass()) != "Electricity" && OptionsCont::getOptions().getBool("device.battery.track-fuel");
     148         1701 :     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         1701 :     myChargeType = (myTrackFuel) ? MSChargingStation::ChargeType::CHARGETYPE_FUEL : MSChargingStation::ChargeType::CHARGETYPE_NORMAL;
     154              : 
     155         1701 :     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         1701 :         if (!chargeLevelTable.empty() && !chargeCurveTable.empty()) {
     159            0 :             LinearApproxHelpers::setPoints(myChargeCurve, chargeLevelTable, chargeCurveTable);
     160            0 :             myMaximumChargeRate = LinearApproxHelpers::getMaximumValue(myChargeCurve);
     161              :         } else {
     162         1701 :             myMaximumChargeRate = maximumChargeRate;
     163              :         }
     164              :     }
     165         1701 : }
     166              : 
     167              : 
     168         3402 : MSDevice_Battery::~MSDevice_Battery() {
     169         3402 : }
     170              : 
     171              : 
     172       447939 : bool MSDevice_Battery::notifyMove(SUMOTrafficObject& tObject, double /* oldPos */, double /* newPos */, double newSpeed) {
     173       447939 :     if (!tObject.isVehicle()) {
     174              :         return false;
     175              :     }
     176       447939 :     notifyMoveInternal(tObject, 0., TS, 0., newSpeed, 0., 0., 0.);
     177       447939 :     return true;
     178              : }
     179              : 
     180              : 
     181              : void
     182       456811 : 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       456811 :     if (meanSpeedVehicleOnLane < myStoppingThreshold) {
     193              :         // Increase vehicle stopped timer
     194       206541 :         increaseVehicleStoppedTimer();
     195              :     } else {
     196              :         // Reset vehicle Stopped
     197       250270 :         resetVehicleStoppedTimer();
     198              :     }
     199              : 
     200              :     // Update Energy from the battery
     201       456811 :     EnergyParams* const params = myHolder.getEmissionParameters();
     202       456811 :     if (getMaximumBatteryCapacity() != 0) {
     203       456811 :         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       456278 :             myConsum = PollutantsInterface::compute(veh.getVehicleType().getEmissionClass(),
     209       456278 :                                                     myTrackFuel ? PollutantsInterface::FUEL : PollutantsInterface::ELEC,
     210       456278 :                                                     meanSpeedVehicleOnLane, veh.getAcceleration(),
     211       912556 :                                                     veh.getSlope(), params) * timeOnLane;
     212              :         }
     213       456811 :         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       456811 :         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       456811 :         setActualBatteryCapacity(getActualBatteryCapacity() - myConsum);
     228              : 
     229              :         // Track total energy consumption and regeneration
     230       456811 :         if (myConsum > 0.0) {
     231       333254 :             myTotalConsumption += myConsum;
     232              :         } else {
     233       123557 :             myTotalRegenerated -= myConsum;
     234              :         }
     235              : 
     236       456811 :         myLastAngle = veh.getAngle();
     237              :     }
     238              : 
     239              :     // Check if vehicle has under their position one charge Station
     240       456811 :     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       456811 :     if (chargingStationID != "") {
     244              :         // if the vehicle is almost stopped, or charge in transit is enabled, then charge vehicle
     245       103550 :         MSChargingStation* const cs = static_cast<MSChargingStation*>(MSNet::getInstance()->getStoppingPlace(chargingStationID, SUMO_TAG_CHARGING_STATION));
     246       103550 :         const MSParkingArea* pa = cs->getParkingArea();
     247       103550 :         if (((meanSpeedVehicleOnLane < myStoppingThreshold) || cs->getChargeInTransit()) && (pa == nullptr || veh.isParking()) && cs->getChargeType() == myChargeType) {
     248              :             // Set Flags Stopped/intransit to
     249       101336 :             if (meanSpeedVehicleOnLane < myStoppingThreshold) {
     250              :                 // vehicle ist almost stopped, then is charging stopped
     251       100005 :                 myChargingStopped = true;
     252              : 
     253              :                 // therefore isn't charging in transit
     254       100005 :                 myChargingInTransit = false;
     255              :             } else {
     256              :                 // vehicle is moving, and the Charging station allow charge in transit
     257         1331 :                 myChargingStopped = false;
     258              : 
     259              :                 // Therefore charge in transit
     260         1331 :                 myChargingInTransit = true;
     261              :             }
     262              : 
     263              :             // get pointer to charging station
     264       101336 :             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       101336 :             if ((myActChargingStation->getChargeInTransit()) || (meanSpeedVehicleOnLane < myStoppingThreshold)) {
     269              :                 // Update Charging start time
     270       101336 :                 increaseChargingStartTime();
     271              :             }
     272              : 
     273              :             // time it takes the vehicle at the station < charging station time delay?
     274       101336 :             if (getChargingStartTime() > myActChargingStation->getChargeDelay()) {
     275              :                 // Enable charging vehicle
     276       100381 :                 myActChargingStation->setChargingVehicle(true);
     277              : 
     278              :                 // Calulate energy charged
     279       203634 :                 myEnergyCharged = MIN2(MIN2(myActChargingStation->getChargingPower(myTrackFuel) * myActChargingStation->getEfficency(), getMaximumChargeRate() * (myTrackFuel ? 1 : 1. / 3600.)) * timeOnLane, getMaximumBatteryCapacity() - getActualBatteryCapacity());
     280              : 
     281              :                 // Update Battery charge
     282       100381 :                 setActualBatteryCapacity(getActualBatteryCapacity() + myEnergyCharged);
     283              :             }
     284              :             // add charge value for output to myActChargingStation
     285       101336 :             myActChargingStation->addChargeValueForOutput(myEnergyCharged, this);
     286              :         }
     287              :         // else disable charging vehicle
     288              :         else {
     289         2214 :             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       103550 :         if (myPreviousNeighbouringChargingStation != nullptr && myPreviousNeighbouringChargingStation != cs) {
     293          485 :             myPreviousNeighbouringChargingStation->setChargingVehicle(false);
     294              :         }
     295       103550 :         myPreviousNeighbouringChargingStation = cs;
     296              :     }
     297              :     // In other case, vehicle will be not charged
     298              :     else {
     299              :         // Disable flags
     300       353261 :         myChargingInTransit = false;
     301       353261 :         myChargingStopped = false;
     302              : 
     303              :         // Disable charging vehicle
     304       353261 :         if (myActChargingStation != nullptr) {
     305          556 :             myActChargingStation->setChargingVehicle(false);
     306              :         }
     307              : 
     308              :         // Set charging station pointer to NULL
     309       353261 :         myActChargingStation = nullptr;
     310              : 
     311              :         // Set energy charged to 0
     312       353261 :         myEnergyCharged = 0;
     313              : 
     314              :         // Reset timer
     315       353261 :         resetChargingStartTime();
     316              :     }
     317       456811 : }
     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       557392 : MSDevice_Battery::setActualBatteryCapacity(const double actualBatteryCapacity) {
     371       557392 :     if (actualBatteryCapacity < 0) {
     372         1340 :         myActualBatteryCapacity = 0;
     373       556052 :     } else if (actualBatteryCapacity > myMaximumBatteryCapacity) {
     374            4 :         myActualBatteryCapacity = myMaximumBatteryCapacity;
     375              :     } else {
     376       556048 :         myActualBatteryCapacity = actualBatteryCapacity;
     377              :     }
     378       557392 : }
     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       353261 : MSDevice_Battery::resetChargingStartTime() {
     419       353261 :     myChargingStartTime = 0;
     420       353261 : }
     421              : 
     422              : 
     423              : void
     424       101336 : MSDevice_Battery::increaseChargingStartTime() {
     425       101336 :     myChargingStartTime += DELTA_T;
     426       101336 : }
     427              : 
     428              : 
     429              : void
     430       250270 : MSDevice_Battery::resetVehicleStoppedTimer() {
     431       250270 :     myVehicleStopped = 0;
     432       250270 : }
     433              : 
     434              : 
     435              : void
     436       206541 : MSDevice_Battery::increaseVehicleStoppedTimer() {
     437       206541 :     myVehicleStopped++;
     438       206541 : }
     439              : 
     440              : 
     441              : void
     442          200 : MSDevice_Battery::setEnergyCharged(const double energyCharged) {
     443          200 :     myEnergyCharged = energyCharged;
     444          200 : }
     445              : 
     446              : 
     447              : double
     448      1385777 : MSDevice_Battery::getActualBatteryCapacity() const {
     449      1385777 :     return myActualBatteryCapacity;
     450              : }
     451              : 
     452              : 
     453              : double
     454       947365 : MSDevice_Battery::getMaximumBatteryCapacity() const {
     455       947365 :     return myMaximumBatteryCapacity;
     456              : }
     457              : 
     458              : 
     459              : double
     460       119416 : MSDevice_Battery::getConsum() const {
     461       119416 :     return myConsum;
     462              : }
     463              : 
     464              : double
     465       120473 : MSDevice_Battery::getTotalConsumption() const {
     466       120473 :     return myTotalConsumption;
     467              : }
     468              : 
     469              : 
     470              : double
     471       119416 : MSDevice_Battery::getTotalRegenerated() const {
     472       119416 :     return myTotalRegenerated;
     473              : }
     474              : 
     475              : 
     476              : bool
     477       119326 : MSDevice_Battery::isChargingStopped() const {
     478       119326 :     return myChargingStopped;
     479              : }
     480              : 
     481              : 
     482              : bool
     483       119326 : MSDevice_Battery::isChargingInTransit() const {
     484       119326 :     return myChargingInTransit;
     485              : }
     486              : 
     487              : 
     488              : SUMOTime
     489       200945 : MSDevice_Battery::getChargingStartTime() const {
     490       200945 :     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       119416 : MSDevice_Battery::getChargingStationID() const {
     505       119416 :     if (myActChargingStation != nullptr) {
     506              :         return myActChargingStation->getID();
     507              :     } else {
     508        90580 :         return "NULL";
     509              :     }
     510              : }
     511              : 
     512              : double
     513       287626 : MSDevice_Battery::getEnergyCharged() const {
     514       287626 :     return myEnergyCharged;
     515              : }
     516              : 
     517              : 
     518              : int
     519       119326 : MSDevice_Battery::getVehicleStopped() const {
     520       119326 :     return myVehicleStopped;
     521              : }
     522              : 
     523              : 
     524              : double
     525        99241 : MSDevice_Battery::getStoppingThreshold() const {
     526        99241 :     return myStoppingThreshold;
     527              : }
     528              : 
     529              : 
     530              : double
     531       100381 : MSDevice_Battery::getMaximumChargeRate() const {
     532       100381 :     double baseVal = (myChargeCurve.empty()) ? myMaximumChargeRate : LinearApproxHelpers::getInterpolatedValue(myChargeCurve, myActualBatteryCapacity / myMaximumBatteryCapacity);
     533       100381 :     return (myChargeLimit < 0) ? baseVal : MIN2(myChargeLimit, baseVal);
     534              : }
     535              : 
     536              : 
     537              : bool
     538          108 : MSDevice_Battery::tracksFuel() const {
     539          108 :     return myTrackFuel;
     540              : }
     541              : 
     542              : 
     543              : MSChargingStation::ChargeType
     544          504 : MSDevice_Battery::getChargeType() const {
     545          504 :     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         1619 : MSDevice_Battery::generateOutput(OutputDevice* tripinfoOut) const {
     607         1619 :     if (tripinfoOut != nullptr) {
     608          209 :         tripinfoOut->openTag("battery");
     609          418 :         tripinfoOut->writeAttr("depleted", toString(myDepletedCount));
     610          418 :         tripinfoOut->writeAttr("actualBatteryCapacity", toString(myActualBatteryCapacity));
     611          418 :         tripinfoOut->writeAttr("totalEnergyConsumed", toString(myTotalConsumption));
     612          418 :         tripinfoOut->writeAttr("totalEnergyRegenerated", toString(myTotalRegenerated));
     613          418 :         tripinfoOut->closeTag();
     614              :     }
     615         1619 : }
     616              : 
     617              : 
     618              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1