SUMO - Simulation of Urban MObility
CEP.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2016-2017 German Aerospace Center (DLR) and others.
4 // PHEMlight module
5 // Copyright (C) 2016-2017 Technische Universitaet Graz, https://www.tugraz.at/
6 /****************************************************************************/
7 //
8 // This program and the accompanying materials
9 // are made available under the terms of the Eclipse Public License v2.0
10 // which accompanies this distribution, and is available at
11 // http://www.eclipse.org/legal/epl-v20.html
12 //
13 /****************************************************************************/
20 //
21 /****************************************************************************/
22 
23 
24 #include "CEP.h"
25 #include "Constants.h"
26 #include "Helpers.h"
27 
28 
29 namespace PHEMlightdll {
30 
31  CEP::CEP(bool heavyVehicle, double vehicleMass, double vehicleLoading, double vehicleMassRot, double crossArea, double cWValue, double f0, double f1, double f2, double f3, double f4, double axleRatio, std::vector<double>& transmissionGearRatios, double auxPower, double ratedPower, double engineIdlingSpeed, double engineRatedSpeed, double effictiveWheelDiameter, double pNormV0, double pNormP0, double pNormV1, double pNormP1, const std::string& vehicelFuelType, std::vector<std::vector<double> >& matrixFC, std::vector<std::string>& headerLinePollutants, std::vector<std::vector<double> >& matrixPollutants, std::vector<std::vector<double> >& matrixSpeedRotational, std::vector<std::vector<double> >& normedDragTable, double idlingFC, std::vector<double>& idlingPollutants) {
32  transmissionGearRatios.size(); // just to make the compiler happy about the unused parameter
34  _resistanceF0 = f0;
35  _resistanceF1 = f1;
36  _resistanceF2 = f2;
37  _resistanceF3 = f3;
38  _resistanceF4 = f4;
39  _cWValue = cWValue;
40  _crossSectionalArea = crossArea;
41  _massVehicle = vehicleMass;
42  _vehicleLoading = vehicleLoading;
43  _vehicleMassRot = vehicleMassRot;
44  _ratedPower = ratedPower;
45  _engineIdlingSpeed = engineIdlingSpeed;
46  _engineRatedSpeed = engineRatedSpeed;
47  _effectiveWheelDiameter = effictiveWheelDiameter;
48  _heavyVehicle = heavyVehicle;
49  _fuelType = vehicelFuelType;
50  _axleRatio = axleRatio;
51  _auxPower = auxPower;
52 
53  _pNormV0 = pNormV0 / 3.6;
54  _pNormP0 = pNormP0;
55  _pNormV1 = pNormV1 / 3.6;
56  _pNormP1 = pNormP1;
57 
58  std::vector<std::string> pollutantIdentifier;
59  std::vector<std::vector<double> > pollutantMeasures;
60  std::vector<std::vector<double> > normalizedPollutantMeasures;
61 
62  // init pollutant identifiers
63  for (int i = 0; i < (int)headerLinePollutants.size(); i++) {
64  pollutantIdentifier.push_back(headerLinePollutants[i]);
65  }
66 
67  // initialize measures
68  for (int i = 0; i < (int)headerLinePollutants.size(); i++) {
69  pollutantMeasures.push_back(std::vector<double>());
70  normalizedPollutantMeasures.push_back(std::vector<double>());
71  }
72 
73  // looping through matrix and assigning values for speed rotational table
74  _speedCurveRotational = std::vector<double>();
75  _speedPatternRotational = std::vector<double>();
76  _gearTransmissionCurve = std::vector<double>();
77  for (int i = 0; i < (int)matrixSpeedRotational.size(); i++) {
78  if (matrixSpeedRotational[i].size() != 3) {
79  return;
80  }
81 
82  _speedPatternRotational.push_back(matrixSpeedRotational[i][0] / 3.6);
83  _gearTransmissionCurve.push_back(matrixSpeedRotational[i][1]);
84  _speedCurveRotational.push_back(matrixSpeedRotational[i][2]);
85  }
86 
87  // looping through matrix and assigning values for drag table
88  _nNormTable = std::vector<double>();
89  _dragNormTable = std::vector<double>();
90  for (int i = 0; i < (int)normedDragTable.size(); i++) {
91  if (normedDragTable[i].size() != 2) {
92  return;
93  }
94 
95  _nNormTable.push_back(normedDragTable[i][0]);
96  _dragNormTable.push_back(normedDragTable[i][1]);
97  }
98 
99  // looping through matrix and assigning values for Fuel consumption
100  _cepCurveFC = std::vector<double>();
101  _normedCepCurveFC = std::vector<double>();
102  _powerPatternFC = std::vector<double>();
103  _normalizedPowerPatternFC = std::vector<double>();
104  for (int i = 0; i < (int)matrixFC.size(); i++) {
105  if (matrixFC[i].size() != 2) {
106  return;
107  }
108 
109  _powerPatternFC.push_back(matrixFC[i][0] * _ratedPower);
110  _normalizedPowerPatternFC.push_back(matrixFC[i][0]);
111  _cepCurveFC.push_back(matrixFC[i][1] * _ratedPower);
112  _normedCepCurveFC.push_back(matrixFC[i][1]);
113 
114  }
115 
116  _powerPatternPollutants = std::vector<double>();
117 
118  double pollutantMultiplyer = 1;
119 
121 
122  // looping through matrix and assigning values for pollutants
123  if (heavyVehicle) {
126  pollutantMultiplyer = _ratedPower;
127  }
128  else {
131  }
132 
133  _normailzedPowerPatternPollutants = std::vector<double>();
134 
135  _cepNormalizedCurvePollutants = std::map<std::string, std::vector<double> >();
136 
137  int headerCount = (int)headerLinePollutants.size();
138  for (int i = 0; i < (int)matrixPollutants.size(); i++) {
139  for (int j = 0; j < (int)matrixPollutants[i].size(); j++) {
140  if ((int)matrixPollutants[i].size() != headerCount + 1) {
141  return;
142  }
143 
144  if (j == 0) {
145  _normailzedPowerPatternPollutants.push_back(matrixPollutants[i][j]);
146  _powerPatternPollutants.push_back(matrixPollutants[i][j] * getNormalizingPower());
147  }
148  else {
149  pollutantMeasures[j - 1].push_back(matrixPollutants[i][j] * pollutantMultiplyer);
150  normalizedPollutantMeasures[j - 1].push_back(matrixPollutants[i][j]);
151  }
152  }
153  }
154 
155  _cepCurvePollutants = std::map<std::string, std::vector<double> >();
156  _idlingValuesPollutants = std::map<std::string, double>();
157 
158  for (int i = 0; i < (int)headerLinePollutants.size(); i++) {
159  _cepCurvePollutants.insert(std::make_pair(pollutantIdentifier[i], pollutantMeasures[i]));
160  _cepNormalizedCurvePollutants.insert(std::make_pair(pollutantIdentifier[i], normalizedPollutantMeasures[i]));
161  _idlingValuesPollutants.insert(std::make_pair(pollutantIdentifier[i], idlingPollutants[i] * pollutantMultiplyer));
162  }
163 
164  _idlingValueFC = idlingFC * _ratedPower;
165  }
166 
167  const bool& CEP::getHeavyVehicle() const {
168  return _heavyVehicle;
169  }
170 
171  const std::string& CEP::getFuelType() const {
172  return _fuelType;
173  }
174 
176  return _normalizingType;
177  }
178 
179  const double& CEP::getRatedPower() const {
180  return _ratedPower;
181  }
182 
183  void CEP::setRatedPower(const double& value) {
184  _ratedPower = value;
185  }
186 
187  const double& CEP::getNormalizingPower() const {
188  return _normalizingPower;
189  }
190 
191  const double& CEP::getDrivingPower() const {
192  return _drivingPower;
193  }
194 
195  void CEP::setDrivingPower(const double& value) {
196  _drivingPower = value;
197  }
198 
199  double CEP::CalcPower(double speed, double acc, double gradient) {
200  //Declaration
201  double power = 0;
202  double rotFactor = GetRotationalCoeffecient(speed);
203  double powerAux = (_auxPower * _ratedPower);
204 
205  //Calculate the power
206  power += (_massVehicle + _vehicleLoading) * Constants::GRAVITY_CONST * (_resistanceF0 + _resistanceF1 * speed + _resistanceF4 * std::pow(speed, 4)) * speed;
207  power += (_crossSectionalArea * _cWValue * Constants::AIR_DENSITY_CONST / 2) * std::pow(speed, 3);
208  power += (_massVehicle * rotFactor + _vehicleMassRot + _vehicleLoading) * acc * speed;
209  power += (_massVehicle + _vehicleLoading) * Constants::GRAVITY_CONST * gradient * 0.01 * speed;
210  power /= 1000;
212  power += powerAux;
213 
214  //Return result
215  return power;
216  }
217 
218  double CEP::CalcEngPower(double power) {
219  if (power < _powerPatternFC.front()) {
220  return _powerPatternFC.front();
221  }
222  if (power > _powerPatternFC.back()) {
223  return _powerPatternFC.back();
224  }
225 
226  return power;
227  }
228 
229  double CEP::GetEmission(const std::string& pollutant, double power, double speed, Helpers* VehicleClass) {
230  //Declaration
231  std::vector<double> emissionCurve;
232  std::vector<double> powerPattern;
233 
234  // bisection search to find correct position in power pattern
235  int upperIndex;
236  int lowerIndex;
237 
238  if (_fuelType != Constants::strBEV) {
239  if (std::abs(speed) <= Constants::ZERO_SPEED_ACCURACY) {
240  if (pollutant == "FC") {
241  return _idlingValueFC;
242  }
243  else {
244  if (_cepCurvePollutants.find(pollutant) == _cepCurvePollutants.end()) {
245  VehicleClass->setErrMsg(std::string("Emission pollutant ") + pollutant + std::string(" not found!"));
246  return 0;
247  }
248 
249  return _idlingValuesPollutants[pollutant];
250  }
251  }
252  }
253 
254  if (pollutant == "FC") {
255  emissionCurve = _cepCurveFC;
256  powerPattern = _powerPatternFC;
257  }
258  else {
259  if (_cepCurvePollutants.find(pollutant) == _cepCurvePollutants.end()) {
260  VehicleClass->setErrMsg(std::string("Emission pollutant ") + pollutant + std::string(" not found!"));
261  return 0;
262  }
263 
264  emissionCurve = _cepCurvePollutants[pollutant];
265  powerPattern = _powerPatternPollutants;
266  }
267 
268  if (emissionCurve.empty()) {
269  VehicleClass->setErrMsg(std::string("Empty emission curve for ") + pollutant + std::string(" found!"));
270  return 0;
271  }
272  if (emissionCurve.size() == 1) {
273  return emissionCurve[0];
274  }
275 
276  // in case that the demanded power is smaller than the first entry (smallest) in the power pattern the first is returned (should never happen)
277  if (power <= powerPattern.front()) {
278  return emissionCurve[0];
279  }
280 
281  // if power bigger than all entries in power pattern return the last (should never happen)
282  if (power >= powerPattern.back()) {
283  return emissionCurve.back();
284  }
285 
286  FindLowerUpperInPattern(lowerIndex, upperIndex, powerPattern, power);
287  return Interpolate(power, powerPattern[lowerIndex], powerPattern[upperIndex], emissionCurve[lowerIndex], emissionCurve[upperIndex]);
288  }
289 
290  double CEP::GetCO2Emission(double _FC, double _CO, double _HC, Helpers* VehicleClass) {
291  //Declaration
292  double fCBr;
293  double fCHC = 0.866;
294  double fCCO = 0.429;
295  double fCCO2 = 0.273;
296 
297 //C# TO C++ CONVERTER NOTE: The following 'switch' operated on a string variable and was converted to C++ 'if-else' logic:
298 // switch (_fuelType)
299 //ORIGINAL LINE: case Constants.strGasoline:
301  fCBr = 0.865;
302  }
303 //ORIGINAL LINE: case Constants.strDiesel:
304  else if (_fuelType == Constants::strDiesel) {
305  fCBr = 0.863;
306  }
307 //ORIGINAL LINE: case Constants.strCNG:
308  else if (_fuelType == Constants::strCNG) {
309  fCBr = 0.693;
310  fCHC = 0.803;
311  }
312 //ORIGINAL LINE: case Constants.strLPG:
313  else if (_fuelType == Constants::strLPG) {
314  fCBr = 0.825;
315  fCHC = 0.825;
316  }
317  else {
318  VehicleClass->setErrMsg(std::string("The propolsion type is not known! (") + _fuelType + std::string(")"));
319  return 0;
320  }
321 
322  return (_FC * fCBr - _CO * fCCO - _HC * fCHC) / fCCO2;
323  }
324 
325  double CEP::GetDecelCoast(double speed, double acc, double gradient) {
326  //Declaration
327  int upperIndex;
328  int lowerIndex;
329 
330  if (speed < Constants::SPEED_DCEL_MIN) {
331  return speed / Constants::SPEED_DCEL_MIN * GetDecelCoast(Constants::SPEED_DCEL_MIN, acc, gradient);
332  }
333 
334  double rotCoeff = GetRotationalCoeffecient(speed);
335  FindLowerUpperInPattern(lowerIndex, upperIndex, _speedPatternRotational, speed);
336  double iGear = Interpolate(speed, _speedPatternRotational[lowerIndex], _speedPatternRotational[upperIndex], _gearTransmissionCurve[lowerIndex], _gearTransmissionCurve[upperIndex]);
337 
338  double iTot = iGear * _axleRatio;
339 
340  double n = (30 * speed * iTot) / ((_effectiveWheelDiameter / 2) * M_PI);
341  double nNorm = (n - _engineIdlingSpeed) / (_engineRatedSpeed - _engineIdlingSpeed);
342 
343  FindLowerUpperInPattern(lowerIndex, upperIndex, _nNormTable, nNorm);
344 
345  double fMot = 0;
346 
347  if (speed >= 10e-2) {
348  fMot = (-Interpolate(nNorm, _nNormTable[lowerIndex], _nNormTable[upperIndex], _dragNormTable[lowerIndex], _dragNormTable[upperIndex]) * _ratedPower * 1000 / speed) / 0.9;
349  }
350 
351  double fRoll = (_resistanceF0 + _resistanceF1 * speed + std::pow(_resistanceF2 * speed, 2) + std::pow(_resistanceF3 * speed, 3) + std::pow(_resistanceF4 * speed, 4)) * (_massVehicle + _vehicleLoading) * Constants::GRAVITY_CONST;
352 
353  double fAir = _cWValue * _crossSectionalArea * 1.2 * 0.5 * std::pow(speed, 2);
354 
355  double fGrad = (_massVehicle + _vehicleLoading) * Constants::GRAVITY_CONST * gradient / 100;
356 
357  return -(fMot + fRoll + fAir + fGrad) / ((_massVehicle + _vehicleLoading) * rotCoeff);
358  }
359 
360  double CEP::GetRotationalCoeffecient(double speed) {
361  //Declaration
362  int upperIndex;
363  int lowerIndex;
364 
365  FindLowerUpperInPattern(lowerIndex, upperIndex, _speedPatternRotational, speed);
366  return Interpolate(speed, _speedPatternRotational[lowerIndex], _speedPatternRotational[upperIndex], _speedCurveRotational[lowerIndex], _speedCurveRotational[upperIndex]);
367  }
368 
369  void CEP::FindLowerUpperInPattern(int& lowerIndex, int& upperIndex, std::vector<double>& pattern, double value) {
370  lowerIndex = 0;
371  upperIndex = 0;
372 
373  if (value <= pattern.front()) {
374  lowerIndex = 0;
375  upperIndex = 0;
376  return;
377  }
378 
379  if (value >= pattern.back()) {
380  lowerIndex = (int)pattern.size() - 1;
381  upperIndex = (int)pattern.size() - 1;
382  return;
383  }
384 
385  // bisection search to find correct position in power pattern
386  int middleIndex = ((int)pattern.size() - 1) / 2;
387  upperIndex = (int)pattern.size() - 1;
388  lowerIndex = 0;
389 
390  while (upperIndex - lowerIndex > 1) {
391  if (pattern[middleIndex] == value) {
392  lowerIndex = middleIndex;
393  upperIndex = middleIndex;
394  return;
395  }
396  else if (pattern[middleIndex] < value) {
397  lowerIndex = middleIndex;
398  middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
399  }
400  else {
401  upperIndex = middleIndex;
402  middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
403  }
404  }
405 
406  if (pattern[lowerIndex] <= value && value < pattern[upperIndex]) {
407  return;
408  }
409  }
410 
411  double CEP::Interpolate(double px, double p1, double p2, double e1, double e2) {
412  if (p2 == p1) {
413  return e1;
414  }
415 
416  return e1 + (px - p1) / (p2 - p1) * (e2 - e1);
417  }
418 
419  double CEP::GetMaxAccel(double speed, double gradient) {
420  double rotFactor = GetRotationalCoeffecient(speed);
421  double pMaxForAcc = GetPMaxNorm(speed) * _ratedPower - CalcPower(speed, 0, gradient);
422 
423  return (pMaxForAcc * 1000) / ((_massVehicle * rotFactor + _vehicleMassRot + _vehicleLoading) * speed);
424  }
425 
426  double CEP::GetPMaxNorm(double speed) {
427  // Linear function between v0 and v1, constant elsewhere
428  if (speed <= _pNormV0) {
429  return _pNormP0;
430  }
431  else if (speed >= _pNormV1) {
432  return _pNormP1;
433  }
434  else {
435  return Interpolate(speed, _pNormV0, _pNormV1, _pNormP0, _pNormP1);
436  }
437  }
438 
440  _heavyVehicle = false;
441  _normalizingType = static_cast<NormalizingType>(0);
442  _ratedPower = 0;
443  _normalizingPower = 0;
444  _drivingPower = 0;
445  _massVehicle = 0;
446  _vehicleLoading = 0;
447  _vehicleMassRot = 0;
449  _cWValue = 0;
450  _resistanceF0 = 0;
451  _resistanceF1 = 0;
452  _resistanceF2 = 0;
453  _resistanceF3 = 0;
454  _resistanceF4 = 0;
455  _axleRatio = 0;
456  _auxPower = 0;
457  _pNormV0 = 0;
458  _pNormP0 = 0;
459  _pNormV1 = 0;
460  _pNormP1 = 0;
461  _engineRatedSpeed = 0;
462  _engineIdlingSpeed = 0;
464  _idlingValueFC = 0;
465  }
466 }
std::vector< double > _speedPatternRotational
Definition: CEP.h:113
double _resistanceF0
Definition: CEP.h:97
static const double SPEED_DCEL_MIN
Definition: Constants.h:39
static const std::string strCNG
Definition: Constants.h:62
double GetEmission(const std::string &pollutant, double power, double speed, Helpers *VehicleClass)
Definition: CEP.cpp:229
std::vector< double > _normailzedPowerPatternPollutants
Definition: CEP.h:116
std::vector< double > _dragNormTable
Definition: CEP.h:129
double _massVehicle
Definition: CEP.h:92
std::map< std::string, std::vector< double > > _cepCurvePollutants
Definition: CEP.h:123
void setDrivingPower(const double &value)
Definition: CEP.cpp:195
double _effectiveWheelDiameter
Definition: CEP.h:111
std::vector< double > _nNormTable
Definition: CEP.h:128
const double & getNormalizingPower() const
Definition: CEP.cpp:187
static double _DRIVE_TRAIN_EFFICIENCY
Definition: Constants.h:77
void setErrMsg(const std::string &value)
Definition: Helpers.cpp:74
double _pNormP0
Definition: CEP.h:105
static const std::string strLPG
Definition: Constants.h:63
double _engineRatedSpeed
Definition: CEP.h:109
void setRatedPower(const double &value)
Definition: CEP.cpp:183
void InitializeInstanceFields()
Definition: CEP.cpp:439
double _pNormV1
Definition: CEP.h:106
double _drivingPower
Definition: CEP.h:84
double _resistanceF1
Definition: CEP.h:98
double GetRotationalCoeffecient(double speed)
Definition: CEP.cpp:360
const double & getDrivingPower() const
Definition: CEP.cpp:191
double _auxPower
Definition: CEP.h:103
double _engineIdlingSpeed
Definition: CEP.h:110
std::map< std::string, double > _idlingValuesPollutants
Definition: CEP.h:126
double _resistanceF2
Definition: CEP.h:99
std::vector< double > _normedCepCurveFC
Definition: CEP.h:120
static const double NORMALIZING_SPEED
Definition: Constants.h:37
NormalizingType _normalizingType
Definition: CEP.h:68
const double & getRatedPower() const
Definition: CEP.cpp:179
double _pNormP1
Definition: CEP.h:107
std::map< std::string, std::vector< double > > _cepNormalizedCurvePollutants
Definition: CEP.h:124
double _normalizingPower
Definition: CEP.h:79
std::vector< double > _normalizedPowerPatternFC
Definition: CEP.h:115
static const double NORMALIZING_ACCELARATION
Definition: Constants.h:38
double _cWValue
Definition: CEP.h:96
static const std::string strDiesel
Definition: Constants.h:61
double GetDecelCoast(double speed, double acc, double gradient)
Definition: CEP.cpp:325
double CalcEngPower(double power)
Definition: CEP.cpp:218
bool _heavyVehicle
Definition: CEP.h:53
double _resistanceF4
Definition: CEP.h:101
std::vector< double > _speedCurveRotational
Definition: CEP.h:122
std::vector< double > _gearTransmissionCurve
Definition: CEP.h:121
static const std::string strGasoline
Definition: Constants.h:60
double GetMaxAccel(double speed, double gradient)
Definition: CEP.cpp:419
double _pNormV0
Definition: CEP.h:104
double _resistanceF3
Definition: CEP.h:100
#define M_PI
Definition: odrSpiral.cpp:40
CEP(bool heavyVehicle, double vehicleMass, double vehicleLoading, double vehicleMassRot, double crossArea, double cWValue, double f0, double f1, double f2, double f3, double f4, double axleRatio, std::vector< double > &transmissionGearRatios, double auxPower, double ratedPower, double engineIdlingSpeed, double engineRatedSpeed, double effictiveWheelDiameter, double pNormV0, double pNormP0, double pNormV1, double pNormP1, const std::string &vehicelFuelType, std::vector< std::vector< double > > &matrixFC, std::vector< std::string > &headerLinePollutants, std::vector< std::vector< double > > &matrixPollutants, std::vector< std::vector< double > > &matrixSpeedRotational, std::vector< std::vector< double > > &normedDragTable, double idlingFC, std::vector< double > &idlingPollutants)
Definition: CEP.cpp:31
std::vector< double > _powerPatternFC
Definition: CEP.h:114
std::vector< double > _cepCurveFC
Definition: CEP.h:119
double GetPMaxNorm(double speed)
Definition: CEP.cpp:426
static const std::string strBEV
Definition: Constants.h:65
const NormalizingType & getNormalizingTypeX() const
Definition: CEP.cpp:175
double Interpolate(double px, double p1, double p2, double e1, double e2)
Definition: CEP.cpp:411
static const double GRAVITY_CONST
Definition: Constants.h:35
const bool & getHeavyVehicle() const
Definition: CEP.cpp:167
double _axleRatio
Definition: CEP.h:102
double _crossSectionalArea
Definition: CEP.h:95
std::vector< double > _powerPatternPollutants
Definition: CEP.h:117
double _idlingValueFC
Definition: CEP.h:125
static const double ZERO_SPEED_ACCURACY
Definition: Constants.h:40
double CalcPower(double speed, double acc, double gradient)
Definition: CEP.cpp:199
double _vehicleLoading
Definition: CEP.h:93
static const double AIR_DENSITY_CONST
Definition: Constants.h:36
double _ratedPower
Definition: CEP.h:73
const std::string & getFuelType() const
Definition: CEP.cpp:171
void FindLowerUpperInPattern(int &lowerIndex, int &upperIndex, std::vector< double > &pattern, double value)
Definition: CEP.cpp:369
double GetCO2Emission(double _FC, double _CO, double _HC, Helpers *VehicleClass)
Definition: CEP.cpp:290
std::string _fuelType
Definition: CEP.h:58
double _vehicleMassRot
Definition: CEP.h:94