1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2013-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    PollutantsInterface.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Michael Behrisch
13 /// @date    Mon, 19.08.2013
14 /// @version $Id$
15 ///
16 // Interface to capsulate different emission models
17 /****************************************************************************/
18 #ifndef PollutantsInterface_h
19 #define PollutantsInterface_h
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <vector>
28 #include <limits>
29 #include <cmath>
30 #include <algorithm>
31 #include <utils/common/StdDefs.h>
32 #include <utils/common/SUMOVehicleClass.h>
33 #include "PHEMCEP.h"
34 
35 
36 // ===========================================================================
37 // class declarations
38 // ===========================================================================
39 class HelpersHBEFA;
40 class HelpersHBEFA3;
41 class HelpersPHEMlight;
42 class HelpersEnergy;
43 
44 
45 // ===========================================================================
46 // class definitions
47 // ===========================================================================
48 /**
49  * @class PollutantsInterface
50  * @brief Helper methods for PHEMlight-based emission computation
51  */
52 class PollutantsInterface {
53 public:
54 
55     /// @brief Enumerating all emission types, including fuel
56     enum EmissionType { CO2, CO, HC, FUEL, NO_X, PM_X, ELEC };
57 
58 
59     /**
60      * @struct Emissions
61      * @brief Storage for collected values of all emission types
62      */
63     struct Emissions {
64         double CO2;
65         double CO;
66         double HC;
67         double fuel;
68         double NOx;
69         double PMx;
70         double electricity;
71 
72         /** @brief Constructor, intializes all members
73          * @param[in] co2 initial value for CO2, defaults to 0
74          * @param[in] co  initial value for CO, defaults to 0
75          * @param[in] hc  initial value for HC, defaults to 0
76          * @param[in] f   initial value for fuel, defaults to 0
77          * @param[in] nox initial value for NOx, defaults to 0
78          * @param[in] pmx initial value for PMx, defaults to 0
79          * @param[in] elec initial value for electricity, defaults to 0
80          */
81         Emissions(double co2 = 0, double co = 0, double hc = 0, double f = 0, double nox = 0, double pmx = 0, double elec = 0)
CO2Emissions82             : CO2(co2), CO(co), HC(hc), fuel(f), NOx(nox), PMx(pmx), electricity(elec) {
83         }
84 
85         /** @brief Add the values of the other struct to this one, scaling the values if needed
86          * @param[in] a the other emission valuess
87          * @param[in] scale scaling factor, defaulting to 1 (no scaling)
88          */
89         void addScaled(const Emissions& a, const double scale = 1.) {
90             CO2 += scale * a.CO2;
91             CO += scale * a.CO;
92             HC += scale * a.HC;
93             fuel += scale * a.fuel;
94             NOx += scale * a.NOx;
95             PMx += scale * a.PMx;
96             electricity += scale * a.electricity;
97         }
98     };
99 
100 
101     /**
102     * @class Helper
103     * @brief abstract superclass for the model helpers
104     */
105     class Helper {
106     public:
107         /** @brief Constructor, intializes the name
108          * @param[in] name the name of the model (string before the '/' in the emission class attribute)
109          */
Helper(std::string name)110         Helper(std::string name) : myName(name) {}
111 
112         /** @brief Returns the name of the model
113          * @return the name of the model (string before the '/' in the emission class attribute)
114          */
getName()115         const std::string& getName() const {
116             return myName;
117         }
118 
119         /** @brief Returns the emission class associated with the given name, aliases are possible
120          * If this method is asked for the "unknown" class it should return the default
121          * (possibly depending on the given vehicle class).
122          * The class name is case insensitive.
123          *
124          * @param[in] eClass the name of the emission class (string after the '/' in the emission class attribute)
125          * @param[in] vc the vehicle class to use when determining default class
126          * @return the name of the model (string before the '/' in the emission class)
127          */
getClassByName(const std::string & eClass,const SUMOVehicleClass vc)128         virtual SUMOEmissionClass getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
129             UNUSED_PARAMETER(vc);
130             if (myEmissionClassStrings.hasString(eClass)) {
131                 return myEmissionClassStrings.get(eClass);
132             }
133             std::string eclower = eClass;
134             std::transform(eclower.begin(), eclower.end(), eclower.begin(), tolower);
135             return myEmissionClassStrings.get(eclower);
136         }
137 
138         /** @brief Returns the complete name of the emission class including the model
139          * @param[in] c the emission class
140          * @return the name of the class (the complete emission class attribute)
141          */
getClassName(const SUMOEmissionClass c)142         const std::string getClassName(const SUMOEmissionClass c) const {
143             return myName + "/" + myEmissionClassStrings.getString(c);
144         }
145 
146         /** @brief Returns whether the class denotes a silent vehicle for interfacing with the noise model.
147          * By default the first class in each model is the silent class.
148          * @param[in] c the emission class
149          * @return whether the class denotes a silent vehicle
150          */
isSilent(const SUMOEmissionClass c)151         virtual bool isSilent(const SUMOEmissionClass c) {
152             return (c & 0xffffffff & ~HEAVY_BIT) == 0;
153         }
154 
155         /// @name Methods for Amitran interfaces
156         /// @{
157 
158         /** @brief Returns the emission class described by the given parameters.
159          * The base is used to determine the model to use and as default return values.
160          * Default implementation returns always base.
161          * @param[in] base the base class giving the model and the default
162          * @param[in] vClass the vehicle class as described in the Amitran interface (Passenger, ...)
163          * @param[in] fuel the fuel type as described in the Amitran interface (Gasoline, Diesel, ...)
164          * @param[in] eClass the emission class as described in the Amitran interface (Euro0, ...)
165          * @param[in] weight the vehicle weight in kg as described in the Amitran interface
166          * @return the class described by the parameters
167          */
getClass(const SUMOEmissionClass base,const std::string & vClass,const std::string & fuel,const std::string & eClass,const double weight)168         virtual SUMOEmissionClass getClass(const SUMOEmissionClass base, const std::string& vClass,
169                                            const std::string& fuel, const std::string& eClass, const double weight) const {
170             UNUSED_PARAMETER(vClass);
171             UNUSED_PARAMETER(fuel);
172             UNUSED_PARAMETER(eClass);
173             UNUSED_PARAMETER(weight);
174             return base;
175         }
176 
177         /** @brief Returns the vehicle class described by this emission class as described in the Amitran interface (Passenger, ...)
178          * Default implementation returns always "Passenger".
179          * @param[in] c the emission class
180          * @return the name of the vehicle class
181          */
getAmitranVehicleClass(const SUMOEmissionClass c)182         virtual std::string getAmitranVehicleClass(const SUMOEmissionClass c) const {
183             UNUSED_PARAMETER(c);
184             return "Passenger";
185         }
186 
187         /** @brief Returns the fuel type described by this emission class as described in the Amitran interface (Gasoline, Diesel, ...)
188          * Default implementation returns always "Gasoline".
189          * @param[in] c the emission class
190          * @return the fuel type
191          */
getFuel(const SUMOEmissionClass c)192         virtual std::string getFuel(const SUMOEmissionClass c) const {
193             UNUSED_PARAMETER(c);
194             return "Gasoline";
195         }
196 
197         /** @brief Returns the Euro emission class described by this emission class as described in the Amitran interface (0, ..., 6)
198          * Default implementation returns always 0.
199          * @param[in] c the emission class
200          * @return the Euro class
201          */
getEuroClass(const SUMOEmissionClass c)202         virtual int getEuroClass(const SUMOEmissionClass c) const {
203             UNUSED_PARAMETER(c);
204             return 0;
205         }
206 
207         /** @brief Returns a reference weight in kg described by this emission class as described in the Amitran interface
208         * It might return -1, if the weight is not important to distinguish different emission classes.
209         * Default implementation returns always -1.
210         * @param[in] c the emission class
211         * @return a reference weight
212         */
getWeight(const SUMOEmissionClass c)213         virtual double getWeight(const SUMOEmissionClass c) const {
214             UNUSED_PARAMETER(c);
215             return -1.;
216         }
217         /// @}
218 
219         /** @brief Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fuel)
220          * @param[in] c The vehicle emission class
221          * @param[in] e the type of emission (CO, CO2, ...)
222          * @param[in] v The vehicle's current velocity
223          * @param[in] a The vehicle's current acceleration
224          * @param[in] slope The road's slope at vehicle's position [deg]
225          * @return The amount emitted by the given emission class when moving with the given velocity and acceleration [mg/s or ml/s]
226          */
227         virtual double compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const std::map<int, double>* param) const = 0;
228 
229         /** @brief Returns the adapted acceleration value, useful for comparing with external PHEMlight references.
230          * Default implementation returns always the input accel.
231          * @param[in] c the emission class
232          * @param[in] v the speed value
233          * @param[in] a the acceleration value
234          * @param[in] slope The road's slope at vehicle's position [deg]
235          * @return the modified acceleration
236          */
getModifiedAccel(const SUMOEmissionClass c,const double v,const double a,const double slope)237         virtual double getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope) const {
238             UNUSED_PARAMETER(c);
239             UNUSED_PARAMETER(v);
240             UNUSED_PARAMETER(slope);
241             return a;
242         }
243 
244         /** @brief Add all known emission classes of this model to the given container
245          * @param[in] list the vector to add to
246          */
addAllClassesInto(std::vector<SUMOEmissionClass> & list)247         void addAllClassesInto(std::vector<SUMOEmissionClass>& list) const {
248             myEmissionClassStrings.addKeysInto(list);
249         }
250 
251 
252     protected:
253         /// @brief the name of the model
254         const std::string myName;
255 
256         /// @brief Mapping between emission class names and integer representations
257         StringBijection<SUMOEmissionClass> myEmissionClassStrings;
258 
259     private:
260         Helper& operator=(const Helper&); // just to avoid a compiler warning
261 
262 
263     };
264 
265 
266     /// @brief the first class in each model representing a zero emission vehicle
267     static const int ZERO_EMISSIONS = 0;
268 
269     /// @brief the bit to set for denoting heavy vehicles
270     static const int HEAVY_BIT = 1 << 15;
271 
272     /** @brief Checks whether the string describes a known vehicle class
273      * @param[in] eClass The string describing the vehicle emission class
274      * @return whether it describes a valid emission class
275      */
276     static SUMOEmissionClass getClassByName(const std::string& eClass, const SUMOVehicleClass vc = SVC_IGNORING);
277 
278 
279     /** @brief Checks whether the string describes a known vehicle class
280      * @param[in] eClass The string describing the vehicle emission class
281      * @return whether it describes a valid emission class
282      */
283     static const std::vector<SUMOEmissionClass> getAllClasses();
284 
285 
286     /** @brief Checks whether the string describes a known vehicle class
287      * @param[in] eClass The string describing the vehicle emission class
288      * @return whether it describes a valid emission class
289      */
290     static std::string getName(const SUMOEmissionClass c);
291 
292 
293     /** @brief Checks whether the emission class describes a bus, truck or similar vehicle
294      * @param[in] c The vehicle emission class
295      * @return whether it describes a heavy vehicle
296      */
297     static bool isHeavy(const SUMOEmissionClass c);
298 
299 
300     /** @brief Checks whether the emission class describes an electric or similar silent vehicle
301      * @param[in] c The vehicle emission class
302      * @return whether it describes a silent vehicle
303      */
304     static bool isSilent(const SUMOEmissionClass c);
305 
306 
307     /** @brief Returns the emission class fittig the given parameters
308      * @param[in] base The base emission class to derive from
309      * @param[in] vClass The vehicle class description (like "truck")
310      * @param[in] eClass The emission class description (like "Euro5")
311      * @param[in] fuel The fuel type (like "Diesel")
312      * @param[in] weight The weight in kg
313      * @return The best fitting emission class related to the base
314      */
315     static SUMOEmissionClass getClass(const SUMOEmissionClass base, const std::string& vClass, const std::string& fuel, const std::string& eClass, const double weight);
316 
317 
318     /** @brief Returns the vehicle class described by the given emission class
319      * @param[in] c The vehicle emission class
320      * @return The Amitran string describing the vehicle class
321      */
322     static std::string getAmitranVehicleClass(const SUMOEmissionClass c);
323 
324 
325     /** @brief Returns the fuel type of the given emission class
326      * @param[in] c The vehicle emission class
327      * @return "Diesel", "Gasoline", "HybridDiesel", or "HybridGasoline"
328      */
329     static std::string getFuel(const SUMOEmissionClass c);
330 
331 
332     /** @brief Returns the Euro norm described by the given emission class
333      * @param[in] c The vehicle emission class
334      * @return A value between 0 and 6 (inclusive)
335      */
336     static int getEuroClass(const SUMOEmissionClass c);
337 
338 
339     /** @brief Returns a representative weight for the given emission class
340      * see http://colombo-fp7.eu/deliverables/COLOMBO_D4.2_ExtendedPHEMSUMO_v1.7.pdf
341      * @param[in] c The vehicle emission class
342      * @return the weight in kg if it matters, 0 otherwise
343      */
344     static double getWeight(const SUMOEmissionClass c);
345 
346 
347     /** @brief Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fuel)
348      * @param[in] c The vehicle emission class
349      * @param[in] e the type of emission (CO, CO2, ...)
350      * @param[in] v The vehicle's current velocity
351      * @param[in] a The vehicle's current acceleration
352      * @param[in] slope The road's slope at vehicle's position [deg]
353      * @return The amount emitted by the given vehicle class when moving with the given velocity and acceleration [mg/s]
354      */
355     static double compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const std::map<int, double>* param = 0);
356 
357 
358     /** @brief Returns the amount of all emitted pollutants given the vehicle type and state (in mg/s or ml/s for fuel)
359      * @param[in] c The vehicle emission class
360      * @param[in] v The vehicle's current velocity
361      * @param[in] a The vehicle's current acceleration
362      * @param[in] slope The road's slope at vehicle's position [deg]
363      * @return The amount emitted by the given vehicle class when moving with the given velocity and acceleration [mg/s]
364      */
365     static Emissions computeAll(const SUMOEmissionClass c, const double v, const double a, const double slope, const std::map<int, double>* param = 0);
366 
367 
368     /** @brief Returns the amount of emitted pollutant given the vehicle type and default values for the state (in mg)
369      * @param[in] c The vehicle emission class
370      * @param[in] e the type of emission (CO, CO2, ...)
371      * @param[in] v The vehicle's average velocity
372      * @param[in] a The vehicle's average acceleration
373      * @param[in] slope The road's slope at vehicle's position [deg]
374      * @param{in] tt the time the vehicle travels
375      * @return The amount emitted by the given vehicle class [mg]
376      */
377     static double computeDefault(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const double tt, const std::map<int, double>* param = 0);
378 
379     /** @brief Returns the adapted acceleration value, useful for comparing with external PHEMlight references.
380      * @param[in] c the emission class
381      * @param[in] v the speed value
382      * @param[in] a the acceleration value
383      * @param[in] slope The road's slope at vehicle's position [deg]
384      * @return the modified acceleration
385      */
386     static double getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope);
387 
getEnergyHelper()388     static const HelpersEnergy& getEnergyHelper() {
389         return myEnergyHelper;
390     }
391 
392 private:
393     /// @brief Instance of HBEFA2Helper which gets cleaned up automatically
394     static HelpersHBEFA myHBEFA2Helper;
395     /// @brief Instance of HBEFA3Helper which gets cleaned up automatically
396     static HelpersHBEFA3 myHBEFA3Helper;
397     /// @brief Instance of PHEMlightHelper which gets cleaned up automatically
398     static HelpersPHEMlight myPHEMlightHelper;
399     /// @brief Instance of EnergyHelper which gets cleaned up automatically
400     static HelpersEnergy myEnergyHelper;
401     /// @brief the known model helpers
402     static Helper* myHelpers[];
403 
404 };
405 
406 
407 #endif
408 
409 /****************************************************************************/
410