Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
V5/cs/CEPHandler.cs
Go to the documentation of this file.
1#define FLEET
2using System.Collections.Generic;
3using System.Linq;
4using System.IO;
5using System.Globalization;
6using Newtonsoft.Json;
7
8namespace PHEMlightdll
9{
10 public class CEPHandler
11 {
12 #region Constructor
13 public CEPHandler() => _ceps = new Dictionary<string, CEP>();
14 #endregion
15
16 #region CEPS
17 private Dictionary<string, CEP> _ceps;
18 public Dictionary<string, CEP> CEPS => _ceps;
19 #endregion
20
21#if FLEET
22 #region FleetShares
23 private Dictionary<string, Dictionary<string, double>> _fleetShares;
24 public Dictionary<string, Dictionary<string, double>> FleetShares => _fleetShares;
25 #endregion
26#endif
27
28 #region GetCEP
29 public bool GetCEP(List<string> DataPath, Helpers Helper, Correction DataCor)
30 {
31 if (!CEPS.ContainsKey(Helper.gClass))
32 {
33 if (!Load(DataPath, Helper, DataCor))
34 return false;
35 }
36 return true;
37 }
38 #endregion
39
40 #if FLEET
41 #region GetFleetCEP
42 public bool GetFleetCEP(List<string> DataPath, string AggClass, Helpers Helper, Correction DataCor)
43 {
44 if (!CEPS.ContainsKey(Helper.gClass))
45 {
46 if (Constants.AGGREGATED_VEHICLECLASSES.Contains(AggClass))
47 {
48 List<CEP> weightedCEPS = new List<CEP>();
49
50 if (FleetShares.ContainsKey(AggClass))
51 {
52 foreach (string aggVehClass in FleetShares[AggClass].Keys)
53 {
54 if (!Helper.setclass(aggVehClass))
55 {
56 return false;
57 }
58 if (!CEPS.ContainsKey(aggVehClass) && !Load(DataPath, Helper, DataCor, true))
59 {
60 return false;
61 }
62 weightedCEPS.Add(CEPS[aggVehClass] * FleetShares[AggClass][aggVehClass]);
63 }
64 if (CEP.CheckClass(weightedCEPS.ToArray()))
65 {
66 _ceps.Add(AggClass, CEP.AddRangeCeps(weightedCEPS.ToArray(), Helper));
67 }
68 else
69 {
70 Helper.ErrMsg = "The aggregated vehicle class (" + AggClass + ") includes heavy and non heavy vehicles! This is not allowed. Aggregated vehicle class not added.";
71 return false;
72 }
73
74 //Set the vehicle class back
75 Helper.gClass = AggClass;
76 Helper.pClass = _ceps[_ceps.Last().Key].FuelType;
77 }
78 else
79 {
80 Helper.ErrMsg = "The aggregated vehicle class (" + AggClass + ") is not available in the FleetShare file!";
81 return false;
82 }
83 }
84 else
85 {
86 Helper.ErrMsg = "The aggregated vehicle class (" + AggClass + ") is a unknown class!";
87 return false;
88 }
89 }
90 return true;
91 }
92 #endregion
93#endif
94
95 #region Correction
96 private bool CalcCorrection(Correction DataCor, Helpers Helper, VEHPHEMLightJSON.Vehicle_Data vehicle_Data)
97 {
98 if (DataCor.UseDet)
99 {
100 DataCor.VehMileage = -1;
101 if (vehicle_Data.Mileage.HasValue) DataCor.VehMileage = vehicle_Data.Mileage.Value;
102
103 if (!DataCor.IniDETfactor(Helper))
104 return false;
105 }
106 if (DataCor.UseTNOx)
107 {
108 if (!DataCor.IniTNOxfactor(Helper))
109 return false;
110 }
111
112 //Return value
113 return true;
114 }
115 #endregion
116
117 #region Load
118 private bool Load(List<string> DataPath, Helpers Helper, Correction DataCor, bool fleetMix = false)
119 {
120 //Deklaration
121 // to hold everything.
122 List<List<double>> matrixFCvalues;
123 List<List<double>> matrixPollutants;
124 List<double> idlingValuesFCvalues;
125 List<double> idlingValuesPollutants;
126 List<string> headerFCvalues;
127 List<string> headerPollutants;
128 VEHPHEMLightJSON.VEH Vehicle;
129
130 if (!ReadVehicleFile(DataPath[0],
131 Helper,
132 fleetMix,
133 out Vehicle))
134 return false;
135
136 if (DataCor != null)
137 {
138 if (!CalcCorrection(DataCor, Helper, Vehicle.VehicleData))
139 return false;
140 }
141
142 if (!ReadEmissionData(true, DataPath[1], Helper, fleetMix, DataCor, out headerFCvalues, out matrixFCvalues, out idlingValuesFCvalues))
143 return false;
144 if (!ReadEmissionData(false, DataPath[2], Helper, fleetMix, DataCor, out headerPollutants, out matrixPollutants, out idlingValuesPollutants))
145 return false;
146
147 _ceps.Add(Helper.gClass, new CEP(Vehicle,
148 headerFCvalues,
149 matrixFCvalues,
150 headerPollutants,
151 matrixPollutants,
152 idlingValuesFCvalues,
153 idlingValuesPollutants));
154 return true;
155 }
156 #endregion
157
158 #region ReadVehicleFile
159 private bool ReadVehicleFile(string DataPath,
160 Helpers Helper,
161 bool fleetMix,
162 out VEHPHEMLightJSON.VEH Vehicle)
163 {
164 string path = "";
165 Vehicle = new VEHPHEMLightJSON.VEH();
166
167 //Open file
168 if (fleetMix)
169 path = DataPath + @"\" + Helper.gClass + ".PHEMLight.veh";
170 else
171 path = DataPath;
172
173 if (!File.Exists(@path))
174 {
175 Helper.ErrMsg = "File do not exist! (" + path + ")";
176 return false;
177 }
178
179 //**** VEH Datei einlesen ****
180 using (StreamReader r = new StreamReader(path))
181 {
182 try
183 {
184 string json = r.ReadToEnd();
185 Vehicle = JsonConvert.DeserializeObject<VEHPHEMLightJSON.VEH>(json);
186 }
187 catch
188 {
189 Helper.ErrMsg = "Error during file read! (" + path + ")";
190 return false;
191 }
192 }
193
194 //**** Vehicle Datei übertragen ****
195 //*** Get the vehicle data
196 if (Vehicle.VehicleData.MassType == null) Vehicle.VehicleData.MassType = "LV";
197 if (Vehicle.VehicleData.FuelType == null) Vehicle.VehicleData.FuelType = "D";
198 if (Vehicle.VehicleData.CalcType == null) Vehicle.VehicleData.CalcType = "Conv";
199 if (Vehicle.VehicleData.Mass == null) Vehicle.VehicleData.Mass = 0;
200 if (Vehicle.VehicleData.Loading == null) Vehicle.VehicleData.Loading = 0;
201 if (Vehicle.VehicleData.RedMassWheel == null) Vehicle.VehicleData.RedMassWheel = 0;
202 if (Vehicle.VehicleData.WheelDiameter == null) Vehicle.VehicleData.WheelDiameter = 0;
203 if (Vehicle.VehicleData.Cw == null) Vehicle.VehicleData.Cw = 0;
204 if (Vehicle.VehicleData.A == null) Vehicle.VehicleData.A = 0;
205
206 // Auxiliaries
207 if (Vehicle.AuxiliariesData.Pauxnorm == null) Vehicle.AuxiliariesData.Pauxnorm = 0;
208
209 // Engine Data
210 if (Vehicle.EngineData.ICEData.Prated == null) Vehicle.EngineData.ICEData.Prated = 0;
211 if (Vehicle.EngineData.ICEData.nrated == null) Vehicle.EngineData.ICEData.nrated = 0;
212 if (Vehicle.EngineData.ICEData.Idling == null) Vehicle.EngineData.ICEData.Idling = 0;
213 if (Vehicle.EngineData.EMData.Prated == null) Vehicle.EngineData.EMData.Prated = 0;
214 if (Vehicle.EngineData.EMData.nrated == null) Vehicle.EngineData.EMData.nrated = 0;
215
216 // Rolling resistance
217 if (Vehicle.RollingResData.Fr0 == null) Vehicle.RollingResData.Fr0 = 0;
218 if (Vehicle.RollingResData.Fr1 == null) Vehicle.RollingResData.Fr1 = 0;
219 if (Vehicle.RollingResData.Fr2 == null) Vehicle.RollingResData.Fr2 = 0;
220 if (Vehicle.RollingResData.Fr3 == null) Vehicle.RollingResData.Fr3 = 0;
221 if (Vehicle.RollingResData.Fr4 == null) Vehicle.RollingResData.Fr4 = 0;
222
223 // Transmission
224 if (Vehicle.TransmissionData.AxelRatio == null) Vehicle.TransmissionData.AxelRatio = 0;
225 if (Vehicle.TransmissionData.Transm == null)
226 {
227 Helper.ErrMsg = "Transmission ratios missing in vehicle file! Calculation stopped! (" + path + ")";
228 return false;
229 }
230 else
231 {
232 if (!Vehicle.TransmissionData.Transm.ContainsKey("Speed"))
233 {
234 Helper.ErrMsg = "No Speed signal in transmission data given! Calculation stopped! (" + path + ")";
235 return false;
236 }
237 if (!Vehicle.TransmissionData.Transm.ContainsKey("GearRatio"))
238 {
239 Helper.ErrMsg = "No GearRatio signal in transmission data given! Calculation stopped! (" + path + ")";
240 return false;
241 }
242 if (!Vehicle.TransmissionData.Transm.ContainsKey("RotMassF"))
243 {
244 Helper.ErrMsg = "No RotMassF signal in transmission data given! Calculation stopped! (" + path + ")";
245 return false;
246 }
247 }
248
249 // Full load and drag
250 if (Vehicle.FLDData.P_n_max_v0 == null) Vehicle.FLDData.P_n_max_v0 = 0;
251 if (Vehicle.FLDData.P_n_max_p0 == null) Vehicle.FLDData.P_n_max_p0 = 0;
252 if (Vehicle.FLDData.P_n_max_v1 == null) Vehicle.FLDData.P_n_max_v1 = 0;
253 if (Vehicle.FLDData.P_n_max_p1 == null) Vehicle.FLDData.P_n_max_p1 = 0;
254 if (Vehicle.FLDData.DragCurve == null)
255 {
256 Helper.ErrMsg = "Drag curve missing in vehicle file! Calculation stopped! (" + path + ")";
257 return false;
258 }
259 else
260 {
261 if (!Vehicle.FLDData.DragCurve.ContainsKey("n_norm"))
262 {
263 Helper.ErrMsg = "No n_norm signal in drag curve data given! Calculation stopped! (" + path + ")";
264 return false;
265 }
266 if (!Vehicle.FLDData.DragCurve.ContainsKey("pe_drag_norm"))
267 {
268 Helper.ErrMsg = "No pe_drag_norm signal in drag curve data given! Calculation stopped! (" + path + ")";
269 return false;
270 }
271 }
272
273 return true;
274 }
275 #endregion
276
277 #region ReadEmissionData
278 private bool ReadEmissionData(bool readFC,
279 string DataPath,
280 Helpers Helper,
281 bool fleetMix,
282 Correction DataCor,
283 out List<string> header,
284 out List<List<double>> matrix,
285 out List<double> idlingValues)
286 {
287 // declare file stream
288 string line;
289 string path = "";
290 header = new List<string>();
291 matrix = new List<List<double>>();
292 idlingValues = new List<double>();
293
294 if (fleetMix)
295 {
296 if (readFC)
297 path = DataPath + @"\" + Helper.gClass + "_FC.csv";
298 else
299 path = DataPath + @"\" + Helper.gClass + ".csv";
300 }
301 else
302 {
303 path = DataPath;
304 }
305
306 if (!File.Exists(path))
307 {
308 Helper.ErrMsg = "File do not exist! (" + path + ")";
309 return false;
310 }
311 StreamReader fileReader = File.OpenText(@path);
312
313 // read header line for pollutant identifiers
314 if ((line = ReadLine(fileReader)) != null)
315 {
316 List<string> entries = split(line, ',');
317 // skip first entry "Pe"
318 for (int i = 1; i < entries.Count; i++)
319 {
320 header.Add(entries[i]);
321 }
322 }
323
324 // skip units
325 ReadLine(fileReader);
326
327 // skip comment
328 ReadLine(fileReader);
329
330 //readIdlingValues
331 line = ReadLine(fileReader);
332
333 List<string> stringIdlings = split(line, ',').ToList();
334 stringIdlings.RemoveAt(0);
335
336 idlingValues = todoubleList(stringIdlings);
337
338 while ((line = ReadLine(fileReader)) != null)
339 {
340 matrix.Add(todoubleList(split(line, ',')));
341 }
342 fileReader.Close();
343
344 //Data correction (Det & TNOx)
345 if (!CorrectEmissionData(DataCor, ref header, ref matrix, ref idlingValues))
346 {
347 Helper.ErrMsg = "Error in correction calculation";
348 return false;
349 }
350
351 //Return value
352 return true;
353 }
354
355 private bool CorrectEmissionData(Correction DataCor,
356 ref List<string> header,
357 ref List<List<double>> matrix,
358 ref List<double> idlingValues)
359 {
360 for (int i = 0; i < header.Count; i++)
361 {
362 double CorF = GetDetTempCor(DataCor, header[i]);
363 if (CorF != 1)
364 {
365 for (int j = 0; j < matrix.Count; j++)
366 {
367 matrix[j][i + 1] *= CorF;
368 }
369 idlingValues[i] *= CorF;
370 }
371 }
372
373 //Return value
374 return true;
375 }
376
377 //Calculate correction factor for detoriation and temperature correction
378 private double GetDetTempCor(Correction DataCor, string Emi)
379 {
380 //Initialisation
381 double CorF = 1;
382
383 if (DataCor != null)
384 {
385 if (DataCor.UseDet)
386 {
387 foreach (string Key in DataCor.DETFactors.Keys)
388 {
389 if (Emi.ToUpper() == Key.ToUpper())
390 {
391 CorF += (DataCor.DETFactors[Key] - 1);
392 break;
393 }
394 }
395 }
396 if (DataCor.UseTNOx)
397 {
398 if (Emi.ToUpper().Contains("NOX")) CorF += (DataCor.TNOxFactor - 1);
399 }
400 }
401
402 //Return value
403 return CorF;
404 }
405 #endregion
406
407#if FLEET
408 #region ReadFleetShares
409 public bool ReadFleetShares(string DataPath, Helpers Helper)
410 {
411 //Declaration
412 string line;
413 string path = DataPath;
414 if (!File.Exists(@path))
415 {
416 Helper.ErrMsg = "FleetShares file does not exist! (" + path + ")";
417 return false;
418 }
419 StreamReader shareReader = File.OpenText(@path);
420
421 _fleetShares = new Dictionary<string, Dictionary<string, double>>();
422
423 while ((line = ReadLine(shareReader)) != null)
424 {
425 if (line.Substring(0, 1) == Helper.CommentPrefix)
426 continue;
427
428 List<string> splitLine = split(line, ',');
429 string aggregateClass = splitLine[0];
430
431 if (!FleetShares.ContainsKey(aggregateClass))
432 FleetShares.Add(aggregateClass, new Dictionary<string, double>());
433
434 string subClass = splitLine[1];
435
436 if (!FleetShares[aggregateClass].ContainsKey(subClass))
437 FleetShares[aggregateClass].Add(subClass, todouble(splitLine[2]));
438 }
439 return true;
440 }
441 #endregion
442 #endif
443
444 #region Functions
445 //Split the string
446 private List<string> split(string s, char delim)
447 {
448 return s.Split(delim).ToList();
449 }
450
451 //Convert string to double
452 private double todouble(string s)
453 {
454 return double.Parse(s, CultureInfo.InvariantCulture);
455 }
456
457 //Convert string to double list
458 private List<double> todoubleList(List<string> s)
459 {
460 return s.Select(p => todouble(p)).Cast<double>().ToList();
461 }
462
463 //Read a line from file
464 private string ReadLine(StreamReader s)
465 {
466 return s.ReadLine();
467 }
468 #endregion
469 }
470
471 //PHEMLight vehicle
472 public class VEHPHEMLightJSON
473 {
474 //Root object
475 public class VEH
476 {
477 public string Type { get; set; }
478 public string Version { get; set; }
479 public Vehicle_Data VehicleData { get; set; }
480 public Aux_Data AuxiliariesData { get; set; }
481 public Engine_Data EngineData { get; set; }
482 public Rollres_Data RollingResData { get; set; }
483 public FullLoadDrag_Data FLDData { get; set; }
484 public Transmission_Data TransmissionData { get; set; }
485
486 public VEH()
487 {
488 VehicleData = new Vehicle_Data();
489 RollingResData = new Rollres_Data();
490 EngineData = new Engine_Data();
491 AuxiliariesData = new Aux_Data();
492 FLDData = new FullLoadDrag_Data();
493 TransmissionData = new Transmission_Data();
494 }
495 }
496
497 #region Vehicle Data
498 // Vehicle data
499 public class Vehicle_Data
500 {
501 public string MassType { get; set; }
502 public string FuelType { get; set; }
503 public string CalcType { get; set; }
504 public double? Mass { get; set; }
505 public double? Loading { get; set; }
506 public double? RedMassWheel { get; set; }
507 public double? WheelDiameter { get; set; }
508 public double? Cw { get; set; }
509 public double? A { get; set; }
510 public double? Mileage { get; set; }
511 }
512 #endregion
513
514 #region Rolling Resistance
515 // Rolling resistance data
516 public class Rollres_Data
517 {
518 public double? Fr0 { get; set; }
519 public double? Fr1 { get; set; }
520 public double? Fr2 { get; set; }
521 public double? Fr3 { get; set; }
522 public double? Fr4 { get; set; }
523 }
524 #endregion
525
526 #region Engine
527 // Engine data
528 public class Engine_Data
529 {
530 public ICE_Data ICEData { get; set; }
531 public EM_Data EMData { get; set; }
532
533 public Engine_Data()
534 {
535 ICEData = new ICE_Data();
536 EMData = new EM_Data();
537 }
538 }
539
540 // ICE engine
541 public class ICE_Data
542 {
543 public double? Prated { get; set; }
544 public double? nrated { get; set; }
545 public double? Idling { get; set; }
546 }
547
548 // EM engine
549 public class EM_Data
550 {
551 public double? Prated { get; set; }
552 public double? nrated { get; set; }
553 }
554 #endregion
555
556 #region Auxiliaries
557 // Auxiliaries data
558 public class Aux_Data
559 {
560 public double? Pauxnorm { get; set; }
561 }
562 #endregion
563
564 #region Full load and Drag data
565 // Full load and Drag data
566 public class FullLoadDrag_Data
567 {
568 public double? P_n_max_v0 { get; set; }
569 public double? P_n_max_p0 { get; set; }
570 public double? P_n_max_v1 { get; set; }
571 public double? P_n_max_p1 { get; set; }
572 public Dictionary<string, List<double>> DragCurve { get; set; }
573
574 public FullLoadDrag_Data()
575 {
576 DragCurve = new Dictionary<string, List<double>>();
577 }
578 }
579 #endregion
580
581 #region Transmission
582 // Transmission data
583 public class Transmission_Data
584 {
585 public double? AxelRatio { get; set; }
586 public Dictionary<string, List<double>> Transm { get; set; }
587
588 public Transmission_Data()
589 {
590 Transm = new Dictionary<string, List<double>>();
591 }
592 }
593 #endregion
594 }
595}
std::map< std::string, CEP * > _ceps
std::vector< std::string > split(const std::string &s, char delim)
bool Load(const std::vector< std::string > &DataPath, Helpers *Helper)
Dictionary< string, CEP > CEPS
Dictionary< string, Dictionary< string, double > > _fleetShares
bool GetFleetCEP(string DataPath, string AggClass, Helpers Helper)
bool 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)
double todouble(const std::string &s)
std::string ReadLine(std::ifstream &s)
bool GetCEP(const std::vector< std::string > &DataPath, Helpers *Helper)
std::vector< double > todoubleList(const std::vector< std::string > &s)
Dictionary< string, Dictionary< string, double > > FleetShares
bool 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)
C++ TraCI client API implementation.