From 495039ad247d69bb23f2677c36a8d15110958b11 Mon Sep 17 00:00:00 2001 From: Byons Date: Thu, 30 Jul 2026 14:04:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=8B=E5=8A=9B=E8=B0=83=E6=95=B4=E7=AC=AC?= =?UTF-8?q?=E4=B8=89=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InkJetPrinter.cpp | 93 +++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/InkJetPrinter.cpp b/InkJetPrinter.cpp index 783ada6..e92ed93 100644 --- a/InkJetPrinter.cpp +++ b/InkJetPrinter.cpp @@ -372,52 +372,52 @@ struct DualModePIDParams { float deadzone; // 死区:误差小于此值时不调整 }; -// 无分流管设备参数(调整后:降低增益,增加稳定性) +// 无分流管设备参数(第二次调整:更保守的参数,优先稳定性) static DualModePIDParams params_no_reclaim = { - // 快速模式:降低Kp和Kd,避免超调 - 0.06f, // fast_Kp (从0.10降到0.06) + // 快速模式:保持不变 + 0.06f, // fast_Kp 0.0f, // fast_Ki - 0.02f, // fast_Kd (从0.05降到0.02) - 8.0f, // fast_maxDelta (从10.0降到8.0) - 10, // fast_cycle (从8增加到10,即1000ms) + 0.02f, // fast_Kd + 8.0f, // fast_maxDelta + 10, // fast_cycle (1000ms) - // 精准模式:降低Ki,减缓积分速度 - 0.018f, // precision_Kp (从0.025降到0.018) - 0.005f, // precision_Ki (从0.010降到0.005) - 0.015f, // precision_Kd (从0.03降到0.015) - 2.5f, // precision_maxDelta (从3.0降到2.5) - 12, // precision_cycle (从10增加到12,即1200ms) - 150.0f, // integral_limit (从250降到150) - 10, // stable_threshold - 10, // stable_count_req + // 精准模式:大幅降低所有参数,优先稳定 + 0.010f, // precision_Kp (从0.018降到0.010,降低45%) + 0.002f, // precision_Ki (从0.005降到0.002,降低60%) + 0.005f, // precision_Kd (从0.015降到0.005,降低67%) + 1.5f, // precision_maxDelta (从2.5降到1.5) + 15, // precision_cycle (从12增加到15,即1500ms) + 100.0f, // integral_limit (从150降到100) + 8, // stable_threshold (从10降到8,更严格) + 15, // stable_count_req (从10增加到15,等待更久) - 80.0f, // switch_threshold (从50增加到80,扩大快速模式工作范围) - 15.0f, // switch_hysteresis (滞后带宽:从快速切到精准需要err<80,从精准切回快速需要err>95) - 8.0f // deadzone (死区:误差±8以内不调整) + 80.0f, // switch_threshold + 15.0f, // switch_hysteresis + 15.0f // deadzone (从8增加到15,更大的不动区) }; -// 有分流管设备参数(调整后) +// 有分流管设备参数(第二次调整) static DualModePIDParams params_with_reclaim = { // 快速模式 - 0.08f, // fast_Kp (从0.12降到0.08) + 0.08f, // fast_Kp 0.0f, // fast_Ki - 0.03f, // fast_Kd (从0.08降到0.03) - 10.0f, // fast_maxDelta (从12.0降到10.0) - 10, // fast_cycle (从8增加到10,即1000ms) + 0.03f, // fast_Kd + 10.0f, // fast_maxDelta + 10, // fast_cycle (1000ms) - // 精准模式 - 0.025f, // precision_Kp (从0.035降到0.025) - 0.008f, // precision_Ki (从0.015降到0.008) - 0.020f, // precision_Kd (从0.05降到0.020) - 3.0f, // precision_maxDelta (从4.0降到3.0) - 12, // precision_cycle (从10增加到12,即1200ms) - 180.0f, // integral_limit (从300降到180) - 15, // stable_threshold - 8, // stable_count_req + // 精准模式:大幅降低 + 0.015f, // precision_Kp (从0.025降到0.015) + 0.003f, // precision_Ki (从0.008降到0.003) + 0.008f, // precision_Kd (从0.020降到0.008) + 2.0f, // precision_maxDelta (从3.0降到2.0) + 15, // precision_cycle (1500ms) + 120.0f, // integral_limit (从180降到120) + 12, // stable_threshold (从15降到12) + 12, // stable_count_req (从8增加到12) - 80.0f, // switch_threshold (从50增加到80) + 80.0f, // switch_threshold 15.0f, // switch_hysteresis - 10.0f // deadzone (死区:误差±10以内不调整) + 18.0f // deadzone (从10增加到18) }; // PID控制器状态 @@ -658,17 +658,23 @@ void InkJetPrinter::pressureAdj() // --------------------------------------------------------------- // 双模式PID控制:根据误差大小自动切换快速/精准模式 // 快速模式:大偏差快速收敛,周期1000ms - // 精准模式:小偏差精准稳压,周期1200ms,等待压力稳定后调整 + // 精准模式:小偏差精准稳压,周期1500ms,等待压力稳定后调整 // 带死区和模式切换滞后,避免频繁调整和模式抖动 // --------------------------------------------------------------- - // 计算误差 - float error = (float)(target - actual); - float abs_error = (error < 0) ? -error : error; + // 计算误差(统一使用平均压力,避免瞬时噪声) + float error_avg = (float)(target - avgPressure); + float abs_error_avg = (error_avg < 0) ? -error_avg : error_avg; // 死区控制:误差很小时不调整,避免频繁微调 - if(abs_error < params.deadzone) + // 使用平均压力判断,与后续调整逻辑一致 + if(abs_error_avg < params.deadzone) { + // 在死区内:清零积分,避免积分累积 + pid_ctrl.integral = 0.0f; + pid_ctrl.adjust_skip = 0; + pid_ctrl.stable_count = 0; + sysPara->para.gearPumpValue = (unsigned short)(int)u; sysPara->devOp->WriteMoterPump(); return; @@ -679,12 +685,12 @@ void InkJetPrinter::pressureAdj() if(pid_ctrl.in_precision_mode) { // 当前在精准模式,需要误差大于阈值+滞后才切回快速模式 - use_precision = (abs_error <= params.switch_threshold + params.switch_hysteresis); + use_precision = (abs_error_avg <= params.switch_threshold + params.switch_hysteresis); } else { // 当前在快速模式,误差小于阈值即切到精准模式 - use_precision = (abs_error <= params.switch_threshold); + use_precision = (abs_error_avg <= params.switch_threshold); } int cycle = use_precision ? params.precision_cycle : params.fast_cycle; @@ -746,8 +752,8 @@ void InkJetPrinter::pressureAdj() pid_ctrl.stable_count = 0; pid_ctrl.in_precision_mode = false; - // 快速模式使用瞬时压力计算 - float delta_u = DualModePID_Calculate((float)target, (float)actual, params, + // 快速模式也使用平均压力,避免瞬时噪声导致过度调整 + float delta_u = DualModePID_Calculate((float)target, (float)avgPressure, params, pid_ctrl, u, 60.0f, (float)maxValue); // 转速上限软限制 @@ -765,7 +771,6 @@ void InkJetPrinter::pressureAdj() sysPara->devOp->WriteMoterPump(); } - static bool firstTime = true; extern void MySleep(unsigned int msec); extern unsigned char test_flag;