Eclipse SUMO - Simulation of Urban MObility
dll_code/Start.cs
Go to the documentation of this file.
1 #define FLEET
2 using System;
3 using System.IO;
4 using System.Collections.Generic;
5 using System.Globalization;
6 using System.Linq;
7 using System.Text;
8 using System.Threading.Tasks;
9 using System.Reflection;
10 
11 namespace PHEMlightdll
12 {
13  public class Start
14  {
15  private List<string> _DataPath;
17  public Helpers Helper = new Helpers();
18 
19  //******************* Parameters of Array or Single calculation *******************
20  //********************************* INPUT ******************************************
21  //*** DATATYP | UNIT | VARIBLE | Description ***
22  //List<string> | [-] | DataFiles (VEH, FC, EMI)| Name of file (e.g. "PC_D_EU4" path neede if not in "Default Vehicles") or aggregated name (PC, HDV, BUS, TW) by FleetMix calculation
23  //List<double> / double | [s] | Time | Time signal
24  //List<double> / double | [m/s] | Velocity | Velocity signal
25  //double | [m/s^2]| acc | Acceleration (ONLY NEDDED BY SINGLE CALCULATION)
26  //List<double> / double | [%] | Gradient | Gradient of the route
27  //out List<VehicleResult> | [-] | VehicleResultsOrg | Returned result list
28  //bool | [-] | fleetMix = false | Optional parameter if fleetMix should be calculate
29  //string | [-] | CommentPref = "c" | Optional parameter for comment prefix
30 
31  //********************************* OUPUT: VehicleResultsOrg **********************
32  //*** DATATYP | UNIT | VARIBLE | Description ***
33  //double | [s] | time | Time
34  //double | [m/s] | speed | Velocity
35  //double | [kW] | power | Calculated power at the engine (ICE for conventional and HEV vehicles, electric engine for BEVs) including engine inertia and auxiliaries; not limited for engine fullload and braking limitations
36  //double | [kW] | P_pos | Positive engine power limited with engine rated power
37  //double | [-] | pNormRated | Engine power normalised with rated engine power and limited with the power range (fullload and drag) as specified in the characteristic curve for fuel consumption
38  //double | [-] | pNormDrive | Engine power normalised with "P_drive" and limited with the power range (fullload and drag) as specified in the characteristic curve for emissions
39  //double | [m/s^2]| acc | Caclulated/given acceleration
40  //double | [g/h] | fc | Calculated fuel consumption (Different unit for BEV vehicles)
41  // | [kWh/h]| |
42  //double | [g/h] | cO2 | Calculated CO2 emissions
43  //double | [g/h] | NOx | Calculated NOx emissions
44  //double | [g/h] | HC | Calculated HC emissions
45  //double | [g/h] | PM | Calculated PM emissions
46  //double | [g/h] | CO | Calculated CO emissions
47 
48  #region calculate
49  //Calculate data from array
50  public bool CALC_Array(List<string> DataFiles,
51  List<double> Time,
52  List<double> Velocity,
53  List<double> Gradient,
54  out List<VehicleResult> VehicleResultsOrg,
55  bool fleetMix = false,
56  string CommentPref = "c")
57  {
58  //Declaration
59  int i;
60  double acc;
61  List<VehicleResult> _VehicleResult = new List<VehicleResult>();
62 
63  //Initialisation
64  Helper.ErrMsg = null;
65 
66  //Borrow
67  Helper.CommentPrefix = CommentPref;
68  _DataPath = new List<string>();
69  //Set path by normal calculation (on given) and set path by fleetmix (on Default Vehicles) calculation
70  for (i = 0; i < DataFiles.Count; i++)
71  {
72  if ((DataFiles[i].LastIndexOf(@"\")) >= 0)
73  {
74  _DataPath.Add(DataFiles[i]);
75  }
76  else
77  {
78  //_DataPath.Add(Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf(@"\")) + @"\Default Vehicles\" + Helper.PHEMDataV);
79  _DataPath.Add(DataFiles[i + 1].Substring(0, DataFiles[i + 1].LastIndexOf(@"\")));
80  _DataPath.Add(DataFiles[i + 1].Substring(0, DataFiles[i + 1].LastIndexOf(@"\")));
81  _DataPath.Add(DataFiles[i + 1].Substring(0, DataFiles[i + 1].LastIndexOf(@"\")));
82  i += 1;
83  }
84  }
85 
86  //Read the vehicle and emission data
87  #if FLEET
88  if (fleetMix)
89  {
90  //Set the vehicle class
91  Helper.gClass = _DataPath[0];
92 
93  //Generate the class
94  DataInput = new CEPHandler();
95 
96  //Read the FleetShares
97  if (!DataInput.ReadFleetShares(DataFiles[1], Helper))
98  {
99  VehicleResultsOrg = null;
100  return false;
101  }
102  //Read the vehicle and emission data
103  if (!DataInput.GetFleetCEP(_DataPath, DataFiles[0], Helper))
104  {
105  VehicleResultsOrg = null;
106  return false;
107  }
108  }
109  else
110  #endif
111  {
112  //Get vehicle string
113  if (!Helper.setclass(DataFiles[0]))
114  {
115  VehicleResultsOrg = null;
116  return false;
117  }
118 
119  //Generate the class
120  DataInput = new CEPHandler();
121 
122  //Read the vehicle and emission data
124  {
125  VehicleResultsOrg = null;
126  return false;
127  }
128  }
129 
130  //Calculate emissions per second
131  for (i = 1; i <= Time.Count - 1; i++)
132  {
133  //Calculate the acceleration
134  acc = (Velocity[i] - Velocity[i - 1]) / (Time[i] - Time[i - 1]);
135 
136  //Calculate and save the data in the List
137  _VehicleResult.Add(PHEMLight.CreateVehicleStateData(Helper,
139  Time[i - 1],
140  Velocity[i - 1],
141  acc,
142  Gradient[i - 1]));
143  if (Helper.ErrMsg != null)
144  {
145  VehicleResultsOrg = null;
146  return false;
147  }
148  }
149  VehicleResultsOrg = _VehicleResult;
150  return true;
151  }
152 
153  //Calculate single data
154  public bool CALC_Single(List<string> DataFiles,
155  double Time,
156  double Velocity,
157  double acc,
158  double Gradient,
159  out List<VehicleResult> VehicleResultsOrg,
160  bool fleetMix = false,
161  string CommentPref = "c")
162  {
163  //Declaration
164  List<VehicleResult> _VehicleResult = new List<VehicleResult>();
165  VehicleResultsOrg = _VehicleResult;
166 
167  //Borrow
168  Helper.CommentPrefix = CommentPref;
169  _DataPath = new List<string>();
170  //Set path by normal calculation (on given) and set path by fleetmix (on Fleetshare file) calculation
171  for (int i = 0; i < DataFiles.Count; i++)
172  {
173  if ((DataFiles[i].LastIndexOf(@"\")) >= 0)
174  {
175  _DataPath.Add(DataFiles[i]);
176  }
177  else
178  {
179  //_DataPath.Add(Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf(@"\")) + @"\Default Vehicles\" + Helper.PHEMDataV);
180  _DataPath.Add(DataFiles[i + 1].Substring(0, DataFiles[i + 1].LastIndexOf(@"\")));
181  _DataPath.Add(DataFiles[i + 1].Substring(0, DataFiles[i + 1].LastIndexOf(@"\")));
182  _DataPath.Add(DataFiles[i + 1].Substring(0, DataFiles[i + 1].LastIndexOf(@"\")));
183  i += 1;
184  }
185  }
186 
187  //Read the vehicle and emission data
188  #if FLEET
189  if (fleetMix)
190  {
191  //Set the vehicle class
192  Helper.gClass = "AggClass_" + DataFiles[0];
193 
194  //Generate the class
195  DataInput = new CEPHandler();
196 
197  //Read the FleetShares
198  if (!DataInput.ReadFleetShares(DataFiles[1], Helper))
199  {
200  VehicleResultsOrg = null;
201  return false;
202  }
203  //Read the vehicle and emission data
204  if (!DataInput.GetFleetCEP(_DataPath, DataFiles[0], Helper))
205  {
206  VehicleResultsOrg = null;
207  return false;
208  }
209  }
210  else
211  #endif
212  {
213  //Get vehicle string
214  if (!Helper.setclass(DataFiles[0]))
215  {
216  VehicleResultsOrg = null;
217  return false;
218  }
219 
220  //Generate the class
221  DataInput = new CEPHandler();
222 
223  //Read the vehicle and emission data
225  {
226  VehicleResultsOrg = null;
227  return false;
228  }
229  }
230 
231  //Calculate and save the data in the List
232  _VehicleResult.Add(PHEMLight.CreateVehicleStateData(Helper,
234  Time,
235  Velocity,
236  acc,
237  Gradient));
238  VehicleResultsOrg = _VehicleResult;
239  return true;
240  }
241  #endregion
242 
243  #region ExportData
244  public bool ExportData(string path, string vehicle, List<VehicleResult> _VehicleResult)
245  {
246  if (path == null || vehicle == null || _VehicleResult == null || _VehicleResult.Count == 0) return false;
247 
248  //Write head
249  StringBuilder allLines = new StringBuilder();
250  string lineEnding = "\r\n";
251 
252  allLines.AppendLine("Vehicletype: ," + vehicle);
253  allLines.AppendLine("Time, Speed, Gradient, Accelaration, Engine power raw, P_pos, P_norm_rated, P_norm_drive, FC, Electric Power, CO2, NOx, CO, HC, PM");
254  allLines.AppendLine("[s], [m/s], [%], [m/s^2], [kW], [kW], [-], [-], [g/h], [kWh/h], [g/h], [g/h], [g/h], [g/h], [g/h]");
255 
256  //Write data
257  foreach (VehicleResult Result in _VehicleResult)
258  {
259  allLines.Append(Result.Time.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
260  allLines.Append(Result.Speed.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
261  allLines.Append(Result.Grad.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
262  allLines.Append(Result.Accelaration.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
263  allLines.Append(Result.Power.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
264  allLines.Append(Result.PPos.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
265  allLines.Append(Result.PNormRated.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
266  allLines.Append(Result.PNormDrive.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
267  allLines.Append(Result.EmissionData.FC.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
268  allLines.Append(Result.EmissionData.FCel.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
269  allLines.Append(Result.EmissionData.CO2.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
270  allLines.Append(Result.EmissionData.NOx.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
271  allLines.Append(Result.EmissionData.CO.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
272  allLines.Append(Result.EmissionData.HC.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
273  allLines.Append(Result.EmissionData.PM.ToString("0.0000", CultureInfo.InvariantCulture) + lineEnding);
274  }
275 
276  // Write the string to a file.
277  if (path.IndexOf(".", 0) < 0)
278  {
279  path = path + ".sta";
280  }
281  try
282  {
283  StreamWriter file = new StreamWriter(path);
284  file.WriteLine(allLines);
285  file.Close();
286  return true;
287  }
288  catch (Exception ex)
289  {
290  return false;
291  }
292  }
293 
294  public bool ExportSumData(string path, string vehicle, string cycle, VehicleResult _VehicleResult)
295  {
296  if (path == null || vehicle == null || cycle == null || _VehicleResult == null) return false;
297  StringBuilder allLines = new StringBuilder();
298 
299  if (path.IndexOf(".", 0) < 0)
300  {
301  path = path + ".erg";
302  }
303 
304  if (!File.Exists(path))
305  {
306  //Write head
307  allLines.AppendLine("PHEMLight Results");
308  allLines.AppendLine("");
309  allLines.AppendLine("Vehicle, Cycle, Time, Speed, Gradient, Accelaration, Engine power raw, P_pos, P_norm_rated, P_norm_drive, FC, Electric Power, CO2, NOx, CO, HC, PM");
310  allLines.AppendLine("[-], [-], [s], [km/h], [%], [m/s^2], [kW], [kW], [-], [-], [g/km], [kWh/km], [g/km], [g/km], [g/km], [g/km], [g/km]");
311  }
312 
313  //Write data
314  allLines.Append(vehicle + ",");
315  allLines.Append(cycle + ",");
316  allLines.Append(_VehicleResult.Time.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
317  allLines.Append(_VehicleResult.Speed.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
318  allLines.Append(_VehicleResult.Grad.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
319  allLines.Append(_VehicleResult.Accelaration.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
320  allLines.Append(_VehicleResult.Power.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
321  allLines.Append(_VehicleResult.PPos.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
322  allLines.Append(_VehicleResult.PNormRated.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
323  allLines.Append(_VehicleResult.PNormDrive.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
324  allLines.Append(_VehicleResult.EmissionData.FC.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
325  allLines.Append(_VehicleResult.EmissionData.FCel.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
326  allLines.Append(_VehicleResult.EmissionData.CO2.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
327  allLines.Append(_VehicleResult.EmissionData.NOx.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
328  allLines.Append(_VehicleResult.EmissionData.CO.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
329  allLines.Append(_VehicleResult.EmissionData.HC.ToString("0.0000", CultureInfo.InvariantCulture) + ",");
330  allLines.Append(_VehicleResult.EmissionData.PM.ToString("0.0000", CultureInfo.InvariantCulture));
331 
332  // Write the string to a file.
333  try
334  {
335  StreamWriter file = new StreamWriter(path, true);
336  file.WriteLine(allLines);
337  file.Close();
338  return true;
339  }
340  catch (Exception ex)
341  {
342  return false;
343  }
344  }
345 
346  public VehicleResult GenerateSumData(List<VehicleResult> _VehicleResult)
347  {
348  //Declaration
349  double sum_time = 0;
350  double sum_speed = 0;
351  double sum_grad = 0;
352  double sum_power = 0;
353  double sum_pPos = 0;
354  double sum_pNormRated = 0;
355  double sum_pNormDrive = 0;
356  double sum_acc = 0;
357  double sum_fc = 0;
358  double sum_fcel = 0;
359  double sum_cO2 = 0;
360  double sum_nOx = 0;
361  double sum_hC = 0;
362  double sum_pM = 0;
363  double sum_cO = 0;
364 
365  if (_VehicleResult == null || _VehicleResult.Count == 0) return new VehicleResult(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
366 
367  //Write data
368  foreach (VehicleResult Result in _VehicleResult)
369  {
370  sum_speed += Result.Speed * 3.6;
371  sum_power += Result.Power;
372  if (Result.PPos > 0) { sum_pPos += Result.PPos; }
373  sum_grad += Result.Grad;
374  sum_pNormRated += Result.PNormRated;
375  sum_pNormDrive += Result.PNormDrive;
376  sum_acc += Result.Accelaration;
377  sum_fcel += Result.EmissionData.FCel;
378  sum_fc += Result.EmissionData.FC;
379  sum_cO2 += Result.EmissionData.CO2;
380  sum_nOx += Result.EmissionData.NOx;
381  sum_hC += Result.EmissionData.HC;
382  sum_pM += Result.EmissionData.PM;
383  sum_cO += Result.EmissionData.CO;
384  }
385 
386  //Build average
387  sum_time = _VehicleResult[_VehicleResult.Count - 1].Time - _VehicleResult[0].Time;
388  sum_power /= _VehicleResult.Count;
389  sum_pPos /= _VehicleResult.Count;
390  sum_grad /= _VehicleResult.Count;
391  sum_pNormRated /= _VehicleResult.Count;
392  sum_pNormDrive /= _VehicleResult.Count;
393  sum_acc /= _VehicleResult.Count;
394  if (sum_speed > 0)
395  {
396  sum_fc /= sum_speed;
397  sum_fcel /= sum_speed;
398  sum_cO2 /= sum_speed;
399  sum_nOx /= sum_speed;
400  sum_hC /= sum_speed;
401  sum_pM /= sum_speed;
402  sum_cO /= sum_speed;
403  }
404  else
405  {
406  sum_fc = 0;
407  sum_fcel = 0;
408  sum_cO2 = 0;
409  sum_nOx = 0;
410  sum_hC = 0;
411  sum_pM = 0;
412  sum_cO = 0;
413  }
414  sum_speed /= _VehicleResult.Count;
415 
416  return new VehicleResult(sum_time,
417  sum_speed,
418  sum_grad,
419  sum_power,
420  sum_pPos,
421  sum_pNormRated,
422  sum_pNormDrive,
423  sum_acc,
424  sum_fc,
425  sum_fcel,
426  sum_cO2,
427  sum_nOx,
428  sum_hC,
429  sum_pM,
430  sum_cO);
431  }
432  #endregion
433  }
434 
435  //Calculation
436  class PHEMLight
437  {
438  #region CreateVehicleStateData
440  CEP currCep,
441  double time,
442  double inputSpeed,
443  double inputAcc,
444  double Gradient = 0)
445  {
446  //Declaration
447  double speed = Math.Max(inputSpeed, 0);
448  double acc;
449  double P_pos;
450 
451  //Speed/Acceleration limitation
452  if (speed == 0)
453  acc = 0;
454  else
455  acc = Math.Min(inputAcc, currCep.GetMaxAccel(speed, Gradient));
456 
457  //Calculate the power
458  double power = currCep.CalcPower(speed, acc, Gradient);
459  double P_eng = currCep.CalcEngPower(power);
460 
461  //Power limitation
462  if (P_eng >= 0)
463  P_pos = power;
464  else
465  P_pos = 0;
466 
467  //Calculate the result values (BEV)
468  if (Helper.tClass == Constants.strBEV)
469  {
470  return new VehicleResult(time,
471  speed,
472  Gradient,
473  power,
474  P_pos,
475  P_eng / currCep.RatedPower,
476  P_eng / currCep.DrivingPower,
477  acc,
478  0,
479  currCep.GetEmission("FC", power, speed, Helper),
480  0,
481  0,
482  0,
483  0,
484  0);
485  }
486 
487  //Calculate the decel costing
488  double decelCoast = currCep.GetDecelCoast(speed, acc, Gradient);
489 
490  //Calculate the result values (Zero emissions by costing, Idling emissions by v <= 0.5m/s²)
491  if (acc >= decelCoast || speed <= Constants.ZERO_SPEED_ACCURACY)
492  {
493  return new VehicleResult(time,
494  speed,
495  Gradient,
496  power,
497  P_pos,
498  P_eng / currCep.RatedPower,
499  P_eng / currCep.DrivingPower,
500  acc,
501  currCep.GetEmission("FC", power, speed, Helper),
502  0,
503  currCep.GetCO2Emission(currCep.GetEmission("FC", power, speed, Helper), currCep.GetEmission("CO", power, speed, Helper), currCep.GetEmission("HC", power, speed, Helper), Helper),
504  currCep.GetEmission("NOx", power, speed, Helper),
505  currCep.GetEmission("HC", power, speed, Helper),
506  currCep.GetEmission("PM", power, speed, Helper),
507  currCep.GetEmission("CO", power, speed, Helper));
508  }
509  else
510  {
511  return new VehicleResult(time,
512  speed,
513  Gradient,
514  power,
515  P_pos,
516  power / currCep.RatedPower,
517  power / currCep.DrivingPower,
518  acc,
519  0,
520  0,
521  0,
522  0,
523  0,
524  0,
525  0);
526  }
527  }
528  #endregion
529  }
530 }
bool ReadFleetShares(string DataPath, Helpers Helper)
Dictionary< string, CEP > CEPS
bool GetFleetCEP(string DataPath, string AggClass, Helpers Helper)
bool GetCEP(const std::vector< std::string > &DataPath, Helpers *Helper)
double GetMaxAccel(double speed, double gradient)
Definition: cpp/CEP.cpp:420
double CalcEngPower(double power)
Definition: cpp/CEP.cpp:219
double GetEmission(const std::string &pollutant, double power, double speed, Helpers *VehicleClass)
Definition: cpp/CEP.cpp:230
double CalcPower(double speed, double acc, double gradient)
Definition: cpp/CEP.cpp:200
double GetCO2Emission(double _FC, double _CO, double _HC, Helpers *VehicleClass)
Definition: cpp/CEP.cpp:291
double GetDecelCoast(double speed, double acc, double gradient)
Definition: cpp/CEP.cpp:326
static const std::string strBEV
Definition: cpp/Constants.h:63
static const double ZERO_SPEED_ACCURACY
Definition: cpp/Constants.h:39
bool setclass(const std::string &VEH)
static VehicleResult CreateVehicleStateData(Helpers Helper, CEP currCep, double time, double inputSpeed, double inputAcc, double Gradient=0)
bool ExportSumData(string path, string vehicle, string cycle, VehicleResult _VehicleResult)
bool CALC_Array(List< string > DataFiles, List< double > Time, List< double > Velocity, List< double > Gradient, out List< VehicleResult > VehicleResultsOrg, bool fleetMix=false, string CommentPref="c")
CEPHandler DataInput
List< string > _DataPath
bool CALC_Single(List< string > DataFiles, double Time, double Velocity, double acc, double Gradient, out List< VehicleResult > VehicleResultsOrg, bool fleetMix=false, string CommentPref="c")
VehicleResult GenerateSumData(List< VehicleResult > _VehicleResult)
bool ExportData(string path, string vehicle, List< VehicleResult > _VehicleResult)