LCOV - code coverage report
Current view: top level - src/microsim/devices - MSDevice_Battery.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 75.4 % 285 215
Test Date: 2025-12-06 15:35:27 Functions: 87.2 % 39 34

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2013-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_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        39900 : MSDevice_Battery::insertOptions(OptionsCont& oc) {
      52        79800 :     insertDefaultAssignmentOptions("battery", "Battery", oc);
      53              :     // custom options
      54        39900 :     oc.doRegister("device.battery.track-fuel", new Option_Bool(false));
      55        79800 :     oc.addDescription("device.battery.track-fuel", "Battery", TL("Track fuel consumption for non-electric vehicles"));
      56        39900 : }
      57              : 
      58              : 
      59              : void
      60      5382009 : MSDevice_Battery::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into, MSDevice_StationFinder* sf) {
      61              :     // Check if vehicle should get a battery
      62     10763910 :     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      5382009 : }
      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              :     SUMOVehicle& veh = static_cast<SUMOVehicle&>(tObject);
     177              :     // Start vehicleStoppedTimer if the vehicle is stopped. In other case reset timer
     178       447939 :     if (veh.getSpeed() < myStoppingThreshold) {
     179              :         // Increase vehicle stopped timer
     180       206541 :         increaseVehicleStoppedTimer();
     181              :     } else {
     182              :         // Reset vehicle Stopped
     183       241398 :         resetVehicleStoppedTimer();
     184              :     }
     185              : 
     186              :     // Update Energy from the battery
     187       447939 :     EnergyParams* const params = myHolder.getEmissionParameters();
     188       447939 :     if (getMaximumBatteryCapacity() != 0) {
     189       447939 :         if (!myTrackFuel && !veh.getVehicleType().getParameter().wasSet(VTYPEPARS_EMISSIONCLASS_SET)) {
     190              :             // no explicit emission class, we fall back to the energy model; a warning has been issued on creation
     191          890 :             myConsum = PollutantsInterface::getEnergyHelper().compute(0, PollutantsInterface::ELEC, veh.getSpeed(), veh.getAcceleration(),
     192          890 :                        veh.getSlope(), params) * TS;
     193              :         } else {
     194       447494 :             myConsum = PollutantsInterface::compute(veh.getVehicleType().getEmissionClass(),
     195       447494 :                                                     myTrackFuel ? PollutantsInterface::FUEL : PollutantsInterface::ELEC,
     196       447494 :                                                     veh.getSpeed(), veh.getAcceleration(),
     197       894988 :                                                     veh.getSlope(), params) * TS;
     198              :         }
     199       447939 :         if (veh.isParking()) {
     200              :             // recuperation from last braking step is ok but further consumption should cease
     201         1184 :             myConsum = MIN2(myConsum, 0.0);
     202              :         }
     203              : 
     204              :         // saturate between 0 and myMaximumBatteryCapacity [Wh]
     205       447939 :         if (myConsum > getActualBatteryCapacity() && getActualBatteryCapacity() > 0 && getMaximumBatteryCapacity() > 0) {
     206           32 :             myDepletedCount++;
     207           32 :             if (myDepletedCount == 1) {
     208           48 :                 WRITE_WARNINGF(TL("Battery of vehicle '%' is depleted, time=%."), veh.getID(), time2string(SIMSTEP));
     209              :             }
     210              :         }
     211              : 
     212              :         // Energy lost/gained from vehicle movement (via vehicle energy model) [Wh]
     213       447939 :         setActualBatteryCapacity(getActualBatteryCapacity() - myConsum);
     214              : 
     215              :         // Track total energy consumption and regeneration
     216       447939 :         if (myConsum > 0.0) {
     217       325182 :             myTotalConsumption += myConsum;
     218              :         } else {
     219       122757 :             myTotalRegenerated -= myConsum;
     220              :         }
     221              : 
     222       447939 :         myLastAngle = veh.getAngle();
     223              :     }
     224              : 
     225              :     // Check if vehicle has under their position one charge Station
     226       447939 :     const std::string chargingStationID = MSNet::getInstance()->getStoppingPlaceID(veh.getLane(), veh.getPositionOnLane(), SUMO_TAG_CHARGING_STATION);
     227              : 
     228              :     // If vehicle is over a charging station
     229       447939 :     if (chargingStationID != "") {
     230              :         // if the vehicle is almost stopped, or charge in transit is enabled, then charge vehicle
     231       103550 :         MSChargingStation* const cs = static_cast<MSChargingStation*>(MSNet::getInstance()->getStoppingPlace(chargingStationID, SUMO_TAG_CHARGING_STATION));
     232       103550 :         const MSParkingArea* pa = cs->getParkingArea();
     233       103550 :         if (((veh.getSpeed() < myStoppingThreshold) || cs->getChargeInTransit()) && (pa == nullptr || veh.isParking()) && cs->getChargeType() == myChargeType) {
     234              :             // Set Flags Stopped/intransit to
     235       101336 :             if (veh.getSpeed() < myStoppingThreshold) {
     236              :                 // vehicle ist almost stopped, then is charging stopped
     237       100005 :                 myChargingStopped = true;
     238              : 
     239              :                 // therefore isn't charging in transit
     240       100005 :                 myChargingInTransit = false;
     241              :             } else {
     242              :                 // vehicle is moving, and the Charging station allow charge in transit
     243         1331 :                 myChargingStopped = false;
     244              : 
     245              :                 // Therefore charge in transit
     246         1331 :                 myChargingInTransit = true;
     247              :             }
     248              : 
     249              :             // get pointer to charging station
     250       101336 :             myActChargingStation = cs;
     251              : 
     252              :             // Only update charging start time if vehicle allow charge in transit, or in other case
     253              :             // if the vehicle not allow charge in transit but it's stopped.
     254       101336 :             if ((myActChargingStation->getChargeInTransit()) || (veh.getSpeed() < myStoppingThreshold)) {
     255              :                 // Update Charging start time
     256       101336 :                 increaseChargingStartTime();
     257              :             }
     258              : 
     259              :             // time it takes the vehicle at the station < charging station time delay?
     260       101336 :             if (getChargingStartTime() > myActChargingStation->getChargeDelay()) {
     261              :                 // Enable charging vehicle
     262       100381 :                 myActChargingStation->setChargingVehicle(true);
     263              : 
     264              :                 // Calulate energy charged
     265       203634 :                 myEnergyCharged = MIN2(MIN2(myActChargingStation->getChargingPower(myTrackFuel) * myActChargingStation->getEfficency(), getMaximumChargeRate() * (myTrackFuel ? 1 : 1. / 3600.)) * TS, getMaximumBatteryCapacity() - getActualBatteryCapacity());
     266              : 
     267              :                 // Update Battery charge
     268       100381 :                 setActualBatteryCapacity(getActualBatteryCapacity() + myEnergyCharged);
     269              :             }
     270              :             // add charge value for output to myActChargingStation
     271       101336 :             myActChargingStation->addChargeValueForOutput(myEnergyCharged, this);
     272              :         }
     273              :         // else disable charging vehicle
     274              :         else {
     275         2214 :             cs->setChargingVehicle(false);
     276              :         }
     277              :         // 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)
     278       103550 :         if (myPreviousNeighbouringChargingStation != nullptr && myPreviousNeighbouringChargingStation != cs) {
     279          485 :             myPreviousNeighbouringChargingStation->setChargingVehicle(false);
     280              :         }
     281       103550 :         myPreviousNeighbouringChargingStation = cs;
     282              :     }
     283              :     // In other case, vehicle will be not charged
     284              :     else {
     285              :         // Disable flags
     286       344389 :         myChargingInTransit = false;
     287       344389 :         myChargingStopped = false;
     288              : 
     289              :         // Disable charging vehicle
     290       344389 :         if (myActChargingStation != nullptr) {
     291          556 :             myActChargingStation->setChargingVehicle(false);
     292              :         }
     293              : 
     294              :         // Set charging station pointer to NULL
     295       344389 :         myActChargingStation = nullptr;
     296              : 
     297              :         // Set energy charged to 0
     298       344389 :         myEnergyCharged = 0;
     299              : 
     300              :         // Reset timer
     301       344389 :         resetChargingStartTime();
     302              :     }
     303              : 
     304              :     // Always return true.
     305              :     return true;
     306              : }
     307              : 
     308              : 
     309              : void
     310            0 : MSDevice_Battery::saveState(OutputDevice& out) const {
     311            0 :     out.openTag(SUMO_TAG_DEVICE);
     312            0 :     out.writeAttr(SUMO_ATTR_ID, getID());
     313              :     std::vector<std::string> internals;
     314            0 :     internals.push_back(toString(myActualBatteryCapacity));
     315            0 :     internals.push_back(toString(myLastAngle));
     316            0 :     internals.push_back(toString(myChargingStopped));
     317            0 :     internals.push_back(toString(myChargingInTransit));
     318            0 :     internals.push_back(toString(myChargingStartTime));
     319            0 :     internals.push_back(toString(myTotalConsumption));
     320            0 :     internals.push_back(toString(myTotalRegenerated));
     321            0 :     internals.push_back(toString(myEnergyCharged));
     322            0 :     internals.push_back(toString(myVehicleStopped));
     323            0 :     internals.push_back(getChargingStationID());
     324            0 :     std::string prevChargingID = (myPreviousNeighbouringChargingStation == nullptr) ? "NULL" : myPreviousNeighbouringChargingStation->getID();
     325            0 :     internals.push_back(prevChargingID);
     326            0 :     internals.push_back(toString(myMaximumChargeRate));
     327            0 :     out.writeAttr(SUMO_ATTR_STATE, toString(internals));
     328            0 :     out.closeTag();
     329            0 : }
     330              : 
     331              : 
     332              : void
     333            0 : MSDevice_Battery::loadState(const SUMOSAXAttributes& attrs) {
     334            0 :     std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
     335            0 :     bis >> myActualBatteryCapacity;
     336            0 :     bis >> myLastAngle;
     337            0 :     bis >> myChargingStopped;
     338            0 :     bis >> myChargingInTransit;
     339            0 :     bis >> myChargingStartTime;
     340            0 :     bis >> myTotalConsumption;
     341            0 :     bis >> myTotalRegenerated;
     342            0 :     bis >> myEnergyCharged;
     343            0 :     bis >> myVehicleStopped;
     344              :     std::string chargingID;
     345            0 :     bis >> chargingID;
     346            0 :     if (chargingID != "NULL") {
     347            0 :         myActChargingStation = dynamic_cast<MSChargingStation*>(MSNet::getInstance()->getStoppingPlace(chargingID, SUMO_TAG_CHARGING_STATION));
     348              :     }
     349              :     std::string prevChargingID;
     350            0 :     bis >> prevChargingID;
     351            0 :     if (prevChargingID != "NULL") {
     352            0 :         myPreviousNeighbouringChargingStation = dynamic_cast<MSChargingStation*>(MSNet::getInstance()->getStoppingPlace(prevChargingID, SUMO_TAG_CHARGING_STATION));
     353              :     }
     354            0 :     bis >> myMaximumChargeRate;
     355            0 : }
     356              : 
     357              : 
     358              : void
     359       548520 : MSDevice_Battery::setActualBatteryCapacity(const double actualBatteryCapacity) {
     360       548520 :     if (actualBatteryCapacity < 0) {
     361         1340 :         myActualBatteryCapacity = 0;
     362       547180 :     } else if (actualBatteryCapacity > myMaximumBatteryCapacity) {
     363            4 :         myActualBatteryCapacity = myMaximumBatteryCapacity;
     364              :     } else {
     365       547176 :         myActualBatteryCapacity = actualBatteryCapacity;
     366              :     }
     367       548520 : }
     368              : 
     369              : 
     370              : void
     371            9 : MSDevice_Battery::setMaximumBatteryCapacity(const double maximumBatteryCapacity) {
     372            9 :     if (myMaximumBatteryCapacity < 0) {
     373            0 :         WRITE_WARNINGF(TL("Trying to set into the battery device of vehicle '%' an invalid % (%)."), getID(), toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY), toString(maximumBatteryCapacity));
     374              :     } else {
     375            9 :         myMaximumBatteryCapacity = maximumBatteryCapacity;
     376              :     }
     377            9 : }
     378              : 
     379              : 
     380              : void
     381            0 : MSDevice_Battery::setStoppingThreshold(const double stoppingThreshold) {
     382            0 :     if (stoppingThreshold < 0) {
     383            0 :         WRITE_WARNINGF(TL("Trying to set into the battery device of vehicle '%' an invalid % (%)."), getID(), toString(SUMO_ATTR_STOPPINGTHRESHOLD), toString(stoppingThreshold));
     384              :     } else {
     385            0 :         myStoppingThreshold = stoppingThreshold;
     386              :     }
     387            0 : }
     388              : 
     389              : 
     390              : void
     391            0 : MSDevice_Battery::setMaximumChargeRate(const double chargeRate) {
     392            0 :     if (chargeRate < 0) {
     393            0 :         WRITE_WARNINGF(TL("Trying to set into the battery device of vehicle '%' an invalid % (%)."), getID(), toString(SUMO_ATTR_MAXIMUMCHARGERATE), toString(chargeRate));
     394              :     } else {
     395            0 :         myMaximumChargeRate = chargeRate;
     396              :     }
     397            0 : }
     398              : 
     399              : 
     400              : void
     401            8 : MSDevice_Battery::setChargeLimit(const double limit) {
     402            8 :     myChargeLimit = limit;
     403            8 : }
     404              : 
     405              : 
     406              : void
     407       344389 : MSDevice_Battery::resetChargingStartTime() {
     408       344389 :     myChargingStartTime = 0;
     409       344389 : }
     410              : 
     411              : 
     412              : void
     413       101336 : MSDevice_Battery::increaseChargingStartTime() {
     414       101336 :     myChargingStartTime += DELTA_T;
     415       101336 : }
     416              : 
     417              : 
     418              : void
     419       241398 : MSDevice_Battery::resetVehicleStoppedTimer() {
     420       241398 :     myVehicleStopped = 0;
     421       241398 : }
     422              : 
     423              : 
     424              : void
     425       206541 : MSDevice_Battery::increaseVehicleStoppedTimer() {
     426       206541 :     myVehicleStopped++;
     427       206541 : }
     428              : 
     429              : 
     430              : void
     431          200 : MSDevice_Battery::setEnergyCharged(const double energyCharged) {
     432          200 :     myEnergyCharged = energyCharged;
     433          200 : }
     434              : 
     435              : 
     436              : double
     437      1368033 : MSDevice_Battery::getActualBatteryCapacity() const {
     438      1368033 :     return myActualBatteryCapacity;
     439              : }
     440              : 
     441              : 
     442              : double
     443       938493 : MSDevice_Battery::getMaximumBatteryCapacity() const {
     444       938493 :     return myMaximumBatteryCapacity;
     445              : }
     446              : 
     447              : 
     448              : double
     449       119416 : MSDevice_Battery::getConsum() const {
     450       119416 :     return myConsum;
     451              : }
     452              : 
     453              : double
     454       120473 : MSDevice_Battery::getTotalConsumption() const {
     455       120473 :     return myTotalConsumption;
     456              : }
     457              : 
     458              : 
     459              : double
     460       119416 : MSDevice_Battery::getTotalRegenerated() const {
     461       119416 :     return myTotalRegenerated;
     462              : }
     463              : 
     464              : 
     465              : bool
     466       119326 : MSDevice_Battery::isChargingStopped() const {
     467       119326 :     return myChargingStopped;
     468              : }
     469              : 
     470              : 
     471              : bool
     472       119326 : MSDevice_Battery::isChargingInTransit() const {
     473       119326 :     return myChargingInTransit;
     474              : }
     475              : 
     476              : 
     477              : SUMOTime
     478       200945 : MSDevice_Battery::getChargingStartTime() const {
     479       200945 :     return myChargingStartTime;
     480              : }
     481              : 
     482              : 
     483              : SUMOTime
     484            0 : MSDevice_Battery::estimateChargingDuration(const double toCharge, const double csPower) const {
     485              :     //if (!myChargeCurve.empty()) {
     486              :     //    // TODO: integrate charge curve
     487              :     //}
     488            0 :     return TIME2STEPS(toCharge / MIN2(csPower, myMaximumChargeRate));
     489              : }
     490              : 
     491              : 
     492              : std::string
     493       119416 : MSDevice_Battery::getChargingStationID() const {
     494       119416 :     if (myActChargingStation != nullptr) {
     495              :         return myActChargingStation->getID();
     496              :     } else {
     497        90580 :         return "NULL";
     498              :     }
     499              : }
     500              : 
     501              : double
     502       287626 : MSDevice_Battery::getEnergyCharged() const {
     503       287626 :     return myEnergyCharged;
     504              : }
     505              : 
     506              : 
     507              : int
     508       119326 : MSDevice_Battery::getVehicleStopped() const {
     509       119326 :     return myVehicleStopped;
     510              : }
     511              : 
     512              : 
     513              : double
     514        99241 : MSDevice_Battery::getStoppingThreshold() const {
     515        99241 :     return myStoppingThreshold;
     516              : }
     517              : 
     518              : 
     519              : double
     520       100381 : MSDevice_Battery::getMaximumChargeRate() const {
     521       100381 :     double baseVal = (myChargeCurve.empty()) ? myMaximumChargeRate : LinearApproxHelpers::getInterpolatedValue(myChargeCurve, myActualBatteryCapacity / myMaximumBatteryCapacity);
     522       100381 :     return (myChargeLimit < 0) ? baseVal : MIN2(myChargeLimit, baseVal);
     523              : }
     524              : 
     525              : 
     526              : bool
     527          108 : MSDevice_Battery::tracksFuel() const {
     528          108 :     return myTrackFuel;
     529              : }
     530              : 
     531              : 
     532              : MSChargingStation::ChargeType
     533          504 : MSDevice_Battery::getChargeType() const {
     534          504 :     return myChargeType;
     535              : }
     536              : 
     537              : 
     538              : std::string
     539          768 : MSDevice_Battery::getParameter(const std::string& key) const {
     540         1536 :     if (key == toString(SUMO_ATTR_ACTUALBATTERYCAPACITY)
     541         1536 :             || key == toString(SUMO_ATTR_CHARGELEVEL)) {
     542           90 :         return toString(getActualBatteryCapacity());
     543          678 :     } else if (key == toString(SUMO_ATTR_ENERGYCONSUMED)) {
     544           90 :         return toString(getConsum());
     545          588 :     } else if (key == "chargePower") {
     546           60 :         return toString(getEnergyCharged() * 3600.);
     547          528 :     } else if (key == "usedAverage") {
     548           60 :         return toString(getTotalConsumption() * 3600 / STEPS2TIME(SIMSTEP - myHolder.getDeparture()));
     549          468 :     } else if (key == toString(SUMO_ATTR_TOTALENERGYCONSUMED)) {
     550           90 :         return toString(getTotalConsumption());
     551          378 :     } else if (key == toString(SUMO_ATTR_TOTALENERGYREGENERATED)) {
     552           90 :         return toString(getTotalRegenerated());
     553          288 :     } else if (key == toString(SUMO_ATTR_ENERGYCHARGED)) {
     554           90 :         return toString(getEnergyCharged());
     555          396 :     } else if (key == toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY) || key == "capacity") {
     556           99 :         return toString(getMaximumBatteryCapacity());
     557           99 :     } else if (key == toString(SUMO_ATTR_MAXIMUMCHARGERATE)) {
     558            0 :         return toString(getMaximumChargeRate());
     559           99 :     } else if (key == toString(SUMO_ATTR_CHARGINGSTATIONID)) {
     560           90 :         return getChargingStationID();
     561              :     }
     562           27 :     throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
     563              : }
     564              : 
     565              : 
     566              : void
     567            9 : MSDevice_Battery::setParameter(const std::string& key, const std::string& value) {
     568              :     double doubleValue;
     569              :     try {
     570            9 :         doubleValue = StringUtils::toDouble(value);
     571            0 :     } catch (NumberFormatException&) {
     572            0 :         throw InvalidArgument("Setting parameter '" + key + "' requires a number for device of type '" + deviceName() + "'");
     573            0 :     }
     574           18 :     if (key == toString(SUMO_ATTR_ACTUALBATTERYCAPACITY) || key == toString(SUMO_ATTR_CHARGELEVEL)) {
     575            0 :         setActualBatteryCapacity(doubleValue);
     576           18 :     } else if (key == toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY) || key == "capacity") {
     577            9 :         setMaximumBatteryCapacity(doubleValue);
     578            0 :     } else if (key == toString(SUMO_ATTR_MAXIMUMCHARGERATE)) {
     579            0 :         setMaximumChargeRate(doubleValue);
     580              :     } else {
     581            0 :         throw InvalidArgument("Setting parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
     582              :     }
     583            9 : }
     584              : 
     585              : 
     586              : void
     587          560 : MSDevice_Battery::notifyParking() {
     588              :     // @note: only charing is performed but no energy is consumed
     589          560 :     notifyMove(myHolder, myHolder.getPositionOnLane(), myHolder.getPositionOnLane(), myHolder.getSpeed());
     590          560 :     myConsum = 0;
     591          560 : }
     592              : 
     593              : 
     594              : void
     595         1619 : MSDevice_Battery::generateOutput(OutputDevice* tripinfoOut) const {
     596         1619 :     if (tripinfoOut != nullptr) {
     597          209 :         tripinfoOut->openTag("battery");
     598          418 :         tripinfoOut->writeAttr("depleted", toString(myDepletedCount));
     599          418 :         tripinfoOut->writeAttr("actualBatteryCapacity", toString(myActualBatteryCapacity));
     600          418 :         tripinfoOut->writeAttr("totalEnergyConsumed", toString(myTotalConsumption));
     601          418 :         tripinfoOut->writeAttr("totalEnergyRegenerated", toString(myTotalRegenerated));
     602          418 :         tripinfoOut->closeTag();
     603              :     }
     604         1619 : }
     605              : 
     606              : 
     607              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1