本帖最后由 gongzq666 于 2018-7-2 12:41 编辑
所谓的pid分别是三个英文单词的第一个字母:比例(P:proportional),积分(I:integral),微分(D:derivative)。
| | | | | file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.gif | | | | file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image003.gif |
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image020.gif
Kd为微分调节的系数,其主要作用就是对整个系统的调节起到抑制的作用。当将微分的这一部分公式进行离散化的时候(Kd*(e(k)-e(k-1)/T))就可以发现,这部分是在当前时间K的偏差与上一周期的偏差上进行求导(斜率),当斜率过大的时候就可以估测出在下一周期K+1上的偏差值,这个就是所谓的提前预测的味道,从而就可以在偏差(e(k))变化较快的时候起到抑制作用。
接下来讲解关于pid算法的具体的实现方法(c语言):
最简单的实现方法,并没有联系在工作过程中的实际情况:
#include<stdio.h>
struct PID
{
float ek;//偏差
float last_ek;//上一次偏差
float integral;//积分项
float y;//控制量
float actual_speed;//实际速度
float Kp,Ki,Kd;//比例、积分、微分,三项的系数
}pid;
voidinit_pid()//pid运算过程中各项参数初始化
{
pid.actual_speed =0.0;
pid.ek =0.0;
pid.last_ek =0.0;
pid.integral =0.0;
pid.y =0.0;
pid.Kp =0.2; //Ki的系数一般设置的比较小,实际应用中主要就是调整这三项的参
pid.Ki =0.02; //数,先调试Kp,使之达到快要震荡之前,然后Kp*0.8左右再调整Ki,
pid.Kd =0.2; //是系统达到稳定状态,kd最后可调可不调,根据实际情况而定。
}
floatcompute_pid(float speed)//进行pid算法运算
{
pid.ek=speed-pid.actual_speed ;//得到偏差
pid.integral +=pid.ek;//得到积分
pid.y =pid.Kp *pid.ek +pid.Ki*pid.integral +pid.Kd *(pid.ek -pid.last_ek );//位置型pid进行运算,得到控制量
pid.actual_speed =pid.y ;//将运算得到的控制量赋值给实际速度,一遍下一次进入该函数的时候能够进行相减得到偏差
pid.last_ek =pid.ek ;//相同道理,这样就能运算微分部分
return pid.y ;
}
int main()
{
int i=0;
init_pid();
while(i++<1000)printf("%f\n",compute_pid(200));
}
通过这个完整的程序就可以知道,我取前一千次的运算值,运算值是逐渐逼近我想要系统达到的要求(在上述程序中就是指实际速度200)。
还有就是在这个基础上会就一些比较专家的条件来修饰这个最基础的算法,用来让这个算法在实际应用中达到更好的效果。比如积分分离的方法,就是在开始的前一段时间,偏差较大,加上积分项反而是一个累赘,会拖慢系统的反应时间,这个时候就要用到 积分分离法,在系统开始的前一段时间让它只进行比例积分,节省时间,然后在系统稳定之后再加入积分项用来消除静差。这样整体上就能节省系统调整的时间。
还有一个方法叫做 抗积分饱和的方法,以电机为例,因为电机并不具备线性的特点,可能你给4v的电压跟给5v的电压,电机到最后做达到的转数都是一样的,这个时候因为反馈回来的偏差一直都存在,关键系统已经趋于稳定,所以偏差使得积分项越来越大,这就造成积分的饱和。解决的方法就是根据电机的特性来给pid控制算法设置上下限,在控制值(y(t))达到我们设置的上限的时候就只加负的偏差,在控制值达到我们所设置的下限的时候只加这的偏差,避免进入积分饱和,这样一来,就算是当来来了一个相反的偏差也能够快速地做出响应,而当进入积分饱和的系统还要从积分饱和的过程中退出来,这要耗费很长的时间,抗积分饱和能够使能系统更加地灵活。
积分分离法与抗积分饱和法这里就不将代码列出来了(网上也有很详细的 代码以及实验过程中数据的变化情况),我希望我对pid的了解能够对在座正在学习或者想学习pid的读者能够有所帮助,能够达到抛砖引玉的作用就更好啦:-0 。希望对你们有帮助,也希望如果您是这方面的大牛,能够看出我里面内容上理解的错误,欢迎前来指正,帮助我学习,因为我也是正在学些这方面知识的小白一枚。。。
|