迁移最新的压力调节算法

This commit is contained in:
2026-08-25 11:05:13 +08:00
parent b3b8a40f77
commit c2ecabffc9
2 changed files with 258 additions and 56 deletions
+240 -48
View File
@@ -745,6 +745,38 @@ float PID_realize(float speed, float act){
} }
#endif #endif
float PID_realize2(float speed, float act){
pid.Kp = 0.08f;
pid.Ki = 0.003f; // 0.015 * (100ms/500ms) = 0.003,防积分饱和
pid.Kd = 0.0f;
pid.SetSpeed = speed;
pid.ActualSpeed = act;
pid.err = pid.SetSpeed - pid.ActualSpeed;
// 增量式PID差分公式:Δu = Kp*(e[k]-e[k-1]) + Ki*e[k] + Kd*(e[k]-2*e[k-1]+e[k-2])
// e[k-2] 用 voltage 字段暂存
float delta_u = pid.Kp * (pid.err - pid.err_last)
+ pid.Ki * pid.err
+ pid.Kd * (pid.err - 2.0f * pid.err_last + pid.voltage);
// 自适应步长:误差大时快速逼近,误差小时精细调节
float absErr = (pid.err < 0) ? -pid.err : pid.err;
float maxStep, minStep;
if(absErr > 50.0f) {
maxStep = 6.0f; minStep = -10.0f; // 大误差:快速逼近
} else if(absErr > 20.0f) {
maxStep = 3.0f; minStep = -5.0f; // 中误差:适中
} else {
maxStep = 1.5f; minStep = -2.5f; // 小误差:精细调节
}
if(delta_u > maxStep) delta_u = maxStep;
if(delta_u < minStep) delta_u = minStep;
pid.voltage = pid.err_last; // 暂存 e[k-2]
pid.err_last = pid.err;
return delta_u;
}
#if 0 #if 0
struct _pid{ struct _pid{
float SetSpeed; //定义设定值 float SetSpeed; //定义设定值
@@ -783,69 +815,186 @@ float PID_realize(float speed, float act){
void InkJetPrinter::pressureAdj(int type) void InkJetPrinter::pressureAdj(int type)
{ {
//float u, actual; if(sysPara->status.gearPumpRunStopFlag || sysPara->status.flagOfSpeedAlarm)
signed short delta_u; {
signed short old = (signed short)sysPara->para.gearPumpValue; sysPara->para.gearPumpValue = 0;
static unsigned int oldPressure = 0; u = 0.0f;
static qint32 printOut = 0; m_rampDone = false;
if(printOut++%2 !=0) { m_adjSkip = 0;
m_lastAvgPressure = 0;
m_bufValidCount = 0;
for(int i = 0; i < 20; i++) m_pressureBuf[i] = 0;
m_bufIdx = 0;
sysPara->devOp->WriteMoterPump();
return; return;
} }
int oldTargetPresuure = sysPara->para.pressure; if(!sysPara->para.gearPumpEnable)
if(type == 1){
sysPara->para.pressure = sysPara->para.pressure*1.2;
}
if(!sysPara->status.gearPumpRunStopFlag)
{ {
if(u > 0 || ((sysPara->para.pressure - sysPara->status.PRESSURE) > 0) ) // 非齿轮泵模式:沿用原有位置式PID
{ if(u > 0 || ((sysPara->para.pressure - sysPara->status.PRESSURE) > 0))
u=PID_realize((float)sysPara->para.pressure,(float)sysPara->status.PRESSURE); u = PID_realize((float)sysPara->para.pressure, (float)sysPara->status.PRESSURE);
sysPara->para.gearPumpValue = (u > 0) ? (unsigned short)u : 0;
if(sysPara->para.gearPumpValue > 800)
sysPara->para.gearPumpValue = 800;
sysPara->devOp->WriteMoterPump();
return;
} }
//回收泵模式限速
int maxValue = sysPara->para.flagOfReclaimPumEnable ? 420 : 800;
if(maxValue < 60) maxValue = 60;
int maxSpeed = (int)sysPara->para.gearPumpSpeedAlarm;
int actual = sysPara->status.PRESSURE;
int target = (int)sysPara->para.pressure;
int cur;
//每次进入都更新滑动平均缓冲
m_pressureBuf[m_bufIdx] = actual;
m_bufIdx = (m_bufIdx + 1) % 20;
if(m_bufValidCount < 20) m_bufValidCount++; // 累积有效点数
// 优化:缓冲区未满时只对有效数据求平均,避免0值拉低平均值
int avgPressure = 0;
for(int i = 0; i < m_bufValidCount; i++) {
avgPressure += m_pressureBuf[i];
} }
//u=PID_realize(350.0,(float)sysPara->status.PRESSURE); avgPressure /= m_bufValidCount;
if(u > 0)
//硬保护:压力超过目标+50,立即强制减速,优先级最高
if(actual > target + 50)
{ {
sysPara->para.gearPumpValue = (unsigned short)u; float overErr = (float)(actual - (target + 50));
float delta = -0.1f * overErr;
if(delta < -15.0f) delta = -15.0f;
u += delta;
if(u < 60.0f) u = 60.0f;
if(u > (float)maxValue) u = (float)maxValue;
m_lastAvgPressure = actual;
sysPara->para.gearPumpValue = (unsigned short)(int)u;
sysPara->devOp->WriteMoterPump();
return;
}
// 软启动:自适应步长,每 800ms 一次
// 自检期间也走此逻辑,自检完成后重置重新收敛
// 软启动阶段不做压力稳定检测,优先快速收敛
if(!m_rampDone)
{
if(++m_adjSkip < 8)
{
sysPara->para.gearPumpValue = (unsigned short)(int)u;
sysPara->devOp->WriteMoterPump();
return;
}
m_adjSkip = 0;
int err = target - actual;
if(err < 0)
{
// 超压:小步减速
u -= 1.0f;
} }
else else
{ {
sysPara->para.gearPumpValue = 0; // 自适应步长:差得远步子大,差得近步子小
float step;
if (err > 200) step = 5.0f;
else if(err > 100) step = 3.0f;
else if(err > 50) step = 2.0f;
else step = 1.0f;
u += step;
} }
if(sysPara->para.gearPumpValue>800) { if(u < 60.0f) u = 60.0f;
sysPara->para.gearPumpValue = 800; if(u > (float)maxValue) u = (float)maxValue;
}
/*********************改回收泵后压力调整*********************************/
if(sysPara->para.gearPumpValue && sysPara->para.flagOfReclaimPumEnable){
sysPara->para.gearPumpValue = (sysPara->para.gearPumpValue + old)/2;
if(sysPara->status.selfCheckDone){
float ratio;
float ratio_c;
ratio = (float)sysPara->status.PRESSURE/sysPara->para.pressure;
if(sysPara->status.PRESSURE < oldPressure){
if((ratio > 1.02 && ratio < 1.8) ||
(ratio > 0.2 && ratio < 0.98)){
ratio_c = ratio*1.15;
sysPara->para.gearPumpValue = (int)(sysPara->para.gearPumpValue*ratio_c);
}
}
}
if(sysPara->para.gearPumpValue < 60){
sysPara->para.gearPumpValue = 75;
}
}
/************************************************************/
if(sysPara->status.gearPumpRunStopFlag) // 转速上限保护:VX4特有,防止回收泵模式下转速超标
if(sysPara->para.flagOfReclaimPumEnable &&
sysPara->status.gearPumpRunSpeed >= maxSpeed)
{ {
sysPara->para.gearPumpValue = 0; u -= 3.0f;
if(u < 60.0f) u = 60.0f;
if(u > (float)maxValue) u = (float)maxValue;
} }
if(sysPara->status.flagOfSpeedAlarm)
sysPara->para.gearPumpValue = 0; cur = (int)u;
// 进入闭环条件:压力已接近目标±30以内
if(sysPara->status.selfCheckDone && err >= -30 && err <= 30)
{
m_rampDone = true;
m_adjSkip = 0;
}
sysPara->para.gearPumpValue = (unsigned short)cur;
sysPara->devOp->WriteMoterPump(); sysPara->devOp->WriteMoterPump();
oldPressure = sysPara->status.PRESSURE; return;
sysPara->para.pressure = oldTargetPresuure; }
//闭环:使用实时压力做快速小步修正,每200ms调整一次
{
m_adjSkip++;
if(m_adjSkip < 2)
{
sysPara->para.gearPumpValue = (unsigned short)(int)u;
sysPara->devOp->WriteMoterPump();
return;
}
m_adjSkip = 0;
float err = (float)(target - actual);
float absErr = err;
if(absErr < 0.0f) absErr = -absErr;
if(absErr < 0.5f)
{
m_lastAvgPressure = actual;
sysPara->para.gearPumpValue = (unsigned short)(int)u;
sysPara->devOp->WriteMoterPump();
return;
}
int pressureChange = actual - m_lastAvgPressure;
m_lastAvgPressure = actual;
float delta_u;
if(absErr <= 5.0f &&
((err > 0.0f && pressureChange > 0) ||
(err < 0.0f && pressureChange < 0)))
{
delta_u = -0.20f * (float)pressureChange;
}
else
{
delta_u = 0.05f * err - 0.20f * (float)pressureChange;
}
float maxDelta;
if(absErr > 30.0f) maxDelta = 1.0f;
else if(absErr > 10.0f) maxDelta = 0.6f;
else maxDelta = 0.3f;
if(delta_u > maxDelta) delta_u = maxDelta;
if(delta_u < -maxDelta) delta_u = -maxDelta;
if(sysPara->para.flagOfReclaimPumEnable &&
sysPara->status.gearPumpRunSpeed >= maxSpeed)
{
if(delta_u > 0.0f) delta_u = 0.0f;
}
u += delta_u;
if(u < 60.0f) u = 60.0f;
if(u > (float)maxValue) u = (float)maxValue;
cur = (int)u;
sysPara->para.gearPumpValue = (unsigned short)cur;
sysPara->devOp->WriteMoterPump();
}
} }
void InkJetPrinter::DacAdjustStore() void InkJetPrinter::DacAdjustStore()
@@ -1163,6 +1312,20 @@ void InkJetPrinter::timerHandler(void){
ControledSwitchFlag = false; ControledSwitchFlag = false;
pulse_3s = 0; pulse_3s = 0;
} }
// 直接恢复压力控制,不走 gearPumpStartFlag 的 3s 等待
// 平滑切换,避免手动操作后自动恢复时出现压力突变
if(m_lastByHand && !sysPara->status.isPumpValveControledByHand)
{
ControledSwitchFlag = true;
u = (float)sysPara->para.gearPumpValue; // 同步当前转速,避免突变
m_rampDone = false; // 重新软启动,适应切换后的压力状态
m_adjSkip = 0;
m_lastAvgPressure = 0;
m_bufValidCount = 0;
for(int i = 0; i < 20; i++) m_pressureBuf[i] = 0;
m_bufIdx = 0;
}
m_lastByHand = sysPara->status.isPumpValveControledByHand;
if(!(sysPara->status.statWarn & WARN_STATUS_INK_SWINT)){//墨线开关,压力抖动 if(!(sysPara->status.statWarn & WARN_STATUS_INK_SWINT)){//墨线开关,压力抖动
InkSwintFlag = true; InkSwintFlag = true;
} }
@@ -1530,11 +1693,19 @@ void InkJetPrinter::timerHandler(void){
if(sysPara->status.selfCheckCnt >= MAX_SELF_CHECK_CNT) if(sysPara->status.selfCheckCnt >= MAX_SELF_CHECK_CNT)
{ {
sysPara->status.selfCheckDone = 1; sysPara->status.selfCheckDone = 1;
// 自检完成平滑进入闭环,不强制跳转造成扰动
m_rampDone = true;
m_adjSkip = 0;
// 同步 gearPumpValue 与 u,防止两者不一致
sysPara->para.gearPumpValue = (unsigned short)u;
LogInfo::setRunStatusText(tr("自检完成!!!")); LogInfo::setRunStatusText(tr("自检完成!!!"));
ui->tabMainWindow->setRunStatus(tr("自检完成!!!")); ui->tabMainWindow->setRunStatus(tr("自检完成!!!"));
qDebug()<<"自检完成!!!"; qDebug()<<"自检完成!!!";
ui->tabPrintSetting->PrintSettingLog(); ui->tabPrintSetting->PrintSettingLog();
ui->tabMainWindow->enableReclaimCtrlButton(true); ui->tabMainWindow->enableReclaimCtrlButton(true);
// 先让软件更新泵/阀的期望状态
autoControlValvePump();
sysPara->devOp->mainInkCtrl(); sysPara->devOp->mainInkCtrl();
sysPara->status.canRunAirPushing = true; sysPara->status.canRunAirPushing = true;
if(sysPara->para.Reciclar) if(sysPara->para.Reciclar)
@@ -1552,7 +1723,28 @@ void InkJetPrinter::timerHandler(void){
if (!sysPara->status.airPushing || ui->tabMainWindow->m_2sFlag) { if (!sysPara->status.airPushing || ui->tabMainWindow->m_2sFlag) {
autoControlValvePump(); autoControlValvePump();
} }
if(sysPara->para.gearPumpEnable && !sysPara->status.isPumpValveControledByHand && ControledSwitchFlag) { // 检测回收泵模式切换,切换时重置泄漏保护学习状态和软启动状态
if(m_lastReclaimMode != sysPara->para.flagOfReclaimPumEnable)
{
m_lastReclaimMode = sysPara->para.flagOfReclaimPumEnable;
gearPumpRunNormalFlag = false; // 泄漏保护重新学习
gearPumpRunNormalValue = 0.0f;
// 仅在压力偏离目标较大时才重置软启动
// 避免模式抖动导致反复重新爬坡
int err = (int)sysPara->para.pressure - sysPara->status.PRESSURE;
if(err < -100 || err > 100) {
m_rampDone = false; // 误差大时重新软启动
m_adjSkip = 0;
m_lastAvgPressure = 0;
m_bufValidCount = 0;
for(int i = 0; i < 20; i++) m_pressureBuf[i] = 0;
m_bufIdx = 0;
}
// 否则保持当前控制状态,只更新maxValue限制
}
// 压力调节改为100ms调用一次
if(pulse_100ms && sysPara->para.gearPumpEnable && !sysPara->status.isPumpValveControledByHand && ControledSwitchFlag) {
pressureAdj(0); pressureAdj(0);
} }
} }
+10
View File
@@ -132,6 +132,16 @@ private:
bool pushButtonStartFlag; bool pushButtonStartFlag;
unsigned char rWarnViscoReady; unsigned char rWarnViscoReady;
//压力控制相关状态变量
bool m_rampDone = false; // 软启动完成标志
int m_adjSkip = 0; // 节拍计数(闭环500ms周期)
int m_lastAvgPressure = 0; // 上次平均压力(微分项用)
int m_pressureBuf[20] = {}; // 压力滑动平均缓冲(20点=2s)
int m_bufIdx = 0; // 滑动平均写入索引
int m_bufValidCount = 0; // 缓冲区有效数据点数(0~20)
bool m_lastReclaimMode = false; // 上次 flagOfReclaimPumEnable 状态
bool m_lastByHand = false; // 上次 isPumpValveControledByHand 状态
}; };
#endif // INKJETPRINTER_H #endif // INKJETPRINTER_H