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