SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHEMCEP.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // Helper class for PHEM Light, holds a specific CEP for a PHEM emission class
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
10 // Copyright (C) 2013-2014 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #ifdef _MSC_VER
25 #include <windows_config.h>
26 #else
27 #include <config.h>
28 #endif
29 
30 #include <cmath>
31 #include <string>
32 #include <utils/common/StdDefs.h>
35 #include "PHEMCEP.h"
36 
37 #ifdef CHECK_MEMORY_LEAKS
38 #include <foreign/nvwa/debug_new.h>
39 #endif // CHECK_MEMORY_LEAKS
40 
41 
42 // ===========================================================================
43 // method definitions
44 // ===========================================================================
45 PHEMCEP::PHEMCEP(bool heavyVehicel, SUMOEmissionClass emissionClass,
46  double vehicleMass, double vehicleLoading, double vehicleMassRot,
47  double crossArea, double cWValue,
48  double f0, double f1, double f2, double f3, double f4,
49  double ratedPower, double pNormV0, double pNormP0, double pNormV1,
50  double pNormP1, std::string vehicelFuelType,
51  const std::vector< std::vector<double> >& matrixFC,
52  const std::vector<std::string>& headerLinePollutants,
53  const std::vector< std::vector<double> >& matrixPollutants,
54  const std::vector< std::vector<double> > matrixSpeedRotational) {
55  _emissionClass = emissionClass;
56  _resistanceF0 = f0;
57  _resistanceF1 = f1;
58  _resistanceF2 = f2;
59  _resistanceF3 = f3;
60  _resistanceF4 = f4;
61  _cwValue = cWValue;
62  _crossSectionalArea = crossArea;
63  _massVehicle = vehicleMass;
64  _vehicleLoading = vehicleLoading;
65  _massRot = vehicleMassRot;
66  _ratedPower = ratedPower;
67  _vehicleFuelType = vehicelFuelType;
68 
69  _pNormV0 = pNormV0 / 3.6;
70  _pNormP0 = pNormP0;
71  _pNormV1 = pNormV1 / 3.6;
72  _pNormP1 = pNormP1;
73 
74  std::vector<std::string> pollutantIdentifier;
75  std::vector< std::vector<double> > pollutantMeasures;
76 
77  // init pollutant identifiers
78  for (int i = 0; i < (int)headerLinePollutants.size(); i++) {
79  pollutantIdentifier.push_back(headerLinePollutants[i]);
80  } // end for
81 
82  // get size of powerPatterns
83  _sizeOfPatternFC = (int)matrixFC.size();
84  _sizeOfPatternPollutants = (int)matrixPollutants.size();
85 
86  // initialize measures
87  for (int i = 0; i < (int)headerLinePollutants.size(); i++) {
88  pollutantMeasures.push_back(std::vector<double>());
89  } // end for
90 
91  // looping through matrix and assigning values for speed rotational table
92  _speedCurveRotational.clear();
94  for (int i = 0; i < (int)matrixSpeedRotational.size(); i++) {
95  if (matrixSpeedRotational[i].size() != 2) {
96  throw InvalidArgument("Error loading vehicle file for: " + SumoEmissionClassStrings.getString(emissionClass));
97  }
98 
99  _speedPatternRotational.push_back(matrixSpeedRotational[i][0] / 3.6);
100  _speedCurveRotational.push_back(matrixSpeedRotational[i][1]);
101 
102  } // end for
103 
104  // looping through matrix and assigning values for Fuel consumption
105  _cepCurveFC.clear();
106  for (int i = 0; i < (int)matrixFC.size(); i++) {
107  if (matrixFC[i].size() != 2) {
108  throw InvalidArgument("Error loading vehicle file for: " + SumoEmissionClassStrings.getString(emissionClass));
109  }
110 
111  _powerPatternFC.push_back(matrixFC[i][0] * _ratedPower);
112  _cepCurveFC.push_back(matrixFC[i][1]);
113 
114  } // end for
115 
116 
117  // looping through matrix and assigning values for pollutants
118  double normalizingPower = 0;
119 
120  if (heavyVehicel) {
121  normalizingPower = _ratedPower;
122  } else {
124  } // end if
125 
126  const int headerCount = (int)headerLinePollutants.size();
127  for (int i = 0; i < (int)matrixPollutants.size(); i++) {
128  for (int j = 0; j < (int)matrixPollutants[i].size(); j++) {
129  if ((int)matrixPollutants[i].size() != headerCount + 1) {
130  return;
131  }
132 
133  if (j == 0) {
134  _powerPatternPollutants.push_back(matrixPollutants[i][j] * normalizingPower);
135  } else {
136  pollutantMeasures[j - 1].push_back(matrixPollutants[i][j]);
137  } // end if
138  } // end for
139  } // end for
140 
141  for (int i = 0; i < headerCount; i++) {
142  _cepCurvePollutants.insert(pollutantIdentifier[i], pollutantMeasures[i]);
143  } // end for
144 
145 } // end of Cep
146 
147 
149  // free power pattern
150  _powerPatternFC.clear();
151  _powerPatternPollutants.clear();
152  _cepCurveFC.clear();
153  _speedCurveRotational.clear();
154  _speedPatternRotational.clear();
155 } // end of ~Cep
156 
157 
158 double
159 PHEMCEP::CalcPower(double v, double a, double slope) const {
160  const double rotFactor = GetRotationalCoeffecient(v);
161  double power = (_massVehicle + _vehicleLoading) * GRAVITY_CONST * (_resistanceF0 + _resistanceF1 * v + _resistanceF4 * pow(v, 4)) * v;
162  power += (_crossSectionalArea * _cwValue * AIR_DENSITY_CONST / 2) * pow(v, 3);
163  power += (_massVehicle * rotFactor + _massRot + _vehicleLoading) * a * v;
164  power += (_massVehicle + _vehicleLoading) * slope * 0.01 * v;
165  return power / 950.;
166 }
167 
168 
169 double
170 PHEMCEP::GetMaxAccel(double v, double a, double gradient) const {
171  UNUSED_PARAMETER(a);
172  const double pMaxForAcc = GetPMaxNorm(v) * _ratedPower - PHEMCEP::CalcPower(v, 0, gradient);
173  return (pMaxForAcc * 1000) / ((_massVehicle * GetRotationalCoeffecient(v) + _massRot + _vehicleLoading) * v);
174 }
175 
176 
177 double
178 PHEMCEP::GetEmission(const std::string& pollutant, double power) const {
179  std::vector<double> emissionCurve;
180  std::vector<double> powerPattern;
181 
182  if (pollutant == "FC") {
183  emissionCurve = _cepCurveFC;
184  powerPattern = _powerPatternFC;
185  } else {
186  if (!_cepCurvePollutants.hasString(pollutant)) {
187  throw InvalidArgument("Emission pollutant " + pollutant + " not found!");
188  }
189 
190  emissionCurve = _cepCurvePollutants.get(pollutant);
191  powerPattern = _powerPatternPollutants;
192  } // end if
193 
194 
195 
196  if (emissionCurve.size() == 0) {
197  throw InvalidArgument("Empty emission curve for " + pollutant + " found!");
198  }
199 
200  if (emissionCurve.size() == 1) {
201  return emissionCurve[0];
202  }
203 
204  // in case that the demanded power is smaller than the first entry (smallest) in the power pattern the first two entries are extrapolated
205  if (power <= powerPattern.front()) {
206  double calcEmission = PHEMCEP::Interpolate(power, powerPattern[0], powerPattern[1], emissionCurve[0], emissionCurve[1]);
207 
208  if (calcEmission < 0) {
209  return 0;
210  } else {
211  return calcEmission;
212  }
213 
214  } // end if
215 
216  // if power bigger than all entries in power pattern the last two values are linearly extrapolated
217  if (power >= powerPattern.back()) {
218  return PHEMCEP::Interpolate(power, powerPattern[powerPattern.size() - 2], powerPattern.back(), emissionCurve[emissionCurve.size() - 2], emissionCurve.back());
219  } // end if
220 
221  // bisection search to find correct position in power pattern
222  int upperIndex;
223  int lowerIndex;
224 
225  PHEMCEP::FindLowerUpperInPattern(lowerIndex, upperIndex, powerPattern, power);
226 
227  return PHEMCEP::Interpolate(power, powerPattern[lowerIndex], powerPattern[upperIndex], emissionCurve[lowerIndex], emissionCurve[upperIndex]);
228 
229 } // end of GetEmission
230 
231 
232 double
233 PHEMCEP::Interpolate(double px, double p1, double p2, double e1, double e2) const {
234  if (p2 == p1) {
235  return e1;
236  }
237  return e1 + (px - p1) / (p2 - p1) * (e2 - e1);
238 } // end of Interpolate
239 
240 
241 double
243  int upperIndex;
244  int lowerIndex;
245 
246  PHEMCEP::FindLowerUpperInPattern(lowerIndex, upperIndex, _speedPatternRotational, speed);
247 
248  return PHEMCEP::Interpolate(speed,
249  _speedPatternRotational[lowerIndex],
250  _speedPatternRotational[upperIndex],
251  _speedCurveRotational[lowerIndex],
252  _speedCurveRotational[upperIndex]);
253 } // end of GetRotationalCoeffecient
254 
255 void
256 PHEMCEP::FindLowerUpperInPattern(int& lowerIndex, int& upperIndex, std::vector<double> pattern, double value) const {
257  if (value <= pattern.front()) {
258  lowerIndex = 0;
259  upperIndex = 0;
260  return;
261 
262  } // end if
263 
264  if (value >= pattern.back()) {
265  lowerIndex = (int)pattern.size() - 1;
266  upperIndex = (int)pattern.size() - 1;
267  return;
268  } // end if
269 
270  // bisection search to find correct position in power pattern
271  int middleIndex = ((int)pattern.size() - 1) / 2;
272  upperIndex = (int)pattern.size() - 1;
273  lowerIndex = 0;
274 
275  while (upperIndex - lowerIndex > 1) {
276  if (pattern[middleIndex] == value) {
277  lowerIndex = middleIndex;
278  upperIndex = middleIndex;
279  return;
280  } else if (pattern[middleIndex] < value) {
281  lowerIndex = middleIndex;
282  middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
283  } else {
284  upperIndex = middleIndex;
285  middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
286  } // end if
287  } // end while
288 
289  if (pattern[lowerIndex] <= value && value < pattern[upperIndex]) {
290  return;
291  } else {
292  throw ProcessError("Error during calculation of position in pattern!");
293  }
294 } // end of FindLowerUpperInPattern
295 
296 
297 double PHEMCEP::GetPMaxNorm(double speed) const {
298  // Linear function between v0 and v1, constant elsewhere
299  if (speed <= _pNormV0) {
300  return _pNormP0;
301  } else if (speed >= _pNormV1) {
302  return _pNormP1;
303  } else {
305  }
306 } // end of GetPMaxNorm
307 
308 /****************************************************************************/
std::vector< double > _powerPatternFC
Definition: PHEMCEP.h:285
bool hasString(const std::string &str) const
double GetEmission(const std::string &pollutantIdentifier, double power) const
Returns a emission measure for power[kW] level.
Definition: PHEMCEP.cpp:178
StringBijection< SUMOEmissionClass > SumoEmissionClassStrings(SumoEmissionClassStringInitializer, SVE_Solo_LKW_D_EU6_II)
std::vector< double > _speedCurveRotational
Definition: PHEMCEP.h:295
double _massVehicle
vehicle mass
Definition: PHEMCEP.h:265
double _resistanceF1
Rolling resistance f1.
Definition: PHEMCEP.h:253
std::string _vehicleFuelType
Definition: PHEMCEP.h:297
const double NORMALIZING_SPEED
Definition: PHEMConstants.h:27
double _pNormP0
Step functions parameter for maximum rated power.
Definition: PHEMCEP.h:275
~PHEMCEP()
Destructor.
Definition: PHEMCEP.cpp:148
double _pNormV1
Step functions parameter for maximum rated power.
Definition: PHEMCEP.h:277
double _resistanceF3
Rolling resistance f3.
Definition: PHEMCEP.h:257
double _massRot
rotational mass of vehicle
Definition: PHEMCEP.h:269
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:38
double GetMaxAccel(double v, double a, double gradient) const
Returns the maximum accelaration for a vehicle at state v,a, slope and loading.
Definition: PHEMCEP.cpp:170
int _sizeOfPatternFC
Definition: PHEMCEP.h:281
double _pNormV0
Step functions parameter for maximum rated power.
Definition: PHEMCEP.h:273
const double NORMALIZING_ACCELARATION
Definition: PHEMConstants.h:28
SUMOEmissionClass
Definition of vehicle emission classes.
double _crossSectionalArea
crosssectional area of vehicle
Definition: PHEMCEP.h:263
double _vehicleLoading
vehicle loading
Definition: PHEMCEP.h:267
double _pNormP1
Step functions parameter for maximum rated power.
Definition: PHEMCEP.h:279
std::vector< double > _speedPatternRotational
Definition: PHEMCEP.h:293
const double GRAVITY_CONST
Definition: PHEMConstants.h:24
PHEMCEP(bool heavyVehicel, SUMOEmissionClass emissionClass, double vehicleMass, double vehicleLoading, double vehicleMassRot, double crossArea, double cWValue, double f0, double f1, double f2, double f3, double f4, double ratedPower, double pNormV0, double pNormP0, double pNormV1, double pNormP1, std::string vehicelFuelType, const std::vector< std::vector< double > > &matrixFC, const std::vector< std::string > &headerLinePollutants, const std::vector< std::vector< double > > &matrixPollutants, const std::vector< std::vector< double > > matrixSpeedRotational)
Definition: PHEMCEP.cpp:45
double GetRotationalCoeffecient(double speed) const
Calculates rotational index for speed.
Definition: PHEMCEP.cpp:242
double _resistanceF4
Rolling resistance f4.
Definition: PHEMCEP.h:259
void insert(const std::string str, const T key)
double _resistanceF0
Rolling resistance f0.
Definition: PHEMCEP.h:251
std::vector< double > _cepCurveFC
Definition: PHEMCEP.h:289
double GetPMaxNorm(double speed) const
Calculates maximum available rated power for speed.
Definition: PHEMCEP.cpp:297
int _sizeOfPatternPollutants
Definition: PHEMCEP.h:283
std::vector< double > _powerPatternPollutants
Definition: PHEMCEP.h:287
const double AIR_DENSITY_CONST
Definition: PHEMConstants.h:25
double Interpolate(double px, double p1, double p2, double e1, double e2) const
Interpolates emission linearly between two known power-emission pairs.
Definition: PHEMCEP.cpp:233
double _ratedPower
rated power of vehicle
Definition: PHEMCEP.h:271
double _cwValue
Cw value.
Definition: PHEMCEP.h:261
double CalcPower(double v, double a, double slope) const
Returns the power of used for a vehicle at state v,a, slope and loading.
Definition: PHEMCEP.cpp:159
StringBijection< std::vector< double > > _cepCurvePollutants
Definition: PHEMCEP.h:291
T get(const std::string &str) const
void FindLowerUpperInPattern(int &lowerIndex, int &upperIndex, std::vector< double > pattern, double value) const
Finds bounding upper and lower index in pattern for value.
Definition: PHEMCEP.cpp:256
SUMOEmissionClass _emissionClass
PHEM emission class of vehicle.
Definition: PHEMCEP.h:249
double _resistanceF2
Rolling resistance f2.
Definition: PHEMCEP.h:255