37PHEMCEP::PHEMCEP(
bool heavyVehicle,
SUMOEmissionClass emissionClass,
const std::string& emissionClassIdentifier,
38 double vehicleMass,
double vehicleLoading,
double vehicleMassRot,
39 double crossArea,
double cdValue,
40 double f0,
double f1,
double f2,
double f3,
double f4,
41 double ratedPower,
double pNormV0,
double pNormP0,
double pNormV1,
double pNormP1,
42 double axleRatio,
double engineIdlingSpeed,
double engineRatedSpeed,
double effectiveWheelDiameter,
44 const std::string& vehicleFuelType,
45 const std::vector< std::vector<double> >& matrixFC,
46 const std::vector<std::string>& headerLinePollutants,
47 const std::vector< std::vector<double> >& matrixPollutants,
48 const std::vector< std::vector<double> >& matrixSpeedRotational,
49 const std::vector< std::vector<double> >& normedDragTable,
50 const std::vector<double>& idlingValuesPollutants) {
51 _emissionClass = emissionClass;
58 _crossSectionalArea = crossArea;
59 _massVehicle = vehicleMass;
60 _vehicleLoading = vehicleLoading;
61 _massRot = vehicleMassRot;
62 _ratedPower = ratedPower;
63 _vehicleFuelType = vehicleFuelType;
65 _pNormV0 = pNormV0 / 3.6;
67 _pNormV1 = pNormV1 / 3.6;
70 _axleRatio = axleRatio;
71 _engineIdlingSpeed = engineIdlingSpeed;
72 _engineRatedSpeed = engineRatedSpeed;
73 _effictiveWheelDiameter = effectiveWheelDiameter;
75 _heavyVehicle = heavyVehicle;
78 std::vector<std::string> pollutantIdentifier;
79 std::vector< std::vector<double> > pollutantMeasures;
80 std::vector<std::vector<double> > normalizedPollutantMeasures;
83 for (
int i = 0; i < (int)headerLinePollutants.size(); i++) {
84 pollutantIdentifier.push_back(headerLinePollutants[i]);
88 _sizeOfPatternFC = (int)matrixFC.size();
89 _sizeOfPatternPollutants = (int)matrixPollutants.size();
92 for (
int i = 0; i < (int)headerLinePollutants.size(); i++) {
93 pollutantMeasures.push_back(std::vector<double>());
94 normalizedPollutantMeasures.push_back(std::vector<double>());
98 _speedCurveRotational.clear();
99 _speedPatternRotational.clear();
100 _gearTransmissionCurve.clear();
101 for (
int i = 0; i < (int)matrixSpeedRotational.size(); i++) {
102 if (matrixSpeedRotational[i].size() != 3) {
103 throw InvalidArgument(
"Error loading vehicle file for: " + emissionClassIdentifier);
106 _speedPatternRotational.push_back(matrixSpeedRotational[i][0] / 3.6);
107 _speedCurveRotational.push_back(matrixSpeedRotational[i][1]);
108 _gearTransmissionCurve.push_back(matrixSpeedRotational[i][2]);
113 _dragNormTable.clear();
114 for (
int i = 0; i < (int) normedDragTable.size(); i++) {
115 if (normedDragTable[i].size() != 2) {
119 _nNormTable.push_back(normedDragTable[i][0]);
120 _dragNormTable.push_back(normedDragTable[i][1]);
126 _powerPatternFC.clear();
127 _normalizedPowerPatternFC.clear();
128 _normedCepCurveFC.clear();
129 for (
int i = 0; i < (int)matrixFC.size(); i++) {
130 if (matrixFC[i].size() != 2) {
131 throw InvalidArgument(
"Error loading vehicle file for: " + emissionClassIdentifier);
134 _powerPatternFC.push_back(matrixFC[i][0] * _ratedPower);
135 _normalizedPowerPatternFC.push_back(matrixFC[i][0]);
136 _cepCurveFC.push_back(matrixFC[i][1] * _ratedPower);
137 _normedCepCurveFC.push_back(matrixFC[i][1]);
141 _powerPatternPollutants.clear();
142 double pollutantMultiplyer = 1;
149 _normalizingPower = _ratedPower;
150 pollutantMultiplyer = _ratedPower;
153 _normalizingPower = _drivingPower;
157 const int headerCount = (int)headerLinePollutants.size();
158 for (
int i = 0; i < (int)matrixPollutants.size(); i++) {
159 for (
int j = 0; j < (int)matrixPollutants[i].size(); j++) {
160 if ((
int)matrixPollutants[i].size() != headerCount + 1) {
165 _normailzedPowerPatternPollutants.push_back(matrixPollutants[i][j]);
166 _powerPatternPollutants.push_back(matrixPollutants[i][j] * _normalizingPower);
168 pollutantMeasures[j - 1].push_back(matrixPollutants[i][j] * pollutantMultiplyer);
169 normalizedPollutantMeasures[j - 1].push_back(matrixPollutants[i][j]);
174 for (
int i = 0; i < (int) headerLinePollutants.size(); i++) {
175 _cepCurvePollutants.insert(pollutantIdentifier[i], pollutantMeasures[i]);
176 _normalizedCepCurvePollutants.insert(pollutantIdentifier[i], normalizedPollutantMeasures[i]);
177 _idlingValuesPollutants.insert(pollutantIdentifier[i], idlingValuesPollutants[i] * pollutantMultiplyer);
180 _idlingFC = idlingFC * _ratedPower;
187 _powerPatternFC.clear();
188 _powerPatternPollutants.clear();
190 _speedCurveRotational.clear();
191 _speedPatternRotational.clear();
196PHEMCEP::GetEmission(
const std::string& pollutant,
double power,
double speed,
bool normalized)
const {
197 std::vector<double> emissionCurve;
198 std::vector<double> powerPattern;
201 if (pollutant ==
"FC") {
204 return _idlingValuesPollutants.get(pollutant);
208 if (pollutant ==
"FC") {
210 emissionCurve = _normedCepCurveFC;
211 powerPattern = _normalizedPowerPatternFC;
213 emissionCurve = _cepCurveFC;
214 powerPattern = _powerPatternFC;
217 if (!_cepCurvePollutants.hasString(pollutant)) {
218 throw InvalidArgument(
"Emission pollutant " + pollutant +
" not found!");
222 emissionCurve = _normalizedCepCurvePollutants.get(pollutant);
223 powerPattern = _normailzedPowerPatternPollutants;
225 emissionCurve = _cepCurvePollutants.get(pollutant);
226 powerPattern = _powerPatternPollutants;
233 if (emissionCurve.size() == 0) {
234 throw InvalidArgument(
"Empty emission curve for " + pollutant +
" found!");
237 if (emissionCurve.size() == 1) {
238 return emissionCurve[0];
242 if (power <= powerPattern.front()) {
243 double calcEmission = PHEMCEP::Interpolate(power, powerPattern[0], powerPattern[1], emissionCurve[0], emissionCurve[1]);
245 if (calcEmission < 0) {
254 if (power >= powerPattern.back()) {
255 return PHEMCEP::Interpolate(power, powerPattern[powerPattern.size() - 2], powerPattern.back(), emissionCurve[emissionCurve.size() - 2], emissionCurve.back());
262 PHEMCEP::FindLowerUpperInPattern(lowerIndex, upperIndex, powerPattern, power);
264 return PHEMCEP::Interpolate(power, powerPattern[lowerIndex], powerPattern[upperIndex], emissionCurve[lowerIndex], emissionCurve[upperIndex]);
270PHEMCEP::Interpolate(
double px,
double p1,
double p2,
double e1,
double e2)
const {
274 return e1 + (px - p1) / (p2 - p1) * (e2 - e1);
278double PHEMCEP::GetDecelCoast(
double speed,
double acc,
double gradient,
double )
const {
283 double rotCoeff = GetRotationalCoeffecient(speed);
288 double iGear = GetGearCoeffecient(speed);
290 double iTot = iGear * _axleRatio;
292 double n = (30 * speed * iTot) / ((_effictiveWheelDiameter / 2) *
M_PI2);
293 double nNorm = (
n - _engineIdlingSpeed) / (_engineRatedSpeed - _engineIdlingSpeed);
295 FindLowerUpperInPattern(lowerIndex, upperIndex, _nNormTable, nNorm);
299 if (speed >= 10e-2) {
300 fMot = (-GetDragCoeffecient(nNorm) * _ratedPower * 1000 / speed) / 0.9;
303 double fRoll = (_resistanceF0
304 + _resistanceF1 * speed
305 + pow(_resistanceF2 * speed, 2)
306 + pow(_resistanceF3 * speed, 3)
307 + pow(_resistanceF4 * speed, 4)) * (_massVehicle + _vehicleLoading) *
GRAVITY_CONST;
309 double fAir = _cdValue * _crossSectionalArea * 1.2 * 0.5 * pow(speed, 2);
311 double fGrad = (_massVehicle + _vehicleLoading) *
GRAVITY_CONST * gradient / 100;
313 return -(fMot + fRoll + fAir + fGrad) / ((_massVehicle + _vehicleLoading) * rotCoeff);
318PHEMCEP::GetRotationalCoeffecient(
double speed)
const {
322 PHEMCEP::FindLowerUpperInPattern(lowerIndex, upperIndex, _speedPatternRotational, speed);
324 return PHEMCEP::Interpolate(speed,
325 _speedPatternRotational[lowerIndex],
326 _speedPatternRotational[upperIndex],
327 _speedCurveRotational[lowerIndex],
328 _speedCurveRotational[upperIndex]);
331double PHEMCEP::GetGearCoeffecient(
double speed)
const {
335 FindLowerUpperInPattern(lowerIndex, upperIndex, _gearTransmissionCurve, speed);
337 return Interpolate(speed,
338 _speedPatternRotational[lowerIndex],
339 _speedPatternRotational[upperIndex],
340 _gearTransmissionCurve[lowerIndex],
341 _gearTransmissionCurve[upperIndex]);
344double PHEMCEP::GetDragCoeffecient(
double nNorm)
const {
348 FindLowerUpperInPattern(lowerIndex, upperIndex, _dragNormTable, nNorm);
350 return Interpolate(nNorm,
351 _nNormTable[lowerIndex],
352 _nNormTable[upperIndex],
353 _dragNormTable[lowerIndex],
354 _dragNormTable[upperIndex]);
357void PHEMCEP::FindLowerUpperInPattern(
int& lowerIndex,
int& upperIndex,
const std::vector<double>& pattern,
double value)
const {
358 if (
value <= pattern.front()) {
365 if (
value >= pattern.back()) {
366 lowerIndex = (int)pattern.size() - 1;
367 upperIndex = (int)pattern.size() - 1;
372 int middleIndex = ((int)pattern.size() - 1) / 2;
373 upperIndex = (int)pattern.size() - 1;
376 while (upperIndex - lowerIndex > 1) {
377 if (pattern[middleIndex] ==
value) {
378 lowerIndex = middleIndex;
379 upperIndex = middleIndex;
381 }
else if (pattern[middleIndex] <
value) {
382 lowerIndex = middleIndex;
383 middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
385 upperIndex = middleIndex;
386 middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
390 if (pattern[lowerIndex] <=
value &&
value < pattern[upperIndex]) {
393 throw ProcessError(
"Error during calculation of position in pattern!");
399PHEMCEP::CalcPower(
double v,
double a,
double slope,
double )
const {
400 const double rotFactor = GetRotationalCoeffecient(v);
401 double power = (_massVehicle + _vehicleLoading) *
GRAVITY_CONST * (_resistanceF0 + _resistanceF1 * v + _resistanceF4 * pow(v, 4)) * v;
403 power += (_massVehicle * rotFactor + _massRot + _vehicleLoading) * a * v;
404 power += (_massVehicle + _vehicleLoading) * slope * 0.01 * v;
410PHEMCEP::GetMaxAccel(
double v,
double a,
double gradient,
double )
const {
412 double rotFactor = GetRotationalCoeffecient(v);
413 const double pMaxForAcc = GetPMaxNorm(v) * _ratedPower - PHEMCEP::CalcPower(v, 0, gradient, _vehicleLoading);
414 return (pMaxForAcc * 1000) / ((_massVehicle * rotFactor + _massRot + _vehicleLoading) * v);
419double PHEMCEP::GetPMaxNorm(
double speed)
const {
421 if (speed <= _pNormV0) {
423 }
else if (speed >= _pNormV1) {
426 return PHEMCEP::Interpolate(speed, _pNormV0, _pNormV1, _pNormP0, _pNormP1);
const double AIR_DENSITY_CONST
const double ZERO_SPEED_ACCURACY
const double SPEED_DCEL_MIN
const double GRAVITY_CONST
const double NORMALIZING_ACCELARATION
const double NORMALIZING_SPEED
const std::string invalid_return< std::string >::value
#define UNUSED_PARAMETER(x)
*brief user defined string literal for JSON values *sa std::size_t n