Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2012-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 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 92524 : MSEmissionExport::write(OutputDevice& of, SUMOTime timestep, int precision) {
44 92524 : const OptionsCont& oc = OptionsCont::getOptions();
45 92524 : const SUMOTime period = string2time(oc.getString("device.emissions.period"));
46 92524 : const SUMOTime begin = string2time(oc.getString("device.emissions.begin"));
47 92524 : const bool scaled = oc.getBool("emission-output.step-scaled");
48 92524 : const bool useGeo = oc.getBool("emission-output.geo");
49 92524 : if ((period > 0 && (timestep - begin) % period != 0) || timestep < begin) {
50 49136 : return;
51 : }
52 : const SumoXMLAttrMask mask = MSDevice_Emissions::getWrittenAttributes();
53 :
54 86776 : of.openTag("timestep").writeAttr("time", time2string(timestep));
55 43388 : of.setPrecision(precision);
56 43388 : MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
57 130080 : for (MSVehicleControl::constVehIt it = vc.loadedVehBegin(); it != vc.loadedVehEnd(); ++it) {
58 86692 : const SUMOVehicle* veh = it->second;
59 86692 : MSDevice_Emissions* emissionsDevice = (MSDevice_Emissions*)veh->getDevice(typeid(MSDevice_Emissions));
60 85360 : if (emissionsDevice != nullptr && (veh->isOnRoad() || veh->isIdling())) {
61 19291 : std::string fclass = veh->getVehicleType().getID();
62 19291 : fclass = fclass.substr(0, fclass.find_first_of("@"));
63 19291 : PollutantsInterface::Emissions emiss = PollutantsInterface::computeAll(
64 19291 : veh->getVehicleType().getEmissionClass(),
65 19291 : veh->getSpeed(), veh->getAcceleration(), veh->getSlope(),
66 19291 : veh->getEmissionParameters());
67 19291 : if (scaled) {
68 600 : PollutantsInterface::Emissions tmp;
69 600 : tmp.addScaled(emiss, TS);
70 600 : emiss = tmp;
71 : }
72 38582 : of.openTag("vehicle");
73 : of.writeAttr(SUMO_ATTR_ID, veh->getID());
74 19291 : of.writeOptionalAttr(SUMO_ATTR_ECLASS, PollutantsInterface::getName(veh->getVehicleType().getEmissionClass()), mask);
75 19291 : of.writeOptionalAttr(SUMO_ATTR_CO2, emiss.CO2, mask);
76 19291 : of.writeOptionalAttr(SUMO_ATTR_CO, emiss.CO, mask);
77 19291 : of.writeOptionalAttr(SUMO_ATTR_HC, emiss.HC, mask);
78 19291 : of.writeOptionalAttr(SUMO_ATTR_NOX, emiss.NOx, mask);
79 19291 : of.writeOptionalAttr(SUMO_ATTR_PMX, emiss.PMx, mask);
80 19291 : of.writeOptionalAttr(SUMO_ATTR_FUEL, emiss.fuel, mask);
81 19291 : of.writeOptionalAttr(SUMO_ATTR_ELECTRICITY, emiss.electricity, mask);
82 19291 : of.writeOptionalAttr(SUMO_ATTR_NOISE, HelpersHarmonoise::computeNoise(veh->getVehicleType().getEmissionClass(), veh->getSpeed(), veh->getAcceleration()), mask);
83 19291 : of.writeOptionalAttr(SUMO_ATTR_ROUTE, veh->getRoute().getID(), mask);
84 19291 : of.writeOptionalAttr(SUMO_ATTR_TYPE, fclass, mask);
85 19291 : if (MSGlobals::gUseMesoSim) {
86 4424 : const MEVehicle* mesoVeh = dynamic_cast<const MEVehicle*>(veh);
87 4424 : of.writeOptionalAttr(SUMO_ATTR_WAITING, mesoVeh->getWaitingSeconds(), mask);
88 4424 : of.writeOptionalAttr(SUMO_ATTR_EDGE, veh->getEdge()->getID(), mask);
89 : } else {
90 14867 : const MSVehicle* microVeh = dynamic_cast<const MSVehicle*>(veh);
91 14867 : of.writeOptionalAttr(SUMO_ATTR_WAITING, microVeh->getWaitingSeconds(), mask);
92 14867 : of.writeOptionalAttr(SUMO_ATTR_LANE, microVeh->getLane()->getID(), mask);
93 : }
94 19291 : of.writeOptionalAttr(SUMO_ATTR_POSITION, veh->getPositionOnLane(), mask);
95 19291 : of.writeOptionalAttr(SUMO_ATTR_SPEED, veh->getSpeed(), mask);
96 19291 : of.writeOptionalAttr(SUMO_ATTR_ANGLE, GeomHelper::naviDegree(veh->getAngle()), mask);
97 :
98 19291 : Position pos = veh->getPosition();
99 19291 : if (useGeo) {
100 60 : of.setPrecision(MAX2(gPrecisionGeo, precision));
101 60 : GeoConvHelper::getFinal().cartesian2geo(pos);
102 : }
103 19291 : of.writeOptionalAttr(SUMO_ATTR_X, pos.x(), mask);
104 19291 : of.writeOptionalAttr(SUMO_ATTR_Y, pos.y(), mask);
105 19291 : if (MSNet::getInstance()->hasElevation()) {
106 56 : of.writeOptionalAttr(SUMO_ATTR_Z, pos.z(), mask);
107 : }
108 19291 : of.setPrecision(precision);
109 :
110 38582 : of.closeTag();
111 : }
112 : }
113 43388 : of.setPrecision(gPrecision);
114 86776 : of.closeTag();
115 : }
|