diff --git a/firmware/controllers/algo/airmass/speed_density_airmass.cpp b/firmware/controllers/algo/airmass/speed_density_airmass.cpp index e32905cbd2..0e9d48ced7 100644 --- a/firmware/controllers/algo/airmass/speed_density_airmass.cpp +++ b/firmware/controllers/algo/airmass/speed_density_airmass.cpp @@ -4,6 +4,12 @@ AirmassResult SpeedDensityAirmass::getAirmass(int rpm) { ScopePerf perf(PE::GetSpeedDensityFuel); + auto map = getMap(rpm); + + return getAirmass(rpm, map); +} + +AirmassResult SpeedDensityAirmass::getAirmass(float rpm, float map) { /** * most of the values are pre-calculated for performance reasons */ @@ -13,8 +19,6 @@ AirmassResult SpeedDensityAirmass::getAirmass(int rpm) { return {}; } - auto map = getMap(rpm); - float ve = getVe(rpm, map); float airMass = getAirmassImpl(ve, map, tChargeK); @@ -32,6 +36,20 @@ AirmassResult SpeedDensityAirmass::getAirmass(int rpm) { }; } +float SpeedDensityAirmass::getAirflow(float rpm, float map) { + auto airmassResult = getAirmass(rpm, map); + + float massPerCycle = airmassResult.CylinderAirmass * engineConfiguration->specs.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) const { float fallbackMap; if (engineConfiguration->enableMapEstimationTableFallback) { diff --git a/firmware/controllers/algo/airmass/speed_density_airmass.h b/firmware/controllers/algo/airmass/speed_density_airmass.h index 2ccee63630..90846cd778 100644 --- a/firmware/controllers/algo/airmass/speed_density_airmass.h +++ b/firmware/controllers/algo/airmass/speed_density_airmass.h @@ -10,6 +10,8 @@ public: {} AirmassResult getAirmass(int rpm) override; + AirmassResult getAirmass(float rpm, float map); + float getAirflow(float rpm, float map); float getMap(int rpm) const; diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index b473761912..6f2fa6b968 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -171,6 +171,10 @@ AirmassModelBase* getAirmassModel(engine_load_mode_e mode) { } } +float getMaxAirflowAtMap(float map) { + return sdAirmass.getAirflow(Sensor::getOrZero(SensorType::Rpm), map); +} + // Per-cylinder base fuel mass static float getBaseFuelMass(int rpm) { ScopePerf perf(PE::GetBaseFuel); diff --git a/firmware/controllers/algo/fuel_math.h b/firmware/controllers/algo/fuel_math.h index f2cb597be9..0febd2e1b7 100644 --- a/firmware/controllers/algo/fuel_math.h +++ b/firmware/controllers/algo/fuel_math.h @@ -34,3 +34,5 @@ float getCylinderFuelTrim(size_t cylinderNumber, int rpm, float fuelLoad); struct AirmassModelBase; AirmassModelBase* getAirmassModel(engine_load_mode_e mode); + +float getMaxAirflowAtMap(float map); diff --git a/firmware/controllers/math/throttle_model.cpp b/firmware/controllers/math/throttle_model.cpp index 1ca14d026a..d33c1eae8c 100644 --- a/firmware/controllers/math/throttle_model.cpp +++ b/firmware/controllers/math/throttle_model.cpp @@ -2,6 +2,8 @@ #include "throttle_model.h" +#include "fuel_math.h" + static const float pressureRatioCorrectionBins[] = { 0.53125, 0.546875, 0.5625, 0.578125, 0.59375, 0.609375, 0.625, 0.640625, 0.65625, 0.671875, 0.6875, 0.703125, 0.71875, 0.734375, 0.750, 0.765625, 0.78125, 0.796875, 0.8125, 0.828125, 0.84375, 0.859375, 0.875, 0.890625, 0.90625, 0.921875, 0.9375, 0.953125 }; static const float pressureRatioCorrectionValues[] = { 1, 0.9993, 0.998, 0.995, 0.991, 0.986, 0.979, 0.972, 0.963, 0.953, 0.942, 0.930, 0.916, 0.901, 0.884, 0.866, 0.845, 0.824, 0.800, 0.774, 0.745, 0.714, 0.679, 0.642, 0.600, 0.553, 0.449, 0.449 }; static float pressureRatioFlowCorrection(float pr) { @@ -141,6 +143,5 @@ float ThrottleModel::effectiveArea(float tps) const { } float ThrottleModel::maxEngineFlow(float map) const { - // TODO: implement this for real by consulting VE table, etc - return 0.5f; + return getMaxAirflowAtMap(map); }