rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
closed_loop_fuel.cpp
Go to the documentation of this file.
1#include "pch.h"
2
3#include "closed_loop_fuel.h"
4#include "tunerstudio.h"
5
6#if EFI_ENGINE_CONTROL
7
9 switch (index) {
10 case 0: return SensorType::Lambda1;
11 case 1: return SensorType::Lambda2;
12 default: return SensorType::Invalid;
13 }
14}
15
16size_t ShortTermFuelTrim::computeStftBin(float rpm, float load, stft_s& cfg) {
17 // Low RPM -> idle
18 if (idleDeadband.lt(rpm, cfg.maxIdleRegionRpm))
19 {
20 return 0;
21 }
22
23 // Low load -> overrun
24 if (overrunDeadband.lt(load, cfg.maxOverrunLoad))
25 {
26 return 1;
27 }
28
29 // High load -> power
30 if (loadDeadband.gt(load, cfg.minPowerLoad))
31 {
32 return 2;
33 }
34
35 // Default -> normal "in the middle" cell
36 return 3;
37}
38
40 const auto& cfg = engineConfiguration->stft;
41
42 // User disable bit
44 return stftDisabledSettings;
45 }
46
47 // Don't correct if tuning seems to be happening
48 if (checkIfTuningVeNow()) {
49 return stftDisabledTuning;
50 }
51
52 // Don't correct if not running
54 return stftDisabledRPM;
55 }
56
57 // Startup delay - allow O2 sensor to warm up, etc
58 if (cfg.startupDelay > engine->fuelComputer.running.timeSinceCrankingInSecs) {
59 return stftDisabledCrankingDelay;
60 }
61
62 // Check that the engine is hot enough (and clt not failed)
64 if (!clt.Valid || clt.Value < cfg.minClt) {
65 return stftDisabledClt;
66 }
67
68 // If all was well, then we're enabled!
69 return stftEnabled;
70}
71
73 const auto& cfg = engineConfiguration->stft;
74
75 // TODO: add check for stftLearningDisabledSettings
76
77 // Pause (but don't reset) correction if the AFR is off scale.
78 // It's probably a transient and poorly tuned transient correction
79 // TODO: use getStoichiometricRatio() instead of STOICH_RATIO
80 auto afr = Sensor::getOrZero(sensor) * STOICH_RATIO;
81 if (!afr || afr < cfg.minAfr || afr > cfg.maxAfr) {
82 return stftDisabledAfrOurOfRange;
83 }
84
85 // Pause correction if DFCO was active recently
86 auto timeSinceDfco = engine->module<DfcoController>()->getTimeSinceCut();
87 if (timeSinceDfco < engineConfiguration->noFuelTrimAfterDfcoTime) {
88 return stftDisabledDFCO;
89 }
90
91 // Pause correction if Accel enrichment was active recently
92 auto timeSinceAccel = engine->module<TpsAccelEnrichment>()->getTimeSinceAcell();
93 if (timeSinceAccel < engineConfiguration->noFuelTrimAfterAccelTime) {
94 return stftDisabledTpsAccel;
95 }
96
97 // Pause if some other cut was active recently
98 auto timeSinceFuelCut = engine->module<LimpManager>()->getTimeSinceAnyCut();
99 // TODO: should duration this be configurable?
100 if (timeSinceFuelCut < 2) {
101 return stftDisabledFuelCut;
102 }
103
104 return stftEnabled;
105}
106
108 for (size_t bank = 0; bank < FT_BANK_COUNT; bank++) {
109 for (size_t bin = 0; bin < STFT_CELL_COUNT; bin++) {
110 auto& cell = banks[bank].cells[bin];
112
113 cell.configure(&stftCfg->cellCfgs[bin], sensor);
114 }
115 }
116}
117
120 if (stftCorrectionState != stftEnabled) {
121 // Learning is also prohibited
122 for (size_t bank = 0; bank < FT_BANK_COUNT; bank++) {
124 }
125 return {};
126 }
127
129
131
132 for (size_t bank = 0; bank < FT_BANK_COUNT; bank++) {
133 auto& cell = banks[bank].cells[stftCorrectionBinIdx];
134
136
138 if (stftLearningState[bank] == stftEnabled) {
139 stftInputError[bank] = cell.getLambdaError();
142 }
143
144 result.banks[bank] = cell.getAdjustment();
145 }
146
147 return result;
148}
149
151 // Do some magic math here?
152}
153
155 return false;
156}
157
158void initStft(void)
159{
161}
162
163/* TODO: move out of here */
165#if EFI_TUNER_STUDIO
166 const bool result = isTuningVeNow();
167#else
168 const bool result = false;
169#endif /* EFI_TUNER_STUDIO */
171 return result;
172}
173
174#endif // EFI_ENGINE_CONTROL
bool gt(float lhs, float rhs)
Definition deadband.h:15
bool lt(float lhs, float rhs)
Definition deadband.h:28
FuelComputer fuelComputer
Definition engine.h:139
RpmCalculator rpmCalculator
Definition engine.h:306
TunerStudioOutputChannels outputChannels
Definition engine.h:109
constexpr auto & module()
Definition engine.h:200
bool isRunning() const
virtual SensorResult get() const =0
static float getOrZero(SensorType type)
Definition sensor.h:83
FuelingBank banks[FT_BANK_COUNT]
stft_state_e getLearningState(SensorType sensor)
bool needsDelayedShutoff() override
Deadband< 2 > loadDeadband
Deadband< 2 > overrunDeadband
void init(stft_s *stftCfg)
void onSlowCallback() override
size_t computeStftBin(float rpm, float load, stft_s &cfg)
Deadband< 25 > idleDeadband
SensorType getSensorForBankIndex(size_t index)
ClosedLoopFuelResult getCorrection(float rpm, float fuelLoad)
stft_state_e getCorrectionState()
void initStft(void)
bool checkIfTuningVeNow()
bool checkIfTuningVeNow()
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
static Lps25Sensor sensor(device)
static CCM_OPTIONAL FunctionalSensor clt(SensorType::Clt, MS2NT(10))
stft_state_e
SensorType
Definition sensor_type.h:18
float banks[FT_BANK_COUNT]
ClosedLoopFuelCellImpl cells[STFT_CELL_COUNT]
scaled_channel< uint8_t, 10, 1 > deadband
scaled_channel< uint8_t, 1, 50 > maxIdleRegionRpm
stft_cell_cfg_s cellCfgs[STFT_CELL_COUNT]
bool isTuningVeNow()