Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-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 MSDevice_Emissions.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Laura Bieker
17 : /// @author Michael Behrisch
18 : /// @date Fri, 30.01.2009
19 : ///
20 : // A device which collects vehicular emissions
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <microsim/MSNet.h>
25 : #include <microsim/MSLane.h>
26 : #include <microsim/MSStop.h>
27 : #include <microsim/MSVehicleControl.h>
28 : #include <microsim/output/MSDetectorControl.h>
29 : #include <utils/options/OptionsCont.h>
30 : #include <utils/emissions/PollutantsInterface.h>
31 : #include <utils/emissions/HelpersEnergy.h>
32 : #include <utils/iodevices/OutputDevice.h>
33 : #include "MSDevice_Emissions.h"
34 :
35 : // ===========================================================================
36 : // static members
37 : // ===========================================================================
38 : SumoXMLAttrMask MSDevice_Emissions::myWrittenAttributes(getDefaultMask());
39 : bool MSDevice_Emissions::myAmInitialized = false;
40 :
41 : // ===========================================================================
42 : // method definitions
43 : // ===========================================================================
44 : // ---------------------------------------------------------------------------
45 : // static initialisation methods
46 : // ---------------------------------------------------------------------------
47 : void
48 43644 : MSDevice_Emissions::insertOptions(OptionsCont& oc) {
49 87288 : insertDefaultAssignmentOptions("emissions", "Emissions", oc);
50 :
51 87288 : oc.doRegister("device.emissions.begin", new Option_String("-1"));
52 87288 : oc.addDescription("device.emissions.begin", "Emissions", TL("Recording begin time for emission-data"));
53 :
54 87288 : oc.doRegister("device.emissions.period", new Option_String("0"));
55 87288 : oc.addDescription("device.emissions.period", "Emissions", TL("Recording period for emission-output"));
56 43644 : }
57 :
58 :
59 : void
60 5104373 : MSDevice_Emissions::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
61 5104373 : OptionsCont& oc = OptionsCont::getOptions();
62 10208746 : if (equippedByDefaultAssignmentOptions(oc, "emissions", v, oc.isSet("emission-output"))) {
63 94460 : into.push_back(new MSDevice_Emissions(v));
64 94460 : initOnce();
65 : }
66 5104373 : }
67 :
68 :
69 : SumoXMLAttrMask
70 43604 : MSDevice_Emissions::getDefaultMask() {
71 43604 : SumoXMLAttrMask mask;
72 : // set all bits to 1
73 : mask.set();
74 43604 : return mask;
75 : }
76 :
77 : void
78 0 : MSDevice_Emissions::cleanup() {
79 0 : myWrittenAttributes = getDefaultMask();
80 0 : myAmInitialized = false;
81 0 : }
82 :
83 : void
84 94460 : MSDevice_Emissions::initOnce() {
85 94460 : if (myAmInitialized) {
86 : return;
87 : }
88 351 : myAmInitialized = true;
89 351 : const OptionsCont& oc = OptionsCont::getOptions();
90 702 : if (oc.isSet("emission-output.attributes")) {
91 : myWrittenAttributes.reset();
92 36 : for (std::string attrName : oc.getStringVector("emission-output.attributes")) {
93 24 : if (!SUMOXMLDefinitions::Attrs.hasString(attrName)) {
94 0 : if (attrName == "all") {
95 : myWrittenAttributes.set();
96 : } else {
97 0 : WRITE_ERRORF(TL("Unknown attribute '%' to write in emission output."), attrName);
98 : }
99 : continue;
100 : }
101 24 : int attr = SUMOXMLDefinitions::Attrs.get(attrName);
102 24 : myWrittenAttributes.set(attr);
103 : }
104 : }
105 : //std::cout << "mask=" << myWrittenAttributes << "\n";
106 : }
107 :
108 :
109 :
110 : // ---------------------------------------------------------------------------
111 : // MSDevice_Emissions-methods
112 : // ---------------------------------------------------------------------------
113 94460 : MSDevice_Emissions::MSDevice_Emissions(SUMOVehicle& holder)
114 188920 : : MSVehicleDevice(holder, "emissions_" + holder.getID()), myEmissions() {
115 94460 : }
116 :
117 :
118 188920 : MSDevice_Emissions::~MSDevice_Emissions() {
119 188920 : }
120 :
121 :
122 : bool
123 31369410 : MSDevice_Emissions::notifyMove(SUMOTrafficObject& veh, double /*oldPos*/, double /*newPos*/, double newSpeed) {
124 31369410 : const SUMOEmissionClass c = veh.getVehicleType().getEmissionClass();
125 31369410 : myEmissions.addScaled(PollutantsInterface::computeAll(c, newSpeed, veh.getAcceleration(), veh.getSlope(), myHolder.getEmissionParameters()), TS);
126 31369410 : return true;
127 : }
128 :
129 :
130 : bool
131 308 : MSDevice_Emissions::notifyIdle(SUMOTrafficObject& veh) {
132 308 : const SUMOEmissionClass c = veh.getVehicleType().getEmissionClass();
133 308 : myEmissions.addScaled(PollutantsInterface::computeAll(c, 0., 0., 0., myHolder.getEmissionParameters()), TS);
134 308 : return true;
135 : }
136 :
137 :
138 : void
139 10776 : MSDevice_Emissions::notifyMoveInternal(const SUMOTrafficObject& veh,
140 : const double /* frontOnLane */,
141 : const double timeOnLane,
142 : const double /* meanSpeedFrontOnLane */,
143 : const double meanSpeedVehicleOnLane,
144 : const double /* travelledDistanceFrontOnLane */,
145 : const double /* travelledDistanceVehicleOnLane */,
146 : const double /* meanLengthOnLane */) {
147 :
148 : // called by meso (see MSMeanData_Emissions::MSLaneMeanDataValues::notifyMoveInternal)
149 10776 : const SUMOEmissionClass c = veh.getVehicleType().getEmissionClass();
150 10776 : myEmissions.addScaled(PollutantsInterface::computeAll(c, meanSpeedVehicleOnLane, veh.getAcceleration(), veh.getSlope(), myHolder.getEmissionParameters()), timeOnLane);
151 10776 : }
152 :
153 :
154 :
155 : void
156 94335 : MSDevice_Emissions::generateOutput(OutputDevice* tripinfoOut) const {
157 94335 : if (tripinfoOut != nullptr) {
158 93816 : const OptionsCont& oc = OptionsCont::getOptions();
159 93816 : const int precision = MAX2(
160 187650 : oc.isDefault("emission-output.precision") ? 6 : oc.getInt("emission-output.precision"),
161 : gPrecision);
162 93816 : tripinfoOut->openTag("emissions");
163 187632 : tripinfoOut->writeAttr("CO_abs", OutputDevice::realString(myEmissions.CO, precision));
164 187632 : tripinfoOut->writeAttr("CO2_abs", OutputDevice::realString(myEmissions.CO2, precision));
165 187632 : tripinfoOut->writeAttr("HC_abs", OutputDevice::realString(myEmissions.HC, precision));
166 187632 : tripinfoOut->writeAttr("PMx_abs", OutputDevice::realString(myEmissions.PMx, precision));
167 187632 : tripinfoOut->writeAttr("NOx_abs", OutputDevice::realString(myEmissions.NOx, precision));
168 187632 : tripinfoOut->writeAttr("fuel_abs", OutputDevice::realString(myEmissions.fuel, precision));
169 187632 : tripinfoOut->writeAttr("electricity_abs", OutputDevice::realString(myEmissions.electricity, precision));
170 187632 : tripinfoOut->closeTag();
171 : }
172 94335 : }
173 :
174 :
175 : /****************************************************************************/
|