diff --git a/firmware/controllers/actuators/electronic_throttle.cpp b/firmware/controllers/actuators/electronic_throttle.cpp index 4dad7da054..98b3582ee5 100644 --- a/firmware/controllers/actuators/electronic_throttle.cpp +++ b/firmware/controllers/actuators/electronic_throttle.cpp @@ -222,29 +222,59 @@ expected EtbController::getClosedLoopAutotune(percent_t actualThrottl // Publish to TS state #if EFI_TUNER_STUDIO + // Amplitude of input (duty cycle %) + float b = 2 * autotuneAmplitude; + + // Ultimate gain per A-H relay tuning rule + float ku = 4 * b / (3.14159f * m_a); + + // The multipliers below are somewhere near the "no overshoot" + // and "some overshoot" flavors of the Ziegler-Nichols method + // Kp + float kp = 0.35f * ku; + float ki = 0.25f * ku / m_tu; + float kd = 0.08f * ku * m_tu; + + // Every 5 cycles (of the throttle), cycle to the next value + if (m_autotuneCounter == 5) { + m_autotuneCounter = 0; + m_autotuneCurrentParam++; + + if (m_autotuneCurrentParam >= 3) { + m_autotuneCurrentParam = 0; + } + } + + m_autotuneCounter++; + + // Multiplex 3 signals on to the {mode, value} format + tsOutputChannels.calibrationMode = static_cast(m_autotuneCurrentParam + 3); + + switch (m_autotuneCurrentParam) { + case 0: + tsOutputChannels.calibrationValue = kp; + break; + case 1: + tsOutputChannels.calibrationValue = ki; + break; + case 2: + tsOutputChannels.calibrationValue = kd; + break; + } + + // Also output to debug channels if configured if (engineConfiguration->debugMode == DBG_ETB_AUTOTUNE) { // a - amplitude of output (TPS %) - tsOutputChannels.debugFloatField1 = m_a; - float b = 2 * autotuneAmplitude; // b - amplitude of input (Duty cycle %) tsOutputChannels.debugFloatField2 = b; // Tu - oscillation period (seconds) tsOutputChannels.debugFloatField3 = m_tu; - // Ultimate gain per A-H relay tuning rule - // Ku - float ku = 4 * b / (3.14159f * m_a); tsOutputChannels.debugFloatField4 = ku; - - // The multipliers below are somewhere near the "no overshoot" - // and "some overshoot" flavors of the Ziegler-Nichols method - // Kp - tsOutputChannels.debugFloatField5 = 0.35f * ku; - // Ki - tsOutputChannels.debugFloatField6 = 0.25f * ku / m_tu; - // Kd - tsOutputChannels.debugFloatField7 = 0.08f * ku * m_tu; + tsOutputChannels.debugFloatField5 = kp; + tsOutputChannels.debugFloatField6 = ki; + tsOutputChannels.debugFloatField7 = kd; } #endif } diff --git a/firmware/controllers/actuators/electronic_throttle.h b/firmware/controllers/actuators/electronic_throttle.h index 075cc5e40b..5c120aac1e 100644 --- a/firmware/controllers/actuators/electronic_throttle.h +++ b/firmware/controllers/actuators/electronic_throttle.h @@ -88,8 +88,14 @@ private: efitick_t m_cycleStartTime = 0; float m_minCycleTps = 0; float m_maxCycleTps = 0; - float m_a = 0; - float m_tu = 0; + // Autotune measured parameters: gain and ultimate period + // These are set to correct order of magnitude starting points + // so we converge more quickly on the correct values + float m_a = 8; + float m_tu = 0.1f; + + uint8_t m_autotuneCounter = 0; + uint8_t m_autotuneCurrentParam = 0; }; void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE); diff --git a/firmware/controllers/bench_test.cpp b/firmware/controllers/bench_test.cpp index 3b926ae3fb..e82d195225 100644 --- a/firmware/controllers/bench_test.cpp +++ b/firmware/controllers/bench_test.cpp @@ -259,9 +259,6 @@ static void handleCommandX14(uint16_t index) { case 0xB: starterRelayBench(); return; - case 0xC: - engine->etbAutoTune = true; - return; case 0xD: engine->directSelfStimulation = true; return; @@ -269,6 +266,12 @@ static void handleCommandX14(uint16_t index) { case 0xE: etbAutocal(0); return; + case 0xC: + engine->etbAutoTune = true; + return; + case 0x10: + engine->etbAutoTune = false; + return; #endif case 0xF: engine->directSelfStimulation = false; diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 0cfb60a0b5..f243ea3260 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -414,6 +414,10 @@ fileVersion = { @@TS_FILE_VERSION@@ } maintainConstantValue = tpsMax, { (calibrationMode == 1 ) ? calibrationValue : tpsMax } maintainConstantValue = tpsMin, { (calibrationMode == 2 ) ? calibrationValue : tpsMin } + maintainConstantValue = etb_pFactor, { (calibrationMode == 3 ) ? calibrationValue : etb_pFactor } + maintainConstantValue = etb_iFactor, { (calibrationMode == 4 ) ? calibrationValue : etb_iFactor } + maintainConstantValue = etb_dFactor, { (calibrationMode == 5 ) ? calibrationValue : etb_dFactor } + requiresPowerCycle = warningLedPin requiresPowerCycle = runningLedPin requiresPowerCycle = binarySerialTxPin @@ -1488,7 +1492,6 @@ cmd_test_inj14 = "w\x00\x13\x00\x0e" cmd_test_inj15 = "w\x00\x13\x00\x0f" cmd_test_inj16 = "w\x00\x13\x00\x10" -; cmd_test_fuel_pump = "w\x00\x14\x00\x01" cmd_calibrate_tps_1_closed = "w\x00\x14\x00\x02" cmd_calibrate_tps_1_wot = "w\x00\x14\x00\x03" @@ -1504,6 +1507,7 @@ cmd_etb_autotune = "w\x00\x14\x00\x0C" cmd_enable_self_stim = "w\x00\x14\x00\x0D" cmb_etb_auto_calibrate = "w\x00\x14\x00\x0E" cmd_disable_self_stim = "w\x00\x14\x00\x0F" +cmd_etb_autotune_stop = "w\x00\x14\x00\x10" cmd_test_radiator_fan = "w\x00\x15\x00\x01" cmd_test_check_engine_light = "w\x00\x16\x00\x01" @@ -2819,11 +2823,14 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" panel = hbridgeHardware, { throttlePedalPositionAdcChannel != 16 || useStepperIdle && useHbridges } dialog = etbAutotune, "PID Autotune" - field = "!Set debug mode below to 'ETB Autotune' to show results" - field = "Debug mode", debugMode - commandButton = "ETB PID Autotune", cmd_etb_autotune + commandButton = "Start ETB PID Autotune", cmd_etb_autotune + commandButton = "Stop ETB PID Autotune", cmd_etb_autotune_stop + commandButton = "Auto Calibrate TPS", cmb_etb_auto_calibrate + field = "!Set debug mode below to 'ETB Autotune' to show more detail" + field = "Debug mode", debugMode + dialog = etbDialogRight panel = etbIdleDialog panel = etbPidDialog