LCOV - code coverage report
Current view: top level - src/microsim/output - MSEmissionExport.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 65 65
Test Date: 2025-07-30 21:30:17 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2012-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    MSEmissionExport.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Mario Krumnow
      17              : /// @author  Michael Behrisch
      18              : /// @author  Jakob Erdmann
      19              : /// @date    2012-04-26
      20              : ///
      21              : // Realises dumping Emission Data
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <utils/iodevices/OutputDevice.h>
      26              : #include <utils/emissions/PollutantsInterface.h>
      27              : #include <utils/emissions/HelpersHarmonoise.h>
      28              : #include <utils/geom/GeomHelper.h>
      29              : #include <utils/geom/GeoConvHelper.h>
      30              : #include <microsim/MSLane.h>
      31              : #include <microsim/MSNet.h>
      32              : #include <microsim/MSVehicle.h>
      33              : #include <microsim/devices/MSDevice_Emissions.h>
      34              : #include <mesosim/MEVehicle.h>
      35              : #include <microsim/MSVehicleControl.h>
      36              : #include "MSEmissionExport.h"
      37              : 
      38              : 
      39              : // ===========================================================================
      40              : // method definitions
      41              : // ===========================================================================
      42              : void
      43       107608 : MSEmissionExport::write(OutputDevice& of, SUMOTime timestep) {
      44       107608 :     MSDevice_Emissions::initOnce();
      45       107608 :     const OptionsCont& oc = OptionsCont::getOptions();
      46       107608 :     const SUMOTime period = string2time(oc.getString("device.emissions.period"));
      47       107608 :     const SUMOTime begin = string2time(oc.getString("device.emissions.begin"));
      48       107608 :     const bool useGeo = oc.getBool("emission-output.geo");
      49       107608 :     if ((period > 0 && (timestep - begin) % period != 0) || timestep < begin) {
      50        63232 :         return;
      51              :     }
      52        44376 :     const SumoXMLAttrMask mask = MSDevice_Emissions::getWrittenAttributes();
      53              : 
      54        88752 :     of.openTag("timestep").writeAttr("time", time2string(timestep));
      55        44376 :     MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
      56       132742 :     for (MSVehicleControl::constVehIt it = vc.loadedVehBegin(); it != vc.loadedVehEnd(); ++it) {
      57        88366 :         const SUMOVehicle* veh = it->second;
      58        88366 :         MSDevice_Emissions* emissionsDevice = (MSDevice_Emissions*)veh->getDevice(typeid(MSDevice_Emissions));
      59        87034 :         if (emissionsDevice != nullptr && (veh->isOnRoad() || veh->isIdling())) {
      60        39530 :             of.openTag("vehicle");
      61        19765 :             of.writeAttr(SUMO_ATTR_ID, veh->getID());
      62        19765 :             writeEmissions(of, static_cast<const MSBaseVehicle*>(veh), true, mask);
      63        19765 :             if (MSGlobals::gUseMesoSim) {
      64         4554 :                 of.writeOptionalAttr(SUMO_ATTR_EDGE, veh->getEdge()->getID(), mask);
      65              :             } else {
      66        15211 :                 of.writeOptionalAttr(SUMO_ATTR_LANE, veh->getLane()->getID(), mask);
      67              :             }
      68        19765 :             of.writeOptionalAttr(SUMO_ATTR_POSITION, veh->getPositionOnLane(), mask);
      69        19765 :             of.writeOptionalAttr(SUMO_ATTR_SPEED, veh->getSpeed(), mask);
      70        19765 :             of.writeOptionalAttr(SUMO_ATTR_ANGLE, GeomHelper::naviDegree(veh->getAngle()), mask);
      71              : 
      72        19765 :             Position pos = veh->getPosition();
      73        19765 :             if (useGeo) {
      74           60 :                 of.setPrecision(gPrecisionGeo);
      75           60 :                 GeoConvHelper::getFinal().cartesian2geo(pos);
      76              :             }
      77        19765 :             of.writeOptionalAttr(SUMO_ATTR_X, pos.x(), mask);
      78        19765 :             of.writeOptionalAttr(SUMO_ATTR_Y, pos.y(), mask);
      79        19765 :             of.setPrecision(gPrecision);
      80        19765 :             if (MSNet::getInstance()->hasElevation()) {
      81           56 :                 of.writeOptionalAttr(SUMO_ATTR_Z, pos.z(), mask);
      82              :             }
      83        39530 :             of.closeTag();
      84              :         }
      85              :     }
      86        88752 :     of.closeTag();
      87              : }
      88              : 
      89              : 
      90              : void
      91      1410736 : MSEmissionExport::writeEmissions(OutputDevice& of, const MSBaseVehicle* const veh, const bool includeType, const SumoXMLAttrMask& mask) {
      92      1410736 :     of.writeFuncAttr(SUMO_ATTR_ECLASS, [ = ]() {
      93        19765 :         return  PollutantsInterface::getName(veh->getVehicleType().getEmissionClass());
      94              :     }, mask);
      95      1390911 :     if (mask.test(SUMO_ATTR_CO2) || mask.test(SUMO_ATTR_CO) || mask.test(SUMO_ATTR_HC) || mask.test(SUMO_ATTR_NOX) || mask.test(SUMO_ATTR_PMX)
      96      2801647 :             || mask.test(SUMO_ATTR_FUEL) || mask.test(SUMO_ATTR_ELECTRICITY)) {
      97        19825 :         PollutantsInterface::Emissions emiss = PollutantsInterface::computeAll(
      98        19825 :                 veh->getVehicleType().getEmissionClass(),
      99        19825 :                 veh->getSpeed(), veh->getAcceleration(), veh->getSlope(),
     100        19825 :                 veh->getEmissionParameters());
     101        39650 :         if (OptionsCont::getOptions().getBool("emission-output.step-scaled")) {
     102          600 :             emiss.addScaled(emiss, TS - 1.);
     103              :         }
     104        19825 :         of.setPrecision(gPrecisionEmissions);
     105        19825 :         of.writeOptionalAttr(SUMO_ATTR_CO2, emiss.CO2, mask);
     106        19825 :         of.writeOptionalAttr(SUMO_ATTR_CO, emiss.CO, mask);
     107        19825 :         of.writeOptionalAttr(SUMO_ATTR_HC, emiss.HC, mask);
     108        19825 :         of.writeOptionalAttr(SUMO_ATTR_NOX, emiss.NOx, mask);
     109        19825 :         of.writeOptionalAttr(SUMO_ATTR_PMX, emiss.PMx, mask);
     110        19825 :         of.writeOptionalAttr(SUMO_ATTR_FUEL, emiss.fuel, mask);
     111        19825 :         of.writeOptionalAttr(SUMO_ATTR_ELECTRICITY, emiss.electricity, mask);
     112        19825 :         of.setPrecision(gPrecision);
     113              :     }
     114      1410736 :     of.writeFuncAttr(SUMO_ATTR_NOISE, [ = ]() {
     115        19735 :         return HelpersHarmonoise::computeNoise(veh->getVehicleType().getEmissionClass(), veh->getSpeed(), veh->getAcceleration());
     116              :     }, mask);
     117      1410736 :     of.writeOptionalAttr(SUMO_ATTR_ROUTE, veh->getRoute().getID(), mask);
     118      1410736 :     if (includeType) {
     119        19765 :         std::string fclass = veh->getVehicleType().getID();
     120        19765 :         fclass = fclass.substr(0, fclass.find_first_of("@"));
     121        19765 :         of.writeOptionalAttr(SUMO_ATTR_TYPE, fclass, mask);
     122              :     }
     123      1410736 :     of.writeFuncAttr(SUMO_ATTR_WAITING, [ = ]() {
     124        19795 :         return veh->getWaitingSeconds();
     125              :     }, mask);
     126      1410736 : }
     127              : 
     128              : 
     129              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1