在上一篇文章中介绍了PID算法是什么,以及PID的位置式和增量式。这篇文章将解释如何在程序中实现位置式和增量式。
位置式核心算法
程序是通过公式推写出来的,所以先把PID的位置式列出来
找出需要定义的变量,为程序编写做好准备。
需要定义的变量有:u_1 , kp , ts , ti , td , e_1 , e_2 , up_1 , ui_1 , ud_1 , x , x_1 (具体含义参考程序编写)
这里需要特别注意,除了ts之外,其他一般都是浮点型
uint ts=50; // 采样周期为50
float kp,ti,td;
float e_1=0,e_2=0; // 定义e(k) 和 e(k-1)
float u_1,up_1,ui_1=0,ud_1=0; // 定义u(k),和三个分量
float x_1; // 当前检测值
float x=40; // 假定将温度控制在40°
while(1)
{
x_1=AD_convert; // 从某一个子函数获取当前检测值,这个函数可以是AD采样或者是数字滤波,甚至是标度变换的子函数
e_1=x-x_1; // 求出误差e(k)
if(e<0.01)
break; //(当温度误差控制在0.01以内时,控制结束)
up_1=kp*e_1;
ud_1=kp*td*(e_1-e_2)/ts;
ui_1=ui_1+kp*ts*e_1/ti; // 意思是上一时刻的ui_1加上这一时刻的ui_1,
// 到了下一时刻又是下一时刻的ui_1与这一时刻的ui_1的相加结果,
// 即通过滚动式的相加达到累加的目。
// 这一句是我认为整个程序中最难分析的一句,
//要真正理解如何表达位置式中e(i)累加的这一项。
u_1=up_1+ud_1+ui_1;
if(u_1>=10)
u_1=10;
if(u_1<=-10)
u_1=-10; // 控制系统的极限输出,起到一个保护系统的作用
e_2=e_1; // 这里又是一个很重要的变量滚动循环,将这一时刻的e_1变为下一时刻的e_2
}
这个程序只展示了核心算法,虽然不能直接使用,但真正在程序编写时都是按照此核心算法为框架编写的,所以掌握核心算法尤为重要。
曾在上一篇PID文章中提到位置式的缺所以陷,就是累加带来的一系列问题。而增量式消除了累加项,所以下面编写增量式的核心算法。
编写的过程与位置式几乎相同,所以将刚才的编写流程列写出来有助于增量式算法的编写。
增量式核心算法
同样先把增量式列出来
参考上面编写位置式算法的步骤照猫画虎。
uint ts=50;
float kp,ti,td;
float e_1=0,e_2=0,e_3=0; // 定义e(k) 和 e(k-1)
float u_1=0,u_2=0,u_deta=0,up_deta=0,ui_deta=0,ud_deta=0; // 定义u(k),u(k-1),u△,和三个分量
float x_1;
float x=40;
while(1)
{
x_1=AD_convert;
e_1=x-x_1;
if(e<0.01)
break;
up_deta=kp*(e_1-e_2);
ud_deta=kp*td*(e_1-2*e_2+e_3)/ts;
ui_deta=kp*ts*e_1/ti; // 此时的ui就没有了刚才位置式的累加量
u_deta=up_deta+ud_deta+ui_deta; //这里算的是u△,真正的u(k)=u△+u(k-1)
u_1=u_deta+u_2;
if(u_1>=10)
u_1=10;
if(u_1<=-10)
u_1=-10; // 控制系统的极限输出,起到一个保护系统的作用
e_3=e_2;
e_2=e_1; // 这里要注意变量循环的顺序
u_2=u_1; //还要注意不要丢失u(k)的变量循环
}
后面的注释只标注了增量式算法在编写时需要特别注意的地方。
这篇文章介绍了位置式和增量式的核心算法,下一篇文章会介绍这种标准PID算法的缺陷以及如何改进。