Closed Loop Idle Ignition Timing small improvements (#5635)

* After-start enrichment handling more similar to OEM and other Standalone EFI systems

* Corrections and tidying-up

* Corrected small mistake in TunerStudio definition

* Compatibility fixes

* Readability fix

* Changed to more appropriate cycles instead of seconds, bugfix for TS

* Typo fix...

* Idle Ignition Timing improvements

* Uninitialized variable for Unit Tests?

* Zero value should disable new feature

---------

Co-authored-by: pchmura4 <>
This commit is contained in:
Patryk Chmura 2023-10-24 23:43:29 +02:00 committed by GitHub
parent 6b8aaa8e30
commit 0a7cd2b08c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 22 additions and 1 deletions

View File

@ -34,7 +34,9 @@ Release template (copy/paste this for new release):
### Added
- DAC with Lua #5601
- TunerStudio cacerts fix script #5536
- TunerStudio cacerts fix script #5536
- Idle Timing Control - Soft Entry mechanism, in case of aggresive PID tuning this can help when engine enters close loop idle
- Idle Timing Control - I factor configurable now
### Fixed
- Changing idle stepper settings causes kernel panic

View File

@ -187,8 +187,19 @@ float IdleController::getIdleTimingAdjustment(int rpm, int targetRpm, Phase phas
if (phase != Phase::Idling) {
m_timingPid.reset();
return 0;
} else {
// If we are entering idle, and the PID settings are aggressive, it's good to make a soft entry upon entering closed loop
if (m_lastPhase == Phase::CrankToIdleTaper) {
m_crankTaperEndTime = engine->fuelComputer.running.timeSinceCrankingInSecs;
m_idleTimingSoftEntryEndTime = m_crankTaperEndTime + engineConfiguration->idleTimingSoftEntryTime;
}
if (engineConfiguration->idleTimingSoftEntryTime > 0.0f) {
// Use interpolation for correction taper
m_timingPid.setErrorAmplification(interpolateClamped(m_crankTaperEndTime, 0.0f, m_idleTimingSoftEntryEndTime, 1.0f, engine->fuelComputer.running.timeSinceCrankingInSecs));
}
}
// We're now in the idle mode, and RPM is inside the Timing-PID regulator work zone!
return m_timingPid.getOutput(targetRpm, rpm, FAST_CALLBACK_PERIOD_MS / 1000.0f);
}

View File

@ -95,6 +95,9 @@ private:
efitimeus_t restoreAfterPidResetTimeUs = 0;
// used by 'dashpot' (hold+decay) logic for iacByTpsTaper
efitimeus_t lastTimeRunningUs = 0;
// used by "soft" idle entry
float m_crankTaperEndTime = 0.0f;
float m_idleTimingSoftEntryEndTime = 0.0f;
// This is stored by getClosedLoop and used in case we want to "do nothing"
float m_lastAutomaticPosition = 0;

View File

@ -1355,6 +1355,7 @@ tChargeMode_e tChargeMode;
int16_t etb_iTermMax;iTerm max value;"", 1, 0, -30000, 30000, 0
pid_s idleTimingPid;See useIdleTimingPidControl
float idleTimingSoftEntryTime
int16_t etbRocExpAverageLength;By the way ETB PID runs at 500hz, length in 1/500 of second here.

View File

@ -3465,11 +3465,14 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@@@ts_command_e_TS_
field = "#Gain is in degrees advance per rpm away from target"
field = "#A good starting point is 0.1 = 10 deg per 100 rpm"
field = "Proportional gain", idleTimingPid_pFactor, {useIdleTimingPidControl == 1}
field = "Integral gain", idleTimingPid_iFactor, {useIdleTimingPidControl == 1}
field = "Derivative gain", idleTimingPid_dFactor, {useIdleTimingPidControl == 1}
field = ""
field = "Min adjustment (retard)", idleTimingPid_minValue, {useIdleTimingPidControl == 1}
field = "Max adjustment (advance)", idleTimingPid_maxValue, {useIdleTimingPidControl == 1}
field = ""
field = "Soft entry time", idleTimingSoftEntryTime, {useIdleTimingPidControl == 1}
field = ""
field = "#Use debug mode 'Timing' to view idle timing adjustment"
; Engine->Fan Settings

View File

@ -26,6 +26,7 @@ TEST(idle_v2, timingPid) {
engineConfiguration->idleTimingPid.pFactor = 0.1;
engineConfiguration->idleTimingPid.minValue = -10;
engineConfiguration->idleTimingPid.maxValue = 10;
engineConfiguration->idleTimingSoftEntryTime = 0.0f;
dut.init();
// Check that out of idle mode it doesn't do anything