迁移最新的压力调节算法
This commit is contained in:
+238
-46
@@ -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)
|
|
||||||
{
|
{
|
||||||
|
// 非齿轮泵模式:沿用原有位置式PID
|
||||||
if(u > 0 || ((sysPara->para.pressure - sysPara->status.PRESSURE) > 0))
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user