Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/emissions/PHEMCEPHandler.cpp
169678 views
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
/****************************************************************************/
14
/// @file PHEMCEPHandler.cpp
15
/// @author Nikolaus Furian
16
/// @author Daniel Krajzewicz
17
/// @author Michael Behrisch
18
/// @author Marek Heinrich
19
/// @date Thu, 13.06.2013
20
///
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"
32
#include <utils/options/OptionsCont.h>
33
#include <utils/common/UtilExceptions.h>
34
35
// ===========================================================================
36
// method definitions
37
// ===========================================================================
38
PHEMCEPHandler::PHEMCEPHandler() {
39
}
40
41
42
PHEMCEPHandler::~PHEMCEPHandler() {
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
52
PHEMCEPHandler&
53
PHEMCEPHandler::getHandlerInstance() {
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
93
OptionsCont& oc = OptionsCont::getOptions();
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*
173
PHEMCEPHandler::GetCep(SUMOEmissionClass emissionClass) {
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
/****************************************************************************/
459
460