Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 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 MSMeanData_Emissions.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Michael Behrisch
17 : /// @date Mon, 10.05.2004
18 : ///
19 : // Emission data collector for edges/lanes that
20 : /****************************************************************************/
21 : #include <config.h>
22 :
23 : #include <limits>
24 : #include <microsim/MSNet.h>
25 : #include <microsim/MSLane.h>
26 : #include <microsim/MSVehicle.h>
27 : #include <microsim/MSVehicleControl.h>
28 : #include <utils/common/SUMOTime.h>
29 : #include <utils/common/ToString.h>
30 : #include <utils/iodevices/OutputDevice.h>
31 : #include "MSMeanData_Emissions.h"
32 : #include <utils/emissions/PollutantsInterface.h>
33 :
34 :
35 : // ===========================================================================
36 : // method definitions
37 : // ===========================================================================
38 : // ---------------------------------------------------------------------------
39 : // MSMeanData_Emissions::MSLaneMeanDataValues - methods
40 : // ---------------------------------------------------------------------------
41 430497 : MSMeanData_Emissions::MSLaneMeanDataValues::MSLaneMeanDataValues(MSLane* const lane,
42 : const double length, const bool doAdd,
43 430497 : const MSMeanData_Emissions* parent)
44 : : MSMeanData::MeanDataValues(lane, length, doAdd, parent),
45 430497 : myEmissions() {}
46 :
47 :
48 860432 : MSMeanData_Emissions::MSLaneMeanDataValues::~MSLaneMeanDataValues() {
49 860432 : }
50 :
51 :
52 : void
53 1236718 : MSMeanData_Emissions::MSLaneMeanDataValues::reset(bool) {
54 1236718 : sampleSeconds = 0.;
55 1236718 : travelledDistance = 0.;
56 1236718 : myEmissions = PollutantsInterface::Emissions();
57 1236718 : resetTime = SIMSTEP;
58 1236718 : }
59 :
60 :
61 : void
62 400092 : MSMeanData_Emissions::MSLaneMeanDataValues::addTo(MSMeanData::MeanDataValues& val) const {
63 : MSLaneMeanDataValues& v = (MSLaneMeanDataValues&) val;
64 400092 : v.sampleSeconds += sampleSeconds;
65 400092 : v.travelledDistance += travelledDistance;
66 400092 : v.myEmissions.addScaled(myEmissions);
67 400092 : }
68 :
69 :
70 : void
71 73235311 : MSMeanData_Emissions::MSLaneMeanDataValues::notifyMoveInternal(const SUMOTrafficObject& veh, const double frontOnLane, const double /*timeOnLane*/, const double meanSpeedFrontOnLane, const double /*meanSpeedVehicleOnLane*/, const double travelledDistanceFrontOnLane, const double /*travelledDistanceVehicleOnLane*/, const double /*meanLengthOnLane*/) {
72 73235311 : if (myParent != nullptr && !myParent->vehicleApplies(veh)) {
73 : return;
74 : }
75 73235199 : if (veh.isVehicle()) {
76 73235199 : sampleSeconds += frontOnLane;
77 73235199 : travelledDistance += travelledDistanceFrontOnLane;
78 73235199 : const double a = veh.getAcceleration();
79 73235199 : myEmissions.addScaled(PollutantsInterface::computeAll(veh.getVehicleType().getEmissionClass(),
80 : // XXX: recheck, which value to use here for the speed. (Leo) Refs. #2579
81 73235199 : meanSpeedFrontOnLane, a, veh.getSlope(),
82 73235199 : static_cast<const SUMOVehicle&>(veh).getEmissionParameters()), frontOnLane);
83 : }
84 : }
85 :
86 : bool
87 616 : MSMeanData_Emissions::MSLaneMeanDataValues::notifyIdle(SUMOTrafficObject& veh) {
88 616 : if (veh.isVehicle()) {
89 616 : myEmissions.addScaled(PollutantsInterface::computeAll(veh.getVehicleType().getEmissionClass(),
90 : 0., 0., 0.,
91 616 : static_cast<const SUMOVehicle&>(veh).getEmissionParameters()), TS);
92 : }
93 616 : return true;
94 : }
95 :
96 :
97 : void
98 39710 : MSMeanData_Emissions::MSLaneMeanDataValues::write(OutputDevice& dev, const SumoXMLAttrMask& attributeMask, const SUMOTime period,
99 : const int /*numLanes*/, const double /*speedLimit*/, const double defaultTravelTime, const int /*numVehicles*/) const {
100 39710 : const double normFactor = double(3600. / STEPS2TIME(period) / myLaneLength);
101 39710 : dev.setPrecision(gPrecisionEmissions);
102 39710 : dev.writeOptionalAttr(SUMO_ATTR_CO_ABS, myEmissions.CO, attributeMask);
103 39710 : dev.writeOptionalAttr(SUMO_ATTR_CO2_ABS, myEmissions.CO2, attributeMask);
104 39710 : dev.writeOptionalAttr(SUMO_ATTR_HC_ABS, myEmissions.HC, attributeMask);
105 39710 : dev.writeOptionalAttr(SUMO_ATTR_PMX_ABS, myEmissions.PMx, attributeMask);
106 39710 : dev.writeOptionalAttr(SUMO_ATTR_NOX_ABS, myEmissions.NOx, attributeMask);
107 39710 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_ABS, myEmissions.fuel, attributeMask);
108 39710 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_ABS, myEmissions.electricity, attributeMask);
109 39710 : if (attributeMask == 0) {
110 79124 : dev.writePadding("\n ");
111 : }
112 39710 : dev.writeOptionalAttr(SUMO_ATTR_CO_NORMED, normFactor * myEmissions.CO, attributeMask);
113 39710 : dev.writeOptionalAttr(SUMO_ATTR_CO2_NORMED, normFactor * myEmissions.CO2, attributeMask);
114 39710 : dev.writeOptionalAttr(SUMO_ATTR_HC_NORMED, normFactor * myEmissions.HC, attributeMask);
115 39710 : dev.writeOptionalAttr(SUMO_ATTR_PMX_NORMED, normFactor * myEmissions.PMx, attributeMask);
116 39710 : dev.writeOptionalAttr(SUMO_ATTR_NOX_NORMED, normFactor * myEmissions.NOx, attributeMask);
117 39710 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_NORMED, normFactor * myEmissions.fuel, attributeMask);
118 39710 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_NORMED, normFactor * myEmissions.electricity, attributeMask);
119 :
120 39710 : if (sampleSeconds > myParent->getMinSamples()) {
121 32269 : double vehFactor = myParent->getMaxTravelTime() / sampleSeconds;
122 32269 : double traveltime = myParent->getMaxTravelTime();
123 32269 : if (travelledDistance > 0.f) {
124 31477 : vehFactor = MIN2(vehFactor, myLaneLength / travelledDistance);
125 62922 : traveltime = MIN2(traveltime, myLaneLength * sampleSeconds / travelledDistance);
126 : }
127 32269 : if (attributeMask == 0) {
128 64242 : dev.writePadding("\n ");
129 : }
130 32269 : dev.setPrecision(gPrecision);
131 32269 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, traveltime, attributeMask);
132 32269 : dev.setPrecision(gPrecisionEmissions);
133 32269 : dev.writeOptionalAttr(SUMO_ATTR_CO_PERVEH, vehFactor * myEmissions.CO, attributeMask);
134 32269 : dev.writeOptionalAttr(SUMO_ATTR_CO2_PERVEH, vehFactor * myEmissions.CO2, attributeMask);
135 32269 : dev.writeOptionalAttr(SUMO_ATTR_HC_PERVEH, vehFactor * myEmissions.HC, attributeMask);
136 32269 : dev.writeOptionalAttr(SUMO_ATTR_PMX_PERVEH, vehFactor * myEmissions.PMx, attributeMask);
137 32269 : dev.writeOptionalAttr(SUMO_ATTR_NOX_PERVEH, vehFactor * myEmissions.NOx, attributeMask);
138 32269 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_PERVEH, vehFactor * myEmissions.fuel, attributeMask);
139 32269 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_PERVEH, vehFactor * myEmissions.electricity, attributeMask);
140 7441 : } else if (defaultTravelTime >= 0.) {
141 1056 : const MSVehicleType* t = MSNet::getInstance()->getVehicleControl().getVType();
142 1056 : const double speed = MIN2(myLaneLength / defaultTravelTime, t->getMaxSpeed());
143 :
144 1056 : if (attributeMask == 0) {
145 2112 : dev.writePadding("\n ");
146 : }
147 1056 : dev.setPrecision(gPrecision);
148 1056 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, defaultTravelTime, attributeMask);
149 1056 : dev.setPrecision(gPrecisionEmissions);
150 1056 : dev.writeOptionalAttr(SUMO_ATTR_CO_PERVEH, PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::CO, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), attributeMask);
151 1056 : dev.writeOptionalAttr(SUMO_ATTR_CO2_PERVEH, PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::CO2, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), attributeMask);
152 1056 : dev.writeOptionalAttr(SUMO_ATTR_HC_PERVEH, PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::HC, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), attributeMask);
153 1056 : dev.writeOptionalAttr(SUMO_ATTR_PMX_PERVEH, PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::PM_X, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), attributeMask);
154 1056 : dev.writeOptionalAttr(SUMO_ATTR_NOX_PERVEH, PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::NO_X, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), attributeMask);
155 1056 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_PERVEH, PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::FUEL, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), attributeMask);
156 1056 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_PERVEH, PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::ELEC, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), attributeMask);
157 : }
158 39710 : dev.setPrecision(gPrecision);
159 39710 : }
160 :
161 :
162 :
163 : // ---------------------------------------------------------------------------
164 : // MSMeanData_Emissions - methods
165 : // ---------------------------------------------------------------------------
166 897 : MSMeanData_Emissions::MSMeanData_Emissions(const std::string& id,
167 : const SUMOTime dumpBegin,
168 : const SUMOTime dumpEnd,
169 : const bool useLanes, const std::string& excludeEmpty,
170 : const bool withInternal,
171 : const bool trackVehicles,
172 : const double maxTravelTime,
173 : const double minSamples,
174 : const std::string& vTypes,
175 : const std::string& writeAttributes,
176 : const std::vector<MSEdge*>& edges,
177 897 : AggregateType aggregate) :
178 : MSMeanData(id, dumpBegin, dumpEnd, useLanes, excludeEmpty,
179 897 : withInternal, trackVehicles, 0, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate)
180 897 : { }
181 :
182 :
183 1794 : MSMeanData_Emissions::~MSMeanData_Emissions() {}
184 :
185 :
186 : MSMeanData::MeanDataValues*
187 430497 : MSMeanData_Emissions::createValues(MSLane* const lane, const double length, const bool doAdd) const {
188 430497 : return new MSLaneMeanDataValues(lane, length, doAdd, this);
189 : }
190 :
191 :
192 : std::vector<std::string>
193 0 : MSMeanData_Emissions::getAttributeNames() const {
194 : std::vector<std::string> result;
195 0 : result.push_back(toString(SUMO_ATTR_CO_ABS));
196 0 : result.push_back(toString(SUMO_ATTR_CO2_ABS));
197 0 : result.push_back(toString(SUMO_ATTR_HC_ABS));
198 0 : result.push_back(toString(SUMO_ATTR_PMX_ABS));
199 0 : result.push_back(toString(SUMO_ATTR_NOX_ABS));
200 0 : result.push_back(toString(SUMO_ATTR_FUEL_ABS));
201 0 : result.push_back(toString(SUMO_ATTR_ELECTRICITY_ABS));
202 0 : result.push_back(toString(SUMO_ATTR_CO_NORMED));
203 0 : result.push_back(toString(SUMO_ATTR_CO2_NORMED));
204 0 : result.push_back(toString(SUMO_ATTR_HC_NORMED));
205 0 : result.push_back(toString(SUMO_ATTR_PMX_NORMED));
206 0 : result.push_back(toString(SUMO_ATTR_NOX_NORMED));
207 0 : result.push_back(toString(SUMO_ATTR_FUEL_NORMED));
208 0 : result.push_back(toString(SUMO_ATTR_ELECTRICITY_NORMED));
209 0 : result.push_back(toString(SUMO_ATTR_CO_PERVEH));
210 0 : result.push_back(toString(SUMO_ATTR_CO2_PERVEH));
211 0 : result.push_back(toString(SUMO_ATTR_HC_PERVEH));
212 0 : result.push_back(toString(SUMO_ATTR_PMX_PERVEH));
213 0 : result.push_back(toString(SUMO_ATTR_NOX_PERVEH));
214 0 : result.push_back(toString(SUMO_ATTR_FUEL_PERVEH));
215 0 : result.push_back(toString(SUMO_ATTR_ELECTRICITY_PERVEH));
216 0 : return result;
217 0 : }
218 :
219 :
220 : bool
221 95 : MSMeanData_Emissions::supports(const SumoXMLAttrMask& attributeMask) {
222 : return
223 95 : attributeMask.test(SUMO_ATTR_CO_ABS) ||
224 89 : attributeMask.test(SUMO_ATTR_CO2_ABS) ||
225 89 : attributeMask.test(SUMO_ATTR_HC_ABS) ||
226 89 : attributeMask.test(SUMO_ATTR_PMX_ABS) ||
227 89 : attributeMask.test(SUMO_ATTR_NOX_ABS) ||
228 89 : attributeMask.test(SUMO_ATTR_FUEL_ABS) ||
229 89 : attributeMask.test(SUMO_ATTR_ELECTRICITY_ABS) ||
230 89 : attributeMask.test(SUMO_ATTR_CO_NORMED) ||
231 89 : attributeMask.test(SUMO_ATTR_CO2_NORMED) ||
232 89 : attributeMask.test(SUMO_ATTR_HC_NORMED) ||
233 89 : attributeMask.test(SUMO_ATTR_PMX_NORMED) ||
234 89 : attributeMask.test(SUMO_ATTR_NOX_NORMED) ||
235 89 : attributeMask.test(SUMO_ATTR_FUEL_NORMED) ||
236 89 : attributeMask.test(SUMO_ATTR_ELECTRICITY_NORMED) ||
237 89 : attributeMask.test(SUMO_ATTR_CO_PERVEH) ||
238 89 : attributeMask.test(SUMO_ATTR_CO2_PERVEH) ||
239 89 : attributeMask.test(SUMO_ATTR_HC_PERVEH) ||
240 89 : attributeMask.test(SUMO_ATTR_PMX_PERVEH) ||
241 89 : attributeMask.test(SUMO_ATTR_NOX_PERVEH) ||
242 184 : attributeMask.test(SUMO_ATTR_FUEL_PERVEH) ||
243 95 : attributeMask.test(SUMO_ATTR_ELECTRICITY_PERVEH);
244 : }
245 :
246 :
247 : /****************************************************************************/
|