rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
dfco.cpp
Go to the documentation of this file.
1// Deceleration Fuel Cut-off
2
3#include "pch.h"
4
5#include "dfco.h"
6#include "closed_loop_fuel.h"
7
10 return false;
11 }
12
13 if (checkIfTuningVeNow()) {
14 return false;
15 }
16
18 const auto clt = Sensor::get(SensorType::Clt);
19 const auto map = Sensor::get(SensorType::Map);
20
21 // If some sensor is broken, inhibit DFCO
22 if (!tps || !clt) {
23 return false;
24 }
25
26 // MAP sensor is optional, only inhibit if the sensor is present but broken
28 if (hasMap && !map) {
29 return false;
30 }
32 // Lua might have reasons to disable
33 return false;
34 }
35
38
39 bool mapActivate = !hasMap || !m_mapHysteresis.test(map.value_or(0), engineConfiguration->coastingFuelCutMap + 1, engineConfiguration->coastingFuelCutMap - 1);
40 bool tpsActivate = tps.Value < engineConfiguration->coastingFuelCutTps;
41 bool cltActivate = clt.Value > engineConfiguration->coastingFuelCutClt;
42 // True if throttle, MAP, and CLT are all acceptable for DFCO to occur
43 bool dfcoAllowed = mapActivate && tpsActivate && cltActivate;
44
45 bool rpmActivate = (rpm > engineConfiguration->coastingFuelCutRpmHigh);
46 bool rpmDeactivate = (rpm < engineConfiguration->coastingFuelCutRpmLow);
47
48 // greater than or equal so that it works if both config params are set to 0
49 bool vssActivate = (vss >= engineConfiguration->coastingFuelCutVssHigh);
50 bool vssDeactivate = (vss < engineConfiguration->coastingFuelCutVssLow);
51
52 // RPM is high enough, VSS high enough, and DFCO allowed
53 if (dfcoAllowed && rpmActivate && vssActivate) {
54 return true;
55 }
56
57 // RPM too low, VSS too low, or DFCO not allowed
58 if (!dfcoAllowed || rpmDeactivate || vssDeactivate) {
59 return false;
60 }
61
62 // No conditions hit, no change to state (provides hysteresis)
63 return m_isDfco;
64}
65
67 // Run state machine
68 bool newState = getState();
69
70 // If fuel is cut, reset the timer
71 if (newState) {
72 m_timeSinceCut.reset();
73 } else {
74 // If fuel is not cut, reset the not-cut timer
75 m_timeSinceNoCut.reset();
76 }
77
78 m_isDfco = newState;
79}
80
82 float cutDelay = engineConfiguration->dfcoDelay;
83
84 // 0 delay means cut immediately, aka timer has always expired
85 bool hasBeenDelay = (cutDelay == 0) || m_timeSinceNoCut.hasElapsedSec(cutDelay);
86
87 return m_isDfco && hasBeenDelay;
88}
89
91 return m_timeSinceCut.getElapsedSeconds();
92}
93
95 float cutTiming = clampF(0, engineConfiguration->dfcoRetardDeg, 30);
96
97 if (m_isDfco) {
98 // While cut, always retard timing
99 return cutTiming;
100 } else {
101 float timeSinceCut = m_timeSinceCut.getElapsedSeconds();
102 float rampInTime = engineConfiguration->dfcoRetardRampInTime;
103
104 if (timeSinceCut > rampInTime) {
105 // Normal operation, no retard
106 return 0;
107 } else {
108 return interpolateClamped(0, cutTiming, 0.5, 0, timeSinceCut);
109 }
110 }
111}
void update()
Definition dfco.cpp:66
float getTimeSinceCut() const
Definition dfco.cpp:90
bool m_isDfco
Definition dfco.h:24
float getTimingRetard() const
Definition dfco.cpp:94
bool cutFuel() const
Definition dfco.cpp:81
Timer m_timeSinceCut
Definition dfco.h:28
Timer m_timeSinceNoCut
Definition dfco.h:29
bool getState() const
Definition dfco.cpp:8
Hysteresis m_mapHysteresis
Definition dfco.h:26
EngineState engineState
Definition engine.h:344
bool test(float value, float rising, float falling)
Definition hysteresis.h:31
virtual bool hasSensor() const
Definition sensor.h:141
virtual SensorResult get() const =0
static float getOrZero(SensorType type)
Definition sensor.h:83
bool checkIfTuningVeNow()
float interpolateClamped(float x1, float y1, float x2, float y2, float x)
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
static CCM_OPTIONAL FunctionalSensor clt(SensorType::Clt, MS2NT(10))
@ DriverThrottleIntent