Eclipse SUMO - Simulation of Urban MObility
PHEMCEPHandler.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-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 /****************************************************************************/
21 // Helper class for PHEM Light, holds CEP data for emission computation
22 /****************************************************************************/
23 #include <config.h>
24 
25 #include <cstdlib>
26 #include <fstream>
27 #include <sstream>
28 #include <string>
29 #include <vector>
30 #include "PHEMCEPHandler.h"
31 #include "PHEMConstants.h"
34 
35 // ===========================================================================
36 // method definitions
37 // ===========================================================================
39 }
40 
41 
43  std::map<SUMOEmissionClass, PHEMCEP*>::iterator iter = _ceps.begin();
44  while (iter != _ceps.end()) {
45  delete (iter->second);
46  iter++;
47  } // end while
48  _ceps.clear();
49 }
50 
51 
54  static PHEMCEPHandler instance;
55  return instance;
56 }
57 
58 
59 bool
60 PHEMCEPHandler::Load(SUMOEmissionClass emissionClass, const std::string& emissionClassIdentifier) {
61  // to hold everything.
62  std::vector< std::vector<double> > matrixSpeedInertiaTable;
63  std::vector< std::vector<double> > normedDragTable;
64  std::vector< std::vector<double> > matrixFC;
65  std::vector< std::vector<double> > matrixPollutants;
66  std::vector<std::string> headerFC;
67  std::vector<std::string> headerPollutants;
68  std::vector<double> idlingValues;
69  std::vector<double> idlingValuesFC;
70 
71  double vehicleMass;
72  double vehicleLoading;
73  double vehicleMassRot;
74  double crosssectionalArea;
75  double cwValue;
76  double f0;
77  double f1;
78  double f2;
79  double f3;
80  double f4;
81  double axleRatio;
82  double ratedPower;
83  double engineIdlingSpeed;
84  double engineRatedSpeed;
85  double effectiveWheelDiameter;
86  std::string vehicleMassType;
87  std::string vehicleFuelType;
88  double pNormV0;
89  double pNormP0;
90  double pNormV1;
91  double pNormP1;
92 
94  //std::string phemPath = oc.getString("phemlight-path") + "/";
95  std::vector<std::string> phemPath;
96  phemPath.push_back(oc.getString("phemlight-path") + "/");
97  if (getenv("PHEMLIGHT_PATH") != nullptr) {
98  phemPath.push_back(std::string(getenv("PHEMLIGHT_PATH")) + "/");
99  }
100  if (getenv("SUMO_HOME") != nullptr) {
101  phemPath.push_back(std::string(getenv("SUMO_HOME")) + "/data/emissions/PHEMlight/");
102  }
103  if (!ReadVehicleFile(phemPath, emissionClassIdentifier,
104  vehicleMass,
105  vehicleLoading,
106  vehicleMassRot,
107  crosssectionalArea,
108  cwValue,
109  f0,
110  f1,
111  f2,
112  f3,
113  f4,
114  axleRatio,
115  ratedPower,
116  engineIdlingSpeed,
117  engineRatedSpeed,
118  effectiveWheelDiameter,
119  vehicleMassType,
120  vehicleFuelType,
121  pNormV0,
122  pNormP0,
123  pNormV1,
124  pNormP1,
125  matrixSpeedInertiaTable,
126  normedDragTable)) {
127  return false;
128  }
129 
130  if (!ReadEmissionData(true, phemPath, emissionClassIdentifier, headerFC, matrixFC, idlingValuesFC)) {
131  return false;
132  }
133 
134  if (!ReadEmissionData(false, phemPath, emissionClassIdentifier, headerPollutants, matrixPollutants, idlingValues)) {
135  return false;
136  }
137 
138  _ceps[emissionClass] = new PHEMCEP(vehicleMassType == "HV",
139  emissionClass, emissionClassIdentifier,
140  vehicleMass,
141  vehicleLoading,
142  vehicleMassRot,
143  crosssectionalArea,
144  cwValue,
145  f0,
146  f1,
147  f2,
148  f3,
149  f4,
150  ratedPower,
151  pNormV0,
152  pNormP0,
153  pNormV1,
154  pNormP1,
155  axleRatio,
156  engineIdlingSpeed,
157  engineRatedSpeed,
158  effectiveWheelDiameter,
159  idlingValuesFC.front(),
160  vehicleFuelType,
161  matrixFC,
162  headerPollutants,
163  matrixPollutants,
164  matrixSpeedInertiaTable,
165  normedDragTable,
166  idlingValues);
167 
168  return true;
169 } // end of Load()
170 
171 
172 PHEMCEP*
174  // check if Cep has been loaded
175  if (_ceps.find(emissionClass) == _ceps.end()) {
176  return nullptr;
177  } // end if
178 
179  return _ceps[emissionClass];
180 } // end of GetCep
181 
182 
183 bool
184 PHEMCEPHandler::ReadVehicleFile(const std::vector<std::string>& path, const std::string& emissionClass,
185  double& vehicleMass,
186  double& vehicleLoading,
187  double& vehicleMassRot,
188  double& crossArea,
189  double& cWValue,
190  double& f0,
191  double& f1,
192  double& f2,
193  double& f3,
194  double& f4,
195  double& axleRatio,
196  double& ratedPower,
197  double& engineIdlingSpeed,
198  double& engineRatedSpeed,
199  double& effectiveWheelDiameter,
200  std::string& vehicleMassType,
201  std::string& vehicleFuelType,
202  double& pNormV0,
203  double& pNormP0,
204  double& pNormV1,
205  double& pNormP1,
206  std::vector< std::vector<double> >& matrixSpeedInertiaTable,
207  std::vector< std::vector<double> >& normedDragTable)
208 
209 {
210  std::ifstream fileVehicle;
211  for (std::vector<std::string>::const_iterator i = path.begin(); i != path.end(); i++) {
212  fileVehicle.open(((*i) + emissionClass + ".PHEMLight.veh").c_str());
213  if (fileVehicle.good()) {
214  break;
215  }
216  }
217  if (!fileVehicle.good()) {
218  return false;
219  }
220 
221  std::string line;
222  std::string cell;
223  std::string commentPrefix = "c";
224  int dataCount = 0;
225 
226  // skip header
227  std::getline(fileVehicle, line);
228 
229  while (std::getline(fileVehicle, line) && dataCount <= 49) {
230  // EOL handling for Linux
231  if (line.size() > 0 && line.substr(line.size() - 1) == "\r") {
232  line = line.substr(0, line.size() - 1);
233  }
234 
235  std::stringstream lineStream(line);
236 
237  if (line.substr(0, 1) == commentPrefix) {
238  continue;
239  } else {
240  dataCount++;
241  }
242 
243  std::getline(lineStream, cell, ',');
244 
245  // reading Mass
246  if (dataCount == 1) {
247  std::istringstream(cell) >> vehicleMass;
248  }
249 
250  // reading vehicle loading
251  if (dataCount == 2) {
252  std::istringstream(cell) >> vehicleLoading;
253  }
254 
255  // reading cWValue
256  if (dataCount == 3) {
257  std::istringstream(cell) >> cWValue;
258  }
259 
260  // reading crossectional area
261  if (dataCount == 4) {
262  std::istringstream(cell) >> crossArea;
263  }
264 
265  // reading vehicle mass rotational
266  if (dataCount == 7) {
267  std::istringstream(cell) >> vehicleMassRot;
268  }
269 
270  // reading rated power
271  if (dataCount == 10) {
272  std::istringstream(cell) >> ratedPower;
273  }
274 
275  // reading engine rated speed
276  if (dataCount == 11) {
277  std::istringstream(cell) >> engineRatedSpeed;
278  }
279 
280  // reading engine idling speed
281  if (dataCount == 12) {
282  std::istringstream(cell) >> engineIdlingSpeed;
283  }
284 
285  // reading f0
286  if (dataCount == 14) {
287  std::istringstream(cell) >> f0;
288  }
289 
290  // reading f1
291  if (dataCount == 15) {
292  std::istringstream(cell) >> f1;
293  }
294 
295  // reading f2
296  if (dataCount == 16) {
297  std::istringstream(cell) >> f2;
298  }
299 
300  // reading f3
301  if (dataCount == 17) {
302  std::istringstream(cell) >> f3;
303  }
304 
305  // reading f4
306  if (dataCount == 18) {
307  std::istringstream(cell) >> f4;
308  }
309  // reading axleRatio
310  if (dataCount == 21) {
311  std::istringstream(cell) >> axleRatio;
312  }
313 
314  // reading effective wheel diameter
315  if (dataCount == 22) {
316  std::istringstream(cell) >> effectiveWheelDiameter;
317  }
318 
319  // reading vehicleMassType
320  if (dataCount == 45) {
321  vehicleMassType = cell;
322  }
323 
324  // reading vehicleFuelType
325  if (dataCount == 46) {
326  vehicleFuelType = cell;
327  }
328 
329  // reading pNormV0
330  if (dataCount == 47) {
331  std::istringstream(cell) >> pNormV0;
332  }
333 
334  // reading pNormP0
335  if (dataCount == 48) {
336  std::istringstream(cell) >> pNormP0;
337  }
338 
339  // reading pNormV1
340  if (dataCount == 49) {
341  std::istringstream(cell) >> pNormV1;
342  }
343 
344  // reading pNormP1
345  if (dataCount == 50) {
346  std::istringstream(cell) >> pNormP1;
347  }
348  } // end while
349 
350  while (std::getline(fileVehicle, line) && line.substr(0, 1) != commentPrefix) {
351  std::stringstream lineStream(line);
352  std::vector<double> vi;
353  while (std::getline(lineStream, cell, ',')) {
354  double entry;
355  std::istringstream(cell) >> entry;
356  vi.push_back(entry);
357 
358  } // end while
359  matrixSpeedInertiaTable.push_back(vi);
360  } // end while
361 
362  while (std::getline(fileVehicle, line)) {
363  if (line.substr(0, 1) == commentPrefix) {
364  continue;
365  }
366 
367  std::stringstream lineStream(line);
368  std::vector<double> vi;
369  while (std::getline(lineStream, cell, ',')) {
370  double entry;
371  std::istringstream(cell) >> entry;
372  vi.push_back(entry);
373 
374  } // end while
375  normedDragTable.push_back(vi);
376  } // end while
377 
378 
379  fileVehicle.close();
380  return true;
381 } // end of ReadVehicleFile
382 
383 
384 bool PHEMCEPHandler::ReadEmissionData(bool readFC, const std::vector<std::string>& path, const std::string& emissionClass,
385  std::vector<std::string>& header, std::vector<std::vector<double> >& matrix, std::vector<double>& idlingValues) {
386 
387  std::string pollutantExtension = "";
388  if (readFC) {
389  pollutantExtension += "_FC";
390  }
391  // declare file stream
392  std::ifstream fileEmission;
393  for (std::vector<std::string>::const_iterator i = path.begin(); i != path.end(); i++) {
394  fileEmission.open(((*i) + emissionClass + pollutantExtension + ".csv").c_str());
395  if (fileEmission.good()) {
396  break;
397  }
398  }
399 
400  if (!fileEmission.good()) {
401  return false;
402  }
403 
404  std::string line;
405  std::string cell;
406  // read header line for pollutant identifiers
407  if (std::getline(fileEmission, line)) {
408  std::stringstream lineStream(line);
409 
410  // skip first entry "Pe"
411  std::getline(lineStream, cell, ',');
412 
413  while (std::getline(lineStream, cell, ',')) {
414  header.push_back(cell);
415  } // end while
416 
417  } // end if
418 
419  // skip units
420  std::getline(fileEmission, line);
421 
422  // skip comments
423  std::getline(fileEmission, line);
424 
425  // reading idlingValues
426  std::getline(fileEmission, line);
427 
428  std::stringstream idlingStream(line);
429  std::string idlingCell;
430 
431  //skipping idle comment
432  std::getline(idlingStream, idlingCell, ',');
433 
434  while (std::getline(idlingStream, idlingCell, ',')) {
435  double entry;
436  std::istringstream(idlingCell) >> entry;
437  idlingValues.push_back(entry);
438  } // end while
439 
440  while (std::getline(fileEmission, line)) {
441  std::stringstream lineStream(line);
442  std::vector <double> vi;
443  while (std::getline(lineStream, cell, ',')) {
444  double entry;
445  std::istringstream(cell) >> entry;
446  vi.push_back(entry);
447 
448  } // end while
449  matrix.push_back(vi);
450  } // end while
451 
452  fileEmission.close();
453 
454  return true;
455 } // end of ReadEmissionData
456 
457 
458 /****************************************************************************/
int SUMOEmissionClass
A storage for options typed value containers)
Definition: OptionsCont.h:89
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
Data Handler for all CEP emission and vehicle Data.
PHEMCEPHandler()
Implementation of Singelton pattern private (copy) constructor and =operator to avoid more than one i...
static PHEMCEPHandler & getHandlerInstance()
Implementatio of Singelton pattern.
~PHEMCEPHandler()
Destructor.
PHEMCEP * GetCep(SUMOEmissionClass emissionClass)
Returns the CEP data for a PHEM emission class.
bool Load(SUMOEmissionClass emissionClass, const std::string &emissionClassIdentifier)
Helper method to load CEP and vehicle files from file system.
bool ReadVehicleFile(const std::vector< std::string > &path, const std::string &emissionClass, double &vehicleMass, double &vehicleLoading, double &vehicleMassRot, double &crossArea, double &cWValue, double &f0, double &f1, double &f2, double &f3, double &f4, double &axleRatio, double &ratedPower, double &engineIdlingSpeed, double &engineRatedSpeed, double &effectiveWheelDiameter, std::string &vehicleMassType, std::string &vehicleFuelType, double &pNormV0, double &pNormP0, double &pNormV1, double &pNormP1, std::vector< std::vector< double > > &matrixSpeedInertiaTable, std::vector< std::vector< double > > &normedDragTable)
Helper method to read a vehicle file from file system.
std::map< SUMOEmissionClass, PHEMCEP * > _ceps
bijection between PHEMEmissionClass and CEPs
bool ReadEmissionData(bool readFC, const std::vector< std::string > &path, const std::string &emissionClass, std::vector< std::string > &header, std::vector< std::vector< double > > &matrix, std::vector< double > &idlingValues)
Helper method to read a CEP file from file system.
Data Handler for a single CEP emission data set.
Definition: PHEMCEP.h:49