fome-fw/firmware/controllers/algo/airmass/speed_density_airmass.cpp

61 lines
1.6 KiB
C++

#include "pch.h"
#include "speed_density_airmass.h"
AirmassResult SpeedDensityAirmass::getAirmass(int rpm, bool postState) {
ScopePerf perf(PE::GetSpeedDensityFuel);
auto map = getMap(rpm, postState);
return getAirmass(rpm, map, postState);
}
AirmassResult SpeedDensityAirmass::getAirmass(float rpm, float map, bool postState) {
/**
* most of the values are pre-calculated for performance reasons
*/
float tChargeK = engine->engineState.sd.tChargeK;
if (cisnan(tChargeK)) {
warning(ObdCode::CUSTOM_ERR_TCHARGE_NOT_READY2, "tChargeK not ready"); // this would happen before we have CLT reading for example
return {};
}
float ve = getVe(rpm, map, postState);
float airMass = getAirmassImpl(ve, map, tChargeK);
if (cisnan(airMass)) {
warning(ObdCode::CUSTOM_ERR_6685, "NaN airMass");
return {};
}
return {
airMass,
map, // AFR/VE table Y axis
};
}
float SpeedDensityAirmass::getAirflow(float rpm, float map, bool postState) {
auto airmassResult = getAirmass(rpm, map, postState);
float massPerCycle = airmassResult.CylinderAirmass * engineConfiguration->cylindersCount;
if (!engineConfiguration->twoStroke) {
// 4 stroke engines only do a half cycle per rev
massPerCycle = massPerCycle / 2;
}
// g/s
return massPerCycle * rpm / 60;
}
float SpeedDensityAirmass::getMap(int rpm, bool postState) const {
float fallbackMap = m_mapEstimationTable->getValue(rpm, Sensor::getOrZero(SensorType::Tps1));
#if EFI_TUNER_STUDIO
if (postState) {
engine->outputChannels.fallbackMap = fallbackMap;
}
#endif // EFI_TUNER_STUDIO
return Sensor::get(SensorType::Map).value_or(fallbackMap);
}