Idle with incremental PID-CIC (EFI_IDLE_INCREMENTAL_PID_CIC) (#520)

* Idle with incremental PID-CIC (EFI_IDLE_INCREMENTAL_PID_CIC)

* typo

* Remove unused targetIdleRpm from TS config
This commit is contained in:
andreika-git 2017-12-28 00:56:04 +02:00 committed by rusefi
parent 30c66f91ea
commit 784508815a
5 changed files with 45 additions and 8 deletions

View File

@ -130,6 +130,8 @@
#define EFI_IDLE_CONTROL TRUE #define EFI_IDLE_CONTROL TRUE
#define EFI_IDLE_INCREMENTAL_PID_CIC FALSE
/** /**
* Control the main power relay based on measured ignition voltage (Vbatt) * Control the main power relay based on measured ignition voltage (Vbatt)
*/ */

View File

@ -126,6 +126,8 @@
#define EFI_IDLE_CONTROL TRUE #define EFI_IDLE_CONTROL TRUE
#define EFI_IDLE_INCREMENTAL_PID_CIC FALSE
/** /**
* Control the main power relay based on measured ignition voltage (Vbatt) * Control the main power relay based on measured ignition voltage (Vbatt)
*/ */

View File

@ -45,7 +45,12 @@ EXTERN_ENGINE
static bool shouldResetPid = false; static bool shouldResetPid = false;
#if EFI_IDLE_INCREMENTAL_PID_CIC || defined(__DOXYGEN__)
// Use new PID with CIC integrator
static PidCic idlePid(&engineConfiguration->idleRpmPid);
#else
static Pid idlePid(&engineConfiguration->idleRpmPid); static Pid idlePid(&engineConfiguration->idleRpmPid);
#endif /* EFI_IDLE_INCREMENTAL_PID_CIC */
// todo: extract interface for idle valve hardware, with solenoid and stepper implementations? // todo: extract interface for idle valve hardware, with solenoid and stepper implementations?
static SimplePwm idleSolenoid; static SimplePwm idleSolenoid;
@ -59,6 +64,10 @@ static float lastCrankingIacPosition;
* that's current position with CLT and IAT corrections * that's current position with CLT and IAT corrections
*/ */
static percent_t currentIdlePosition = -100.0f; static percent_t currentIdlePosition = -100.0f;
/**
* the same as currentIdlePosition, but without adjustments (iacByTpsTaper, afterCrankingIACtaperDuration)
*/
static percent_t baseIdlePosition = currentIdlePosition;
void idleDebug(const char *msg, percent_t value) { void idleDebug(const char *msg, percent_t value) {
scheduleMsg(logger, "idle debug: %s%f", msg, value); scheduleMsg(logger, "idle debug: %s%f", msg, value);
@ -155,9 +164,10 @@ percent_t getIdlePosition(void) {
} }
static float autoIdle(float cltCorrection) { static float autoIdle(float cltCorrection) {
if (getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) > boardConfiguration->idlePidDeactivationTpsThreshold) { percent_t tpsPos = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
// just leave IAC position as is if (tpsPos > boardConfiguration->idlePidDeactivationTpsThreshold) {
return currentIdlePosition; // just leave IAC position as is (but don't return currentIdlePosition - it may already contain additionalAir)
return baseIdlePosition;
} }
// get Target RPM for Auto-PID from a separate table // get Target RPM for Auto-PID from a separate table
@ -172,6 +182,16 @@ static float autoIdle(float cltCorrection) {
percent_t newValue = idlePid.getValue(targetRpm, getRpmE(engine), engineConfiguration->idleRpmPid.period); percent_t newValue = idlePid.getValue(targetRpm, getRpmE(engine), engineConfiguration->idleRpmPid.period);
#if EFI_IDLE_INCREMENTAL_PID_CIC || defined(__DOXYGEN__)
// Treat the 'newValue' as if it contains not an actual IAC position, but an incremental delta.
// So we add this delta to the base IAC position, with a smooth taper for TPS transients.
newValue = baseIdlePosition + interpolateClamped(0.0f, newValue, boardConfiguration->idlePidDeactivationTpsThreshold, 0.0f, tpsPos);
// apply the PID limits
newValue = maxF(newValue, CONFIG(idleRpmPid.minValue));
newValue = minF(newValue, CONFIG(idleRpmPid.maxValue));
#endif /* EFI_IDLE_INCREMENTAL_PID_CIC */
return newValue; return newValue;
} }
@ -212,19 +232,28 @@ static msg_t ivThread(int param) {
undoIdleBlipIfNeeded(); undoIdleBlipIfNeeded();
float clt = engine->sensors.clt; float clt = engine->sensors.clt;
float cltCorrection = cisnan(clt) ? 1 : interpolate2d("cltT", clt, config->cltIdleCorrBins, config->cltIdleCorr, bool isRunning = engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE);
CLT_CURVE_SIZE) / PERCENT_MULT; float cltCorrection;
if (cisnan(clt))
cltCorrection = 1.0f;
// Use separate CLT correction table for cranking
else if (engineConfiguration->overrideCrankingIacSetting && !isRunning)
cltCorrection = interpolate2d("cltCrankingT", clt, config->cltCrankingCorrBins, config->cltCrankingCorr, CLT_CRANKING_CURVE_SIZE) / PERCENT_MULT;
else
cltCorrection = interpolate2d("cltT", clt, config->cltIdleCorrBins, config->cltIdleCorr, CLT_CURVE_SIZE) / PERCENT_MULT;
float iacPosition; float iacPosition;
if (timeToStopBlip != 0) { if (timeToStopBlip != 0) {
iacPosition = blipIdlePosition; iacPosition = blipIdlePosition;
} else if (!engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE)) { baseIdlePosition = iacPosition;
} else if (!isRunning) {
// during cranking it's always manual mode, PID would make no sence during cranking // during cranking it's always manual mode, PID would make no sence during cranking
iacPosition = cltCorrection * engineConfiguration->crankingIACposition; iacPosition = cltCorrection * engineConfiguration->crankingIACposition;
// save cranking position & cycles counter for taper transition // save cranking position & cycles counter for taper transition
lastCrankingIacPosition = iacPosition; lastCrankingIacPosition = iacPosition;
lastCrankingCyclesCounter = engine->rpmCalculator.getRevolutionCounterSinceStart(); lastCrankingCyclesCounter = engine->rpmCalculator.getRevolutionCounterSinceStart();
baseIdlePosition = iacPosition;
} else { } else {
if (engineConfiguration->idleMode == IM_MANUAL) { if (engineConfiguration->idleMode == IM_MANUAL) {
// let's re-apply CLT correction // let's re-apply CLT correction
@ -233,6 +262,9 @@ static msg_t ivThread(int param) {
iacPosition = autoIdle(cltCorrection); iacPosition = autoIdle(cltCorrection);
} }
// store 'base' iacPosition without adjustments
baseIdlePosition = iacPosition;
percent_t tpsPos = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE); percent_t tpsPos = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
float additionalAir = (float)engineConfiguration->iacByTpsTaper; float additionalAir = (float)engineConfiguration->iacByTpsTaper;
iacPosition += interpolateClamped(0.0f, 0.0f, boardConfiguration->idlePidDeactivationTpsThreshold, additionalAir, tpsPos); iacPosition += interpolateClamped(0.0f, 0.0f, boardConfiguration->idlePidDeactivationTpsThreshold, additionalAir, tpsPos);

View File

@ -1507,8 +1507,8 @@ cmd_stop_engine = "w\x00\x99\x00\x00"
field = "Use separate Advance Table for idle", useSeparateAdvanceForIdle field = "Use separate Advance Table for idle", useSeparateAdvanceForIdle
field = "Use separate VE Table for idle", useSeparateVeForIdle field = "Use separate VE Table for idle", useSeparateVeForIdle
field = "Cranking Idle Air", crankingIACposition field = "Cranking Idle Air", crankingIACposition
field = "# Warmup Idle multipplier is apploed to target RPM" ; field = "# Warmup Idle multipplier is apploed to target RPM"
field = "Auto target", targetIdleRpm, { idleMode == 0} ; field = "Auto target", targetIdleRpm, { idleMode == 0}
field = "idle P", idleRpmPid_pFactor, { idleMode == 0} field = "idle P", idleRpmPid_pFactor, { idleMode == 0}
field = "idle I", idleRpmPid_iFactor, { idleMode == 0} field = "idle I", idleRpmPid_iFactor, { idleMode == 0}
field = "idle D", idleRpmPid_dFactor, { idleMode == 0} field = "idle D", idleRpmPid_dFactor, { idleMode == 0}

View File

@ -56,6 +56,7 @@
#define EFI_ENGINE_CONTROL TRUE #define EFI_ENGINE_CONTROL TRUE
#define EFI_IDLE_CONTROL FALSE #define EFI_IDLE_CONTROL FALSE
#define EFI_IDLE_INCREMENTAL_PID_CIC FALSE
#define EFI_MAIN_RELAY_CONTROL FALSE #define EFI_MAIN_RELAY_CONTROL FALSE
#define EFI_HIP_9011 FALSE #define EFI_HIP_9011 FALSE
#define EFI_ELECTRONIC_THROTTLE_BODY FALSE #define EFI_ELECTRONIC_THROTTLE_BODY FALSE