Line data Source code
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 : /****************************************************************************/
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 92 : PHEMCEPHandler::PHEMCEPHandler() {
39 92 : }
40 :
41 :
42 92 : PHEMCEPHandler::~PHEMCEPHandler() {
43 : std::map<SUMOEmissionClass, PHEMCEP*>::iterator iter = _ceps.begin();
44 92 : while (iter != _ceps.end()) {
45 0 : delete (iter->second);
46 : iter++;
47 : } // end while
48 : _ceps.clear();
49 92 : }
50 :
51 :
52 : PHEMCEPHandler&
53 942732 : PHEMCEPHandler::getHandlerInstance() {
54 942732 : static PHEMCEPHandler instance;
55 942732 : return instance;
56 : }
57 :
58 :
59 : bool
60 0 : 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 0 : OptionsCont& oc = OptionsCont::getOptions();
94 : //std::string phemPath = oc.getString("phemlight-path") + "/";
95 : std::vector<std::string> phemPath;
96 0 : phemPath.push_back(oc.getString("phemlight-path") + "/");
97 0 : if (getenv("PHEMLIGHT_PATH") != nullptr) {
98 0 : phemPath.push_back(std::string(getenv("PHEMLIGHT_PATH")) + "/");
99 : }
100 0 : if (getenv("SUMO_HOME") != nullptr) {
101 0 : phemPath.push_back(std::string(getenv("SUMO_HOME")) + "/data/emissions/PHEMlight/");
102 : }
103 0 : 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 0 : if (!ReadEmissionData(true, phemPath, emissionClassIdentifier, headerFC, matrixFC, idlingValuesFC)) {
131 : return false;
132 : }
133 :
134 0 : if (!ReadEmissionData(false, phemPath, emissionClassIdentifier, headerPollutants, matrixPollutants, idlingValues)) {
135 : return false;
136 : }
137 :
138 0 : _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 0 : idlingValues);
167 :
168 0 : return true;
169 0 : } // end of Load()
170 :
171 :
172 : PHEMCEP*
173 942732 : PHEMCEPHandler::GetCep(SUMOEmissionClass emissionClass) {
174 : // check if Cep has been loaded
175 942732 : if (_ceps.find(emissionClass) == _ceps.end()) {
176 : return nullptr;
177 : } // end if
178 :
179 0 : return _ceps[emissionClass];
180 : } // end of GetCep
181 :
182 :
183 : bool
184 0 : 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 0 : std::ifstream fileVehicle;
211 0 : for (std::vector<std::string>::const_iterator i = path.begin(); i != path.end(); i++) {
212 0 : fileVehicle.open(((*i) + emissionClass + ".PHEMLight.veh").c_str());
213 0 : if (fileVehicle.good()) {
214 : break;
215 : }
216 : }
217 0 : if (!fileVehicle.good()) {
218 : return false;
219 : }
220 :
221 : std::string line;
222 : std::string cell;
223 0 : std::string commentPrefix = "c";
224 : int dataCount = 0;
225 :
226 : // skip header
227 0 : std::getline(fileVehicle, line);
228 :
229 0 : while (std::getline(fileVehicle, line) && dataCount <= 49) {
230 : // EOL handling for Linux
231 0 : if (line.size() > 0 && line.substr(line.size() - 1) == "\r") {
232 0 : line = line.substr(0, line.size() - 1);
233 : }
234 :
235 0 : std::stringstream lineStream(line);
236 :
237 0 : if (line.substr(0, 1) == commentPrefix) {
238 : continue;
239 : } else {
240 0 : dataCount++;
241 : }
242 :
243 0 : std::getline(lineStream, cell, ',');
244 :
245 : // reading Mass
246 0 : if (dataCount == 1) {
247 0 : std::istringstream(cell) >> vehicleMass;
248 : }
249 :
250 : // reading vehicle loading
251 0 : if (dataCount == 2) {
252 0 : std::istringstream(cell) >> vehicleLoading;
253 : }
254 :
255 : // reading cWValue
256 0 : if (dataCount == 3) {
257 0 : std::istringstream(cell) >> cWValue;
258 : }
259 :
260 : // reading crossectional area
261 0 : if (dataCount == 4) {
262 0 : std::istringstream(cell) >> crossArea;
263 : }
264 :
265 : // reading vehicle mass rotational
266 0 : if (dataCount == 7) {
267 0 : std::istringstream(cell) >> vehicleMassRot;
268 : }
269 :
270 : // reading rated power
271 0 : if (dataCount == 10) {
272 0 : std::istringstream(cell) >> ratedPower;
273 : }
274 :
275 : // reading engine rated speed
276 0 : if (dataCount == 11) {
277 0 : std::istringstream(cell) >> engineRatedSpeed;
278 : }
279 :
280 : // reading engine idling speed
281 0 : if (dataCount == 12) {
282 0 : std::istringstream(cell) >> engineIdlingSpeed;
283 : }
284 :
285 : // reading f0
286 0 : if (dataCount == 14) {
287 0 : std::istringstream(cell) >> f0;
288 : }
289 :
290 : // reading f1
291 0 : if (dataCount == 15) {
292 0 : std::istringstream(cell) >> f1;
293 : }
294 :
295 : // reading f2
296 0 : if (dataCount == 16) {
297 0 : std::istringstream(cell) >> f2;
298 : }
299 :
300 : // reading f3
301 0 : if (dataCount == 17) {
302 0 : std::istringstream(cell) >> f3;
303 : }
304 :
305 : // reading f4
306 0 : if (dataCount == 18) {
307 0 : std::istringstream(cell) >> f4;
308 : }
309 : // reading axleRatio
310 0 : if (dataCount == 21) {
311 0 : std::istringstream(cell) >> axleRatio;
312 : }
313 :
314 : // reading effective wheel diameter
315 0 : if (dataCount == 22) {
316 0 : std::istringstream(cell) >> effectiveWheelDiameter;
317 : }
318 :
319 : // reading vehicleMassType
320 0 : if (dataCount == 45) {
321 : vehicleMassType = cell;
322 : }
323 :
324 : // reading vehicleFuelType
325 0 : if (dataCount == 46) {
326 : vehicleFuelType = cell;
327 : }
328 :
329 : // reading pNormV0
330 0 : if (dataCount == 47) {
331 0 : std::istringstream(cell) >> pNormV0;
332 : }
333 :
334 : // reading pNormP0
335 0 : if (dataCount == 48) {
336 0 : std::istringstream(cell) >> pNormP0;
337 : }
338 :
339 : // reading pNormV1
340 0 : if (dataCount == 49) {
341 0 : std::istringstream(cell) >> pNormV1;
342 : }
343 :
344 : // reading pNormP1
345 0 : if (dataCount == 50) {
346 0 : std::istringstream(cell) >> pNormP1;
347 : }
348 0 : } // end while
349 :
350 0 : while (std::getline(fileVehicle, line) && line.substr(0, 1) != commentPrefix) {
351 0 : std::stringstream lineStream(line);
352 : std::vector<double> vi;
353 0 : while (std::getline(lineStream, cell, ',')) {
354 : double entry;
355 0 : std::istringstream(cell) >> entry;
356 0 : vi.push_back(entry);
357 :
358 : } // end while
359 0 : matrixSpeedInertiaTable.push_back(vi);
360 0 : } // end while
361 :
362 0 : while (std::getline(fileVehicle, line)) {
363 0 : if (line.substr(0, 1) == commentPrefix) {
364 0 : continue;
365 : }
366 :
367 0 : std::stringstream lineStream(line);
368 : std::vector<double> vi;
369 0 : while (std::getline(lineStream, cell, ',')) {
370 : double entry;
371 0 : std::istringstream(cell) >> entry;
372 0 : vi.push_back(entry);
373 :
374 : } // end while
375 0 : normedDragTable.push_back(vi);
376 0 : } // end while
377 :
378 :
379 0 : fileVehicle.close();
380 : return true;
381 0 : } // end of ReadVehicleFile
382 :
383 :
384 0 : 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 0 : std::string pollutantExtension = "";
388 0 : if (readFC) {
389 : pollutantExtension += "_FC";
390 : }
391 : // declare file stream
392 0 : std::ifstream fileEmission;
393 0 : for (std::vector<std::string>::const_iterator i = path.begin(); i != path.end(); i++) {
394 0 : fileEmission.open(((*i) + emissionClass + pollutantExtension + ".csv").c_str());
395 0 : if (fileEmission.good()) {
396 : break;
397 : }
398 : }
399 :
400 0 : if (!fileEmission.good()) {
401 : return false;
402 : }
403 :
404 : std::string line;
405 : std::string cell;
406 : // read header line for pollutant identifiers
407 0 : if (std::getline(fileEmission, line)) {
408 0 : std::stringstream lineStream(line);
409 :
410 : // skip first entry "Pe"
411 0 : std::getline(lineStream, cell, ',');
412 :
413 0 : while (std::getline(lineStream, cell, ',')) {
414 0 : header.push_back(cell);
415 : } // end while
416 :
417 0 : } // end if
418 :
419 : // skip units
420 0 : std::getline(fileEmission, line);
421 :
422 : // skip comments
423 0 : std::getline(fileEmission, line);
424 :
425 : // reading idlingValues
426 0 : std::getline(fileEmission, line);
427 :
428 0 : std::stringstream idlingStream(line);
429 : std::string idlingCell;
430 :
431 : //skipping idle comment
432 0 : std::getline(idlingStream, idlingCell, ',');
433 :
434 0 : while (std::getline(idlingStream, idlingCell, ',')) {
435 : double entry;
436 0 : std::istringstream(idlingCell) >> entry;
437 0 : idlingValues.push_back(entry);
438 : } // end while
439 :
440 0 : while (std::getline(fileEmission, line)) {
441 0 : std::stringstream lineStream(line);
442 : std::vector <double> vi;
443 0 : while (std::getline(lineStream, cell, ',')) {
444 : double entry;
445 0 : std::istringstream(cell) >> entry;
446 0 : vi.push_back(entry);
447 :
448 : } // end while
449 0 : matrix.push_back(vi);
450 0 : } // end while
451 :
452 0 : fileEmission.close();
453 :
454 : return true;
455 0 : } // end of ReadEmissionData
456 :
457 :
458 : /****************************************************************************/
|