vss based dfco (#3845)

* vss based dfco

* fix digits while we're here

* fix some other digits for fun

* don't use custom assert

* simplify test

* less than or equal, test vss behavior

* even better than comments are tooltips
This commit is contained in:
Matthew Kennedy 2022-01-27 11:05:18 -08:00 committed by GitHub
parent 173b60344f
commit 2444090933
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 19 deletions

View File

@ -5,7 +5,6 @@ bool DfcoController::getState() const {
return false;
}
auto rpm = Sensor::getOrZero(SensorType::Rpm);
const auto [tpsValid, tpsPos] = Sensor::get(SensorType::DriverThrottleIntent);
const auto [cltValid, clt] = Sensor::get(SensorType::Clt);
const auto [mapValid, map] = Sensor::get(SensorType::Map);
@ -15,6 +14,9 @@ bool DfcoController::getState() const {
return false;
}
float rpm = Sensor::getOrZero(SensorType::Rpm);
float vss = Sensor::getOrZero(SensorType::VehicleSpeed);
bool mapActivate = map < engineConfiguration->coastingFuelCutMap;
bool tpsActivate = tpsPos < engineConfiguration->coastingFuelCutTps;
bool cltActivate = clt > engineConfiguration->coastingFuelCutClt;
@ -24,13 +26,17 @@ bool DfcoController::getState() const {
bool rpmActivate = (rpm > engineConfiguration->coastingFuelCutRpmHigh);
bool rpmDeactivate = (rpm < engineConfiguration->coastingFuelCutRpmLow);
// RPM is high enough, and DFCO allowed
if (dfcoAllowed && rpmActivate) {
// greater than or equal so that it works if both config params are set to 0
bool vssActivate = (vss >= engineConfiguration->coastingFuelCutVssHigh);
bool vssDeactivate = (vss < engineConfiguration->coastingFuelCutVssLow);
// RPM is high enough, VSS high enough, and DFCO allowed
if (dfcoAllowed && rpmActivate && vssActivate) {
return true;
}
// RPM too low, or DFCO not allowed
if (!dfcoAllowed || rpmDeactivate) {
// RPM too low, VSS too low, or DFCO not allowed
if (!dfcoAllowed || rpmDeactivate || vssDeactivate) {
return false;
}

View File

@ -1172,16 +1172,18 @@ int16_t tps2Max;Full throttle#2. tpsMax value as 10 bit ADC value. Not Voltage!\
uint8_t autoscale tpsAccelLookback;+How long to look back for TPS-based acceleration enrichment. Increasing this time will trigger enrichment for longer when a throttle position change occurs.;"sec", 0.05, 0, 0, 5, 2
uint8_t[3] unused1689;;"", 1,0,0,0,0
float tpsAccelEnrichmentThreshold;+Maximum change delta of TPS percentage over the 'length'. Actual TPS change has to be above this value in order for TPS/TPS acceleration to kick in.;"roc", 1, 0, 0, 200, 3
uint8_t coastingFuelCutVssLow;+Below this speed, disable DFCO. Use this to prevent jerkiness from fuel enable/disable in low gears.;"kph", 1, 0, 0, 255, 0
uint8_t coastingFuelCutVssHigh;+Above this speed, allow DFCO. Use this to prevent jerkiness from fuel enable/disable in low gears.;"kph", 1, 0, 0, 255, 0
uint8_t[1] unused1689;;"", 1,0,0,0,0
float tpsAccelEnrichmentThreshold;+Maximum change delta of TPS percentage over the 'length'. Actual TPS change has to be above this value in order for TPS/TPS acceleration to kick in.;"roc", 1, 0, 0, 200, 1
int engineLoadAccelLength;;"cycles", 1, 0, 1, 200, 0
uint32_t uartConsoleSerialSpeed;Band rate for primary TTL;"BPs", 1, 0, 0, 1000000, 0
float tpsDecelEnleanmentThreshold;For decel we simply multiply delta of TPS and tFor decel we do not use table?!;"roc", 1, 0, 0, 200, 3
float tpsDecelEnleanmentMultiplier;Magic multiplier, we multiply delta of TPS and get fuel squirt duration;"coeff", 1, 0, 0, 200, 3
float tpsDecelEnleanmentThreshold;For decel we simply multiply delta of TPS and tFor decel we do not use table?!;"roc", 1, 0, 0, 200, 1
float tpsDecelEnleanmentMultiplier;Magic multiplier, we multiply delta of TPS and get fuel squirt duration;"coeff", 1, 0, 0, 200, 2
float slowAdcAlpha;+ExpAverage alpha coefficient;"coeff", 1, 0, 0, 200, 3
debug_mode_e debugMode;+See http://rusefi.com/s/debugmode\n\nset debug_mode X
@ -1359,7 +1361,7 @@ float[CRANKING_ADVANCE_CURVE_SIZE] crankingAdvance ;+Optional timing advance
int16_t coastingFuelCutRpmHigh;+This sets the RPM above which fuel cut is active.;"rpm", 1, 0, 0, 5000, 0
int16_t coastingFuelCutRpmLow;+This sets the RPM below which fuel cut is deactivated, this prevents jerking or issues transitioning to idle;"rpm", 1, 0, 0, 5000, 0
int16_t coastingFuelCutTps;+Throttle position below which fuel cut is active. With an electronic throttle enabled, this checks against pedal position.;"%", 1, 0, 0, 20, 1
int16_t coastingFuelCutTps;+Throttle position below which fuel cut is active. With an electronic throttle enabled, this checks against pedal position.;"%", 1, 0, 0, 20, 0
int16_t coastingFuelCutClt;+Fuel cutoff is disabled when the engine is cold.;"C", 1, 0, -100, 100, 0
int16_t pidExtraForLowRpm;+Increases PID reaction for RPM<target by adding extra percent to PID-error;"%", 1, 0, 0, 100, 0

View File

@ -3623,8 +3623,10 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00"
dialog = coastingFuelCutControl, "Coasting Fuel Cutoff Settings"
field = "Enable Coasting Fuel Cutoff", coastingFuelCutEnabled
field = "No cut below CLT", coastingFuelCutClt, {coastingFuelCutEnabled == 1}
field = "Cut fuel above", coastingFuelCutRpmHigh, {coastingFuelCutEnabled == 1}
field = "Restore fuel below", coastingFuelCutRpmLow, {coastingFuelCutEnabled == 1}
field = "RPM cut fuel above", coastingFuelCutRpmHigh, {coastingFuelCutEnabled == 1}
field = "RPM restore fuel below", coastingFuelCutRpmLow, {coastingFuelCutEnabled == 1}
field = "Vehicle speed cut above", coastingFuelCutVssHigh, {coastingFuelCutEnabled == 1}
field = "Vehicle speed restore below", coastingFuelCutVssLow, {coastingFuelCutEnabled == 1}
field = "Cut fuel below TPS", coastingFuelCutTps, {coastingFuelCutEnabled == 1}
field = "Cut fuel below MAP", coastingFuelCutMap, {coastingFuelCutEnabled == 1}

View File

@ -50,22 +50,26 @@ TEST(fuelCut, coasting) {
// process
eth.engine.periodicFastCallback();
// Define some helpers for not-cut and cut
#define EXPECT_NORMAL() EXPECT_FLOAT_EQ(normalInjDuration, engine->injectionDuration)
#define EXPECT_CUT() EXPECT_FLOAT_EQ(0, engine->injectionDuration)
// this is normal injection mode (the throttle is opened), no fuel cut-off
assertEqualsM("inj dur#1 norm", normalInjDuration, engine->injectionDuration);
EXPECT_NORMAL();
// 'releasing' the throttle
Sensor::setMockValue(SensorType::DriverThrottleIntent, 0);
eth.engine.periodicFastCallback();
// Fuel cut-off is enabled now
assertEqualsM("inj dur#2 cut", 0.0f, engine->injectionDuration);
EXPECT_CUT();
// Now drop the CLT below threshold
Sensor::setMockValue(SensorType::Clt, engineConfiguration->coastingFuelCutClt - 1);
eth.engine.periodicFastCallback();
// Fuel cut-off should be diactivated - the engine is 'cold'
assertEqualsM("inj dur#3 clt", normalInjDuration, engine->injectionDuration);
EXPECT_NORMAL();
// restore CLT
Sensor::setMockValue(SensorType::Clt, hotClt);
@ -74,27 +78,56 @@ TEST(fuelCut, coasting) {
eth.engine.periodicFastCallback();
// Fuel cut-off is enabled - nothing should change
assertEqualsM("inj dur#4 mid", normalInjDuration, engine->injectionDuration);
EXPECT_NORMAL();
// Now drop RPM just below RpmLow threshold
Sensor::setMockValue(SensorType::Rpm, engineConfiguration->coastingFuelCutRpmLow - 1);
eth.engine.periodicFastCallback();
// Fuel cut-off is now disabled (the engine is idling)
assertEqualsM("inj dur#5 idle", normalInjDuration, engine->injectionDuration);
EXPECT_NORMAL();
// Now change RPM just below RpmHigh threshold
Sensor::setMockValue(SensorType::Rpm, engineConfiguration->coastingFuelCutRpmHigh - 1);
eth.engine.periodicFastCallback();
// Fuel cut-off is still disabled
assertEqualsM("inj dur#6 mid", normalInjDuration, engine->injectionDuration);
EXPECT_NORMAL();
// Now set RPM just above RpmHigh threshold
Sensor::setMockValue(SensorType::Rpm, engineConfiguration->coastingFuelCutRpmHigh + 1);
eth.engine.periodicFastCallback();
// Fuel cut-off is active again!
assertEqualsM("inj dur#7 cut", 0.0f, engine->injectionDuration);
EXPECT_CUT();
// Configure vehicle speed thresholds
engineConfiguration->coastingFuelCutVssHigh = 50;
engineConfiguration->coastingFuelCutVssLow = 40;
// High speed, should still be cut.
Sensor::setMockValue(SensorType::VehicleSpeed, 55);
eth.engine.periodicFastCallback();
EXPECT_CUT();
// Between thresholds, still cut.
Sensor::setMockValue(SensorType::VehicleSpeed, 45);
eth.engine.periodicFastCallback();
EXPECT_CUT();
// Below lower threshold, normal fuel resumes
Sensor::setMockValue(SensorType::VehicleSpeed, 35);
eth.engine.periodicFastCallback();
EXPECT_NORMAL();
// Between thresholds, still normal.
Sensor::setMockValue(SensorType::VehicleSpeed, 45);
eth.engine.periodicFastCallback();
EXPECT_NORMAL();
// Back above upper, cut again.
Sensor::setMockValue(SensorType::VehicleSpeed, 55);
eth.engine.periodicFastCallback();
EXPECT_CUT();
}