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 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 430086 : MSMeanData_Emissions::MSLaneMeanDataValues::MSLaneMeanDataValues(MSLane* const lane,
42 : const double length, const bool doAdd,
43 430086 : const MSMeanData_Emissions* parent)
44 : : MSMeanData::MeanDataValues(lane, length, doAdd, parent),
45 430086 : myEmissions() {}
46 :
47 :
48 860170 : MSMeanData_Emissions::MSLaneMeanDataValues::~MSLaneMeanDataValues() {
49 860170 : }
50 :
51 :
52 : void
53 1236317 : MSMeanData_Emissions::MSLaneMeanDataValues::reset(bool) {
54 1236317 : sampleSeconds = 0.;
55 1236317 : travelledDistance = 0.;
56 1236317 : myEmissions = PollutantsInterface::Emissions();
57 1236317 : resetTime = SIMSTEP;
58 1236317 : }
59 :
60 :
61 : void
62 399799 : MSMeanData_Emissions::MSLaneMeanDataValues::addTo(MSMeanData::MeanDataValues& val) const {
63 : MSLaneMeanDataValues& v = (MSLaneMeanDataValues&) val;
64 399799 : v.sampleSeconds += sampleSeconds;
65 399799 : v.travelledDistance += travelledDistance;
66 399799 : v.myEmissions.addScaled(myEmissions);
67 399799 : }
68 :
69 :
70 : void
71 73164021 : 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 73164021 : if (myParent != nullptr && !myParent->vehicleApplies(veh)) {
73 : return;
74 : }
75 73163909 : if (veh.isVehicle()) {
76 73163909 : sampleSeconds += frontOnLane;
77 73163909 : travelledDistance += travelledDistanceFrontOnLane;
78 73163909 : const double a = veh.getAcceleration();
79 73163909 : myEmissions.addScaled(PollutantsInterface::computeAll(veh.getVehicleType().getEmissionClass(),
80 : // XXX: recheck, which value to use here for the speed. (Leo) Refs. #2579
81 73163909 : meanSpeedFrontOnLane, a, veh.getSlope(),
82 73163909 : 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 39605 : 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 39605 : const double normFactor = double(3600. / STEPS2TIME(period) / myLaneLength);
101 39605 : dev.setPrecision(gPrecisionEmissions);
102 39605 : dev.writeOptionalAttr(SUMO_ATTR_CO_ABS, myEmissions.CO, attributeMask);
103 39605 : dev.writeOptionalAttr(SUMO_ATTR_CO2_ABS, myEmissions.CO2, attributeMask);
104 39605 : dev.writeOptionalAttr(SUMO_ATTR_HC_ABS, myEmissions.HC, attributeMask);
105 39605 : dev.writeOptionalAttr(SUMO_ATTR_PMX_ABS, myEmissions.PMx, attributeMask);
106 39605 : dev.writeOptionalAttr(SUMO_ATTR_NOX_ABS, myEmissions.NOx, attributeMask);
107 39605 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_ABS, myEmissions.fuel, attributeMask);
108 39605 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_ABS, myEmissions.electricity, attributeMask);
109 39605 : if (attributeMask == 0) {
110 79066 : dev.writePadding("\n ");
111 : }
112 39605 : dev.writeOptionalAttr(SUMO_ATTR_CO_NORMED, normFactor * myEmissions.CO, attributeMask);
113 39605 : dev.writeOptionalAttr(SUMO_ATTR_CO2_NORMED, normFactor * myEmissions.CO2, attributeMask);
114 39605 : dev.writeOptionalAttr(SUMO_ATTR_HC_NORMED, normFactor * myEmissions.HC, attributeMask);
115 39605 : dev.writeOptionalAttr(SUMO_ATTR_PMX_NORMED, normFactor * myEmissions.PMx, attributeMask);
116 39605 : dev.writeOptionalAttr(SUMO_ATTR_NOX_NORMED, normFactor * myEmissions.NOx, attributeMask);
117 39605 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_NORMED, normFactor * myEmissions.fuel, attributeMask);
118 39605 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_NORMED, normFactor * myEmissions.electricity, attributeMask);
119 :
120 39605 : if (sampleSeconds > myParent->getMinSamples()) {
121 32203 : double vehFactor = myParent->getMaxTravelTime() / sampleSeconds;
122 32203 : double traveltime = myParent->getMaxTravelTime();
123 32203 : if (travelledDistance > 0.f) {
124 31411 : vehFactor = MIN2(vehFactor, myLaneLength / travelledDistance);
125 62790 : traveltime = MIN2(traveltime, myLaneLength * sampleSeconds / travelledDistance);
126 : }
127 32203 : if (attributeMask == 0) {
128 64262 : dev.writePadding("\n ");
129 : }
130 32203 : dev.setPrecision(gPrecision);
131 32203 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, traveltime, attributeMask);
132 32203 : dev.setPrecision(gPrecisionEmissions);
133 32203 : dev.writeOptionalAttr(SUMO_ATTR_CO_PERVEH, vehFactor * myEmissions.CO, attributeMask);
134 32203 : dev.writeOptionalAttr(SUMO_ATTR_CO2_PERVEH, vehFactor * myEmissions.CO2, attributeMask);
135 32203 : dev.writeOptionalAttr(SUMO_ATTR_HC_PERVEH, vehFactor * myEmissions.HC, attributeMask);
136 32203 : dev.writeOptionalAttr(SUMO_ATTR_PMX_PERVEH, vehFactor * myEmissions.PMx, attributeMask);
137 32203 : dev.writeOptionalAttr(SUMO_ATTR_NOX_PERVEH, vehFactor * myEmissions.NOx, attributeMask);
138 32203 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_PERVEH, vehFactor * myEmissions.fuel, attributeMask);
139 32203 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_PERVEH, vehFactor * myEmissions.electricity, attributeMask);
140 7402 : } 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 39605 : dev.setPrecision(gPrecision);
159 39605 : dev.closeTag();
160 39604 : }
161 :
162 :
163 :
164 : // ---------------------------------------------------------------------------
165 : // MSMeanData_Emissions - methods
166 : // ---------------------------------------------------------------------------
167 888 : MSMeanData_Emissions::MSMeanData_Emissions(const std::string& id,
168 : const SUMOTime dumpBegin,
169 : const SUMOTime dumpEnd,
170 : const bool useLanes, const bool withEmpty,
171 : const bool printDefaults,
172 : const bool withInternal,
173 : const bool trackVehicles,
174 : const double maxTravelTime,
175 : const double minSamples,
176 : const std::string& vTypes,
177 : const std::string& writeAttributes,
178 : const std::vector<MSEdge*>& edges,
179 888 : bool aggregate) :
180 : MSMeanData(id, dumpBegin, dumpEnd, useLanes, withEmpty, printDefaults,
181 888 : withInternal, trackVehicles, 0, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate)
182 888 : { }
183 :
184 :
185 1776 : MSMeanData_Emissions::~MSMeanData_Emissions() {}
186 :
187 :
188 : MSMeanData::MeanDataValues*
189 430086 : MSMeanData_Emissions::createValues(MSLane* const lane, const double length, const bool doAdd) const {
190 430086 : return new MSLaneMeanDataValues(lane, length, doAdd, this);
191 : }
192 :
193 :
194 : /****************************************************************************/
|