Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.
4 : // PHEMlight module
5 : // Copyright 2016 Technische Universitaet Graz, https://www.tugraz.at/
6 : // This program and the accompanying materials are made available under the
7 : // terms of the Eclipse Public License 2.0 which is available at
8 : // https://www.eclipse.org/legal/epl-2.0/
9 : // This Source Code may also be made available under the following Secondary
10 : // Licenses when the conditions for such availability set forth in the Eclipse
11 : // Public License 2.0 are satisfied: GNU General Public License, version 2
12 : // or later which is available at
13 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
14 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
15 : /****************************************************************************/
16 : /// @file CEPHandler.cpp
17 : /// @author Martin Dippold
18 : /// @author Michael Behrisch
19 : /// @date July 2016
20 : ///
21 : //
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <fstream>
26 : #include <sstream>
27 : #include "CEPHandler.h"
28 : #include "CEP.h"
29 : #include "Helpers.h"
30 : #include "Constants.h"
31 :
32 :
33 : namespace PHEMlightdll {
34 :
35 92818 : CEPHandler::CEPHandler() {
36 92818 : _ceps = std::map<std::string, CEP*>();
37 92818 : }
38 :
39 363 : const std::map<std::string, CEP*>& CEPHandler::getCEPS() const {
40 363 : return _ceps;
41 : }
42 :
43 121 : bool CEPHandler::GetCEP(const std::vector<std::string>& DataPath, Helpers* Helper) {
44 121 : if (getCEPS().find(Helper->getgClass()) == getCEPS().end()) {
45 121 : if (!Load(DataPath, Helper)) {
46 : return false;
47 : }
48 : }
49 : return true;
50 : }
51 :
52 121 : bool CEPHandler::Load(const std::vector<std::string>& DataPath, Helpers* Helper) {
53 : //Deklaration
54 : // get string identifier for PHEM emission class
55 : //C# TO C++ CONVERTER TODO TASK: There is no native C++ equivalent to 'ToString':
56 121 : std::string emissionRep = Helper->getgClass();
57 :
58 : // to hold everything.
59 : std::vector<std::vector<double> > matrixSpeedInertiaTable;
60 : std::vector<std::vector<double> > normedTragTableSpeedInertiaTable;
61 : std::vector<std::vector<double> > matrixFC;
62 : std::vector<std::vector<double> > matrixPollutants;
63 : std::vector<double> idlingValuesFC;
64 : std::vector<double> idlingValuesPollutants;
65 : std::vector<std::string> headerFC;
66 : std::vector<std::string> headerPollutants;
67 :
68 : double vehicleMass;
69 : double vehicleLoading;
70 : double vehicleMassRot;
71 : double crosssectionalArea;
72 : double cwValue;
73 : double f0;
74 : double f1;
75 : double f2;
76 : double f3;
77 : double f4;
78 : double axleRatio;
79 : std::vector<double> transmissionGearRatios;
80 : double auxPower;
81 : double ratedPower;
82 : double engineIdlingSpeed;
83 : double engineRatedSpeed;
84 : double effectiveWhellDiameter;
85 : std::string vehicleMassType;
86 : std::string vehicleFuelType;
87 : double pNormV0;
88 : double pNormP0;
89 : double pNormV1;
90 : double pNormP1;
91 :
92 121 : if (!ReadVehicleFile(DataPath, emissionRep, Helper, vehicleMass, vehicleLoading, vehicleMassRot, crosssectionalArea, cwValue, f0, f1, f2, f3, f4, axleRatio, auxPower, ratedPower, engineIdlingSpeed, engineRatedSpeed, effectiveWhellDiameter, transmissionGearRatios, vehicleMassType, vehicleFuelType, pNormV0, pNormP0, pNormV1, pNormP1, matrixSpeedInertiaTable, normedTragTableSpeedInertiaTable)) {
93 : return false;
94 : }
95 :
96 121 : if (!ReadEmissionData(true, DataPath, emissionRep, Helper, headerFC, matrixFC, idlingValuesFC)) {
97 : return false;
98 : }
99 :
100 121 : if (!ReadEmissionData(false, DataPath, emissionRep, Helper, headerPollutants, matrixPollutants, idlingValuesPollutants)) {
101 : return false;
102 : }
103 :
104 242 : _ceps.insert(std::make_pair(Helper->getgClass(), new CEP(vehicleMassType == Constants::HeavyVehicle, vehicleMass, vehicleLoading, vehicleMassRot, crosssectionalArea, cwValue, f0, f1, f2, f3, f4, axleRatio, transmissionGearRatios, auxPower, ratedPower, engineIdlingSpeed, engineRatedSpeed, effectiveWhellDiameter, pNormV0, pNormP0, pNormV1, pNormP1, vehicleFuelType, matrixFC, headerPollutants, matrixPollutants, matrixSpeedInertiaTable, normedTragTableSpeedInertiaTable, idlingValuesFC.front(), idlingValuesPollutants)));
105 :
106 121 : return true;
107 121 : }
108 :
109 121 : bool CEPHandler::ReadVehicleFile(const std::vector<std::string>& DataPath, const std::string& emissionClass, Helpers* Helper, double& vehicleMass, double& vehicleLoading, double& vehicleMassRot, double& crossArea, double& cWValue, double& f0, double& f1, double& f2, double& f3, double& f4, double& axleRatio, double& auxPower, double& ratedPower, double& engineIdlingSpeed, double& engineRatedSpeed, double& effectiveWheelDiameter, std::vector<double>& transmissionGearRatios, 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) {
110 121 : vehicleMass = 0;
111 121 : vehicleLoading = 0;
112 121 : vehicleMassRot = 0;
113 121 : crossArea = 0;
114 121 : cWValue = 0;
115 121 : f0 = 0;
116 121 : f1 = 0;
117 121 : f2 = 0;
118 121 : f3 = 0;
119 121 : f4 = 0;
120 121 : axleRatio = 0;
121 121 : ratedPower = 0;
122 121 : auxPower = 0;
123 121 : engineIdlingSpeed = 0;
124 121 : engineRatedSpeed = 0;
125 121 : effectiveWheelDiameter = 0;
126 : vehicleMassType = "";
127 : vehicleFuelType = "";
128 121 : pNormV0 = 0;
129 121 : pNormP0 = 0;
130 121 : pNormV1 = 0;
131 121 : pNormP1 = 0;
132 121 : transmissionGearRatios = std::vector<double>();
133 121 : matrixSpeedInertiaTable = std::vector<std::vector<double> >();
134 121 : normedDragTable = std::vector<std::vector<double> >();
135 : std::string line;
136 : std::string cell;
137 : int dataCount = 0;
138 :
139 : //Open file
140 121 : std::ifstream vehicleReader;
141 238 : for (std::vector<std::string>::const_iterator i = DataPath.begin(); i != DataPath.end(); i++) {
142 476 : vehicleReader.open(((*i) + emissionClass + ".PHEMLight.veh").c_str());
143 238 : if (vehicleReader.good()) {
144 : break;
145 : }
146 : }
147 121 : if (!vehicleReader.good()) {
148 0 : Helper->setErrMsg("File does not exist! (" + emissionClass + ".PHEMLight.veh)");
149 0 : return false;
150 : }
151 :
152 : // skip header
153 121 : ReadLine(vehicleReader);
154 :
155 26378 : while ((line = ReadLine(vehicleReader)) != "" && dataCount <= 49) {
156 13068 : if (line.substr(0, 1) == Helper->getCommentPrefix()) {
157 7018 : continue;
158 : }
159 : else {
160 6050 : dataCount++;
161 : }
162 :
163 12100 : cell = split(line, ',')[0];
164 :
165 : // reading Mass
166 6050 : if (dataCount == 1) {
167 121 : vehicleMass = todouble(cell);
168 : }
169 :
170 : // reading vehicle loading
171 6050 : if (dataCount == 2) {
172 121 : vehicleLoading = todouble(cell);
173 : }
174 :
175 : // reading cWValue
176 6050 : if (dataCount == 3) {
177 121 : cWValue = todouble(cell);
178 : }
179 :
180 : // reading crossectional area
181 6050 : if (dataCount == 4) {
182 121 : crossArea = todouble(cell);
183 : }
184 :
185 : // reading vehicle mass rotational
186 6050 : if (dataCount == 7) {
187 121 : vehicleMassRot = todouble(cell);
188 : }
189 :
190 : // reading rated power
191 6050 : if (dataCount == 9) {
192 121 : auxPower = todouble(cell);
193 : }
194 :
195 : // reading rated power
196 6050 : if (dataCount == 10) {
197 121 : ratedPower = todouble(cell);
198 : }
199 :
200 : // reading engine rated speed
201 6050 : if (dataCount == 11) {
202 121 : engineRatedSpeed = todouble(cell);
203 : }
204 :
205 : // reading engine idling speed
206 6050 : if (dataCount == 12) {
207 121 : engineIdlingSpeed = todouble(cell);
208 : }
209 :
210 : // reading f0
211 6050 : if (dataCount == 14) {
212 121 : f0 = todouble(cell);
213 : }
214 :
215 : // reading f1
216 6050 : if (dataCount == 15) {
217 121 : f1 = todouble(cell);
218 : }
219 :
220 : // reading f2
221 6050 : if (dataCount == 16) {
222 121 : f2 = todouble(cell);
223 : }
224 :
225 : // reading f3
226 6050 : if (dataCount == 17) {
227 121 : f3 = todouble(cell);
228 : }
229 :
230 : // reading f4
231 6050 : if (dataCount == 18) {
232 121 : f4 = todouble(cell);
233 : }
234 :
235 : // reading axleRatio
236 6050 : if (dataCount == 21) {
237 121 : axleRatio = todouble(cell);
238 : }
239 :
240 : // reading effective wheel diameter
241 6050 : if (dataCount == 22) {
242 121 : effectiveWheelDiameter = todouble(cell);
243 : }
244 :
245 6050 : if (dataCount >= 23 && dataCount <= 40) {
246 2178 : transmissionGearRatios.push_back(todouble(cell));
247 : }
248 :
249 : // reading vehicleMassType
250 6050 : if (dataCount == 45) {
251 : vehicleMassType = cell;
252 : }
253 :
254 : // reading vehicleFuelType
255 6050 : if (dataCount == 46) {
256 : vehicleFuelType = cell;
257 : }
258 :
259 : // reading pNormV0
260 6050 : if (dataCount == 47) {
261 121 : pNormV0 = todouble(cell);
262 : }
263 :
264 : // reading pNormP0
265 6050 : if (dataCount == 48) {
266 121 : pNormP0 = todouble(cell);
267 : }
268 :
269 : // reading pNormV1
270 6050 : if (dataCount == 49) {
271 121 : pNormV1 = todouble(cell);
272 : }
273 :
274 : // reading pNormP1
275 6050 : if (dataCount == 50) {
276 121 : pNormP1 = todouble(cell);
277 : }
278 : }
279 :
280 1982 : while ((line = ReadLine(vehicleReader)) != "" && line.substr(0, 1) != Helper->getCommentPrefix()) {
281 870 : if (line.substr(0, 1) == Helper->getCommentPrefix()) {
282 0 : continue;
283 : }
284 :
285 1740 : matrixSpeedInertiaTable.push_back(todoubleList(split(line, ',')));
286 : }
287 :
288 3872 : while ((line = ReadLine(vehicleReader)) != "") {
289 1815 : if (line.substr(0, 1) == Helper->getCommentPrefix()) {
290 0 : continue;
291 : }
292 :
293 3630 : normedDragTable.push_back(todoubleList(split(line, ',')));
294 : }
295 :
296 : return true;
297 121 : }
298 :
299 242 : bool CEPHandler::ReadEmissionData(bool readFC, const std::vector<std::string>& DataPath, const std::string& emissionClass, Helpers* Helper, std::vector<std::string>& header, std::vector<std::vector<double> >& matrix, std::vector<double>& idlingValues) {
300 : // declare file stream
301 : std::string line;
302 242 : header = std::vector<std::string>();
303 242 : matrix = std::vector<std::vector<double> >();
304 242 : idlingValues = std::vector<double>();
305 :
306 242 : std::string pollutantExtension = "";
307 242 : if (readFC) {
308 242 : pollutantExtension += std::string("_FC");
309 : }
310 :
311 242 : std::ifstream fileReader;
312 476 : for (std::vector<std::string>::const_iterator i = DataPath.begin(); i != DataPath.end(); i++) {
313 952 : fileReader.open(((*i) + emissionClass + pollutantExtension + ".csv").c_str());
314 476 : if (fileReader.good()) {
315 : break;
316 : }
317 : }
318 242 : if (!fileReader.good()) {
319 0 : Helper->setErrMsg("File does not exist! (" + emissionClass + pollutantExtension + ".csv)");
320 0 : return false;
321 : }
322 :
323 : // read header line for pollutant identifiers
324 484 : if ((line = ReadLine(fileReader)) != "") {
325 242 : std::vector<std::string> entries = split(line, ',');
326 : // skip first entry "Pe"
327 1089 : for (int i = 1; i < (int)entries.size(); i++) {
328 847 : header.push_back(entries[i]);
329 : }
330 242 : }
331 :
332 : // skip units
333 242 : ReadLine(fileReader);
334 :
335 : // skip comment
336 242 : ReadLine(fileReader);
337 :
338 : //readIdlingValues
339 242 : line = ReadLine(fileReader);
340 :
341 242 : std::vector<std::string> stringIdlings = split(line, ',');
342 : stringIdlings.erase(stringIdlings.begin());
343 :
344 242 : idlingValues = todoubleList(stringIdlings);
345 :
346 11132 : while ((line = ReadLine(fileReader)) != "") {
347 10648 : matrix.push_back(todoubleList(split(line, ',')));
348 : }
349 : return true;
350 242 : }
351 :
352 14543 : std::vector<std::string> CEPHandler::split(const std::string& s, char delim) {
353 : std::vector<std::string> elems;
354 14543 : std::stringstream ss(s);
355 : std::string item;
356 58414 : while (std::getline(ss, item, delim)) {
357 43871 : elems.push_back(item);
358 : }
359 14543 : return elems;
360 14543 : }
361 :
362 41088 : double CEPHandler::todouble(const std::string& s) {
363 41088 : std::stringstream ss(s);
364 : double item;
365 : ss >> item;
366 41088 : return item;
367 41088 : }
368 :
369 8251 : std::vector<double> CEPHandler::todoubleList(const std::vector<std::string>& s) {
370 : std::vector<double> result;
371 44741 : for (std::vector<std::string>::const_iterator i = s.begin(); i != s.end(); ++i) {
372 36490 : result.push_back(todouble(*i));
373 : }
374 8251 : return result;
375 0 : }
376 :
377 22771 : std::string CEPHandler::ReadLine(std::ifstream& s) {
378 : std::string line;
379 22771 : std::getline(s, line);
380 : size_t lastNWChar = line.find_last_not_of(" \n\r\t");
381 22771 : if (lastNWChar != std::string::npos) {
382 22408 : line.erase(lastNWChar + 1);
383 : }
384 22771 : return line;
385 : }
386 : }
|