From 89338bd4f99b296bdb5c920516f4e259c3d36f73 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Thu, 12 Sep 2024 22:55:49 -0700 Subject: [PATCH] implement DFCO hysteresis #478 --- firmware/controllers/algo/fuel/dfco.cpp | 5 +++-- firmware/controllers/algo/fuel/dfco.h | 3 +++ unit_tests/tests/ignition_injection/test_fuelCut.cpp | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/firmware/controllers/algo/fuel/dfco.cpp b/firmware/controllers/algo/fuel/dfco.cpp index 13384b3135..a6176818ee 100644 --- a/firmware/controllers/algo/fuel/dfco.cpp +++ b/firmware/controllers/algo/fuel/dfco.cpp @@ -20,7 +20,8 @@ bool DfcoController::getState() const { } // MAP sensor is optional, only inhibit if the sensor is present but broken - if (Sensor::hasSensor(SensorType::Map) && !map) { + bool hasMap = Sensor::hasSensor(SensorType::Map); + if (hasMap && !map) { return false; } @@ -31,7 +32,7 @@ bool DfcoController::getState() const { interpolate2d(rpm, config->dfcoMapRpmValuesBins, config->dfcoMapRpmValues) : engineConfiguration->coastingFuelCutMap; - bool mapActivate = map.value_or(0) < mapThreshold; + bool mapActivate = !hasMap || !m_mapHysteresis.test(map.value_or(0), mapThreshold + 1, mapThreshold - 1); bool tpsActivate = tps.Value < engineConfiguration->coastingFuelCutTps; bool cltActivate = clt.Value > engineConfiguration->coastingFuelCutClt; // True if throttle, MAP, and CLT are all acceptable for DFCO to occur diff --git a/firmware/controllers/algo/fuel/dfco.h b/firmware/controllers/algo/fuel/dfco.h index 9e9765d4a0..ffc9a4e935 100644 --- a/firmware/controllers/algo/fuel/dfco.h +++ b/firmware/controllers/algo/fuel/dfco.h @@ -5,6 +5,7 @@ #pragma once #include "engine_module.h" #include "timer.h" +#include "limp_manager.h" // DFCO = deceleration fuel cut off, ie, save gas when your foot is off the pedal class DfcoController : public EngineModule { @@ -19,6 +20,8 @@ class DfcoController : public EngineModule { bool getState() const; bool m_isDfco = false; + mutable Hysteresis m_mapHysteresis; + Timer m_timeSinceCut; Timer m_timeSinceNoCut; }; diff --git a/unit_tests/tests/ignition_injection/test_fuelCut.cpp b/unit_tests/tests/ignition_injection/test_fuelCut.cpp index 9b83e3246f..8f27597d58 100644 --- a/unit_tests/tests/ignition_injection/test_fuelCut.cpp +++ b/unit_tests/tests/ignition_injection/test_fuelCut.cpp @@ -243,12 +243,12 @@ TEST(fuelCut, mapTable) { EXPECT_NORMAL(); // Drop MAP to just above the interpolated cutoff curve - Sensor::setMockValue(SensorType::Map, 41); + Sensor::setMockValue(SensorType::Map, 43); eth.engine.periodicFastCallback(); EXPECT_NORMAL(); // Drop MAP to just below the interpolated cutoff curve - Sensor::setMockValue(SensorType::Map, 39); + Sensor::setMockValue(SensorType::Map, 37); eth.engine.periodicFastCallback(); EXPECT_CUT();