迁移最新的压力调节算法
This commit is contained in:
+247
-55
@@ -745,6 +745,38 @@ float PID_realize(float speed, float act){
|
||||
}
|
||||
#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
|
||||
struct _pid{
|
||||
float SetSpeed; //定义设定值
|
||||
@@ -783,69 +815,186 @@ float PID_realize(float speed, float act){
|
||||
|
||||
void InkJetPrinter::pressureAdj(int type)
|
||||
{
|
||||
//float u, actual;
|
||||
signed short delta_u;
|
||||
signed short old = (signed short)sysPara->para.gearPumpValue;
|
||||
static unsigned int oldPressure = 0;
|
||||
static qint32 printOut = 0;
|
||||
if(printOut++%2 !=0) {
|
||||
if(sysPara->status.gearPumpRunStopFlag || sysPara->status.flagOfSpeedAlarm)
|
||||
{
|
||||
sysPara->para.gearPumpValue = 0;
|
||||
u = 0.0f;
|
||||
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;
|
||||
sysPara->devOp->WriteMoterPump();
|
||||
return;
|
||||
}
|
||||
|
||||
int oldTargetPresuure = sysPara->para.pressure;
|
||||
if(type == 1){
|
||||
sysPara->para.pressure = sysPara->para.pressure*1.2;
|
||||
}
|
||||
if(!sysPara->status.gearPumpRunStopFlag)
|
||||
if(!sysPara->para.gearPumpEnable)
|
||||
{
|
||||
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);
|
||||
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];
|
||||
}
|
||||
avgPressure /= m_bufValidCount;
|
||||
|
||||
//硬保护:压力超过目标+50,立即强制减速,优先级最高
|
||||
if(actual > target + 50)
|
||||
{
|
||||
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)
|
||||
{
|
||||
u=PID_realize((float)sysPara->para.pressure,(float)sysPara->status.PRESSURE);
|
||||
sysPara->para.gearPumpValue = (unsigned short)(int)u;
|
||||
sysPara->devOp->WriteMoterPump();
|
||||
return;
|
||||
}
|
||||
}
|
||||
//u=PID_realize(350.0,(float)sysPara->status.PRESSURE);
|
||||
if(u > 0)
|
||||
{
|
||||
sysPara->para.gearPumpValue = (unsigned short)u;
|
||||
}
|
||||
else
|
||||
{
|
||||
sysPara->para.gearPumpValue = 0;
|
||||
m_adjSkip = 0;
|
||||
|
||||
int err = target - actual;
|
||||
|
||||
if(err < 0)
|
||||
{
|
||||
// 超压:小步减速
|
||||
u -= 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 自适应步长:差得远步子大,差得近步子小
|
||||
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(u < 60.0f) u = 60.0f;
|
||||
if(u > (float)maxValue) u = (float)maxValue;
|
||||
|
||||
// 转速上限保护:VX4特有,防止回收泵模式下转速超标
|
||||
if(sysPara->para.flagOfReclaimPumEnable &&
|
||||
sysPara->status.gearPumpRunSpeed >= maxSpeed)
|
||||
{
|
||||
u -= 3.0f;
|
||||
if(u < 60.0f) u = 60.0f;
|
||||
if(u > (float)maxValue) u = (float)maxValue;
|
||||
}
|
||||
|
||||
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();
|
||||
return;
|
||||
}
|
||||
|
||||
if(sysPara->para.gearPumpValue>800) {
|
||||
sysPara->para.gearPumpValue = 800;
|
||||
}
|
||||
/*********************改回收泵后压力调整*********************************/
|
||||
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)
|
||||
//闭环:使用实时压力做快速小步修正,每200ms调整一次
|
||||
{
|
||||
sysPara->para.gearPumpValue = 0;
|
||||
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();
|
||||
}
|
||||
if(sysPara->status.flagOfSpeedAlarm)
|
||||
sysPara->para.gearPumpValue = 0;
|
||||
sysPara->devOp->WriteMoterPump();
|
||||
oldPressure = sysPara->status.PRESSURE;
|
||||
sysPara->para.pressure = oldTargetPresuure;
|
||||
}
|
||||
|
||||
void InkJetPrinter::DacAdjustStore()
|
||||
@@ -1163,6 +1312,20 @@ void InkJetPrinter::timerHandler(void){
|
||||
ControledSwitchFlag = false;
|
||||
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)){//墨线开关,压力抖动
|
||||
InkSwintFlag = true;
|
||||
}
|
||||
@@ -1530,11 +1693,19 @@ void InkJetPrinter::timerHandler(void){
|
||||
if(sysPara->status.selfCheckCnt >= MAX_SELF_CHECK_CNT)
|
||||
{
|
||||
sysPara->status.selfCheckDone = 1;
|
||||
// 自检完成平滑进入闭环,不强制跳转造成扰动
|
||||
m_rampDone = true;
|
||||
m_adjSkip = 0;
|
||||
// 同步 gearPumpValue 与 u,防止两者不一致
|
||||
sysPara->para.gearPumpValue = (unsigned short)u;
|
||||
LogInfo::setRunStatusText(tr("自检完成!!!"));
|
||||
ui->tabMainWindow->setRunStatus(tr("自检完成!!!"));
|
||||
qDebug()<<"自检完成!!!";
|
||||
ui->tabPrintSetting->PrintSettingLog();
|
||||
ui->tabMainWindow->enableReclaimCtrlButton(true);
|
||||
|
||||
// 先让软件更新泵/阀的期望状态
|
||||
autoControlValvePump();
|
||||
sysPara->devOp->mainInkCtrl();
|
||||
sysPara->status.canRunAirPushing = true;
|
||||
if(sysPara->para.Reciclar)
|
||||
@@ -1552,7 +1723,28 @@ void InkJetPrinter::timerHandler(void){
|
||||
if (!sysPara->status.airPushing || ui->tabMainWindow->m_2sFlag) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -3249,4 +3441,4 @@ void InkJetPrinter::resetPressureCnt(){
|
||||
|
||||
void InkJetPrinter::pressureAdjustForsystemseeting(){
|
||||
pressureAdj(1);
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -132,6 +132,16 @@ private:
|
||||
bool pushButtonStartFlag;
|
||||
|
||||
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