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