一、PID 的数学模型
在工业应用中 PID 及其衍生算法是应用最广泛的算法之一,是当之无愧的万能
算法,如果能够熟练掌握 PID 算法的设计与实现过程,对于一般的研发人员来
讲,应该是足够应对一般研发问题了,而难能可贵的是,在很多控制算法当
中,PID 控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的
经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的。PID
算法的一般形式:
二、PID 的 C 语言实现
1.位置式 PID 的 C 语言实现
上边已经抽象出了位置性 PID 和增量型 PID 的数学表达式,这里重点讲解 C 语
言代码的实现过程。
第一步:定义 PID 变量结构体,代码如下:
struct t_pid{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际值
float err; //定义偏差值
float err_last; //定义上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
float voltage; //定义电压值(控制执行器的变量)
float integral; //定义积分值
}pid;
第二部:初始化变量,代码如下:
void PID_init(){
pid.SetSpeed=0.0;
pid.ActualSpeed=0.0;
pid.err=0.0;
pid.err_last=0.0;
pid.voltage=0.0;
pid.integral=0.0;
pid.Kp=0.2;
pid.Ki=0.015;
pid.Kd=0.2;
}
统一初始化变量,尤其是 Kp,Ki,Kd 三个参数,调试过程当中,对于要求的控制
效果,可以通过调节这三个量直接进行调节。
第三步:编写控制算法,代码如下:
float PID_realize(float speed){
pid.SetSpeed=speed;
pid.err=pid.SetSpeed-pid.ActualSpeed;
pid.integral+=pid.err;
pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.er
r-pid.err_last);
pid.err_last=pid.err;
pid.ActualSpeed=pid.voltage*1.0;
return pid.ActualSpeed;
}
注意:这里用了最基本的算法实现形式,没有考虑死区问题,没有设定上下
限,只是对公式的一种直接的实现,后面的介绍当中还会逐渐的对此改进。
到此为止,PID 的基本实现部分就初步完成了。下面是测试代码:
int main(){
PID_init();
int count=0;
while(count<1000)
{
float speed=PID_realize(200.0);
printf("%f\n",speed);
count++;
}
return 0;
}
2.增量型 PID 的 C 语言实现
上一节中介绍了最简单的位置型 PID 的实现手段,这一节讲解增量式 PID 的实
现方法。
#include
#include
struct t_pid{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际值
float err; //定义偏差值
float err_next; //定义上一个偏差值
float err_last; //定义最上前的偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
}pid;
void PID_init(){
pid.SetSpeed=0.0;
pid.ActualSpeed=0.0;
pid.err=0.0;
pid.err_last=0.0;
pid.err_next=0.0;
pid.Kp=0.2;
pid.Ki=0.015;
pid.Kd=0.2;
}
float PID_realize(float speed){
pid.SetSpeed=speed;
pid.err=pid.SetSpeed-pid.ActualSpeed;
float incrementSpeed=pid.Kp*(pid.err-
pid.err_next)+pid.Ki*pid.err+pid.Kd*(pid.err-
2*pid.err_next+pid.err_last);
pid.ActualSpeed+=incrementSpeed;
pid.err_last=pid.err_next;
pid.err_next=pid.err;
return pid.ActualSpeed;
}
int main(){
PID_init();
int count=0;
while(count<1000)
{
float speed=PID_realize(200.0);
printf("%f\n",speed);
count++;
}
return 0;
}
3.积分分离的 PID 控制算法
在普通 PID 控制中,引入积分环节的目的,主要是为了消除静差,提高控制精
度。但是在启动、结束或大幅度增减设定时,短时间内系统输出有很大的偏
差,会造成 PID 运算的积分积累,导致控制量超过执行机构可能允许的最大动
作范围对应极限控制量,从而引起较大的超调,甚至是震荡,这是绝对不允许
的。
为了克服这一问题,引入了积分分离的概念,其基本思路是 当被控量与设定值
偏差较大时,取消积分作用; 当被控量接近给定值时,引入积分控制,以消除
静差,提高精度。其具体实现代码如下:
pid.Kp=0.2;
pid.Ki=0.04;
pid.Kd=0.2; //初始化过程
if(abs(pid.err)>200)
{
index=0;
}else{
index=1;
pid.integral+=pid.err;
}
pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(p
id.err-pid.err_last); //算法具体实现过程
}
4.专家 PID 和模糊 PID
从前面的讲解中不难看出,PID 的控制思想非常简单,其主要问题点和难点在
于比例、积分、微分环节上的参数整定过程,对于执行器控制模型确定或者控
制模型简单的系统而言,参数的整定可以通过计算获得,对于一般精度要求不
是很高的执行器系统,可以采用拼凑的方法进行实验型的整定。
然而,在实际的控制系统中,线性系统毕竟是少数,大部分的系统属于非线性
系统,或者说是系统模型不确定的系统,如果控制精度要求较高的话,那么对
于参数的整定过程是有难度的。专家 PID 和模糊 PID 就是为满足这方面的需求
而设计的。专家算法和模糊算法都归属于智能算法的范畴,智能算法最大的优
点就是在控制模型未知的情况下,可以对模型进行控制。这里需要注意的是,
专家 PID 也好,模糊 PID 也罢,绝对不是专家系统或模糊算法与 PID 控制算法
的简单加和,他是专家系统或者模糊算法在 PID 控制器参数整定上的应用。也
就是说,智能算法是辅助 PID 进行参数整定的手段。
专家系统、模糊算法,需要参数整定就一定要有整定的依据,也就是说什么情
况下整定什么值是要有依据的,这个依据是一些逻辑的组合,只要找出其中的
逻辑组合关系来,这些依据就再明显不过了。下面先说一下专家 PID 的 C 语言
实现。正如前面所说,需要找到一些依据,还得从 PID 系数本身说起。
三、PID 算法参数整定方法
1.临界比例度法
(1)将调节器的积分时间置于最大,微分时间置零,比例度 δ 适当,平衡操
作一段时间,把系统投入自动运行。
(2)将比例度 δ 逐渐减小,得到等幅振荡过程,记下临界比例度和临界振荡
周期值。
(3)根据和值,采用经验公式,计算出调节器各个参数,即 δ、、的值。
(4)按“先 P 后 I 最后 D”的操作程序将调节器整定参数调到计算值上。若还
不够满意,可再作进一步调整。
临界振荡整定计算公式
2.衰减曲线法
在纯比例作用下,由大到小调整比例度以得到具有衰减比(4:1)的过渡过
程,记下此时的比例度及振荡周期,根据经验公式,求出相应的积分时间和微
分时间。
衰减曲线法控制器参数计算表
3.经验法
根据经验先将控制器参数放在某些数值上,直接在闭合的控制系统中通过改变
给定值以施加干扰,看输出曲线的形状,以 δ、、,对控制过程的规律为指
导,调整相应的参数进行凑试,直到合适为止。
长期的生产实践中总结出来的参数表
4.经验口诀
参数整定找最佳,从小到大顺序查。
先是比例后积分,最后再把微分加。
曲线振荡很频繁,比例度盘要放大。
曲线漂浮绕大湾,比例度盘往小扳。
曲线偏离回复慢,积分时间往下降。
曲线波动周期长,积分时间再加长。
曲线振荡频率快,先把微分降下来。
动差大来波动慢。微分时间应加长。
理想曲线两个波,前高后低 4 比 1。
一看二调多分析,调节质量不会低
更多 PID 资料(链接如果过期请加 QQ:951359927)
http://pan.baidu.com/s/1o76GVqU (国内讲解最形象的 PID 高清视频)
http://pan.baidu.com/s/1czocKu (国外简易 PID 参数整定计算器)