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 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 429913 : MSMeanData_Emissions::MSLaneMeanDataValues::MSLaneMeanDataValues(MSLane* const lane,
42 : const double length, const bool doAdd,
43 429913 : const MSMeanData_Emissions* parent)
44 : : MSMeanData::MeanDataValues(lane, length, doAdd, parent),
45 429913 : myEmissions() {}
46 :
47 :
48 859826 : MSMeanData_Emissions::MSLaneMeanDataValues::~MSLaneMeanDataValues() {
49 859826 : }
50 :
51 :
52 : void
53 1235324 : MSMeanData_Emissions::MSLaneMeanDataValues::reset(bool) {
54 1235324 : sampleSeconds = 0.;
55 1235324 : travelledDistance = 0.;
56 1235324 : myEmissions = PollutantsInterface::Emissions();
57 1235324 : resetTime = SIMSTEP;
58 1235324 : }
59 :
60 :
61 : void
62 398666 : MSMeanData_Emissions::MSLaneMeanDataValues::addTo(MSMeanData::MeanDataValues& val) const {
63 : MSLaneMeanDataValues& v = (MSLaneMeanDataValues&) val;
64 398666 : v.sampleSeconds += sampleSeconds;
65 398666 : v.travelledDistance += travelledDistance;
66 398666 : v.myEmissions.addScaled(myEmissions);
67 398666 : }
68 :
69 :
70 : void
71 68334821 : 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 68334821 : if (myParent != nullptr && !myParent->vehicleApplies(veh)) {
73 : return;
74 : }
75 68334709 : if (veh.isVehicle()) {
76 68334709 : sampleSeconds += frontOnLane;
77 68334709 : travelledDistance += travelledDistanceFrontOnLane;
78 68334709 : const double a = veh.getAcceleration();
79 68334709 : myEmissions.addScaled(PollutantsInterface::computeAll(veh.getVehicleType().getEmissionClass(),
80 : // XXX: recheck, which value to use here for the speed. (Leo) Refs. #2579
81 68334709 : meanSpeedFrontOnLane, a, veh.getSlope(),
82 68334709 : 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 39368 : MSMeanData_Emissions::MSLaneMeanDataValues::write(OutputDevice& dev, long long int attributeMask, const SUMOTime period,
99 : const int /*numLanes*/, const double /*speedLimit*/, const double defaultTravelTime, const int /*numVehicles*/) const {
100 39368 : const double normFactor = double(3600. / STEPS2TIME(period) / myLaneLength);
101 39368 : dev.writeOptionalAttr(SUMO_ATTR_CO_ABS, OutputDevice::realString(myEmissions.CO, 6), attributeMask);
102 39368 : dev.writeOptionalAttr(SUMO_ATTR_CO2_ABS, OutputDevice::realString(myEmissions.CO2, 6), attributeMask);
103 39368 : dev.writeOptionalAttr(SUMO_ATTR_HC_ABS, OutputDevice::realString(myEmissions.HC, 6), attributeMask);
104 39368 : dev.writeOptionalAttr(SUMO_ATTR_PMX_ABS, OutputDevice::realString(myEmissions.PMx, 6), attributeMask);
105 39368 : dev.writeOptionalAttr(SUMO_ATTR_NOX_ABS, OutputDevice::realString(myEmissions.NOx, 6), attributeMask);
106 39368 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_ABS, OutputDevice::realString(myEmissions.fuel, 6), attributeMask);
107 39368 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_ABS, OutputDevice::realString(myEmissions.electricity, 6), attributeMask);
108 39368 : if (attributeMask == 0) {
109 39296 : dev << "\n ";
110 : }
111 39368 : dev.writeOptionalAttr(SUMO_ATTR_CO_NORMED, OutputDevice::realString(normFactor * myEmissions.CO, 6), attributeMask);
112 39368 : dev.writeOptionalAttr(SUMO_ATTR_CO2_NORMED, OutputDevice::realString(normFactor * myEmissions.CO2, 6), attributeMask);
113 39368 : dev.writeOptionalAttr(SUMO_ATTR_HC_NORMED, OutputDevice::realString(normFactor * myEmissions.HC, 6), attributeMask);
114 39368 : dev.writeOptionalAttr(SUMO_ATTR_PMX_NORMED, OutputDevice::realString(normFactor * myEmissions.PMx, 6), attributeMask);
115 39368 : dev.writeOptionalAttr(SUMO_ATTR_NOX_NORMED, OutputDevice::realString(normFactor * myEmissions.NOx, 6), attributeMask);
116 39368 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_NORMED, OutputDevice::realString(normFactor * myEmissions.fuel, 6), attributeMask);
117 39368 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_NORMED, OutputDevice::realString(normFactor * myEmissions.electricity, 6), attributeMask);
118 :
119 39368 : if (sampleSeconds > myParent->getMinSamples()) {
120 32038 : double vehFactor = myParent->getMaxTravelTime() / sampleSeconds;
121 : double traveltime = myParent->getMaxTravelTime();
122 32038 : if (travelledDistance > 0.f) {
123 31246 : vehFactor = MIN2(vehFactor, myLaneLength / travelledDistance);
124 31246 : traveltime = MIN2(traveltime, myLaneLength * sampleSeconds / travelledDistance);
125 : }
126 32038 : if (attributeMask == 0) {
127 31966 : dev << "\n ";
128 : }
129 32038 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, OutputDevice::realString(traveltime), attributeMask);
130 32038 : dev.writeOptionalAttr(SUMO_ATTR_CO_PERVEH, OutputDevice::realString(vehFactor * myEmissions.CO, 6), attributeMask);
131 32038 : dev.writeOptionalAttr(SUMO_ATTR_CO2_PERVEH, OutputDevice::realString(vehFactor * myEmissions.CO2, 6), attributeMask);
132 32038 : dev.writeOptionalAttr(SUMO_ATTR_HC_PERVEH, OutputDevice::realString(vehFactor * myEmissions.HC, 6), attributeMask);
133 32038 : dev.writeOptionalAttr(SUMO_ATTR_PMX_PERVEH, OutputDevice::realString(vehFactor * myEmissions.PMx, 6), attributeMask);
134 32038 : dev.writeOptionalAttr(SUMO_ATTR_NOX_PERVEH, OutputDevice::realString(vehFactor * myEmissions.NOx, 6), attributeMask);
135 32038 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_PERVEH, OutputDevice::realString(vehFactor * myEmissions.fuel, 6), attributeMask);
136 64076 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_PERVEH, OutputDevice::realString(vehFactor * myEmissions.electricity, 6), attributeMask);
137 7330 : } else if (defaultTravelTime >= 0.) {
138 1056 : const MSVehicleType* t = MSNet::getInstance()->getVehicleControl().getVType();
139 1056 : const double speed = MIN2(myLaneLength / defaultTravelTime, t->getMaxSpeed());
140 :
141 1056 : if (attributeMask == 0) {
142 1056 : dev << "\n ";
143 : }
144 2112 : dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, OutputDevice::realString(defaultTravelTime), attributeMask);
145 2112 : dev.writeOptionalAttr(SUMO_ATTR_CO_PERVEH, OutputDevice::realString(PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::CO, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), 6), attributeMask);
146 2112 : dev.writeOptionalAttr(SUMO_ATTR_CO2_PERVEH, OutputDevice::realString(PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::CO2, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), 6), attributeMask);
147 2112 : dev.writeOptionalAttr(SUMO_ATTR_HC_PERVEH, OutputDevice::realString(PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::HC, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), 6), attributeMask);
148 2112 : dev.writeOptionalAttr(SUMO_ATTR_PMX_PERVEH, OutputDevice::realString(PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::PM_X, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), 6), attributeMask);
149 2112 : dev.writeOptionalAttr(SUMO_ATTR_NOX_PERVEH, OutputDevice::realString(PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::NO_X, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), 6), attributeMask);
150 2112 : dev.writeOptionalAttr(SUMO_ATTR_FUEL_PERVEH, OutputDevice::realString(PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::FUEL, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), 6), attributeMask);
151 2112 : dev.writeOptionalAttr(SUMO_ATTR_ELECTRICITY_PERVEH, OutputDevice::realString(PollutantsInterface::computeDefault(t->getEmissionClass(), PollutantsInterface::ELEC, speed, t->getCarFollowModel().getMaxAccel(), 0, defaultTravelTime, t->getEmissionParameters()), 6), attributeMask);
152 : }
153 39368 : dev.closeTag();
154 39368 : }
155 :
156 :
157 :
158 : // ---------------------------------------------------------------------------
159 : // MSMeanData_Emissions - methods
160 : // ---------------------------------------------------------------------------
161 873 : MSMeanData_Emissions::MSMeanData_Emissions(const std::string& id,
162 : const SUMOTime dumpBegin,
163 : const SUMOTime dumpEnd,
164 : const bool useLanes, const bool withEmpty,
165 : const bool printDefaults,
166 : const bool withInternal,
167 : const bool trackVehicles,
168 : const double maxTravelTime,
169 : const double minSamples,
170 : const std::string& vTypes,
171 : const std::string& writeAttributes,
172 : const std::vector<MSEdge*>& edges,
173 873 : bool aggregate) :
174 : MSMeanData(id, dumpBegin, dumpEnd, useLanes, withEmpty, printDefaults,
175 873 : withInternal, trackVehicles, 0, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate)
176 873 : { }
177 :
178 :
179 1746 : MSMeanData_Emissions::~MSMeanData_Emissions() {}
180 :
181 :
182 : MSMeanData::MeanDataValues*
183 429913 : MSMeanData_Emissions::createValues(MSLane* const lane, const double length, const bool doAdd) const {
184 429913 : return new MSLaneMeanDataValues(lane, length, doAdd, this);
185 : }
186 :
187 :
188 : /****************************************************************************/
|