Line data Source code
1 : 2 : #include "pch.h" 3 : 4 : #include "dfco.h" 5 : 6 483 : bool DfcoController::getState() const { 7 483 : if (!engineConfiguration->coastingFuelCutEnabled) { 8 466 : return false; 9 : } 10 : 11 17 : const auto tps = Sensor::get(SensorType::DriverThrottleIntent); 12 17 : const auto clt = Sensor::get(SensorType::Clt); 13 17 : const auto map = Sensor::get(SensorType::Map); 14 : 15 : // If some sensor is broken, inhibit DFCO 16 17 : if (!tps || !clt || !map) { 17 0 : return false; 18 : } 19 17 : if (engine->engineState.lua.disableDecelerationFuelCutOff) { 20 : // Lua might have reasons to disable 21 0 : return false; 22 : } 23 : 24 17 : float rpm = Sensor::getOrZero(SensorType::Rpm); 25 17 : float vss = Sensor::getOrZero(SensorType::VehicleSpeed); 26 : 27 17 : bool mapActivate = map.Value < engineConfiguration->coastingFuelCutMap; 28 17 : bool tpsActivate = tps.Value < engineConfiguration->coastingFuelCutTps; 29 17 : bool cltActivate = clt.Value > engineConfiguration->coastingFuelCutClt; 30 : // True if throttle, MAP, and CLT are all acceptable for DFCO to occur 31 17 : bool dfcoAllowed = mapActivate && tpsActivate && cltActivate; 32 : 33 17 : bool rpmActivate = (rpm > engineConfiguration->coastingFuelCutRpmHigh); 34 17 : bool rpmDeactivate = (rpm < engineConfiguration->coastingFuelCutRpmLow); 35 : 36 : // greater than or equal so that it works if both config params are set to 0 37 17 : bool vssActivate = (vss >= engineConfiguration->coastingFuelCutVssHigh); 38 17 : bool vssDeactivate = (vss < engineConfiguration->coastingFuelCutVssLow); 39 : 40 : // RPM is high enough, VSS high enough, and DFCO allowed 41 17 : if (dfcoAllowed && rpmActivate && vssActivate) { 42 7 : return true; 43 : } 44 : 45 : // RPM too low, VSS too low, or DFCO not allowed 46 10 : if (!dfcoAllowed || rpmDeactivate || vssDeactivate) { 47 6 : return false; 48 : } 49 : 50 : // No conditions hit, no change to state (provides hysteresis) 51 4 : return m_isDfco; 52 : } 53 : 54 483 : void DfcoController::update() { 55 : // Run state machine 56 483 : bool newState = getState(); 57 : 58 : // If fuel is cut, reset the timer 59 483 : if (newState) { 60 8 : m_timeSinceCut.reset(); 61 : } else { 62 : // If fuel is not cut, reset the not-cut timer 63 475 : m_timeSinceNoCut.reset(); 64 : } 65 : 66 483 : m_isDfco = newState; 67 483 : } 68 : 69 488 : bool DfcoController::cutFuel() const { 70 488 : float cutDelay = engineConfiguration->dfcoDelay; 71 : 72 : // 0 delay means cut immediately, aka timer has always expired 73 488 : bool hasBeenDelay = (cutDelay == 0) || m_timeSinceNoCut.hasElapsedSec(cutDelay); 74 : 75 488 : return m_isDfco && hasBeenDelay; 76 : } 77 : 78 1 : float DfcoController::getTimeSinceCut() const { 79 1 : return m_timeSinceCut.getElapsedSeconds(); 80 : }