From 044766ec708218cabfb09f4f2a328c141622cc8b Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Wed, 15 Apr 2020 06:48:17 -0700 Subject: [PATCH] New clt consumers part 1 (#1301) * idle * CLT test prep * idle target * header * air interpolate * ancient comment * fuel cut * fuel cut, idle tests * cleanup --- firmware/console/status_loop.cpp | 3 --- .../controllers/actuators/idle_thread.cpp | 9 +++++---- firmware/controllers/algo/engine2.cpp | 2 +- .../controllers/algo/engine_configuration.cpp | 14 ++++++-------- firmware/controllers/algo/fuel_math.cpp | 11 ++++++++--- firmware/controllers/math/speed_density.cpp | 12 ++++++++---- firmware/controllers/math/speed_density.h | 2 +- unit_tests/engine_test_helper.cpp | 3 ++- unit_tests/engine_test_helper.h | 1 + unit_tests/tests/test_engine_math.cpp | 19 ++++++++++++------- unit_tests/tests/test_fuelCut.cpp | 10 +++++----- unit_tests/tests/test_fuel_map.cpp | 5 +++-- unit_tests/tests/test_idle_controller.cpp | 6 ++---- .../test_startOfCrankingPrimingPulse.cpp | 4 +--- 14 files changed, 55 insertions(+), 46 deletions(-) diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index 2bc70924b4..434d4a12e4 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -353,9 +353,6 @@ static void printSensors(Logging *log) { reportSensorF(log, GAUGE_NAME_DWELL_DUTY, "%", getCoilDutyCycle(rpm PASS_ENGINE_PARAMETER_SUFFIX), 2); - -// debugFloat(&logger, "tch", getTCharge1(tps), 2); - for (int i = 0;ifsioAdc[i] != EFI_ADC_NONE) { strcpy(buf, "adcX"); diff --git a/firmware/controllers/actuators/idle_thread.cpp b/firmware/controllers/actuators/idle_thread.cpp index 718c8e0d75..502f6c2b8a 100644 --- a/firmware/controllers/actuators/idle_thread.cpp +++ b/firmware/controllers/actuators/idle_thread.cpp @@ -318,8 +318,9 @@ static percent_t automaticIdleController(float tpsPos DECLARE_ENGINE_PARAMETER_S int idlePidLowerRpm = targetRpm + CONFIG(idlePidRpmDeadZone); if (CONFIG(idlePidRpmUpperLimit) > 0) { engine->engineState.idle.idleState = PID_UPPER; - if (CONFIG(useIacTableForCoasting) && hasCltSensor()) { - percent_t iacPosForCoasting = interpolate2d("iacCoasting", getCoolantTemperature(), CONFIG(iacCoastingBins), CONFIG(iacCoasting)); + const auto [cltValid, clt] = Sensor::get(SensorType::Clt); + if (CONFIG(useIacTableForCoasting) && cltValid) { + percent_t iacPosForCoasting = interpolate2d("iacCoasting", clt, CONFIG(iacCoastingBins), CONFIG(iacCoasting)); newValue = interpolateClamped(idlePidLowerRpm, newValue, idlePidLowerRpm + CONFIG(idlePidRpmUpperLimit), iacPosForCoasting, rpm); } else { // Well, just leave it as is, without PID regulation... @@ -390,7 +391,7 @@ static percent_t automaticIdleController(float tpsPos DECLARE_ENGINE_PARAMETER_S finishIdleTestIfNeeded(); undoIdleBlipIfNeeded(); - float clt = getCoolantTemperature(); + const auto [cltValid, clt] = Sensor::get(SensorType::Clt); #if EFI_SHAFT_POSITION_INPUT bool isRunning = engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE); #else @@ -398,7 +399,7 @@ static percent_t automaticIdleController(float tpsPos DECLARE_ENGINE_PARAMETER_S #endif /* EFI_SHAFT_POSITION_INPUT */ // cltCorrection is used only for cranking or running in manual mode float cltCorrection; - if (!hasCltSensor()) + if (!cltValid) cltCorrection = 1.0f; // Use separate CLT correction table for cranking else if (engineConfiguration->overrideCrankingIacSetting && !isRunning) { diff --git a/firmware/controllers/algo/engine2.cpp b/firmware/controllers/algo/engine2.cpp index 041c530441..3b623586b9 100644 --- a/firmware/controllers/algo/engine2.cpp +++ b/firmware/controllers/algo/engine2.cpp @@ -220,7 +220,7 @@ void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { void EngineState::updateTChargeK(int rpm, float tps DECLARE_ENGINE_PARAMETER_SUFFIX) { #if EFI_ENGINE_CONTROL - float newTCharge = getTCharge(rpm, tps, getCoolantTemperature(), getIntakeAirTemperature() PASS_ENGINE_PARAMETER_SUFFIX); + float newTCharge = getTCharge(rpm, tps PASS_ENGINE_PARAMETER_SUFFIX); // convert to microsecs and then to seconds efitick_t curTime = getTimeNowNt(); float secsPassed = (float)NT2US(curTime - timeSinceLastTChargeK) / 1000000.0f; diff --git a/firmware/controllers/algo/engine_configuration.cpp b/firmware/controllers/algo/engine_configuration.cpp index e0543b37ca..8f08db107f 100644 --- a/firmware/controllers/algo/engine_configuration.cpp +++ b/firmware/controllers/algo/engine_configuration.cpp @@ -29,6 +29,7 @@ #include "engine_math.h" #include "speed_density.h" #include "advance_map.h" +#include "sensor.h" #include "hip9011_lookup.h" #if EFI_MEMS @@ -609,14 +610,11 @@ void setTargetRpmCurve(int rpm DECLARE_CONFIG_PARAMETER_SUFFIX) { } int getTargetRpmForIdleCorrection(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - float clt = getCoolantTemperature(); - int targetRpm; - if (!hasCltSensor()) { - // error is already reported, let's take first value from the table should be good enough error handing solution - targetRpm = CONFIG(cltIdleRpm)[0]; - } else { - targetRpm = interpolate2d("cltRpm", clt, CONFIG(cltIdleRpmBins), CONFIG(cltIdleRpm)); - } + // error is already reported, let's take the value at 0C since that should be a nice high idle + float clt = Sensor::get(SensorType::Clt).value_or(0); + + int targetRpm = interpolate2d("cltRpm", clt, CONFIG(cltIdleRpmBins), CONFIG(cltIdleRpm)); + return targetRpm + engine->fsioState.fsioIdleTargetRPMAdjustment; } diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index a8bffc1d73..90242f5af7 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -364,8 +364,13 @@ float getFuelCutOffCorrection(efitick_t nowNt, int rpm DECLARE_ENGINE_PARAMETER_ // coasting fuel cut-off correction if (CONFIG(coastingFuelCutEnabled)) { - auto [valid, tpsPos] = Sensor::get(SensorType::Tps1); - if (!valid) { + auto [tpsValid, tpsPos] = Sensor::get(SensorType::Tps1); + if (!tpsValid) { + return 1.0f; + } + + const auto [cltValid, clt] = Sensor::get(SensorType::Clt); + if (!cltValid) { return 1.0f; } @@ -375,7 +380,7 @@ float getFuelCutOffCorrection(efitick_t nowNt, int rpm DECLARE_ENGINE_PARAMETER_ bool mapDeactivate = (map >= CONFIG(coastingFuelCutMap)); bool tpsDeactivate = (tpsPos >= CONFIG(coastingFuelCutTps)); // If no CLT sensor (or broken), don't allow DFCO - bool cltDeactivate = hasCltSensor() ? (getCoolantTemperature() < (float)CONFIG(coastingFuelCutClt)) : true; + bool cltDeactivate = clt < (float)CONFIG(coastingFuelCutClt); bool rpmDeactivate = (rpm < CONFIG(coastingFuelCutRpmLow)); bool rpmActivate = (rpm > CONFIG(coastingFuelCutRpmHigh)); diff --git a/firmware/controllers/math/speed_density.cpp b/firmware/controllers/math/speed_density.cpp index 4ad47b95e2..733016ce55 100644 --- a/firmware/controllers/math/speed_density.cpp +++ b/firmware/controllers/math/speed_density.cpp @@ -16,6 +16,7 @@ #include "maf2map.h" #include "config_engine_specs.h" #include "perf_trace.h" +#include "sensor.h" #if defined(HAS_OS_ACCESS) #error "Unexpected OS ACCESS HERE" @@ -35,10 +36,13 @@ baroCorr_Map3D_t baroCorrMap("baro"); #define tpMax 100 // http://rusefi.com/math/t_charge.html /***panel:Charge Temperature*/ -temperature_t getTCharge(int rpm, float tps, float coolantTemp, float airTemp DECLARE_ENGINE_PARAMETER_SUFFIX) { - if (cisnan(coolantTemp) || cisnan(airTemp)) { - warning(CUSTOM_ERR_NAN_TCHARGE, "t-getTCharge NaN"); - return coolantTemp; +temperature_t getTCharge(int rpm, float tps DECLARE_ENGINE_PARAMETER_SUFFIX) { + const auto [cltValid, coolantTemp] = Sensor::get(SensorType::Clt); + const auto [iatValid, airTemp] = Sensor::get(SensorType::Iat); + + if (!cltValid || !iatValid) { + warning(CUSTOM_ERR_NAN_TCHARGE, "getTCharge invalid iat/clt"); + return airTemp; } DISPLAY_STATE(Engine) diff --git a/firmware/controllers/math/speed_density.h b/firmware/controllers/math/speed_density.h index 67b9ebb0ef..8d581aa2b5 100644 --- a/firmware/controllers/math/speed_density.h +++ b/firmware/controllers/math/speed_density.h @@ -10,7 +10,7 @@ #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, float coolantTemperature, float airTemperature DECLARE_ENGINE_PARAMETER_SUFFIX); +temperature_t getTCharge(int rpm, float tps DECLARE_ENGINE_PARAMETER_SUFFIX); float getCylinderAirMass(float volumetricEfficiency, float MAP, float tempK DECLARE_ENGINE_PARAMETER_SUFFIX); float sdMath(float airMass, float AFR DECLARE_ENGINE_PARAMETER_SUFFIX); diff --git a/unit_tests/engine_test_helper.cpp b/unit_tests/engine_test_helper.cpp index 512c65e54c..dcd8f09539 100644 --- a/unit_tests/engine_test_helper.cpp +++ b/unit_tests/engine_test_helper.cpp @@ -65,9 +65,10 @@ EngineTestHelper::EngineTestHelper(engine_type_e engineType, configuration_callb engine->engineConfigurationPtr->iat.adcChannel = TEST_IAT_CHANNEL; // magic voltage to get nice CLT testCltValue = 1.492964; - //todosetMockCltVoltage(1.492964 PASS_ENGINE_PARAMETER_SUFFIX); + Sensor::setMockValue(SensorType::Clt, 70); // magic voltage to get nice IAT testIatValue = 4.03646; + Sensor::setMockValue(SensorType::Iat, 30); // this is needed to have valid CLT and IAT. //todo: reuse initPeriodicEvents(PASS_ENGINE_PARAMETER_SIGNATURE) method diff --git a/unit_tests/engine_test_helper.h b/unit_tests/engine_test_helper.h index 54e65d81bc..a6dc70a7a7 100644 --- a/unit_tests/engine_test_helper.h +++ b/unit_tests/engine_test_helper.h @@ -12,6 +12,7 @@ #include "rpm_calculator.h" #include "main_trigger_callback.h" #include "unit_test_framework.h" +#include "sensor.h" extern EnginePins enginePins; diff --git a/unit_tests/tests/test_engine_math.cpp b/unit_tests/tests/test_engine_math.cpp index dd3cc9fdc0..d4a35a62c2 100644 --- a/unit_tests/tests/test_engine_math.cpp +++ b/unit_tests/tests/test_engine_math.cpp @@ -41,14 +41,16 @@ TEST(misc, testEngineMath) { ASSERT_NEAR( 50, getOneDegreeTimeMs(600) * 180, EPS4D) << "600 RPM"; ASSERT_EQ( 5, getOneDegreeTimeMs(6000) * 180) << "6000 RPM"; - ASSERT_FLOAT_EQ(312.5, getTCharge(1000, 0, 300, 350 PASS_ENGINE_PARAMETER_SUFFIX)); - ASSERT_FLOAT_EQ(313.5833, getTCharge(1000, 50, 300, 350 PASS_ENGINE_PARAMETER_SUFFIX)); - ASSERT_FLOAT_EQ(314.6667, getTCharge(1000, 100, 300, 350 PASS_ENGINE_PARAMETER_SUFFIX)); + Sensor::setMockValue(SensorType::Clt, 300); + Sensor::setMockValue(SensorType::Iat, 350); + ASSERT_FLOAT_EQ(312.5, getTCharge(1000, 0 PASS_ENGINE_PARAMETER_SUFFIX)); + ASSERT_FLOAT_EQ(313.5833, getTCharge(1000, 50 PASS_ENGINE_PARAMETER_SUFFIX)); + ASSERT_FLOAT_EQ(314.6667, getTCharge(1000, 100 PASS_ENGINE_PARAMETER_SUFFIX)); - ASSERT_FLOAT_EQ(312.5, getTCharge(4000, 0, 300, 350 PASS_ENGINE_PARAMETER_SUFFIX)); - ASSERT_FLOAT_EQ(320.0833, getTCharge(4000, 50, 300, 350 PASS_ENGINE_PARAMETER_SUFFIX)); - ASSERT_FLOAT_EQ(327.6667, getTCharge(4000, 100, 300, 350 PASS_ENGINE_PARAMETER_SUFFIX)); + ASSERT_FLOAT_EQ(312.5, getTCharge(4000, 0 PASS_ENGINE_PARAMETER_SUFFIX)); + ASSERT_FLOAT_EQ(320.0833, getTCharge(4000, 50 PASS_ENGINE_PARAMETER_SUFFIX)); + ASSERT_FLOAT_EQ(327.6667, getTCharge(4000, 100 PASS_ENGINE_PARAMETER_SUFFIX)); // test Air Interpolation mode engineConfiguration->tChargeMode = TCHARGE_MODE_AIR_INTERP; @@ -58,8 +60,11 @@ TEST(misc, testEngineMath) { // 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); ASSERT_NEAR(0.5464f, engine->engineState.sd.airMassInOneCylinder, EPS4D); + + Sensor::setMockValue(SensorType::Clt, 90); + Sensor::setMockValue(SensorType::Iat, 20); // calc. airFlow using airMass, and find tCharge - ASSERT_FLOAT_EQ(59.1175f, getTCharge(/*RPM*/1000, /*TPS*/0, /*CLT*/90.0f, /*IAT*/20.0f PASS_ENGINE_PARAMETER_SUFFIX)); + ASSERT_FLOAT_EQ(59.1175f, getTCharge(/*RPM*/1000, /*TPS*/0 PASS_ENGINE_PARAMETER_SUFFIX)); ASSERT_FLOAT_EQ(65.5625f/*kg/h*/, engine->engineState.airFlow); } diff --git a/unit_tests/tests/test_fuelCut.cpp b/unit_tests/tests/test_fuelCut.cpp index 73a25cd5cf..9df1d37ca9 100644 --- a/unit_tests/tests/test_fuelCut.cpp +++ b/unit_tests/tests/test_fuelCut.cpp @@ -12,8 +12,6 @@ #include "fsio_impl.h" TEST(fuelCut, coasting) { - printf("*************************************************** testCoastingFuelCut\r\n"); - WITH_ENGINE_TEST_HELPER(TEST_ENGINE); // configure coastingFuelCut @@ -30,7 +28,8 @@ TEST(fuelCut, coasting) { setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð); // mock CLT - just above threshold ('hot engine') - float hotClt = engine->sensors.clt = engineConfiguration->coastingFuelCutClt + 1; + float hotClt = engineConfiguration->coastingFuelCutClt + 1; + Sensor::setMockValue(SensorType::Clt, hotClt); // mock TPS - throttle is opened Sensor::setMockValue(SensorType::Tps1, 60); // set 'running' RPM - just above RpmHigh threshold @@ -57,14 +56,14 @@ TEST(fuelCut, coasting) { assertEqualsM("inj dur#2 cut", 0.0f, ENGINE(injectionDuration)); // Now drop the CLT below threshold - engine->sensors.clt = engineConfiguration->coastingFuelCutClt - 1; + Sensor::setMockValue(SensorType::Clt, engineConfiguration->coastingFuelCutClt - 1); eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); // Fuel cut-off should be diactivated - the engine is 'cold' assertEqualsM("inj dur#3 clt", normalInjDuration, ENGINE(injectionDuration)); // restore CLT - engine->sensors.clt = hotClt; + Sensor::setMockValue(SensorType::Clt, hotClt); // And set RPM - somewhere between RpmHigh and RpmLow threshold engine->rpmCalculator.mockRpm = (engineConfiguration->coastingFuelCutRpmHigh + engineConfiguration->coastingFuelCutRpmLow) / 2; eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); @@ -115,6 +114,7 @@ TEST(fuelCut, criticalEngineTemperature) { ASSERT_FALSE(engine->stopEngineRequestTimeNt > 0); engine->sensors.mockClt = 200; // 200C is really hot! + Sensor::setMockValue(SensorType::Clt, 200); eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); eth.engine.periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE); diff --git a/unit_tests/tests/test_fuel_map.cpp b/unit_tests/tests/test_fuel_map.cpp index d95253dc66..d283338255 100644 --- a/unit_tests/tests/test_fuel_map.cpp +++ b/unit_tests/tests/test_fuel_map.cpp @@ -65,6 +65,9 @@ TEST(misc, testFuelMap) { eth.engine.updateSlowSensors(PASS_ENGINE_PARAMETER_SIGNATURE); + Sensor::setMockValue(SensorType::Clt, 36.605f); + Sensor::setMockValue(SensorType::Iat, 30.0f); + // because all the correction tables are zero printf("*************************************************** getRunningFuel 1\r\n"); eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE); @@ -86,10 +89,8 @@ TEST(misc, testFuelMap) { setFlatInjectorLag(0 PASS_CONFIG_PARAMETER_SUFFIX); - ASSERT_FALSE(cisnan(getIntakeAirTemperature())); float iatCorrection = getIatFuelCorrection(-KELV PASS_ENGINE_PARAMETER_SUFFIX); ASSERT_EQ( 2, iatCorrection) << "IAT"; - ASSERT_FALSE(cisnan(getCoolantTemperature())); float cltCorrection = getCltFuelCorrection(PASS_ENGINE_PARAMETER_SIGNATURE); ASSERT_EQ( 1, cltCorrection) << "CLT"; float injectorLag = getInjectorLag(getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE) PASS_ENGINE_PARAMETER_SUFFIX); diff --git a/unit_tests/tests/test_idle_controller.cpp b/unit_tests/tests/test_idle_controller.cpp index 912feb42b0..47332d085d 100644 --- a/unit_tests/tests/test_idle_controller.cpp +++ b/unit_tests/tests/test_idle_controller.cpp @@ -51,8 +51,6 @@ TEST(idle, fsioPidParameters) { // see also util.pid test TEST(idle, timingPid) { - print("******************************************* testTimingPidController\r\n"); - WITH_ENGINE_TEST_HELPER(TEST_ENGINE); // set PID settings @@ -70,9 +68,9 @@ TEST(idle, timingPid) { engineConfiguration->idleTimingPidWorkZone = 100; engineConfiguration->idlePidFalloffDeltaRpm = 30; - // setup target rpm curve (we need only 1 value when CLT sensor is disabled) + // setup target rpm curve const int idleRpmTarget = 700; - engineConfiguration->cltIdleRpm[0] = idleRpmTarget; + setArrayValues(engineConfiguration->cltIdleRpm, idleRpmTarget); // setup other settings engineConfiguration->idleTimingPid = pidS; diff --git a/unit_tests/tests/test_startOfCrankingPrimingPulse.cpp b/unit_tests/tests/test_startOfCrankingPrimingPulse.cpp index 52a9468773..a13a96d6e4 100644 --- a/unit_tests/tests/test_startOfCrankingPrimingPulse.cpp +++ b/unit_tests/tests/test_startOfCrankingPrimingPulse.cpp @@ -31,8 +31,6 @@ TEST(engine, testPlainCrankingWithoutAdvancedFeatures) { TEST(engine, testStartOfCrankingPrimingPulse) { - printf("*************************************************** testStartOfCrankingPrimingPulse\r\n"); - WITH_ENGINE_TEST_HELPER(TEST_ENGINE); engineConfiguration->startOfCrankingPrimingPulse = 4; @@ -43,8 +41,8 @@ TEST(engine, testStartOfCrankingPrimingPulse) { ASSERT_NEAR( 70, engine->sensors.clt, EPS4D) << "CLT#1"; // we need below freezing temperature to get prime fuel - // todo: less cruel CLT value assignment which would survive 'updateSlowSensors' engine->sensors.clt = -10; + Sensor::setMockValue(SensorType::Clt, -10); // prod code invokes this on ECU start, here we have to mimic this behavior startPrimeInjectionPulse(PASS_ENGINE_PARAMETER_SIGNATURE);