Eclipse SUMO - Simulation of Urban MObility
HelpersPHEMlight.cpp
Go to the documentation of this file.
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 /****************************************************************************/
16 // Helper methods for PHEMlight-based emission computation
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <limits>
26 #include <cmath>
27 #ifdef INTERNAL_PHEM
28 #include "PHEMCEPHandler.h"
29 #include "PHEMConstants.h"
30 #endif
33 #include "HelpersPHEMlight.h"
34 
35 // idle speed is usually given in rpm (but may depend on electrical consumers). Actual speed depends on the gear so this number is only a rough estimate
36 #define IDLE_SPEED (10 / 3.6)
37 
38 // ===========================================================================
39 // method definitions
40 // ===========================================================================
41 HelpersPHEMlight::HelpersPHEMlight() : PollutantsInterface::Helper("PHEMlight"), myIndex(PHEMLIGHT_BASE) {
43 }
44 
45 
47 HelpersPHEMlight::getClassByName(const std::string& eClass, const SUMOVehicleClass vc) {
48  if (eClass == "unknown" && !myEmissionClassStrings.hasString("unknown")) {
49  myEmissionClassStrings.addAlias("unknown", getClassByName("PC_G_EU4", vc));
50  }
51  if (myEmissionClassStrings.hasString(eClass)) {
52  return myEmissionClassStrings.get(eClass);
53  }
54  if (eClass.size() < 6) {
55  throw InvalidArgument("Unknown emission class '" + eClass + "'.");
56  }
57  int index = myIndex++;
58  const std::string type = eClass.substr(0, 3);
59  if (type == "HDV" || type == "LB_" || type == "RB_" || type == "LSZ" || eClass.find("LKW") != std::string::npos) {
61  }
62  myEmissionClassStrings.insert(eClass, index);
63 #ifdef INTERNAL_PHEM
64  if (type == "HDV" || type == "LCV" || type == "PC_" || !PHEMCEPHandler::getHandlerInstance().Load(index, eClass)) {
65 #endif
66  std::vector<std::string> phemPath;
67  phemPath.push_back(OptionsCont::getOptions().getString("phemlight-path") + "/");
68  if (getenv("PHEMLIGHT_PATH") != nullptr) {
69  phemPath.push_back(std::string(getenv("PHEMLIGHT_PATH")) + "/");
70  }
71  if (getenv("SUMO_HOME") != nullptr) {
72  phemPath.push_back(std::string(getenv("SUMO_HOME")) + "/data/emissions/PHEMlight/");
73  }
75  myHelper.setPHEMDataV("V4");
76  myHelper.setclass(eClass);
77  if (!myCEPHandler.GetCEP(phemPath, &myHelper)) {
78  myEmissionClassStrings.remove(eClass, index);
79  myIndex--;
80  throw InvalidArgument("File for PHEM emission class " + eClass + " not found.\n" + myHelper.getErrMsg());
81  }
82  myCEPs[index] = myCEPHandler.getCEPS().find(myHelper.getgClass())->second;
83 #ifdef INTERNAL_PHEM
84  }
85 #endif
86  std::string eclower = eClass;
87  std::transform(eclower.begin(), eclower.end(), eclower.begin(), tolower);
88  myEmissionClassStrings.addAlias(eclower, index);
89  return index;
90 }
91 
92 
94 HelpersPHEMlight::getClass(const SUMOEmissionClass base, const std::string& vClass, const std::string& fuel, const std::string& eClass, const double weight) const {
95  std::string eClassOffset = "0";
96  if (eClass.length() == 5 && eClass.substr(0, 4) == "Euro") {
97  if (eClass[4] >= '0' && eClass[4] <= '6') {
98  eClassOffset = eClass.substr(4, 1);
99  }
100  }
101  std::string desc;
102  if (vClass == "Passenger") {
103  desc = "PKW_";
104  if (fuel == "Gasoline") {
105  desc += "G_";
106  } else if (fuel == "Diesel") {
107  desc += "D_";
108  } else if (fuel == "HybridGasoline") {
109  desc = "H_" + desc + "G_";
110  } else if (fuel == "HybridDiesel") {
111  desc = "H_" + desc + "G_";
112  }
113  desc += "EU" + eClassOffset;
114  } else if (vClass == "Moped") {
115  desc = "KKR_G_EU" + eClassOffset;
116  } else if (vClass == "Motorcycle") {
117  desc = "MR_G_EU" + eClassOffset;
118  if (fuel == "Gasoline2S") {
119  desc += "_2T";
120  } else {
121  desc += "_4T";
122  }
123  } else if (vClass == "Delivery") {
124  desc = "LNF_";
125  if (fuel == "Gasoline") {
126  desc += "G_";
127  } else if (fuel == "Diesel") {
128  desc += "D_";
129  }
130  desc += "EU" + eClassOffset + "_I";
131  if (weight > 1305.) {
132  desc += "I";
133  if (weight > 1760.) {
134  desc += "I";
135  }
136  }
137  } else if (vClass == "UrbanBus") {
138  desc = "LB_D_EU" + eClassOffset;
139  } else if (vClass == "Coach") {
140  desc = "RB_D_EU" + eClassOffset;
141  } else if (vClass == "Truck") {
142  desc = "Solo_LKW_D_EU" + eClassOffset + "_I";
143  if (weight > 1305.) {
144  desc += "I";
145  }
146  } else if (vClass == "Trailer") {
147  desc = "LSZ_D_EU" + eClassOffset;
148  }
149  if (myEmissionClassStrings.hasString(desc)) {
150  return myEmissionClassStrings.get(desc);
151  }
152  return base;
153 }
154 
155 
156 std::string
158  const std::string name = myEmissionClassStrings.getString(c);
159  if (name.find("KKR_") != std::string::npos) {
160  return "Moped";
161  } else if (name.find("RB_") != std::string::npos) {
162  return "Coach";
163  } else if (name.find("LB_") != std::string::npos) {
164  return "UrbanBus";
165  } else if (name.find("LNF_") != std::string::npos) {
166  return "Delivery";
167  } else if (name.find("LSZ_") != std::string::npos) {
168  return "Trailer";
169  } else if (name.find("MR_") != std::string::npos) {
170  return "Motorcycle";
171  } else if (name.find("LKW_") != std::string::npos) {
172  return "Truck";
173  }
174  return "Passenger";
175 }
176 
177 
178 std::string
180  const std::string name = myEmissionClassStrings.getString(c);
181  std::string fuel = "Gasoline";
182  if (name.find("_D_") != std::string::npos) {
183  fuel = "Diesel";
184  }
185  if (name.find("H_") != std::string::npos) {
186  fuel = "Hybrid" + fuel;
187  }
188  return fuel;
189 }
190 
191 
192 int
194  const std::string name = myEmissionClassStrings.getString(c);
195  if (name.find("_EU1") != std::string::npos) {
196  return 1;
197  } else if (name.find("_EU2") != std::string::npos) {
198  return 2;
199  } else if (name.find("_EU3") != std::string::npos) {
200  return 3;
201  } else if (name.find("_EU4") != std::string::npos) {
202  return 4;
203  } else if (name.find("_EU5") != std::string::npos) {
204  return 5;
205  } else if (name.find("_EU6") != std::string::npos) {
206  return 6;
207  }
208  return 0;
209 }
210 
211 
212 double
214  const std::string name = myEmissionClassStrings.getString(c);
215  if (name.find("LNF_") != std::string::npos) {
216  if (name.find("_III") != std::string::npos) {
217  return 2630.;
218  } else if (name.find("_II") != std::string::npos) {
219  return 1532.;
220  } else if (name.find("_I") != std::string::npos) {
221  return 652.;
222  }
223  }
224  if (name.find("Solo_LKW_") != std::string::npos) {
225  if (name.find("_II") != std::string::npos) {
226  return 8398.;
227  } else if (name.find("_I") != std::string::npos) {
228  return 18702.;
229  }
230  }
231  return -1.;
232 }
233 
234 
235 double
236 HelpersPHEMlight::getEmission(const PHEMCEP* oldCep, PHEMlightdll::CEP* currCep, const std::string& e, const double p, const double v) const {
237  if (oldCep != nullptr) {
238  return oldCep->GetEmission(e, p, v);
239  }
240  return currCep->GetEmission(e, p, v, &myHelper);
241 }
242 
243 
244 double
245 HelpersPHEMlight::getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope) const {
246  PHEMlightdll::CEP* currCep = myCEPs.count(c) == 0 ? 0 : myCEPs.find(c)->second;
247  if (currCep != nullptr) {
248  return v == 0.0 ? 0.0 : MIN2(a, currCep->GetMaxAccel(v, slope));
249  }
250  return a;
251 }
252 
253 
254 double
255 HelpersPHEMlight::compute(const SUMOEmissionClass c, const PollutantsInterface::EmissionType e, const double v, const double a, const double slope, const std::map<int, double>* /* param */) const {
256  if (c == PHEMLIGHT_BASE) { // zero emission class
257  return 0.;
258  }
259  const double corrSpeed = MAX2((double) 0.0, v);
260  double power = 0.;
261 #ifdef INTERNAL_PHEM
262  const PHEMCEP* const oldCep = PHEMCEPHandler::getHandlerInstance().GetCep(c);
263  if (oldCep != nullptr) {
264  if (v > IDLE_SPEED && a < oldCep->GetDecelCoast(corrSpeed, a, slope, 0)) {
265  // coasting without power use only works if the engine runs above idle speed and
266  // the vehicle does not accelerate beyond friction losses
267  return 0;
268  }
269  power = oldCep->CalcPower(corrSpeed, a, slope);
270  }
271 #else
272  const PHEMCEP* const oldCep = 0;
273 #endif
274  PHEMlightdll::CEP* currCep = myCEPs.count(c) == 0 ? 0 : myCEPs.find(c)->second;
275  if (currCep != nullptr) {
276  const double corrAcc = getModifiedAccel(c, corrSpeed, a, slope);
277  if (currCep->getFuelType() != PHEMlightdll::Constants::strBEV && corrAcc < currCep->GetDecelCoast(corrSpeed, corrAcc, slope) && corrSpeed > PHEMlightdll::Constants::ZERO_SPEED_ACCURACY) {
278  // the IDLE_SPEED fix above is now directly in the decel coast calculation.
279  return 0;
280  }
281  power = currCep->CalcPower(corrSpeed, corrAcc, slope);
282  }
283  const std::string& fuelType = oldCep != nullptr ? oldCep->GetVehicleFuelType() : currCep->getFuelType();
284  switch (e) {
286  return getEmission(oldCep, currCep, "CO", power, corrSpeed) / SECONDS_PER_HOUR * 1000.;
288  if (oldCep != nullptr) {
289  return getEmission(oldCep, currCep, "FC", power, corrSpeed) * 3.15 / SECONDS_PER_HOUR * 1000.;
290  }
291  return currCep->GetCO2Emission(getEmission(nullptr, currCep, "FC", power, corrSpeed),
292  getEmission(nullptr, currCep, "CO", power, corrSpeed),
293  getEmission(nullptr, currCep, "HC", power, corrSpeed), &myHelper) / SECONDS_PER_HOUR * 1000.;
295  return getEmission(oldCep, currCep, "HC", power, corrSpeed) / SECONDS_PER_HOUR * 1000.;
297  return getEmission(oldCep, currCep, "NOx", power, corrSpeed) / SECONDS_PER_HOUR * 1000.;
299  return getEmission(oldCep, currCep, "PM", power, corrSpeed) / SECONDS_PER_HOUR * 1000.;
301  if (fuelType == PHEMlightdll::Constants::strDiesel) { // divide by average diesel density of 836 g/l
302  return getEmission(oldCep, currCep, "FC", power, corrSpeed) / 836. / SECONDS_PER_HOUR * 1000.;
303  } else if (fuelType == PHEMlightdll::Constants::strGasoline) { // divide by average gasoline density of 742 g/l
304  return getEmission(oldCep, currCep, "FC", power, corrSpeed) / 742. / SECONDS_PER_HOUR * 1000.;
305  } else if (fuelType == PHEMlightdll::Constants::strBEV) {
306  return 0;
307  } else {
308  return getEmission(oldCep, currCep, "FC", power, corrSpeed) / SECONDS_PER_HOUR * 1000.; // surely false, but at least not additionally modified
309  }
310  }
312  if (fuelType == PHEMlightdll::Constants::strBEV) {
313  return getEmission(oldCep, currCep, "FC", power, corrSpeed) / SECONDS_PER_HOUR * 1000.;
314  }
315  return 0;
316  }
317  // should never get here
318  return 0.;
319 }
320 
321 
322 /****************************************************************************/
PHEMlightdll::CEPHandler::GetCEP
bool GetCEP(const std::vector< std::string > &DataPath, Helpers *Helper)
Definition: CEPHandler.cpp:39
PHEMlightdll::Helpers::setCommentPrefix
void setCommentPrefix(const std::string &value)
Definition: Helpers.cpp:79
SUMOVehicleClass
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
Definition: SUMOVehicleClass.h:133
HelpersPHEMlight::getAmitranVehicleClass
std::string getAmitranVehicleClass(const SUMOEmissionClass c) const
Returns the vehicle class described by this emission class as described in the Amitran interface (Pas...
Definition: HelpersPHEMlight.cpp:157
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
PHEMCEPHandler.h
PHEMCEP
Data Handler for a single CEP emission data set.
Definition: PHEMCEP.h:51
PHEMCEP::CalcPower
double CalcPower(double v, double a, double slope, double vehicleLoading=0) const
Returns the power of used for a vehicle at state v,a, slope and loading.
Definition: PHEMCEP.cpp:399
PHEMlightdll::CEPHandler::getCEPS
const std::map< std::string, CEP * > & getCEPS() const
Definition: CEPHandler.cpp:35
PHEMCEP::GetEmission
double GetEmission(const std::string &pollutantIdentifier, double power, double speed, bool normalized=false) const
Returns a emission measure for power[kW] level.
Definition: PHEMCEP.cpp:196
PHEMlightdll::Helpers::setPHEMDataV
void setPHEMDataV(const std::string &value)
Definition: Helpers.cpp:87
StringBijection::getString
const std::string & getString(const T key) const
Definition: StringBijection.h:106
OptionsCont.h
PHEMlightdll::Constants::strBEV
static const std::string strBEV
Definition: Constants.h:62
PollutantsInterface::EmissionType
EmissionType
Enumerating all emission types, including fuel.
Definition: PollutantsInterface.h:55
PollutantsInterface::FUEL
@ FUEL
Definition: PollutantsInterface.h:55
PHEMlightdll::CEP::GetEmission
double GetEmission(const std::string &pollutant, double power, double speed, Helpers *VehicleClass)
Definition: CEP.cpp:226
HelpersPHEMlight::getFuel
std::string getFuel(const SUMOEmissionClass c) const
Returns the fuel type described by this emission class as described in the Amitran interface (Gasolin...
Definition: HelpersPHEMlight.cpp:179
HelpersPHEMlight::myHelper
PHEMlightdll::Helpers myHelper
Definition: HelpersPHEMlight.h:131
HelpersPHEMlight::myIndex
int myIndex
the index of the next class
Definition: HelpersPHEMlight.h:129
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:57
SUMOEmissionClass
int SUMOEmissionClass
Definition: SUMOVehicleClass.h:231
PollutantsInterface::HEAVY_BIT
static const int HEAVY_BIT
the bit to set for denoting heavy vehicles
Definition: PollutantsInterface.h:264
PHEMConstants.h
PHEMlightdll::Helpers::getErrMsg
const std::string & getErrMsg() const
Definition: Helpers.cpp:67
PHEMCEPHandler::GetCep
PHEMCEP * GetCep(SUMOEmissionClass emissionClass)
Returns the CEP data for a PHEM emission class.
Definition: PHEMCEPHandler.cpp:173
PHEMlightdll::CEP::getFuelType
const std::string & getFuelType() const
Definition: CEP.cpp:168
HelpersPHEMlight::getClassByName
SUMOEmissionClass getClassByName(const std::string &eClass, const SUMOVehicleClass vc)
Checks whether the string describes a known vehicle class.
Definition: HelpersPHEMlight.cpp:47
PollutantsInterface::CO
@ CO
Definition: PollutantsInterface.h:55
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
HelpersPHEMlight.h
SECONDS_PER_HOUR
const double SECONDS_PER_HOUR
Definition: PHEMConstants.h:23
StringBijection::addAlias
void addAlias(const std::string str, const T key)
Definition: StringBijection.h:86
PHEMlightdll::CEP::GetCO2Emission
double GetCO2Emission(double _FC, double _CO, double _HC, Helpers *VehicleClass)
Definition: CEP.cpp:287
HelpersPHEMlight::HelpersPHEMlight
HelpersPHEMlight()
Constructor.
Definition: HelpersPHEMlight.cpp:41
HelpersPHEMlight::compute
double compute(const SUMOEmissionClass c, const PollutantsInterface::EmissionType e, const double v, const double a, const double slope, const std::map< int, double > *param) const
Returns the amount of emitted pollutant given the vehicle type and state (in mg/s or in ml/s for fuel...
Definition: HelpersPHEMlight.cpp:255
StringBijection::insert
void insert(const std::string str, const T key, bool checkDuplicates=true)
Definition: StringBijection.h:71
StringBijection::get
T get(const std::string &str) const
Definition: StringBijection.h:97
PollutantsInterface::PM_X
@ PM_X
Definition: PollutantsInterface.h:55
PHEMlightdll::CEP::GetMaxAccel
double GetMaxAccel(double speed, double gradient)
Definition: CEP.cpp:416
PollutantsInterface::HC
@ HC
Definition: PollutantsInterface.h:55
IDLE_SPEED
#define IDLE_SPEED
Definition: HelpersPHEMlight.cpp:36
PollutantsInterface::NO_X
@ NO_X
Definition: PollutantsInterface.h:55
HelpersPHEMlight::myCEPHandler
PHEMlightdll::CEPHandler myCEPHandler
Definition: HelpersPHEMlight.h:130
HelpersPHEMlight::getModifiedAccel
double getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope) const
Returns the adapted acceleration value, useful for comparing with external PHEMlight references.
Definition: HelpersPHEMlight.cpp:245
PollutantsInterface::ELEC
@ ELEC
Definition: PollutantsInterface.h:55
PHEMCEP::GetVehicleFuelType
const std::string & GetVehicleFuelType() const
Getter function to recieve vehicle data from CEP.
Definition: PHEMCEP.h:222
PollutantsInterface::CO2
@ CO2
Definition: PollutantsInterface.h:55
PHEMlightdll::Constants::strDiesel
static const std::string strDiesel
Definition: Constants.h:58
HelpersPHEMlight::getClass
SUMOEmissionClass getClass(const SUMOEmissionClass base, const std::string &vClass, const std::string &fuel, const std::string &eClass, const double weight) const
Returns the emission class described by the given parameters.
Definition: HelpersPHEMlight.cpp:94
PHEMlightdll::Constants::strGasoline
static const std::string strGasoline
Definition: Constants.h:57
HelpersPHEMlight::myCEPs
std::map< SUMOEmissionClass, PHEMlightdll::CEP * > myCEPs
Definition: HelpersPHEMlight.h:132
PollutantsInterface::Helper::myEmissionClassStrings
StringBijection< SUMOEmissionClass > myEmissionClassStrings
Mapping between emission class names and integer representations.
Definition: PollutantsInterface.h:253
PHEMlightdll::Helpers::getgClass
const std::string & getgClass() const
Definition: Helpers.cpp:59
PHEMlightdll::CEP::CalcPower
double CalcPower(double speed, double acc, double gradient)
Definition: CEP.cpp:196
InvalidArgument
Definition: UtilExceptions.h:56
HelpersPHEMlight::getWeight
double getWeight(const SUMOEmissionClass c) const
Returns a reference weight in kg described by this emission class as described in the Amitran interfa...
Definition: HelpersPHEMlight.cpp:213
config.h
PHEMCEPHandler::getHandlerInstance
static PHEMCEPHandler & getHandlerInstance()
Implementatio of Singelton pattern.
Definition: PHEMCEPHandler.cpp:53
StringBijection::hasString
bool hasString(const std::string &str) const
Definition: StringBijection.h:116
HelpersPHEMlight::getEuroClass
int getEuroClass(const SUMOEmissionClass c) const
Returns the Euro emission class described by this emission class as described in the Amitran interfac...
Definition: HelpersPHEMlight.cpp:193
PollutantsInterface
Helper methods for PHEMlight-based emission computation.
Definition: PollutantsInterface.h:51
HelpersPHEMlight::getEmission
double getEmission(const PHEMCEP *oldCep, PHEMlightdll::CEP *currCep, const std::string &e, const double p, const double v) const
Returns the amount of emitted pollutant given the vehicle type and state (in mg/s or in ml/s for fuel...
Definition: HelpersPHEMlight.cpp:236
PHEMlightdll::Helpers::setclass
bool setclass(const std::string &VEH)
Definition: Helpers.cpp:237
Constants.h
StringBijection::remove
void remove(const std::string str, const T key)
Definition: StringBijection.h:91
PHEMlightdll::Constants::ZERO_SPEED_ACCURACY
static const double ZERO_SPEED_ACCURACY
Definition: Constants.h:37
PHEMlightdll::CEP
Definition: CEP.h:36
HelpersPHEMlight::PHEMLIGHT_BASE
static const int PHEMLIGHT_BASE
Definition: HelpersPHEMlight.h:50