引子
本文将分析《手把手教你看懂并理解Arduino PID控制库》中第三个问题:PID控制参数突变对系统的影响。
问题定义
在PID控制实际的应用过程中,可能会存在需要突然改变PID调谐参数Kp、Ki、Kd的情形,那么如果突然改变调谐参数,会有什么影响呢?首先先看一张图:
如果在系统运行的过程中,对调谐参数进行较大的改变,那么Output会产生一个突变,有点略微像“坑”。下图给出了一个改变PID参数对输出影响的量化分析:
上述现象描述了在系统进入稳态后,突然改变PID参数导致的变化,起主要引起输出较大变化的因子为I参数,由于进入稳态P参数相乘因子E变化不大,D参数同样不大,但是I参数相乘因子是关于时间的积分(可以想象如果一开始被控量与设定值相距较远,而积分表示的是带方向的面积和,所以必然存在一个方向会有较大面积,见下图),所以,会引起较大的变化。
解决方案
先看一组算式,又要感谢伟大的数学家了。
第一个等式在KI是常数的时候没问题,不是常数的时候需要评估,尽管不完全成立,但如果在稳态时E非常小,那么,也是可以接受。这似乎和经典的PID等式不一样。换个角度,经典的PID控制I项,也仅仅是为了消除静态误差而确定的,如果在这个大前提下,换一种方式消除静态误差也是可以的,仅仅是牺牲了”力度”。
代码
/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double ITerm, lastInput;
double kp, ki, kd;
int SampleTime = 1000; //1 sec
void Compute()
{
unsigned long now = millis();
int timeChange = (now - lastTime);
if(timeChange>=SampleTime)
{
/*Compute all the working error variables*/
double error = Setpoint - Input;
ITerm += (ki * error);
double dInput = (Input - lastInput);
/*Compute PID Output*/
Output = kp * error + ITerm - kd * dInput;
/*Remember some variables for next time*/
lastInput = Input;
lastTime = now;
}
}
void SetTunings(double Kp, double Ki, double Kd)
{
double SampleTimeInSec = ((double)SampleTime)/1000;
kp = Kp;
ki = Ki * SampleTimeInSec;
kd = Kd / SampleTimeInSec;
}
void SetSampleTime(int NewSampleTime)
{
if (NewSampleTime > 0)
{
double ratio = (double)NewSampleTime
/ (double)SampleTime;
ki *= ratio;
kd /= ratio;
SampleTime = (unsigned long)NewSampleTime;
}
}
变量Iterm用于完成上述算法。
结果
图示
量化结果
从图表中可以看出,尽管PID参数发生了较大的改变,但输出仍然变得连续。在上述过程中,牺牲了系统的响应的“灵敏度”增加了控制的稳定性,系统的灵敏度往往可以通过增加计算频率来改善,大幅提高采样频率可以起到较快的更新积分项的作用。
目前这种做法在温度控制中,有较好的控制效果。
NOTE:如有不足之处请告知。^.^
下一章将介绍如果在系统运行过程中,设定值突然改变对系统的影响
PS:转载请注明出处:欧阳天华