Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
PollutantsInterface.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2013-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/****************************************************************************/
19// Interface to capsulate different emission models
20/****************************************************************************/
21#include <config.h>
22
23#include <limits>
24#include <cmath>
31
32#include "HelpersHBEFA.h"
33#include "HelpersHBEFA3.h"
34#include "HelpersHBEFA4.h"
35#include "HelpersPHEMlight.h"
36#include "HelpersEnergy.h"
37#include "HelpersMMPEVEM.h"
38#include "HelpersPHEMlight5.h"
39#include "PollutantsInterface.h"
40
41
42// ===========================================================================
43// static definitions
44// ===========================================================================
45const double PollutantsInterface::Helper::ZERO_SPEED_ACCURACY = .5;
46PollutantsInterface::Helper PollutantsInterface::myZeroHelper("Zero", PollutantsInterface::ZERO_EMISSIONS, PollutantsInterface::ZERO_EMISSIONS);
47HelpersHBEFA PollutantsInterface::myHBEFA2Helper;
48HelpersHBEFA3 PollutantsInterface::myHBEFA3Helper;
49HelpersPHEMlight PollutantsInterface::myPHEMlightHelper;
50HelpersEnergy PollutantsInterface::myEnergyHelper;
51HelpersMMPEVEM PollutantsInterface::myMMPEVEMHelper;
52HelpersPHEMlight5 PollutantsInterface::myPHEMlight5Helper;
53HelpersHBEFA4 PollutantsInterface::myHBEFA4Helper;
54PollutantsInterface::Helper* PollutantsInterface::myHelpers[] = {
55 &PollutantsInterface::myZeroHelper,
56 &PollutantsInterface::myHBEFA2Helper, &PollutantsInterface::myHBEFA3Helper,
57 &PollutantsInterface::myPHEMlightHelper, &PollutantsInterface::myEnergyHelper,
58 &PollutantsInterface::myMMPEVEMHelper, &PollutantsInterface::myPHEMlight5Helper,
59 &PollutantsInterface::myHBEFA4Helper
60};
61std::vector<std::string> PollutantsInterface::myAllClassesStr;
62
63
64// ===========================================================================
65// method definitions
66// ===========================================================================
67
68// ---------------------------------------------------------------------------
69// PollutantsInterface::Emissions - methods
70// ---------------------------------------------------------------------------
71
72PollutantsInterface::Emissions::Emissions(double co2, double co, double hc, double f, double nox, double pmx, double elec) :
73 CO2(co2),
74 CO(co),
75 HC(hc),
76 fuel(f),
77 NOx(nox),
78 PMx(pmx),
79 electricity(elec) {
80}
81
82
83void PollutantsInterface::Emissions::addScaled(const Emissions& a, const double scale) {
84 CO2 += scale * a.CO2;
85 CO += scale * a.CO;
86 HC += scale * a.HC;
87 fuel += scale * a.fuel;
88 NOx += scale * a.NOx;
89 PMx += scale * a.PMx;
90 electricity += scale * a.electricity;
91}
92
93// ---------------------------------------------------------------------------
94// PollutantsInterface::Helper - methods
95// ---------------------------------------------------------------------------
96
97PollutantsInterface::Helper::Helper(std::string name, const int baseIndex, const int defaultClass) :
98 myName(name),
99 myBaseIndex(baseIndex) {
100 if (defaultClass != -1) {
101 myEmissionClassStrings.insert("default", defaultClass);
102 myEmissionClassStrings.addAlias("unknown", defaultClass);
103 }
104}
105
106
107const
108std::string& PollutantsInterface::Helper::getName() const {
109 return myName;
110}
111
112
114PollutantsInterface::Helper::getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
116 myVolumetricFuel = OptionsCont::getOptions().exists("emissions.volumetric-fuel") && OptionsCont::getOptions().getBool("emissions.volumetric-fuel");
117 if (myEmissionClassStrings.hasString(eClass)) {
118 return myEmissionClassStrings.get(eClass);
119 }
120 return myEmissionClassStrings.get(StringUtils::to_lower_case(eClass));
121}
122
123
124const std::string
125PollutantsInterface::Helper::getClassName(const SUMOEmissionClass c) const {
126 return myName + "/" + myEmissionClassStrings.getString(c);
127}
128
129
130bool
131PollutantsInterface::Helper::isSilent(const SUMOEmissionClass c) {
132 return (c & (int)0xffffffff & ~HEAVY_BIT) == 0;
133}
134
135
137PollutantsInterface::Helper::getClass(const SUMOEmissionClass base, const std::string& vClass, const std::string& fuel, const std::string& eClass, const double weight) const {
138 UNUSED_PARAMETER(vClass);
139 UNUSED_PARAMETER(fuel);
140 UNUSED_PARAMETER(eClass);
141 UNUSED_PARAMETER(weight);
142 return base;
143}
144
145
146std::string
147PollutantsInterface::Helper::getAmitranVehicleClass(const SUMOEmissionClass c) const {
149 return "Passenger";
150}
151
152
153std::string
154PollutantsInterface::Helper::getFuel(const SUMOEmissionClass c) const {
156 return "Gasoline";
157}
158
159
160int
161PollutantsInterface::Helper::getEuroClass(const SUMOEmissionClass c) const {
163 return 0;
164}
165
166
167double
168PollutantsInterface::Helper::getWeight(const SUMOEmissionClass c) const {
170 return -1.;
171}
172
173
174double
175PollutantsInterface::Helper::compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const EnergyParams* param) const {
180 UNUSED_PARAMETER(slope);
181 UNUSED_PARAMETER(param);
182 return 0.;
183}
184
185
186double
187PollutantsInterface::Helper::getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) const {
190 UNUSED_PARAMETER(slope);
191 UNUSED_PARAMETER(param);
192 return a;
193}
194
195
196double
197PollutantsInterface::Helper::getCoastingDecel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) const {
198 // the interpolation for small v is basically the same as in PHEMlightdllV5::CEP::GetDecelCoast
200 return v / PHEMlightdllV5::Constants::SPEED_DCEL_MIN * getCoastingDecel(c, PHEMlightdllV5::Constants::SPEED_DCEL_MIN, a, slope, param);
201 }
202 if (param == nullptr) {
203 param = EnergyParams::getDefault();
204 }
205 // the magic numbers below come from a linear interpolation with http://ts-sim-service-ba/svn/simo/trunk/projects/sumo/data/emissions/linear.py
206 const double mass = param->getDouble(SUMO_ATTR_MASS);
207 const double incl = param->getDouble(SUMO_ATTR_FRONTSURFACEAREA) / mass * -9.05337017 + -0.00017774;
208 const double grad = slope == 0. ? 0. : PHEMlightdllV5::Constants::GRAVITY_CONST * sin(DEG2RAD(slope));
209 return MIN2(0., incl * v + 0.00001066 * mass + -0.38347107 - 20.0 * incl - grad);
210}
211
212
213void
214PollutantsInterface::Helper::addAllClassesInto(std::vector<SUMOEmissionClass>& list) const {
215 myEmissionClassStrings.addKeysInto(list);
216}
217
218
219bool
220PollutantsInterface::Helper::includesClass(const SUMOEmissionClass c) const {
221 return (c >> 16) == (myBaseIndex >> 16);
222}
223
224// ---------------------------------------------------------------------------
225// PollutantsInterface - methods
226// ---------------------------------------------------------------------------
227
229PollutantsInterface::getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
230 const std::string::size_type sep = eClass.find("/");
231 const std::string model = eClass.substr(0, sep); // this includes the case of no separator
232 for (int i = 0; i < 8; i++) {
233 if (myHelpers[i]->getName() == model) {
234 if (sep != std::string::npos) {
235 const std::string subClass = eClass.substr(sep + 1);
236 if (subClass == "zero") {
237 return myZeroHelper.getClassByName("default", vc);
238 }
239 return myHelpers[i]->getClassByName(subClass, vc);
240 }
241 return myHelpers[i]->getClassByName("default", vc);
242 }
243 }
244 if (sep == std::string::npos) {
245 if (eClass == "zero") {
246 return myZeroHelper.getClassByName("default", vc);
247 }
248 WRITE_WARNINGF("Emission classes should always use the model as a prefix, please recheck '%'. In later SUMO versions this might become an error.", eClass)
249 // default HBEFA2
250 return myHBEFA2Helper.getClassByName(eClass, vc);
251 }
252 throw InvalidArgument(TLF("Unknown emission class '%'.", eClass));
253}
254
255
256const std::vector<SUMOEmissionClass>
257PollutantsInterface::getAllClasses() {
258 std::vector<SUMOEmissionClass> result;
259 for (int i = 0; i < 8; i++) {
260 myHelpers[i]->addAllClassesInto(result);
261 }
262 return result;
263}
264
265
266const std::vector<std::string>&
267PollutantsInterface::getAllClassesStr() {
268 // first check if myAllClassesStr has to be filled
269 if (myAllClassesStr.empty()) {
270 // first obtain all emissionClasses
271 std::vector<SUMOEmissionClass> emissionClasses;
272 for (int i = 0; i < 8; i++) {
273 myHelpers[i]->addAllClassesInto(emissionClasses);
274 }
275 // now write all emissionClasses in myAllClassesStr
276 for (const auto& i : emissionClasses) {
277 myAllClassesStr.push_back(getName(i));
278 }
279 }
280 return myAllClassesStr;
281}
282
283std::string
284PollutantsInterface::getName(const SUMOEmissionClass c) {
285 return myHelpers[c >> 16]->getClassName(c);
286}
287
288
289std::string
290PollutantsInterface::getPollutantName(const EmissionType e) {
291 switch (e) {
292 case CO2:
293 return "CO2";
294 case CO:
295 return "CO";
296 case HC:
297 return "HC";
298 case FUEL:
299 return "fuel";
300 case NO_X:
301 return "NOx";
302 case PM_X:
303 return "PMx";
304 case ELEC:
305 return "electricity";
306 default:
307 throw InvalidArgument("Unknown emission type '" + toString(e) + "'");
308 }
309}
310
311bool
312PollutantsInterface::isHeavy(const SUMOEmissionClass c) {
313 return (c & HEAVY_BIT) != 0;
314}
315
316
317bool
318PollutantsInterface::isSilent(const SUMOEmissionClass c) {
319 return myHelpers[c >> 16]->isSilent(c);
320}
321
322
324PollutantsInterface::getClass(const SUMOEmissionClass base, const std::string& vClass,
325 const std::string& fuel, const std::string& eClass, const double weight) {
326 return myHelpers[base >> 16]->getClass(base, vClass, fuel, eClass, weight);
327}
328
329
330std::string
331PollutantsInterface::getAmitranVehicleClass(const SUMOEmissionClass c) {
332 return myHelpers[c >> 16]->getAmitranVehicleClass(c);
333}
334
335
336std::string
337PollutantsInterface::getFuel(const SUMOEmissionClass c) {
338 return myHelpers[c >> 16]->getFuel(c);
339}
340
341
342int
343PollutantsInterface::getEuroClass(const SUMOEmissionClass c) {
344 return myHelpers[c >> 16]->getEuroClass(c);
345}
346
347
348double
349PollutantsInterface::getWeight(const SUMOEmissionClass c) {
350 return myHelpers[c >> 16]->getWeight(c);
351}
352
353
354double
355PollutantsInterface::compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const EnergyParams* param) {
356 return myHelpers[c >> 16]->compute(c, e, v, a, slope, param);
357}
358
359
360PollutantsInterface::Emissions
361PollutantsInterface::computeAll(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
362 const Helper* const h = myHelpers[c >> 16];
363 return Emissions(h->compute(c, CO2, v, a, slope, param), h->compute(c, CO, v, a, slope, param), h->compute(c, HC, v, a, slope, param),
364 h->compute(c, FUEL, v, a, slope, param), h->compute(c, NO_X, v, a, slope, param), h->compute(c, PM_X, v, a, slope, param),
365 h->compute(c, ELEC, v, a, slope, param));
366}
367
368
369double
370PollutantsInterface::computeDefault(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const double tt, const EnergyParams* param) {
371 const Helper* const h = myHelpers[c >> 16];
372 return (h->compute(c, e, v, 0, slope, param) + h->compute(c, e, v - a, a, slope, param)) * tt / 2.;
373}
374
375
376double
377PollutantsInterface::getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
378 return myHelpers[c >> 16]->getModifiedAccel(c, v, a, slope, param);
379}
380
381
382double
383PollutantsInterface::getCoastingDecel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) {
384 return myHelpers[c >> 16]->getCoastingDecel(c, v, a, slope, param);
385}
386
387
388const HelpersEnergy&
389PollutantsInterface::getEnergyHelper() {
390 return myEnergyHelper;
391}
392
393/****************************************************************************/
#define DEG2RAD(x)
Definition GeomHelper.h:35
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define TLF(string,...)
Definition MsgHandler.h:306
int SUMOEmissionClass
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SUMO_ATTR_MASS
@ SUMO_ATTR_FRONTSURFACEAREA
Front surface area.
T MIN2(T a, T b)
Definition StdDefs.h:80
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
double getDouble(SumoXMLAttr attr) const
Returns the value for a given key.
static const EnergyParams * getDefault()
Helper methods for energy-based electricity consumption computation based on the battery device.
Helper methods for HBEFA3-based emission computation.
Helper methods for HBEFA4-based emission computation.
Helper methods for HBEFA-based emission computation.
This helper class allows the PollutantsInterface to load and use different MMPEVEMs.
Helper methods for PHEMlight-based emission computation.
Helper methods for PHEMlight-based emission computation.
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool).
static OptionsCont & getOptions()
Retrieves the options.
static const double SPEED_DCEL_MIN
static const double GRAVITY_CONST
static std::string to_lower_case(const std::string &str)
Transfers the content to lower case.
#define UNUSED_PARAMETER(x)
*brief create JSON pointer *sa reference_tokens const std::string & a
Definition json.hpp:12278
json_pointer result
Definition json.hpp:12459