refactor decel fuel cut (#3830)
* refactor dfco * s * output channel logs dfco * slightly cheeky comment
This commit is contained in:
parent
304b45e039
commit
717d931e78
|
@ -287,6 +287,7 @@ uint16_t rpmAcceleration;dRPM;"RPM/s",1, 0, 0, 0, 0
|
|||
bit launchIsLaunchCondition;
|
||||
bit launchCombinedConditions
|
||||
bit launchActivatePinState
|
||||
bit dfcoActive
|
||||
|
||||
uint8_t TEMPLOG_MAP_AT_CYCLE_COUNT;;"", 1, 0, -10000, 10000, 3
|
||||
uint8_t boostControllerOutput;;"", 1, 0, -10000, 10000, 0
|
||||
|
|
|
@ -661,6 +661,7 @@ static void updateFlags() {
|
|||
engine->outputChannels.isIgnitionEnabledIndicator = engine->limpManager.allowIgnition().value;
|
||||
engine->outputChannels.isInjectionEnabledIndicator = engine->limpManager.allowInjection().value;
|
||||
engine->outputChannels.isCylinderCleanupActivated = engine->isCylinderCleanupMode;
|
||||
engine->outputChannels.dfcoActive = engine->module<DfcoController>()->cutFuel();
|
||||
|
||||
#if EFI_LAUNCH_CONTROL
|
||||
engine->outputChannels.launchTriggered = engine->launchController.isLaunchCondition;
|
||||
|
|
|
@ -22,6 +22,7 @@ CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/advance_map.cpp \
|
|||
$(PROJECT_DIR)/controllers/algo/airmass/speed_density_base.cpp \
|
||||
$(PROJECT_DIR)/controllers/algo/fuel/fuel_computer.cpp \
|
||||
$(PROJECT_DIR)/controllers/algo/fuel/injector_model.cpp \
|
||||
$(PROJECT_DIR)/controllers/algo/fuel/dfco.cpp \
|
||||
$(PROJECT_DIR)/controllers/algo/nmea.cpp \
|
||||
$(PROJECT_DIR)/controllers/algo/defaults/default_base_engine.cpp \
|
||||
$(PROJECT_DIR)/controllers/algo/defaults/default_cranking.cpp \
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "boost_control.h"
|
||||
#include "ignition_controller.h"
|
||||
#include "alternator_controller.h"
|
||||
#include "dfco.h"
|
||||
|
||||
#ifndef EFI_UNIT_TEST
|
||||
#error EFI_UNIT_TEST must be defined!
|
||||
|
@ -182,6 +183,7 @@ public:
|
|||
IgnitionController,
|
||||
AcController,
|
||||
PrimeController,
|
||||
DfcoController,
|
||||
EngineModule // dummy placeholder so the previous entries can all have commas
|
||||
> engineModules;
|
||||
|
||||
|
|
|
@ -123,8 +123,7 @@ void EngineState::periodicFastCallback() {
|
|||
// todo: move this into slow callback, no reason for CLT corr to be here
|
||||
running.coolantTemperatureCoefficient = getCltFuelCorrection();
|
||||
|
||||
// Fuel cut-off isn't just 0 or 1, it can be tapered
|
||||
fuelCutoffCorrection = getFuelCutOffCorrection(nowNt, rpm);
|
||||
engine->module<DfcoController>()->update();
|
||||
|
||||
// post-cranking fuel enrichment.
|
||||
// for compatibility reasons, apply only if the factor is greater than unity (only allow adding fuel)
|
||||
|
|
|
@ -59,10 +59,6 @@ public:
|
|||
// Angle between firing the main (primary) spark and the secondary (trailing) spark
|
||||
angle_t trailingSparkAngle = 0;
|
||||
|
||||
// fuel-related;
|
||||
float fuelCutoffCorrection = 0;
|
||||
efitick_t coastingFuelCutStartTime = 0;
|
||||
|
||||
efitick_t timeSinceLastTChargeK;
|
||||
|
||||
float currentVe = 0;
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#include "pch.h"
|
||||
|
||||
bool DfcoController::getState() const {
|
||||
if (!engineConfiguration->coastingFuelCutEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto rpm = Sensor::getOrZero(SensorType::Rpm);
|
||||
const auto [tpsValid, tpsPos] = Sensor::get(SensorType::Tps1);
|
||||
const auto [cltValid, clt] = Sensor::get(SensorType::Clt);
|
||||
const auto [mapValid, map] = Sensor::get(SensorType::Map);
|
||||
|
||||
// If some sensor is broken, inhibit DFCO
|
||||
if (!tpsValid || !cltValid || !mapValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mapActivate = map < engineConfiguration->coastingFuelCutMap;
|
||||
bool tpsActivate = tpsPos < engineConfiguration->coastingFuelCutTps;
|
||||
bool cltActivate = clt > engineConfiguration->coastingFuelCutClt;
|
||||
// True if throttle, MAP, and CLT are all acceptable for DFCO to occur
|
||||
bool dfcoAllowed = mapActivate && tpsActivate && cltActivate;
|
||||
|
||||
bool rpmActivate = (rpm > engineConfiguration->coastingFuelCutRpmHigh);
|
||||
bool rpmDeactivate = (rpm < engineConfiguration->coastingFuelCutRpmLow);
|
||||
|
||||
// RPM is high enough, and DFCO allowed
|
||||
if (dfcoAllowed && rpmActivate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// RPM too low, or DFCO not allowed
|
||||
if (!dfcoAllowed || rpmDeactivate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No conditions hit, no change to state (provides hysteresis)
|
||||
return m_isDfco;
|
||||
}
|
||||
|
||||
void DfcoController::update() {
|
||||
// Run state machine
|
||||
m_isDfco = getState();
|
||||
}
|
||||
|
||||
bool DfcoController::cutFuel() const {
|
||||
return m_isDfco;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
// DFCO = deceleration fuel cut off, ie, save gas when your foot is off the pedal
|
||||
class DfcoController : public EngineModule {
|
||||
public:
|
||||
void update();
|
||||
|
||||
bool cutFuel() const;
|
||||
|
||||
private:
|
||||
bool getState() const;
|
||||
bool m_isDfco = false;
|
||||
};
|
|
@ -280,8 +280,10 @@ float getInjectionMass(int rpm) {
|
|||
float cycleFuelMass = getCycleFuelMass(isCranking, baseFuelMass);
|
||||
efiAssert(CUSTOM_ERR_ASSERT, !cisnan(cycleFuelMass), "NaN cycleFuelMass", 0);
|
||||
|
||||
// Fuel cut-off isn't just 0 or 1, it can be tapered
|
||||
cycleFuelMass *= engine->engineState.fuelCutoffCorrection;
|
||||
if (engine->module<DfcoController>()->cutFuel()) {
|
||||
// If decel fuel cut, zero out fuel
|
||||
cycleFuelMass = 0;
|
||||
}
|
||||
|
||||
float durationMultiplier = getInjectionModeDurationMultiplier();
|
||||
float injectionFuelMass = cycleFuelMass * durationMultiplier;
|
||||
|
@ -347,57 +349,6 @@ float getIatFuelCorrection() {
|
|||
return interpolate2d(iat, config->iatFuelCorrBins, config->iatFuelCorr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called from EngineState::periodicFastCallback to update the state.
|
||||
* @note The returned value is float, not boolean - to implement taper (smoothed correction).
|
||||
* @return Fuel duration correction for fuel cut-off control (ex. if coasting). No correction if 1.0
|
||||
*/
|
||||
float getFuelCutOffCorrection(efitick_t nowNt, int rpm) {
|
||||
// no corrections by default
|
||||
float fuelCorr = 1.0f;
|
||||
|
||||
// coasting fuel cut-off correction
|
||||
if (engineConfiguration->coastingFuelCutEnabled) {
|
||||
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;
|
||||
}
|
||||
|
||||
const auto [mapValid, map] = Sensor::get(SensorType::Map);
|
||||
if (!mapValid) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
// gather events
|
||||
bool mapDeactivate = (map >= engineConfiguration->coastingFuelCutMap);
|
||||
bool tpsDeactivate = (tpsPos >= engineConfiguration->coastingFuelCutTps);
|
||||
// If no CLT sensor (or broken), don't allow DFCO
|
||||
bool cltDeactivate = clt < (float)engineConfiguration->coastingFuelCutClt;
|
||||
bool rpmDeactivate = (rpm < engineConfiguration->coastingFuelCutRpmLow);
|
||||
bool rpmActivate = (rpm > engineConfiguration->coastingFuelCutRpmHigh);
|
||||
|
||||
// state machine (coastingFuelCutStartTime is also used as a flag)
|
||||
if (!mapDeactivate && !tpsDeactivate && !cltDeactivate && rpmActivate) {
|
||||
engine->engineState.coastingFuelCutStartTime = nowNt;
|
||||
} else if (mapDeactivate || tpsDeactivate || rpmDeactivate || cltDeactivate) {
|
||||
engine->engineState.coastingFuelCutStartTime = 0;
|
||||
}
|
||||
// enable fuelcut?
|
||||
if (engine->engineState.coastingFuelCutStartTime != 0) {
|
||||
// todo: add taper - interpolate using (nowNt - coastingFuelCutStartTime)?
|
||||
fuelCorr = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// todo: add other fuel cut-off checks here (possibly cutFuelOnHardLimit?)
|
||||
return fuelCorr;
|
||||
}
|
||||
|
||||
float getBaroCorrection() {
|
||||
if (Sensor::hasSensor(SensorType::BarometricPressure)) {
|
||||
// Default to 1atm if failed
|
||||
|
|
|
@ -22,7 +22,6 @@ angle_t getInjectionOffset(float rpm, float load);
|
|||
float getIatFuelCorrection();
|
||||
|
||||
float getCltFuelCorrection();
|
||||
float getFuelCutOffCorrection(efitick_t nowNt, int rpm);
|
||||
angle_t getCltTimingCorrection();
|
||||
float getCrankingFuel(float baseFuel);
|
||||
float getCrankingFuel3(float baseFuel, uint32_t revolutionCounterSinceStart);
|
||||
|
|
|
@ -1235,6 +1235,7 @@ gaugeCategory = DynoView
|
|||
indicator = { acState }, "AC off", "AC on", white, black, blue, white
|
||||
indicator = { isIdleClosedLoop }, "not idling", "idling", white, black, green, black
|
||||
indicator = { isIdleCoasting }, "not coasting", "coasting", white, black, green, black
|
||||
indicator = { dfcoActive }, "no decel cut", "decel cut", white, black, yellow, black
|
||||
|
||||
; error codes
|
||||
indicator = { isTpsError}, "tps", "tps error", white, black, red, black
|
||||
|
|
Loading…
Reference in New Issue