Eclipse SUMO - Simulation of Urban MObility
Correction.cs
Go to the documentation of this file.
1 using System;
2 using System.IO;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7 using Newtonsoft.Json;
8 
9 namespace PHEMlightdll
10 {
11  public class Correction
12  {
13  public Correction(string PathCor)
14  {
15  UseDet = false;
16  UseTNOx = false;
17  AmbTemp = 20;
18  Year = DateTime.Now.Year;
19  VehMileage = -1;
20  DETFilePath = Path.Combine(PathCor, "Deterioration.det");
21  VMAFilePath = Path.Combine(PathCor, "Mileage.vma");
22  TNOxFilePath = Path.Combine(PathCor, "NOxCor.tno");
23  }
24 
25  #region ReadDetoriationFiles
26  private DET DETdata;
27  private VMA VMAdata;
28  public Dictionary<string, double> DETFactors;
29 
30  #region Properties
31  public bool UseDet { get; set; }
32 
33  public string DETFilePath { get; set; }
34 
35  public string VMAFilePath { get; set; }
36 
37  public int Year { get; set; }
38 
39  public double VehMileage { get; set; }
40  #endregion
41 
42  //Read the file
43  public bool ReadDet(ref string ErrMSG)
44  {
45  //Read Detoriation file
46  if (!ReadDETFile(ref ErrMSG))
47  return false;
48 
49  if (!ReadVMAFile(ref ErrMSG))
50  return false;
51 
52  // Return value
53  return true;
54  }
55  private bool ReadDETFile(ref string ErrMSG)
56  {
57  //Check the file if exist
58  if ((string.IsNullOrEmpty(DETFilePath)) || (!File.Exists(DETFilePath)))
59  {
60  ErrMSG = "File not found (" + DETFilePath + ") !";
61  return false;
62  }
63 
64  //**** Datei einlesen ****
65  DETdata = new DET();
66  using (StreamReader r = new StreamReader(DETFilePath))
67  {
68  try
69  {
70  string json = r.ReadToEnd();
71  DETdata = JsonConvert.DeserializeObject<DET>(json);
72  }
73  catch
74  {
75  ErrMSG = "Error during file read! " + "(" + DETFilePath + ")";
76  return false;
77  }
78  }
79 
80  // Return value
81  return true;
82  }
83  private bool ReadVMAFile(ref string ErrMSG)
84  {
85  //Check the file if exist
86  if ((string.IsNullOrEmpty(VMAFilePath)) || (!File.Exists(VMAFilePath)))
87  {
88  ErrMSG = "File not found (" + VMAFilePath + ") !";
89  return false;
90  }
91 
92  //**** Datei einlesen ****
93  VMAdata = new VMA();
94  using (StreamReader r = new StreamReader(VMAFilePath))
95  {
96  try
97  {
98  string json = r.ReadToEnd();
99  VMAdata = JsonConvert.DeserializeObject<VMA>(json);
100  }
101  catch
102  {
103  ErrMSG = "Error during file read! " + "(" + VMAFilePath + ")";
104  return false;
105  }
106  }
107 
108  // Return value
109  return true;
110  }
111  #endregion
112 
113  #region CalcDetoriation
114  //Initialise the Detoriation Factor for the vehicle
115  public bool IniDETfactor(Helpers Helper)
116  {
117  //Initialise
118  DETFactors = new Dictionary<string, double>();
119 
120  if (DETdata.Vehicle.ContainsKey(Helper.vClass))
121  {
122  if (DETdata.Vehicle[Helper.vClass].PropulsionClass.ContainsKey(Helper.pClass))
123  {
124  foreach (string Key in DETdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].Emission.Keys)
125  {
126  string EUclass = Helper.eClass.Replace("EU", "EURO ");
127 
128  //PC special classes check (ab, c, d, d-Temp). If available use otherwise use "EURO 6" if available
129  if ((Helper.vClass == Constants.strPKW | Helper.vClass == Constants.strLNF) & EUclass.Length > 6)
130  {
131  string EUclassShort = EUclass.Substring(0, 6);
132 
133  if (!DETdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].Emission[Key].EUClass.ContainsKey(EUclass) &
134  DETdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].Emission[Key].EUClass.ContainsKey(EUclassShort))
135  EUclass = EUclassShort;
136  }
137 
138  //Get the factor
139  if (DETdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].Emission[Key].EUClass.ContainsKey(EUclass))
140  {
141  List<double> Mileage = DETdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].Emission[Key].Mileage;
142  List<double> Factor = DETdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].Emission[Key].EUClass[EUclass];
143  if (VehMileage < 0) VehMileage = GetMileage(Helper);
144 
145  for (int i = 1; i < Mileage.Count; i++)
146  {
147  if (i == 1 & Mileage[i] > VehMileage)
148  {
149  DETFactors.Add(Key, Factor[0]);
150  break;
151  }
152  else if (i == Mileage.Count - 1 && VehMileage > Mileage[i])
153  {
154  DETFactors.Add(Key, Factor[i]);
155  break;
156  }
157  else if (VehMileage < Mileage[i])
158  {
159  DETFactors.Add(Key, Interpolate(VehMileage, Mileage[i - 1], Mileage[i], Factor[i - 1], Factor[i]));
160  break;
161  }
162  }
163  }
164  else
165  {
166  DETFactors.Add(Key, 1);
167  }
168  }
169  }
170  }
171 
172  //Return value
173  return true;
174  }
175 
176  //Get the milage of the vehicle
177  private double GetMileage(Helpers Helper)
178  {
179  // Initialise
180  double Mileage = 0;
181 
182  if (VMAdata.Vehicle.ContainsKey(Helper.vClass))
183  {
184  if (VMAdata.Vehicle[Helper.vClass].PropulsionClass.ContainsKey(Helper.pClass))
185  {
186  string Sclass = "0";
187  switch (Helper.sClass)
188  {
189  case "":
190  Sclass = "0";
191  break;
192  case "I":
193  Sclass = "1";
194  break;
195  case "II":
196  Sclass = "2";
197  break;
198  case "III":
199  Sclass = "3";
200  break;
201  }
202 
203  if (VMAdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].SizeClass.ContainsKey(Sclass))
204  {
205  string EUclass = Helper.eClass.Replace("EU", "EURO ");
206 
207  //PC special classes check (ab, c, d, d-Temp). If available use otherwise use "EURO 6" if available
208  if ((Helper.vClass == Constants.strPKW | Helper.vClass == Constants.strLNF) & EUclass.Length > 6)
209  {
210  string EUclassShort = EUclass.Substring(0, 6);
211 
212  if (!VMAdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].SizeClass[Sclass].EUClass.ContainsKey(EUclass) &
213  VMAdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].SizeClass[Sclass].EUClass.ContainsKey(EUclassShort))
214  EUclass = EUclassShort;
215  }
216 
217  if (VMAdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].SizeClass[Sclass].EUClass.ContainsKey(EUclass))
218  {
219  //Calculate Mileage
220  List<double> Factor = VMAdata.Vehicle[Helper.vClass].PropulsionClass[Helper.pClass].SizeClass[Sclass].EUClass[EUclass];
221  int AnzYear = Year - 2020 + 1;
222  Mileage = Factor[0] * Math.Pow(AnzYear, 3) + Factor[1] * Math.Pow(AnzYear, 2) + Factor[2] * AnzYear + Factor[3];
223 
224  //Check calculated mileage
225  if (Mileage < 0) Mileage = 0;
226  }
227  }
228  }
229  }
230 
231 
232  //Return value
233  return Mileage;
234  }
235  #endregion
236 
237  #region ReadTNOx
238  private TNOx TNOxdata;
239 
240  #region Properties
241  public bool UseTNOx { get; set; }
242 
243  public string TNOxFilePath { get; set; }
244 
245  public double AmbTemp { get; set; }
246 
247  public double TNOxFactor { get; set; }
248  #endregion
249 
250  //Read the file
251  public bool ReadTNOx(ref string ErrMSG)
252  {
253  //Check the file if exist
254  if ((string.IsNullOrEmpty(TNOxFilePath)) || (!File.Exists(TNOxFilePath)))
255  {
256  ErrMSG = "File not found (" + TNOxFilePath + ") !";
257  return false;
258  }
259 
260  //**** Datei einlesen ****
261  TNOxdata = new TNOx();
262  using (StreamReader r = new StreamReader(TNOxFilePath))
263  {
264  try
265  {
266  string json = r.ReadToEnd();
267  TNOxdata = JsonConvert.DeserializeObject<TNOx>(json);
268  }
269  catch
270  {
271  ErrMSG = "Error during file read! " + " (" + TNOxFilePath + ")";
272  return false;
273  }
274  }
275 
276  // Return value
277  return true;
278  }
279  #endregion
280 
281  #region Calculate TNOx
282  public bool IniTNOxfactor(Helpers Helper)
283  {
284  //Initialise
285  TNOxFactor = 1;
286 
287  //Calculation only for diesel vehicles
288  if (Helper.pClass != Constants.strDiesel) return true;
289 
290  if (TNOxdata.Vehicle.ContainsKey(Helper.vClass))
291  {
292  string EUclass = Helper.eClass.Replace("EU", "EURO ");
293 
294  //PC special classes check (ab, c, d, d-Temp). If available use otherwise use "EURO 6" if available
295  if ((Helper.vClass == Constants.strPKW | Helper.vClass == Constants.strLNF) & EUclass.Length > 6)
296  {
297  string EUclassShort = EUclass.Substring(0, 6);
298 
299  if (!TNOxdata.Vehicle[Helper.vClass].EUClass.ContainsKey(EUclass) &
300  TNOxdata.Vehicle[Helper.vClass].EUClass.ContainsKey(EUclassShort))
301  EUclass = EUclassShort;
302  }
303 
304 
305  if (TNOxdata.Vehicle[Helper.vClass].EUClass.ContainsKey(EUclass))
306  {
307  //Check/set temperature borders, because calculation is a straight function
308  if (AmbTemp < TNOxdata.Vehicle[Helper.vClass].EUClass[EUclass].TB[0])
309  TNOxFactor = TNOxdata.Vehicle[Helper.vClass].EUClass[EUclass].m + TNOxdata.Vehicle[Helper.vClass].EUClass[EUclass].c * TNOxdata.Vehicle[Helper.vClass].EUClass[EUclass].TB[0];
310  else if (AmbTemp > TNOxdata.Vehicle[Helper.vClass].EUClass[EUclass].TB[1])
311  TNOxFactor = 1;
312  else
313  TNOxFactor = TNOxdata.Vehicle[Helper.vClass].EUClass[EUclass].m + TNOxdata.Vehicle[Helper.vClass].EUClass[EUclass].c * AmbTemp;
314  }
315  }
316 
317  //Return value
318  return true;
319  }
320  #endregion
321 
322  #region Interpolate
323  private double Interpolate(double px, double p1, double p2, double e1, double e2)
324  {
325  if (p2 == p1)
326  return e1;
327 
328  return e1 + (px - p1) / (p2 - p1) * (e2 - e1);
329  }
330  #endregion
331 
332  #region Classes
333  #region Detoriation
334  //Detoriation correction
335  private class DET
336  {
337  public string Type { get; set; }
338  public string Model { get; set; }
339  public Dictionary<string, VehicledataDET> Vehicle { get; set; }
340 
341  public DET()
342  {
343  Vehicle = new Dictionary<string, VehicledataDET>();
344  }
345  }
346 
347  public class VehicledataDET
348  {
349  public Dictionary<string, PropClassDET> PropulsionClass { get; set; }
350 
351  public VehicledataDET()
352  {
353  PropulsionClass = new Dictionary<string, PropClassDET>();
354  }
355  }
356 
357  public class PropClassDET
358  {
359  public Dictionary<string, EmissionClassDET> Emission { get; set; }
360 
361  public PropClassDET()
362  {
363  Emission = new Dictionary<string, EmissionClassDET>();
364  }
365  }
366 
367  public class EmissionClassDET
368  {
369  public List<double> Mileage { get; set; }
370  public Dictionary<string, List<double>> EUClass { get; set; }
371 
373  {
374  Mileage = new List<double>();
375  EUClass = new Dictionary<string, List<double>>();
376  }
377  }
378  #endregion
379 
380  #region Vehicle Mileage
381  //Mileage correction for Detoriation
382  private class VMA
383  {
384  public string Type { get; set; }
385  public string Model { get; set; }
386  public Dictionary<string, VehicledataVMA> Vehicle { get; set; }
387 
388  public VMA()
389  {
390  Vehicle = new Dictionary<string, VehicledataVMA>();
391  }
392  }
393 
394  public class VehicledataVMA
395  {
396  public Dictionary<string, PropClassVMA> PropulsionClass { get; set; }
397 
398  public VehicledataVMA()
399  {
400  PropulsionClass = new Dictionary<string, PropClassVMA>();
401  }
402  }
403 
404  public class PropClassVMA
405  {
406  public Dictionary<string, EmissionClassVMA> SizeClass { get; set; }
407 
408  public PropClassVMA()
409  {
410  SizeClass = new Dictionary<string, EmissionClassVMA>();
411  }
412  }
413 
414  public class EmissionClassVMA
415  {
416  public Dictionary<string, List<double>> EUClass { get; set; }
417 
419  {
420  EUClass = new Dictionary<string, List<double>>();
421  }
422  }
423  #endregion
424 
425  #region TNOx
426  //TNOx correction
427  private class TNOx
428  {
429  public string Type { get; set; }
430  public string Model { get; set; }
431  public Dictionary<string, Vehicledata> Vehicle { get; set; }
432 
433  public TNOx()
434  {
435  Vehicle = new Dictionary<string, Vehicledata>();
436  }
437  }
438 
439  public class Vehicledata
440  {
441  public Dictionary<string, EmissionClass> EUClass { get; set; }
442 
443  public Vehicledata()
444  {
445  EUClass = new Dictionary<string, EmissionClass>();
446  }
447  }
448 
449  public class EmissionClass
450  {
451  public double m { get; set; }
452  public double c { get; set; }
453  public List<double> TB { get; set; }
454 
455  public EmissionClass()
456  {
457  TB = new List<double>();
458  }
459  }
460  #endregion
461  #endregion
462  }
463 }
static const std::string strPKW
Definition: cpp/Constants.h:47
static const std::string strDiesel
Definition: cpp/Constants.h:59
static const std::string strLNF
Definition: cpp/Constants.h:48
Dictionary< string, VehicledataDET > Vehicle
Definition: Correction.cs:339
Dictionary< string, List< double > > EUClass
Definition: Correction.cs:370
Dictionary< string, List< double > > EUClass
Definition: Correction.cs:416
Dictionary< string, EmissionClassDET > Emission
Definition: Correction.cs:359
Dictionary< string, EmissionClassVMA > SizeClass
Definition: Correction.cs:406
Dictionary< string, Vehicledata > Vehicle
Definition: Correction.cs:431
Dictionary< string, VehicledataVMA > Vehicle
Definition: Correction.cs:386
Dictionary< string, PropClassDET > PropulsionClass
Definition: Correction.cs:349
Dictionary< string, EmissionClass > EUClass
Definition: Correction.cs:441
Dictionary< string, PropClassVMA > PropulsionClass
Definition: Correction.cs:396
bool ReadVMAFile(ref string ErrMSG)
Definition: Correction.cs:83
bool IniDETfactor(Helpers Helper)
Definition: Correction.cs:115
double GetMileage(Helpers Helper)
Definition: Correction.cs:177
double Interpolate(double px, double p1, double p2, double e1, double e2)
Definition: Correction.cs:323
bool ReadDet(ref string ErrMSG)
Definition: Correction.cs:43
Dictionary< string, double > DETFactors
Definition: Correction.cs:28
Correction(string PathCor)
Definition: Correction.cs:13
bool ReadTNOx(ref string ErrMSG)
Definition: Correction.cs:251
bool ReadDETFile(ref string ErrMSG)
Definition: Correction.cs:55
bool IniTNOxfactor(Helpers Helper)
Definition: Correction.cs:282
C++ TraCI client API implementation.
Definition: Vehicle.h:34