Skip to content

Commit

Permalink
refactoring coasting decel to allow param insertion #14285
Browse files Browse the repository at this point in the history
  • Loading branch information
behrisch committed Feb 2, 2024
1 parent 9048722 commit 1ba5488
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 44 deletions.
29 changes: 13 additions & 16 deletions src/foreign/PHEMlight/V5/cpp/CEP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,6 @@ namespace PHEMlightdllV5 {
privateCalcType = value;
}

bool CEP::isHBEV() const {
return getFuelType() == Constants::strBEV || getFuelType() == Constants::strHybrid;
}

const double& CEP::getRatedPower() const {
return privateRatedPower;
}
Expand Down Expand Up @@ -258,7 +254,7 @@ namespace PHEMlightdllV5 {
return power;
}

double CEP::GetEmission(const std::string& pollutant, double power, double speed, Helpers* VehicleClass) {
double CEP::GetEmission(const std::string& pollutant, double power, double speed, Helpers* VehicleClass, const double drivingPower) {
//Declaration
std::vector<double>* emissionCurve = nullptr;
std::vector<double>* powerPattern = nullptr;
Expand Down Expand Up @@ -295,7 +291,7 @@ namespace PHEMlightdllV5 {
emissionCurve = &_cepCurvePollutants[pollutant];
powerPattern = &_normalizedPowerPatternPollutants;
if (!getHeavyVehicle()) {
normalizingPower = CalcPower(Constants::NORMALIZING_SPEED, Constants::NORMALIZING_ACCELARATION, 0, (getCalcType() == "HEV" || getCalcType() == "BEV"));
normalizingPower = drivingPower;
}
}

Expand Down Expand Up @@ -418,16 +414,14 @@ namespace PHEMlightdllV5 {
return true;
}

double CEP::GetDecelCoast(double speed, double acc, double gradient) {
double CEP::getFMot(const double speed) {
if (speed < 10e-2) {
return 0.;
}
//Declaration
int upperIndex;
int lowerIndex;

if (speed < Constants::SPEED_DCEL_MIN) {
return speed / Constants::SPEED_DCEL_MIN * GetDecelCoast(Constants::SPEED_DCEL_MIN, acc, gradient);
}

double rotCoeff = GetRotationalCoeffecient(speed);
FindLowerUpperInPattern(lowerIndex, upperIndex, _speedPatternRotational, speed);
double iGear = Interpolate(speed, _speedPatternRotational[lowerIndex], _speedPatternRotational[upperIndex], _gearTransmissionCurve[lowerIndex], _gearTransmissionCurve[upperIndex]);

Expand All @@ -437,13 +431,16 @@ namespace PHEMlightdllV5 {
double nNorm = (n - _engineIdlingSpeed) / (_engineRatedSpeed - _engineIdlingSpeed);

FindLowerUpperInPattern(lowerIndex, upperIndex, _nNormTable, nNorm);
return (-Interpolate(nNorm, _nNormTable[lowerIndex], _nNormTable[upperIndex], _dragNormTable[lowerIndex], _dragNormTable[upperIndex]) * getRatedPower() * 1000 / speed) / Constants::getDRIVE_TRAIN_EFFICIENCY();
}

double fMot = 0;
double CEP::GetDecelCoast(double speed, double acc, double gradient) {

if (speed >= 10e-2) {
fMot = (-Interpolate(nNorm, _nNormTable[lowerIndex], _nNormTable[upperIndex], _dragNormTable[lowerIndex], _dragNormTable[upperIndex]) * getRatedPower() * 1000 / speed) / Constants::getDRIVE_TRAIN_EFFICIENCY();
if (speed < Constants::SPEED_DCEL_MIN) {
return speed / Constants::SPEED_DCEL_MIN * GetDecelCoast(Constants::SPEED_DCEL_MIN, acc, gradient);
}

double fMot = getFMot(speed);
double rotCoeff = GetRotationalCoeffecient(speed);
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;

double fAir = _cWValue * _crossSectionalArea * Constants::AIR_DENSITY_CONST * 0.5 * std::pow(speed, 2);
Expand Down
9 changes: 6 additions & 3 deletions src/foreign/PHEMlight/V5/cpp/CEP.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ namespace PHEMlightdllV5 {
void setFuelType(const std::string& value);
const std::string& getCalcType() const;
void setCalcType(const std::string& value);
bool isHBEV() const;

public:
const double& getRatedPower() const;
Expand All @@ -86,9 +85,13 @@ namespace PHEMlightdllV5 {
double getCWValue() const {
return _cWValue;
}
double getResistance(const double speed) const {
double getResistance(const double speed, const bool full=false) const {
if (full) {
return _resistanceF0 + _resistanceF1 * speed + std::pow(_resistanceF2 * speed, 2) + std::pow(_resistanceF3 * speed, 3) + std::pow(_resistanceF4 * speed, 4);
}
return _resistanceF0 + _resistanceF1 * speed + _resistanceF4 * std::pow(speed, 4);
}
double getFMot(const double speed);

protected:
double _massVehicle;
Expand Down Expand Up @@ -136,7 +139,7 @@ namespace PHEMlightdllV5 {

double CalcEngPower(double power);

double GetEmission(const std::string& pollutant, double power, double speed, Helpers* VehicleClass);
double GetEmission(const std::string& pollutant, double power, double speed, Helpers* VehicleClass, const double drivingPower);

double GetCO2Emission(double _FC, double _CO, double _HC, Helpers* VehicleClass);

Expand Down
25 changes: 19 additions & 6 deletions src/utils/emissions/EnergyParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,28 +120,41 @@ EnergyParams::getDouble(SumoXMLAttr attr) const {
}


const std::vector<double>&
EnergyParams::getDoubles(SumoXMLAttr attr) const {
double
EnergyParams::getDoubleOptional(SumoXMLAttr attr, const double def) const {
auto it = myMap.find(attr);
if (it != myMap.end()) {
return it->second;
}
if (mySecondaryParams != nullptr) {
return mySecondaryParams->getDoubles(attr);
return mySecondaryParams->getDouble(attr);
}
return def;
}


const std::vector<double>&
EnergyParams::getDoubles(SumoXMLAttr attr) const {
auto it = myVecMap.find(attr);
if (it != myVecMap.end()) {
return it->second;
}
if (mySecondaryParams != nullptr) {
return mySecondaryParams->getDoubles(attr);
}
throw UnknownElement("Unknown Energy Model parameter: " + toString(attr));
}


const CharacteristicMap&
EnergyParams::getCharacteristicMap(SumoXMLAttr attr) const {
if (mySecondaryParams != nullptr) {
return mySecondaryParams->getCharacteristicMap(attr);
}
auto it = myCharacteristicMapMap.find(attr);
if (it != myCharacteristicMapMap.end()) {
return it->second;
}
if (mySecondaryParams != nullptr) {
return mySecondaryParams->getCharacteristicMap(attr);
}
throw UnknownElement("Unknown Energy Model parameter: " + toString(attr));
}

Expand Down
1 change: 1 addition & 0 deletions src/utils/emissions/EnergyParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class EnergyParams {
void setDouble(SumoXMLAttr attr, double value);

double getDouble(SumoXMLAttr attr) const;
double getDoubleOptional(SumoXMLAttr attr, const double def) const;

/**@brief Returns the value for a given key
* @param[in] key The key to ask for
Expand Down
52 changes: 34 additions & 18 deletions src/utils/emissions/HelpersPHEMlight5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,16 @@ HelpersPHEMlight5::getClassByName(const std::string& eClass, const SUMOVehicleCl


double
HelpersPHEMlight5::getEmission(PHEMlightdllV5::CEP* currCep, const std::string& e, const double p, const double v) const {
return currCep->GetEmission(e, p, v, &myHelper);
HelpersPHEMlight5::getEmission(PHEMlightdllV5::CEP* currCep, const std::string& e, const double p, const double v, const double drivingPower) const {
return currCep->GetEmission(e, p, v, &myHelper, drivingPower);
}


double
HelpersPHEMlight5::calcPower(PHEMlightdllV5::CEP* currCep, const double v, const double a, const double slope, const EnergyParams* param) const {
// copy of CEP::CalcPower
const double power = calcWheelPower(currCep, v, a, slope, param) / PHEMlightdllV5::Constants::_DRIVE_TRAIN_EFFICIENCY;
if (!currCep->isHBEV()) {
if (!(currCep->getCalcType() == "HEV" || currCep->getCalcType() == "BEV")) {
return power + currCep->getAuxPower();
}
return power;
Expand Down Expand Up @@ -161,8 +161,22 @@ HelpersPHEMlight5::getModifiedAccel(const SUMOEmissionClass c, const double v, c


double
HelpersPHEMlight5::getCoastingDecel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* /* param */) const {
return myCEPs.find(c)->second->GetDecelCoast(v, a, slope);
HelpersPHEMlight5::getCoastingDecel(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams* param) const {
PHEMlightdllV5::CEP* const currCep = myCEPs.find(c)->second;
// this is a copy of CEP::GetDecelCoast
if (v < PHEMlightdllV5::Constants::SPEED_DCEL_MIN) {
return v / PHEMlightdllV5::Constants::SPEED_DCEL_MIN * getCoastingDecel(c, PHEMlightdllV5::Constants::SPEED_DCEL_MIN, a, slope, param);
}
const double rotFactor = currCep->GetRotationalCoeffecient(v);
const double mass = currCep->getVehicleMass();
const double load = currCep->getVehicleLoading();
const double cw = currCep->getCrossSectionalArea() * currCep->getCWValue();

const double fRoll = currCep->getResistance(v, true) * (mass + load) * PHEMlightdllV5::Constants::GRAVITY_CONST;
const double fAir = cw * PHEMlightdllV5::Constants::AIR_DENSITY_CONST * 0.5 * std::pow(v, 2);
const double fGrad = (mass + load) * PHEMlightdllV5::Constants::GRAVITY_CONST * slope / 100;

return -(currCep->getFMot(v) + fRoll + fAir + fGrad) / ((mass + load) * rotFactor);
}


Expand All @@ -176,42 +190,44 @@ HelpersPHEMlight5::compute(const SUMOEmissionClass c, const PollutantsInterface:
PHEMlightdllV5::CEP* const currCep = myCEPs.find(c)->second;
const double corrAcc = getModifiedAccel(c, corrSpeed, a, slope, param);
const bool isBEV = currCep->getFuelType() == PHEMlightdllV5::Constants::strBEV;
const bool isHybrid = currCep->getFuelType() == PHEMlightdllV5::Constants::strHybrid;
const bool isHybrid = currCep->getCalcType() == PHEMlightdllV5::Constants::strHybrid;
const double power_raw = calcPower(currCep, corrSpeed, corrAcc, slope, param);
const double power = isHybrid ? calcWheelPower(currCep, corrSpeed, corrAcc, slope, param) : currCep->CalcEngPower(power_raw);

if (!isBEV && corrAcc < currCep->GetDecelCoast(corrSpeed, corrAcc, slope) &&
if (!isBEV && corrAcc < getCoastingDecel(c, corrSpeed, corrAcc, slope, param) &&
corrSpeed > PHEMlightdllV5::Constants::ZERO_SPEED_ACCURACY) {
return 0.;
}
// TODO: this is probably only needed for non-heavy vehicles, so if execution speed becomes an issue
const double drivingPower = calcPower(currCep, PHEMlightdllV5::Constants::NORMALIZING_SPEED, PHEMlightdllV5::Constants::NORMALIZING_ACCELARATION, 0, param);
switch (e) {
case PollutantsInterface::CO:
return getEmission(currCep, "CO", power, corrSpeed) / SECONDS_PER_HOUR * 1000.;
return getEmission(currCep, "CO", power, corrSpeed, drivingPower) / SECONDS_PER_HOUR * 1000.;
case PollutantsInterface::CO2:
return currCep->GetCO2Emission(getEmission(currCep, "FC", power, corrSpeed),
getEmission(currCep, "CO", power, corrSpeed),
getEmission(currCep, "HC", power, corrSpeed), &myHelper) / SECONDS_PER_HOUR * 1000.;
return currCep->GetCO2Emission(getEmission(currCep, "FC", power, corrSpeed, drivingPower),
getEmission(currCep, "CO", power, corrSpeed, drivingPower),
getEmission(currCep, "HC", power, corrSpeed, drivingPower), &myHelper) / SECONDS_PER_HOUR * 1000.;
case PollutantsInterface::HC:
return getEmission(currCep, "HC", power, corrSpeed) / SECONDS_PER_HOUR * 1000.;
return getEmission(currCep, "HC", power, corrSpeed, drivingPower) / SECONDS_PER_HOUR * 1000.;
case PollutantsInterface::NO_X:
return getEmission(currCep, "NOx", power, corrSpeed) / SECONDS_PER_HOUR * 1000.;
return getEmission(currCep, "NOx", power, corrSpeed, drivingPower) / SECONDS_PER_HOUR * 1000.;
case PollutantsInterface::PM_X:
return getEmission(currCep, "PM", power, corrSpeed) / SECONDS_PER_HOUR * 1000.;
return getEmission(currCep, "PM", power, corrSpeed, drivingPower) / SECONDS_PER_HOUR * 1000.;
case PollutantsInterface::FUEL: {
if (myVolumetricFuel && currCep->getFuelType() == PHEMlightdllV5::Constants::strDiesel) { // divide by average diesel density of 836 g/l
return getEmission(currCep, "FC", power, corrSpeed) / 836. / SECONDS_PER_HOUR * 1000.;
return getEmission(currCep, "FC", power, corrSpeed, drivingPower) / 836. / SECONDS_PER_HOUR * 1000.;
}
if (myVolumetricFuel && currCep->getFuelType() == PHEMlightdllV5::Constants::strGasoline) { // divide by average gasoline density of 742 g/l
return getEmission(currCep, "FC", power, corrSpeed) / 742. / SECONDS_PER_HOUR * 1000.;
return getEmission(currCep, "FC", power, corrSpeed, drivingPower) / 742. / SECONDS_PER_HOUR * 1000.;
}
if (isBEV) {
return 0.;
}
return getEmission(currCep, "FC", power, corrSpeed) / SECONDS_PER_HOUR * 1000.; // still in mg even if myVolumetricFuel is set!
return getEmission(currCep, "FC", power, corrSpeed, drivingPower) / SECONDS_PER_HOUR * 1000.; // still in mg even if myVolumetricFuel is set!
}
case PollutantsInterface::ELEC:
if (isBEV) {
return (getEmission(currCep, "FC_el", power, corrSpeed) + currCep->getAuxPower()) / SECONDS_PER_HOUR * 1000.;
return (getEmission(currCep, "FC_el", power, corrSpeed, drivingPower) + currCep->getAuxPower()) / SECONDS_PER_HOUR * 1000.;
}
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/emissions/HelpersPHEMlight5.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class HelpersPHEMlight5 : public HelpersPHEMlight {
* @param[in] v The vehicle's current velocity
* @return The amount of the pollutant emitted by the given emission class when moving with the given velocity and acceleration [mg/s or ml/s]
*/
double getEmission(PHEMlightdllV5::CEP* currCep, const std::string& e, const double p, const double v) const;
double getEmission(PHEMlightdllV5::CEP* currCep, const std::string& e, const double p, const double v, const double drivingPower) const;

/** @brief Returns the total power needed.
* @param[in] currCep the emission class
Expand Down

0 comments on commit 1ba5488

Please sign in to comment.