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 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/xml/SUMOXMLDefinitions.h>
30 : #include <utils/options/OptionsCont.h>
31 : #include <utils/emissions/PollutantsInterface.h>
32 : #include <utils/emissions/HelpersEnergy.h>
33 : #include <utils/iodevices/OutputDevice.h>
34 : #include "MSDevice_Emissions.h"
35 :
36 : // ===========================================================================
37 : // static members
38 : // ===========================================================================
39 : SumoXMLAttrMask MSDevice_Emissions::myWrittenAttributes(getDefaultMask());
40 : bool MSDevice_Emissions::myAmInitialized = false;
41 :
42 : // ===========================================================================
43 : // method definitions
44 : // ===========================================================================
45 : // ---------------------------------------------------------------------------
46 : // static initialisation methods
47 : // ---------------------------------------------------------------------------
48 : void
49 39784 : MSDevice_Emissions::insertOptions(OptionsCont& oc) {
50 79568 : insertDefaultAssignmentOptions("emissions", "Emissions", oc);
51 :
52 79568 : oc.doRegister("device.emissions.begin", new Option_String("-1"));
53 79568 : oc.addDescription("device.emissions.begin", "Emissions", TL("Recording begin time for emission-data"));
54 :
55 79568 : oc.doRegister("device.emissions.period", new Option_String("0"));
56 79568 : oc.addDescription("device.emissions.period", "Emissions", TL("Recording period for emission-output"));
57 39784 : }
58 :
59 :
60 : void
61 5371074 : MSDevice_Emissions::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
62 5371074 : OptionsCont& oc = OptionsCont::getOptions();
63 10742148 : if (equippedByDefaultAssignmentOptions(oc, "emissions", v, oc.isSet("emission-output"))) {
64 94526 : into.push_back(new MSDevice_Emissions(v));
65 : }
66 5371074 : }
67 :
68 :
69 : SumoXMLAttrMask
70 39746 : MSDevice_Emissions::getDefaultMask() {
71 39746 : SumoXMLAttrMask mask;
72 : // set all bits to 1
73 : mask.set();
74 39746 : 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 107608 : MSDevice_Emissions::initOnce() {
85 107608 : if (myAmInitialized) {
86 : return;
87 : }
88 167 : myAmInitialized = true;
89 167 : const OptionsCont& oc = OptionsCont::getOptions();
90 334 : 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 334 : OutputDevice::getDeviceByOption("emission-output").setExpectedAttributes(0);
106 : }
107 :
108 :
109 :
110 : // ---------------------------------------------------------------------------
111 : // MSDevice_Emissions-methods
112 : // ---------------------------------------------------------------------------
113 94526 : MSDevice_Emissions::MSDevice_Emissions(SUMOVehicle& holder)
114 189052 : : MSVehicleDevice(holder, "emissions_" + holder.getID()), myEmissions() {
115 94526 : }
116 :
117 :
118 189052 : MSDevice_Emissions::~MSDevice_Emissions() {
119 189052 : }
120 :
121 :
122 : bool
123 31381952 : MSDevice_Emissions::notifyMove(SUMOTrafficObject& veh, double /*oldPos*/, double /*newPos*/, double newSpeed) {
124 31381952 : const SUMOEmissionClass c = veh.getVehicleType().getEmissionClass();
125 31381952 : myEmissions.addScaled(PollutantsInterface::computeAll(c, newSpeed, veh.getAcceleration(), veh.getSlope(), myHolder.getEmissionParameters()), TS);
126 31381952 : 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 11424 : 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 11424 : const SUMOEmissionClass c = veh.getVehicleType().getEmissionClass();
150 11424 : myEmissions.addScaled(PollutantsInterface::computeAll(c, meanSpeedVehicleOnLane, veh.getAcceleration(), veh.getSlope(), myHolder.getEmissionParameters()), timeOnLane);
151 11424 : }
152 :
153 :
154 :
155 : void
156 94401 : MSDevice_Emissions::generateOutput(OutputDevice* tripinfoOut) const {
157 94401 : if (tripinfoOut != nullptr) {
158 93852 : tripinfoOut->setPrecision(gPrecisionEmissions);
159 93852 : tripinfoOut->openTag("emissions");
160 93852 : tripinfoOut->writeAttr(SUMO_ATTR_CO_ABS, myEmissions.CO);
161 93852 : tripinfoOut->writeAttr(SUMO_ATTR_CO2_ABS, myEmissions.CO2);
162 93852 : tripinfoOut->writeAttr(SUMO_ATTR_HC_ABS, myEmissions.HC);
163 93852 : tripinfoOut->writeAttr(SUMO_ATTR_PMX_ABS, myEmissions.PMx);
164 93852 : tripinfoOut->writeAttr(SUMO_ATTR_NOX_ABS, myEmissions.NOx);
165 93852 : tripinfoOut->writeAttr(SUMO_ATTR_FUEL_ABS, myEmissions.fuel);
166 93852 : tripinfoOut->writeAttr(SUMO_ATTR_ELECTRICITY_ABS, myEmissions.electricity);
167 93852 : tripinfoOut->closeTag();
168 93852 : tripinfoOut->setPrecision(gPrecision);
169 : }
170 94401 : }
171 :
172 :
173 : /****************************************************************************/
|