LCOV - code coverage report
Current view: top level - src/microsim/trigger - MSChargingStation.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 91.0 % 166 151
Test Date: 2025-11-13 15:38:19 Functions: 86.4 % 22 19

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    MSChargingStation.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Tamas Kurczveil
      17              : /// @author  Pablo Alvarez Lopez
      18              : /// @author  Mirko Barthauer
      19              : /// @date    20-12-13
      20              : ///
      21              : // Charging Station for Electric vehicles
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <cassert>
      26              : #include <utils/common/StringUtils.h>
      27              : #include <utils/vehicle/SUMOVehicle.h>
      28              : #include <microsim/MSParkingArea.h>
      29              : #include <microsim/MSVehicleType.h>
      30              : #include <microsim/MSStoppingPlace.h>
      31              : #include <microsim/devices/MSDevice_Battery.h>
      32              : #include <microsim/MSNet.h>
      33              : #include "MSChargingStation.h"
      34              : 
      35              : 
      36              : // ===========================================================================
      37              : // member method definitions
      38              : // ===========================================================================
      39              : 
      40        12157 : MSChargingStation::MSChargingStation(const std::string& chargingStationID, MSLane& lane, double startPos, double endPos,
      41              :                                      const std::string& name, double chargingPower, double efficency, bool chargeInTransit,
      42        12157 :                                      SUMOTime chargeDelay, const std::string& chargeType, SUMOTime waitingTime) :
      43        12157 :     MSStoppingPlace(chargingStationID, SUMO_TAG_CHARGING_STATION, std::vector<std::string>(), lane, startPos, endPos, name),
      44        24314 :     myChargeInTransit(chargeInTransit), myChargeType(stringToChargeType(chargeType)) {
      45        12157 :     if (chargingPower < 0) {
      46            0 :         WRITE_WARNING(TLF("Attribute % for chargingStation with ID='%' is invalid (%).", toString(SUMO_ATTR_CHARGINGPOWER), getID(), toString(chargingPower)))
      47              :     } else {
      48        12157 :         myChargingPower = chargingPower;
      49              :     }
      50        12157 :     if (efficency < 0 || efficency > 1) {
      51            6 :         WRITE_WARNING(TLF("Attribute % for chargingStation with ID='%' is invalid (%).", toString(SUMO_ATTR_EFFICIENCY), getID(), toString(efficency)))
      52              :     } else {
      53        12155 :         myEfficiency = efficency;
      54              :     }
      55        12157 :     if (chargeDelay < 0) {
      56            0 :         WRITE_WARNING(TLF("Attribute % for chargingStation with ID='%' is invalid (%).", toString(SUMO_ATTR_CHARGEDELAY), getID(), toString(chargeDelay)))
      57              :     } else {
      58        12157 :         myChargeDelay = chargeDelay;
      59              :     }
      60        12157 :     if (waitingTime < 0) {
      61            0 :         WRITE_WARNING(TLF("Attribute % for chargingStation with ID='%' is invalid (%).", toString(SUMO_ATTR_WAITINGTIME), getID(), toString(waitingTime)))
      62              :     } else {
      63        12157 :         myWaitingTime = waitingTime;
      64              :     }
      65        12157 :     if (getBeginLanePosition() > getEndLanePosition()) {
      66            0 :         WRITE_WARNING(TLF("ChargingStation with ID='%' doesn't have a valid position (% < %).", getID(), toString(getBeginLanePosition()), toString(getEndLanePosition())));
      67              :     }
      68        12157 : }
      69              : 
      70              : 
      71           11 : MSChargingStation::MSChargingStation(const std::string& chargingStationID, const MSParkingArea* parkingArea, const std::string& name, double chargingPower,
      72           11 :                                      double efficency, bool chargeInTransit, SUMOTime chargeDelay, const std::string& chargeType, SUMOTime waitingTime) :
      73           11 :     MSChargingStation(chargingStationID, const_cast<MSLane&>(parkingArea->getLane()), parkingArea->getBeginLanePosition(), parkingArea->getEndLanePosition(),
      74           22 :                       name, chargingPower, efficency, chargeInTransit, chargeDelay, chargeType, waitingTime) {
      75           11 :     myParkingArea = parkingArea;
      76           11 : }
      77              : 
      78              : 
      79        23948 : MSChargingStation::~MSChargingStation() {
      80        36070 : }
      81              : 
      82              : 
      83              : double
      84        78563 : MSChargingStation::getChargingPower(bool usingFuel) const {
      85        78563 :     if (usingFuel) {
      86         1968 :         return myChargingPower;
      87              :     } else {
      88              :         // Convert from [Ws] to [Wh] (3600s / 1h):
      89        76595 :         return myChargingPower / 3600;
      90              :     }
      91              : }
      92              : 
      93              : 
      94              : double
      95        78225 : MSChargingStation::getEfficency() const {
      96        78225 :     return myEfficiency;
      97              : }
      98              : 
      99              : 
     100              : bool
     101        81225 : MSChargingStation::getChargeInTransit() const {
     102        81225 :     return myChargeInTransit;
     103              : }
     104              : 
     105              : 
     106              : SUMOTime
     107        78423 : MSChargingStation::getChargeDelay() const {
     108        78423 :     return myChargeDelay;
     109              : }
     110              : 
     111              : 
     112              : MSChargingStation::ChargeType
     113        78367 : MSChargingStation::getChargeType() const {
     114        78367 :     return myChargeType;
     115              : }
     116              : 
     117              : 
     118              : SUMOTime
     119            0 : MSChargingStation::getWaitingTime() const {
     120            0 :     return myWaitingTime;
     121              : }
     122              : 
     123              : 
     124              : const MSParkingArea*
     125        84836 : MSChargingStation::getParkingArea() const {
     126        84836 :     return myParkingArea;
     127              : }
     128              : 
     129              : 
     130              : void
     131          511 : MSChargingStation::setChargingPower(double chargingPower) {
     132          511 :     myChargingPower = chargingPower;
     133          511 : }
     134              : 
     135              : 
     136              : void
     137          511 : MSChargingStation::setEfficiency(double efficiency) {
     138          511 :     myEfficiency = efficiency;
     139          511 : }
     140              : 
     141              : 
     142              : void
     143           10 : MSChargingStation::setChargeDelay(SUMOTime delay) {
     144           10 :     myChargeDelay = delay;
     145           10 : }
     146              : 
     147              : 
     148              : void
     149           10 : MSChargingStation::setChargeInTransit(bool value) {
     150           10 :     myChargeInTransit = value;
     151           10 : }
     152              : 
     153              : 
     154              : void
     155        80113 : MSChargingStation::setChargingVehicle(bool value) {
     156        80113 :     myChargingVehicle = value;
     157        80113 : }
     158              : 
     159              : 
     160              : bool
     161            0 : MSChargingStation::vehicleIsInside(const double position) const {
     162            0 :     if ((position >= getBeginLanePosition()) && (position <= getEndLanePosition())) {
     163              :         return true;
     164              :     } else {
     165            0 :         return false;
     166              :     }
     167              : }
     168              : 
     169              : 
     170              : bool
     171            0 : MSChargingStation::isCharging() const {
     172            0 :     return myChargingVehicle;
     173              : }
     174              : 
     175              : 
     176              : void
     177        77981 : MSChargingStation::addChargeValueForOutput(double WCharged, MSDevice_Battery* battery) {
     178       155962 :     if (!OptionsCont::getOptions().isSet("chargingstations-output")) {
     179         1727 :         return;
     180              :     }
     181        76254 :     std::string status = "";
     182        76254 :     if (battery->getChargingStartTime() > myChargeDelay) {
     183        75558 :         if (battery->getHolder().getSpeed() < battery->getStoppingThreshold()) {
     184              :             status = "chargingStopped";
     185          647 :         } else if (myChargeInTransit) {
     186              :             status = "chargingInTransit";
     187              :         } else {
     188              :             status = "noCharging";
     189              :         }
     190              :     } else {
     191          696 :         if (myChargeInTransit) {
     192              :             status = "waitingChargeInTransit";
     193          341 :         } else if (battery->getHolder().getSpeed() < battery->getStoppingThreshold()) {
     194              :             status = "waitingChargeStopped";
     195              :         } else {
     196              :             status = "noWaitingCharge";
     197              :         }
     198              :     }
     199              :     // update total charge
     200        76254 :     myTotalCharge += WCharged;
     201              :     // create charge row and insert it in myChargeValues
     202              :     const std::string vehID = battery->getHolder().getID();
     203              :     if (myChargeValues.count(vehID) == 0) {
     204          357 :         myChargedVehicles.push_back(vehID);
     205              :     }
     206        76254 :     Charge C(MSNet::getInstance()->getCurrentTimeStep(), vehID, battery->getHolder().getVehicleType().getID(),
     207              :              status, WCharged, battery->getActualBatteryCapacity(), battery->getMaximumBatteryCapacity(),
     208       228762 :              myChargingPower, myEfficiency, myTotalCharge);
     209        76254 :     myChargeValues[vehID].push_back(C);
     210        76254 : }
     211              : 
     212              : 
     213              : void
     214          376 : MSChargingStation::writeChargingStationOutput(OutputDevice& output) {
     215          376 :     int chargingSteps = 0;
     216          627 :     for (const auto& item : myChargeValues) {
     217          251 :         chargingSteps += (int)item.second.size();
     218              :     }
     219          376 :     output.openTag(SUMO_TAG_CHARGING_STATION);
     220          376 :     output.writeAttr(SUMO_ATTR_ID, myID);
     221          376 :     output.writeAttr(SUMO_ATTR_TOTALENERGYCHARGED, myTotalCharge);
     222          376 :     output.writeAttr(SUMO_ATTR_CHARGINGSTEPS, chargingSteps);
     223              :     // start writing
     224          376 :     if (myChargeValues.size() > 0) {
     225          377 :         for (const std::string& vehID : myChargedVehicles) {
     226              :             int iStart = 0;
     227          251 :             const auto& chargeSteps = myChargeValues[vehID];
     228          502 :             while (iStart < (int)chargeSteps.size()) {
     229          251 :                 int iEnd = iStart + 1;
     230          251 :                 double charged = chargeSteps[iStart].WCharged;
     231        71784 :                 while (iEnd < (int)chargeSteps.size() && chargeSteps[iEnd].timeStep == chargeSteps[iEnd - 1].timeStep + DELTA_T) {
     232        71533 :                     charged += chargeSteps[iEnd].WCharged;
     233        71533 :                     iEnd++;
     234              :                 }
     235          251 :                 writeVehicle(output, chargeSteps, iStart, iEnd, charged);
     236              :                 iStart = iEnd;
     237              :             }
     238              :         }
     239              :     }
     240              :     // close charging station tag
     241          376 :     output.closeTag();
     242          376 : }
     243              : 
     244              : 
     245              : void
     246        49444 : MSChargingStation::writeAggregatedChargingStationOutput(OutputDevice& output, bool includeUnfinished) {
     247              :     std::vector<std::string> terminatedChargers;
     248        54122 :     for (const auto& item : myChargeValues) {
     249              :         const Charge& lastCharge = item.second.back();
     250              :         // no charge during the last time step == has stopped charging
     251         4678 :         bool finished = lastCharge.timeStep < SIMSTEP - DELTA_T;
     252         4678 :         if (finished || includeUnfinished) {
     253          106 :             if (finished) {
     254          102 :                 terminatedChargers.push_back(item.first);
     255              :             }
     256              :             // aggregate values
     257          106 :             double charged = 0.;
     258          106 :             double minPower = lastCharge.chargingPower;
     259          106 :             double maxPower = lastCharge.chargingPower;
     260          106 :             double minCharge = lastCharge.WCharged;
     261          106 :             double maxCharge = lastCharge.WCharged;
     262          106 :             double minEfficiency = lastCharge.chargingEfficiency;
     263          106 :             double maxEfficiency = lastCharge.chargingEfficiency;
     264         4576 :             for (const auto& charge : item.second) {
     265         4470 :                 charged += charge.WCharged;
     266         4470 :                 if (charge.chargingPower < minPower) {
     267            0 :                     minPower = charge.chargingPower;
     268              :                 }
     269         4470 :                 if (charge.chargingPower > maxPower) {
     270            0 :                     maxPower = charge.chargingPower;
     271              :                 }
     272         4470 :                 if (charge.WCharged < minCharge) {
     273           32 :                     minCharge = charge.WCharged;
     274              :                 }
     275         4470 :                 if (charge.WCharged > maxCharge) {
     276            3 :                     maxCharge = charge.WCharged;
     277              :                 }
     278         4470 :                 if (charge.chargingEfficiency < minEfficiency) {
     279            0 :                     minEfficiency = charge.chargingEfficiency;
     280              :                 }
     281         4470 :                 if (charge.chargingEfficiency > maxEfficiency) {
     282            0 :                     maxEfficiency = charge.chargingEfficiency;
     283              :                 }
     284              :             }
     285              :             // actually write the data
     286          106 :             output.openTag(SUMO_TAG_CHARGING_EVENT);
     287          106 :             output.writeAttr(SUMO_ATTR_CHARGINGSTATIONID, myID);
     288          106 :             output.writeAttr(SUMO_ATTR_VEHICLE, lastCharge.vehicleID);
     289          106 :             output.writeAttr(SUMO_ATTR_TYPE, lastCharge.vehicleType);
     290          106 :             output.writeAttr(SUMO_ATTR_TOTALENERGYCHARGED_VEHICLE, charged);
     291          106 :             output.writeAttr(SUMO_ATTR_CHARGINGBEGIN, time2string(item.second.at(0).timeStep));
     292          106 :             if (finished) {
     293          204 :                 output.writeAttr(SUMO_ATTR_CHARGINGEND, time2string(lastCharge.timeStep));
     294              :             }
     295          106 :             output.writeAttr(SUMO_ATTR_ACTUALBATTERYCAPACITY, lastCharge.actualBatteryCapacity);
     296          106 :             output.writeAttr(SUMO_ATTR_MAXIMUMBATTERYCAPACITY, lastCharge.maxBatteryCapacity);
     297          106 :             output.writeAttr(SUMO_ATTR_MINPOWER, minPower);
     298          106 :             output.writeAttr(SUMO_ATTR_MAXPOWER, maxPower);
     299          106 :             output.writeAttr(SUMO_ATTR_MINCHARGE, minCharge);
     300          106 :             output.writeAttr(SUMO_ATTR_MAXCHARGE, maxCharge);
     301          106 :             output.writeAttr(SUMO_ATTR_MINEFFICIENCY, minEfficiency);
     302          106 :             output.writeAttr(SUMO_ATTR_MAXEFFICIENCY, maxEfficiency);
     303          212 :             output.closeTag();
     304              :         }
     305              :     }
     306              : 
     307              :     // clear charging data of vehicles which terminated charging
     308        49546 :     for (auto vehID : terminatedChargers) {
     309              :         myChargeValues.erase(vehID);
     310              :     }
     311        49444 : }
     312              : 
     313              : 
     314              : void
     315          251 : MSChargingStation::writeVehicle(OutputDevice& out, const std::vector<Charge>& chargeSteps, int iStart, int iEnd, double charged) {
     316          251 :     const Charge& first = chargeSteps[iStart];
     317          251 :     out.openTag(SUMO_TAG_VEHICLE);
     318          251 :     out.writeAttr(SUMO_ATTR_ID, first.vehicleID);
     319          251 :     out.writeAttr(SUMO_ATTR_TYPE, first.vehicleType);
     320          251 :     out.writeAttr(SUMO_ATTR_TOTALENERGYCHARGED_VEHICLE, charged);
     321          251 :     out.writeAttr(SUMO_ATTR_CHARGINGBEGIN, time2string(first.timeStep));
     322          251 :     out.writeAttr(SUMO_ATTR_CHARGINGEND, time2string(chargeSteps[iEnd - 1].timeStep));
     323        72035 :     for (int i = iStart; i < iEnd; i++) {
     324        71784 :         const Charge& c = chargeSteps[i];
     325        71784 :         out.openTag(SUMO_TAG_STEP);
     326        71784 :         out.writeAttr(SUMO_ATTR_TIME, time2string(c.timeStep));
     327              :         // charge values
     328        71784 :         out.writeAttr(SUMO_ATTR_CHARGING_STATUS, c.status);
     329        71784 :         out.writeAttr(SUMO_ATTR_ENERGYCHARGED, c.WCharged);
     330        71784 :         out.writeAttr(SUMO_ATTR_PARTIALCHARGE, c.totalEnergyCharged);
     331              :         // charging values of charging station in this timestep
     332        71784 :         out.writeAttr(SUMO_ATTR_CHARGINGPOWER, c.chargingPower);
     333        71784 :         out.writeAttr(SUMO_ATTR_EFFICIENCY, c.chargingEfficiency);
     334              :         // battery status of vehicle
     335        71784 :         out.writeAttr(SUMO_ATTR_ACTUALBATTERYCAPACITY, c.actualBatteryCapacity);
     336        71784 :         out.writeAttr(SUMO_ATTR_MAXIMUMBATTERYCAPACITY, c.maxBatteryCapacity);
     337              :         // close tag timestep
     338       143568 :         out.closeTag();
     339              :     }
     340          251 :     out.closeTag();
     341          251 : }
     342              : 
     343              : 
     344              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1