LCOV - code coverage report
Current view: top level - src/tools - TrajectoriesHandler.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 77.6 % 125 97
Test Date: 2024-12-21 15:45:41 Functions: 80.0 % 10 8

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2014-2024 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    TrajectoriesHandler.cpp
      15              : /// @author  Michael Behrisch
      16              : /// @date    14.03.2014
      17              : ///
      18              : // An XML-Handler for amitran and netstate trajectories
      19              : /****************************************************************************/
      20              : #include <config.h>
      21              : 
      22              : #include <string>
      23              : #include <utility>
      24              : #include <iostream>
      25              : #include <utils/common/UtilExceptions.h>
      26              : #include <utils/common/MsgHandler.h>
      27              : #include <utils/common/ToString.h>
      28              : #include <utils/emissions/PollutantsInterface.h>
      29              : #include <utils/emissions/EnergyParams.h>
      30              : #include <utils/geom/GeomHelper.h>
      31              : #include <utils/iodevices/OutputDevice.h>
      32              : #include <utils/xml/SUMOSAXHandler.h>
      33              : #include <utils/xml/SUMOXMLDefinitions.h>
      34              : #include "TrajectoriesHandler.h"
      35              : 
      36              : 
      37              : // ===========================================================================
      38              : // method definitions
      39              : // ===========================================================================
      40          996 : TrajectoriesHandler::TrajectoriesHandler(const bool computeA, const bool computeAForward,
      41              :         const bool accelZeroCorrection, const SUMOEmissionClass defaultClass, EnergyParams* params,
      42          996 :         long long int attributes, const double defaultSlope, std::ostream* stdOut, OutputDevice* xmlOut) :
      43              :     SUMOSAXHandler(""),
      44          996 :     myComputeA(computeA),
      45          996 :     myComputeAForward(computeAForward),
      46          996 :     myAccelZeroCorrection(accelZeroCorrection),
      47          996 :     myDefaultClass(defaultClass),
      48          996 :     myParams(params), myAttributes(attributes),
      49         1992 :     myDefaultSlope(defaultSlope), myStdOut(stdOut), myXMLOut(xmlOut), myCurrentTime(-1), myStepSize(TS) {}
      50              : 
      51              : 
      52         1992 : TrajectoriesHandler::~TrajectoriesHandler() {}
      53              : 
      54              : 
      55              : void
      56          592 : TrajectoriesHandler::myStartElement(int element,
      57              :                                     const SUMOSAXAttributes& attrs) {
      58          592 :     bool ok = true;
      59          592 :     switch (element) {
      60            2 :         case SUMO_TAG_TRAJECTORIES:
      61            2 :             myStepSize = attrs.getFloat("timeStepSize") / 1000.;
      62            2 :             break;
      63            0 :         case SUMO_TAG_TIMESTEP:
      64            0 :             myCurrentTime = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME, nullptr, ok);
      65            0 :             break;
      66            4 :         case SUMO_TAG_VEHICLE:
      67            4 :             if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
      68            0 :                 double v = attrs.getFloat(SUMO_ATTR_SPEED);
      69            0 :                 double a = INVALID_VALUE;
      70            0 :                 double s = INVALID_VALUE;
      71            0 :                 writeEmissions(std::cout, attrs.getString(SUMO_ATTR_ID), myDefaultClass, myParams, myAttributes, STEPS2TIME(myCurrentTime), v, a, s);
      72              :             } else {
      73            4 :                 const std::string acId = attrs.getString(SUMO_ATTR_ACTORCONFIG);
      74            4 :                 const std::string id = attrs.getString(SUMO_ATTR_ID);
      75              :                 if (myEmissionClassByType.count(acId) == 0) {
      76            0 :                     WRITE_WARNINGF(TL("Unknown actor configuration '%' for vehicle '%'!"), acId, id);
      77              :                 } else {
      78            4 :                     myEmissionClassByVehicle[id] = myEmissionClassByType.count(acId) > 0 ? myEmissionClassByType[acId] : myDefaultClass;
      79              :                 }
      80              :             }
      81              :             break;
      82            2 :         case SUMO_TAG_ACTORCONFIG: {
      83            2 :             const std::string id = attrs.getString(SUMO_ATTR_ID);
      84            2 :             const std::string vClass = attrs.getString(SUMO_ATTR_VEHICLECLASS);
      85            2 :             const std::string fuel = attrs.getString(SUMO_ATTR_FUEL);
      86            2 :             const std::string eClass = attrs.getString(SUMO_ATTR_EMISSIONCLASS);
      87            2 :             const double weight = attrs.getOpt<double>(SUMO_ATTR_WEIGHT, id.c_str(), ok, 0.) * 10.;
      88            2 :             myEmissionClassByType[id] = PollutantsInterface::getClass(myDefaultClass, vClass, fuel, eClass, weight);
      89              :             break;
      90              :         }
      91          584 :         case SUMO_TAG_MOTIONSTATE: {
      92          584 :             const std::string id = attrs.getString(SUMO_ATTR_VEHICLE);
      93              :             if (myEmissionClassByVehicle.count(id) == 0) {
      94            0 :                 WRITE_WARNINGF(TL("Motion state for unknown vehicle '%'!"), id);
      95            0 :                 myEmissionClassByVehicle[id] = myDefaultClass;
      96              :             }
      97          584 :             const SUMOEmissionClass c = myEmissionClassByVehicle[id];
      98          584 :             double v = attrs.getFloat(SUMO_ATTR_SPEED) / 100.;
      99          584 :             double a = attrs.hasAttribute(SUMO_ATTR_ACCELERATION) ? attrs.get<double>(SUMO_ATTR_ACCELERATION, id.c_str(), ok) / 1000. : INVALID_VALUE;
     100          584 :             double s = attrs.hasAttribute(SUMO_ATTR_SLOPE) ? RAD2DEG(asin(attrs.get<double>(SUMO_ATTR_SLOPE, id.c_str(), ok) / 10000.)) : INVALID_VALUE;
     101          584 :             const SUMOTime time = attrs.getOpt<int>(SUMO_ATTR_TIME, id.c_str(), ok, INVALID_VALUE);
     102          584 :             if (myXMLOut != nullptr) {
     103         1168 :                 writeXMLEmissions(id, c, nullptr, time, v, a, s);
     104              :             }
     105          584 :             if (myStdOut != nullptr) {
     106            0 :                 writeEmissions(*myStdOut, id, c, nullptr, myAttributes, STEPS2TIME(time), v, a, s);
     107              :             }
     108              :             break;
     109              :         }
     110              :         default:
     111              :             break;
     112              :     }
     113          592 : }
     114              : 
     115              : 
     116              : const PollutantsInterface::Emissions
     117      1171329 : TrajectoriesHandler::computeEmissions(const std::string id, const SUMOEmissionClass c,
     118              :                                       EnergyParams* params,
     119              :                                       double& v, double& a, double& s) {
     120              : 
     121      1171329 :     if (myComputeA) {
     122              :         if (myLastV.count(id) == 0) {
     123            0 :             a = 0.;
     124              :         } else {
     125      1171037 :             a = v - myLastV[id];
     126              :         }
     127      1171037 :         myLastV[id] = v;
     128      1171037 :         if (myComputeAForward) {
     129            0 :             v -= a;
     130              :         }
     131              :     }
     132      1171329 :     if (myAccelZeroCorrection) {
     133            0 :         a = PollutantsInterface::getModifiedAccel(c, v, a, s, params);
     134              :     }
     135      1171329 :     if (a == INVALID_VALUE) {
     136            0 :         throw ProcessError(TL("Acceleration information is missing; try running with --compute-a."));
     137              :     }
     138      1171329 :     if (s == INVALID_VALUE) {
     139      1171329 :         s = myDefaultSlope;
     140              :     }
     141      1171329 :     const PollutantsInterface::Emissions result = PollutantsInterface::computeAll(c, v, a, s, params);
     142      1171329 :     mySums[id].addScaled(result, myStepSize);
     143      1171329 :     if (id != "") {
     144         1164 :         mySums[""].addScaled(result, myStepSize);
     145              :     }
     146      1171329 :     return result;
     147              : }
     148              : 
     149              : 
     150              : void
     151     12878217 : TrajectoriesHandler::writeOptional(std::ostream& o, long long int attributes, const SumoXMLAttr attr, double v) {
     152     12878217 :     if ((attributes & ((long long int)1 << attr)) != 0) {
     153              :         o << ";" << v;
     154              :     }
     155     12878217 : }
     156              : 
     157              : 
     158              : bool
     159      1171740 : TrajectoriesHandler::writeEmissions(std::ostream& o, const std::string id,
     160              :                                     const SUMOEmissionClass c,
     161              :                                     EnergyParams* params,
     162              :                                     long long int attributes,
     163              :                                     double t, double& v,
     164              :                                     double& a, double& s) {
     165      1171740 :     if (myComputeA && myLastV.count(id) == 0) {
     166          993 :         myLastV[id] = v;
     167          993 :         myLastSlope[id] = s;
     168          993 :         return false;
     169              :     }
     170      1170747 :     if (myComputeAForward) {
     171            0 :         t -= TS;
     172            0 :         const double nextS = s;
     173            0 :         s = myLastSlope[id];
     174            0 :         myLastSlope[id] = nextS;
     175              :     }
     176      2341494 :     const PollutantsInterface::Emissions e = computeEmissions(id, c, params, v, a, s);
     177              :     o << t;
     178      1170747 :     writeOptional(o, attributes, SUMO_ATTR_SPEED, v);
     179      1170747 :     writeOptional(o, attributes, SUMO_ATTR_ACCELERATION, a);
     180      1170747 :     writeOptional(o, attributes, SUMO_ATTR_SLOPE, s);
     181      1170747 :     writeOptional(o, attributes, SUMO_ATTR_CO_ABS, e.CO);
     182      1170747 :     writeOptional(o, attributes, SUMO_ATTR_CO2_ABS, e.CO2);
     183      1170747 :     writeOptional(o, attributes, SUMO_ATTR_HC_ABS, e.HC);
     184      1170747 :     writeOptional(o, attributes, SUMO_ATTR_PMX_ABS, e.PMx);
     185      1170747 :     writeOptional(o, attributes, SUMO_ATTR_NOX_ABS, e.NOx);
     186      1170747 :     writeOptional(o, attributes, SUMO_ATTR_FUEL_ABS, e.fuel);
     187      1170747 :     writeOptional(o, attributes, SUMO_ATTR_ELECTRICITY_ABS, e.electricity);
     188      1170747 :     writeOptional(o, attributes, SUMO_ATTR_AMOUNT, PollutantsInterface::getCoastingDecel(c, v, a, s, params));
     189              :     o << std::endl;
     190              :     return true;
     191              : }
     192              : 
     193              : 
     194              : bool
     195          584 : TrajectoriesHandler::writeXMLEmissions(const std::string id,
     196              :                                        const SUMOEmissionClass c,
     197              :                                        EnergyParams* params,
     198              :                                        SUMOTime t, double& v,
     199              :                                        double a, double s) {
     200          584 :     if (myComputeA && myLastV.count(id) == 0) {
     201            2 :         myLastV[id] = v;
     202            2 :         return false;
     203              :     }
     204          582 :     if (myCurrentTime != t) {
     205          299 :         if (myCurrentTime != -1) {
     206          594 :             myXMLOut->closeTag();
     207              :         }
     208          299 :         myCurrentTime = t;
     209          598 :         myXMLOut->openTag(SUMO_TAG_TIMESTEP).writeAttr(SUMO_ATTR_TIME, time2string(t));
     210              :     }
     211          582 :     const PollutantsInterface::Emissions e = computeEmissions(id, c, params, v, a, s);
     212         1746 :     myXMLOut->openTag("vehicle").writeAttr("id", id).writeAttr("eclass", PollutantsInterface::getName(c));
     213         2910 :     myXMLOut->writeAttr("CO2", e.CO2).writeAttr("CO", e.CO).writeAttr("HC", e.HC).writeAttr("NOx", e.NOx);
     214         2328 :     myXMLOut->writeAttr("PMx", e.PMx).writeAttr("fuel", e.fuel).writeAttr("electricity", e.electricity);
     215         1746 :     myXMLOut->writeAttr("speed", v).closeTag();
     216          582 :     return true;
     217              : }
     218              : 
     219              : 
     220              : void
     221          995 : TrajectoriesHandler::writeSums(std::ostream& o, const std::string id) {
     222          995 :     o << "CO:" << mySums[id].CO << std::endl
     223          995 :       << "CO2:" << mySums[id].CO2 << std::endl
     224          995 :       << "HC:" << mySums[id].HC << std::endl
     225          995 :       << "NOx:" << mySums[id].NOx << std::endl
     226          995 :       << "PMx:" << mySums[id].PMx << std::endl
     227          995 :       << "fuel:" << mySums[id].fuel << std::endl
     228          995 :       << "electricity:" << mySums[id].electricity << std::endl;
     229          995 : }
     230              : 
     231              : 
     232              : void
     233            0 : TrajectoriesHandler::writeNormedSums(std::ostream& o, const std::string id, const double factor) {
     234            0 :     o << mySums[id].fuel / factor << ","
     235            0 :       << mySums[id].electricity / factor << ","
     236            0 :       << mySums[id].CO2 / factor << ","
     237            0 :       << mySums[id].NOx / factor << ","
     238            0 :       << mySums[id].CO / factor << ","
     239            0 :       << mySums[id].HC / factor << ","
     240            0 :       << mySums[id].PMx / factor << std::endl;
     241            0 : }
     242              : 
     243              : 
     244              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1