From 5e7ddc9f244f3cbf4ee4c354960cebdca1ac3d3d Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Wed, 22 Jul 2020 13:11:07 -0700 Subject: [PATCH 1/2] start refactor --- firmware/console/status_loop.cpp | 2 +- .../algo/airmass/speed_density_base.cpp | 20 ++++++++++++++ .../algo/airmass/speed_density_base.h | 10 +++++++ firmware/controllers/algo/algo.mk | 1 + firmware/controllers/algo/fuel_math.cpp | 8 +++--- firmware/controllers/math/speed_density.cpp | 27 ++++--------------- firmware/controllers/math/speed_density.h | 4 +-- unit_tests/tests/test_engine_math.cpp | 2 +- unit_tests/tests/test_fuel_map.cpp | 2 +- unit_tests/tests/test_fuel_math.cpp | 8 +++--- unit_tests/tests/test_speed_density.cpp | 2 +- 11 files changed, 51 insertions(+), 35 deletions(-) create mode 100644 firmware/controllers/algo/airmass/speed_density_base.cpp create mode 100644 firmware/controllers/algo/airmass/speed_density_base.h diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index 1d63ea8d7e..e909f76461 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -288,7 +288,7 @@ static void showFuelInfo2(float rpm, float engineLoad) { float baseFuelMs = getBaseTableFuel((int) rpm, engineLoad); - float magicAir = getCylinderAirMass(1, 100, convertCelsiusToKelvin(20) PASS_ENGINE_PARAMETER_SUFFIX); + float magicAir = SpeedDensityBase::getAirmassImpl(1, 100, convertCelsiusToKelvin(20) PASS_ENGINE_PARAMETER_SUFFIX); scheduleMsg(&logger, "SD magic fuel %.2f", getInjectionDurationForAirmass(magicAir, 14.7 PASS_ENGINE_PARAMETER_SUFFIX)); scheduleMsg(&logger, "inj flow %.2fcc/min displacement %.2fL", engineConfiguration->injector.flow, diff --git a/firmware/controllers/algo/airmass/speed_density_base.cpp b/firmware/controllers/algo/airmass/speed_density_base.cpp new file mode 100644 index 0000000000..1d12ac1fba --- /dev/null +++ b/firmware/controllers/algo/airmass/speed_density_base.cpp @@ -0,0 +1,20 @@ + +#include "global.h" +#include "speed_density_base.h" + +EXTERN_ENGINE; + +/** + * is J/g*K + * aka + */ +#define GAS_R 0.28705 + +float idealGasLaw(float volume, float pressure, float temperature) { + return volume * pressure / (GAS_R * temperature); +} + +float SpeedDensityBase::getAirmassImpl(float ve, float manifoldPressure, float temperature DECLARE_ENGINE_PARAMETER_SUFFIX) { + float cycleAir = ve * idealGasLaw(CONFIG(specs.displacement), manifoldPressure, temperature); + return cycleAir / CONFIG(specs.cylindersCount); +} diff --git a/firmware/controllers/algo/airmass/speed_density_base.h b/firmware/controllers/algo/airmass/speed_density_base.h new file mode 100644 index 0000000000..5d11c806ef --- /dev/null +++ b/firmware/controllers/algo/airmass/speed_density_base.h @@ -0,0 +1,10 @@ +#pragma once + +#include "engine.h" + +float idealGasLaw(float volume, float pressure, float temperature); + +class SpeedDensityBase { +public: + static float getAirmassImpl(float ve, float manifoldPressure, float temperature DECLARE_ENGINE_PARAMETER_SUFFIX); +}; diff --git a/firmware/controllers/algo/algo.mk b/firmware/controllers/algo/algo.mk index ae6b29e0a4..b4f6ed9fd6 100644 --- a/firmware/controllers/algo/algo.mk +++ b/firmware/controllers/algo/algo.mk @@ -11,3 +11,4 @@ CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/advance_map.cpp \ $(PROJECT_DIR)/controllers/algo/engine2.cpp \ $(PROJECT_DIR)/controllers/gauges/lcd_menu_tree.cpp \ $(PROJECT_DIR)/controllers/algo/event_registry.cpp \ + $(PROJECT_DIR)/controllers/algo/airmass/speed_density_base.cpp \ diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index 0c5e69da55..02d31504b5 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -32,6 +32,7 @@ #include "speed_density.h" #include "perf_trace.h" #include "sensor.h" +#include "speed_density_base.h" EXTERN_ENGINE; @@ -204,7 +205,7 @@ float getInjectionDurationForAirmass(float airMass, float afr DECLARE_ENGINE_PAR AirmassResult getAirmass(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) { switch (CONFIG(fuelAlgorithm)) { case LM_SPEED_DENSITY: - return getSpeedDensityAirmass(getMap(PASS_ENGINE_PARAMETER_SIGNATURE) PASS_ENGINE_PARAMETER_SUFFIX); + return getSpeedDensityAirmass(PASS_ENGINE_PARAMETER_SIGNATURE); case LM_REAL_MAF: { float maf = getRealMaf(PASS_ENGINE_PARAMETER_SIGNATURE) + engine->engineLoadAccelEnrichment.getEngineLoadEnrichment(PASS_ENGINE_PARAMETER_SIGNATURE); return getRealMafAirmass(maf, rpm PASS_ENGINE_PARAMETER_SUFFIX); @@ -513,8 +514,9 @@ float getStandardAirCharge(DECLARE_ENGINE_PARAMETER_SIGNATURE) { float totalDisplacement = CONFIG(specs.displacement); float cylDisplacement = totalDisplacement / CONFIG(specs.cylindersCount); - // Calculation of 100% VE air mass in g/cyl - 1 cylinder filling at 1.204/L - air density at 20C - return cylDisplacement * 1.204f; + // Calculation of 100% VE air mass in g/cyl - 1 cylinder filling at 1.204/L + // 101.325kpa, 20C + return idealGasLaw(cylDisplacement, 101.325f, 273.15f + 20.0f); } #endif diff --git a/firmware/controllers/math/speed_density.cpp b/firmware/controllers/math/speed_density.cpp index 9518586ec5..fb5847f461 100644 --- a/firmware/controllers/math/speed_density.cpp +++ b/firmware/controllers/math/speed_density.cpp @@ -15,6 +15,7 @@ #include "engine_math.h" #include "perf_trace.h" #include "sensor.h" +#include "map.h" #if defined(HAS_OS_ACCESS) #error "Unexpected OS ACCESS HERE" @@ -111,27 +112,7 @@ temperature_t getTCharge(int rpm, float tps DECLARE_ENGINE_PARAMETER_SUFFIX) { return Tcharge; } -/** - * is J/g*K - */ -#define GAS_R 0.28705 - -/** - * @return air mass in grams - */ -static float getCycleAirMass(float volumetricEfficiency, float MAP, float tempK DECLARE_ENGINE_PARAMETER_SUFFIX) { - return (CONFIG(specs.displacement) * volumetricEfficiency * MAP) / (GAS_R * tempK); -} - -float getCylinderAirMass(float volumetricEfficiency, float MAP, float tempK DECLARE_ENGINE_PARAMETER_SUFFIX) { - return getCycleAirMass(volumetricEfficiency, MAP, tempK PASS_ENGINE_PARAMETER_SUFFIX) - / CONFIG(specs.cylindersCount); -} - -/** - * @return per cylinder injection time, in Milliseconds - */ -AirmassResult getSpeedDensityAirmass(float map DECLARE_ENGINE_PARAMETER_SUFFIX) { +AirmassResult getSpeedDensityAirmass(DECLARE_ENGINE_PARAMETER_SIGNATURE) { ScopePerf perf(PE::GetSpeedDensityFuel); /** @@ -142,6 +123,8 @@ AirmassResult getSpeedDensityAirmass(float map DECLARE_ENGINE_PARAMETER_SUFFIX) warning(CUSTOM_ERR_TCHARGE_NOT_READY2, "tChargeK not ready"); // this would happen before we have CLT reading for example return {}; } + + float map = getMap(PASS_ENGINE_PARAMETER_SIGNATURE); efiAssert(CUSTOM_ERR_ASSERT, !cisnan(map), "NaN map", {}); engine->engineState.sd.manifoldAirPressureAccelerationAdjustment = engine->engineLoadAccelEnrichment.getEngineLoadEnrichment(PASS_ENGINE_PARAMETER_SIGNATURE); @@ -149,7 +132,7 @@ AirmassResult getSpeedDensityAirmass(float map DECLARE_ENGINE_PARAMETER_SUFFIX) float adjustedMap = engine->engineState.sd.adjustedManifoldAirPressure = map + engine->engineState.sd.manifoldAirPressureAccelerationAdjustment; efiAssert(CUSTOM_ERR_ASSERT, !cisnan(adjustedMap), "NaN adjustedMap", {}); - float airMass = getCylinderAirMass(ENGINE(engineState.currentBaroCorrectedVE), adjustedMap, tChargeK PASS_ENGINE_PARAMETER_SUFFIX); + float airMass = SpeedDensityBase::getAirmassImpl(ENGINE(engineState.currentBaroCorrectedVE), adjustedMap, tChargeK PASS_ENGINE_PARAMETER_SUFFIX); if (cisnan(airMass)) { warning(CUSTOM_ERR_6685, "NaN airMass"); return {}; diff --git a/firmware/controllers/math/speed_density.h b/firmware/controllers/math/speed_density.h index 842b017ce2..9e2565592b 100644 --- a/firmware/controllers/math/speed_density.h +++ b/firmware/controllers/math/speed_density.h @@ -9,13 +9,13 @@ #include "engine.h" #include "airmass.h" +#include "speed_density_base.h" #define gramm_second_to_cc_minute(gs) ((gs) / 0.0119997981) #define cc_minute_to_gramm_second(ccm) ((ccm) * 0.0119997981) temperature_t getTCharge(int rpm, float tps DECLARE_ENGINE_PARAMETER_SUFFIX); -float getCylinderAirMass(float volumetricEfficiency, float MAP, float tempK DECLARE_ENGINE_PARAMETER_SUFFIX); void setDefaultVETable(DECLARE_ENGINE_PARAMETER_SIGNATURE); void initSpeedDensity(DECLARE_ENGINE_PARAMETER_SIGNATURE); -AirmassResult getSpeedDensityAirmass(float map DECLARE_ENGINE_PARAMETER_SUFFIX); +AirmassResult getSpeedDensityAirmass(DECLARE_ENGINE_PARAMETER_SIGNATURE); diff --git a/unit_tests/tests/test_engine_math.cpp b/unit_tests/tests/test_engine_math.cpp index d4a35a62c2..9b008e2b33 100644 --- a/unit_tests/tests/test_engine_math.cpp +++ b/unit_tests/tests/test_engine_math.cpp @@ -58,7 +58,7 @@ TEST(misc, testEngineMath) { engineConfiguration->tChargeAirCoefMax = 0.902f; engineConfiguration->tChargeAirFlowMax = 153.6f; // calc. some airMass given the engine displacement=1.839 and 4 cylinders (FORD_ESCORT_GT) - engine->engineState.sd.airMassInOneCylinder = getCylinderAirMass(/*VE*/1.0f, /*MAP*/100.0f, /*tChargeK*/273.15f + 20.0f PASS_ENGINE_PARAMETER_SUFFIX); + engine->engineState.sd.airMassInOneCylinder = SpeedDensityBase::getAirmassImpl(/*VE*/1.0f, /*MAP*/100.0f, /*tChargeK*/273.15f + 20.0f PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_NEAR(0.5464f, engine->engineState.sd.airMassInOneCylinder, EPS4D); Sensor::setMockValue(SensorType::Clt, 90); diff --git a/unit_tests/tests/test_fuel_map.cpp b/unit_tests/tests/test_fuel_map.cpp index efcbe3971b..8d4d53c938 100644 --- a/unit_tests/tests/test_fuel_map.cpp +++ b/unit_tests/tests/test_fuel_map.cpp @@ -29,7 +29,7 @@ TEST(misc, testMafFuelMath) { // Check results EXPECT_NEAR(0.277777f * 0.75f, airmass.CylinderAirmass, EPS4D); - EXPECT_NEAR(70.9884, airmass.EngineLoadPercent, EPS4D); + EXPECT_NEAR(70.9814f, airmass.EngineLoadPercent, EPS4D); } TEST(misc, testFuelMap) { diff --git a/unit_tests/tests/test_fuel_math.cpp b/unit_tests/tests/test_fuel_math.cpp index 4b2da7e964..9278203044 100644 --- a/unit_tests/tests/test_fuel_math.cpp +++ b/unit_tests/tests/test_fuel_math.cpp @@ -10,22 +10,22 @@ TEST(FuelMath, getStandardAirCharge) { CONFIG(specs.displacement) = 1.839f; CONFIG(specs.cylindersCount) = 4; - EXPECT_FLOAT_EQ(0.553539f, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE)); + EXPECT_FLOAT_EQ(0.5535934f, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE)); // LS 5.3 liter v8 CONFIG(specs.displacement) = 5.327f; CONFIG(specs.cylindersCount) = 8; - EXPECT_FLOAT_EQ(0.80171353f, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE)); + EXPECT_FLOAT_EQ(0.80179232f, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE)); // Chainsaw - single cylinder 32cc CONFIG(specs.displacement) = 0.032f; CONFIG(specs.cylindersCount) = 1; - EXPECT_FLOAT_EQ(0.038528003, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE)); + EXPECT_FLOAT_EQ(0.038531788f, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE)); // Leopard 1 47.666 liter v12 CONFIG(specs.displacement) = 47.666f; CONFIG(specs.cylindersCount) = 12; - EXPECT_FLOAT_EQ(4.782489f, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE)); + EXPECT_FLOAT_EQ(4.782959f, getStandardAirCharge(PASS_ENGINE_PARAMETER_SIGNATURE)); } diff --git a/unit_tests/tests/test_speed_density.cpp b/unit_tests/tests/test_speed_density.cpp index d8e0faf5ee..a212a93bb2 100644 --- a/unit_tests/tests/test_speed_density.cpp +++ b/unit_tests/tests/test_speed_density.cpp @@ -25,7 +25,7 @@ TEST(big, testSpeedDensity) { engineConfiguration->injector.flow = gramm_second_to_cc_minute(5.303); - float airMass = getCylinderAirMass(0.92, 98, 293.16 PASS_ENGINE_PARAMETER_SUFFIX); + float airMass = SpeedDensityBase::getAirmassImpl(0.92, 98, 293.16 PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_FLOAT_EQ(0.9371106624, airMass); From b544c140a38c4a6a41455da8a5debc1d2c2b0841 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Wed, 22 Jul 2020 18:24:20 -0700 Subject: [PATCH 2/2] comment headers, notes --- .../algo/airmass/speed_density_base.cpp | 19 +++++++++++++++---- .../algo/airmass/speed_density_base.h | 9 +++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/firmware/controllers/algo/airmass/speed_density_base.cpp b/firmware/controllers/algo/airmass/speed_density_base.cpp index 1d12ac1fba..f13e847df2 100644 --- a/firmware/controllers/algo/airmass/speed_density_base.cpp +++ b/firmware/controllers/algo/airmass/speed_density_base.cpp @@ -1,3 +1,11 @@ +/** + * @file speed_density_base.cpp + * + * Base for speed density (ie, ideal gas law) math shared by multiple fueling modes. + * + * @date July 22, 2020 + * @author Matthew Kennedy, (C) 2020 + */ #include "global.h" #include "speed_density_base.h" @@ -5,13 +13,16 @@ EXTERN_ENGINE; /** - * is J/g*K - * aka + * Derived via: + * (8.31 J K mol^-1) <- ideal gas constant R + * / + * (28.97g mol^-1) <- molar mass of air + * = 0.28705 J*K/g */ -#define GAS_R 0.28705 +#define AIR_R 0.28705f float idealGasLaw(float volume, float pressure, float temperature) { - return volume * pressure / (GAS_R * temperature); + return volume * pressure / (AIR_R * temperature); } float SpeedDensityBase::getAirmassImpl(float ve, float manifoldPressure, float temperature DECLARE_ENGINE_PARAMETER_SUFFIX) { diff --git a/firmware/controllers/algo/airmass/speed_density_base.h b/firmware/controllers/algo/airmass/speed_density_base.h index 5d11c806ef..29c2bad791 100644 --- a/firmware/controllers/algo/airmass/speed_density_base.h +++ b/firmware/controllers/algo/airmass/speed_density_base.h @@ -1,3 +1,12 @@ +/** + * @file speed_density_base.h + * + * Base for speed density (ie, ideal gas law) math shared by multiple fueling modes. + * + * @date July 22, 2020 + * @author Matthew Kennedy, (C) 2020 + */ + #pragma once #include "engine.h"