前言
本文将讲述PID算法中积分项的优化,对于已经理解普通PID算法控制原理并想继续深入了解PID的你有一定的帮助。
PID算法相比一般的位式控制算法有了很大的改进,普通的PID在合适的参数整合下也能起到很好的控制作用。
本文PID中积分项的优化只是锦上添花。
以下是本篇文章的正文内容
一、简述PID的积分
在学习积分项优化之前要清楚知道积分的作用。
(1)积分是过去所有偏差的和,在系统中起到的作用是消除静差。
(2)积分系数太大导致稳定后出现超调,积分系数太小导致稳定后系统波动。
(3)积分项并非无穷大,可能小于0,可能等于0
(4)要最大化积分的作用,主要是调整好积分系数
积分优化的目的是让积分不要起到干扰作用。
二、积分分离
1.内容讲解
所谓的积分分离就是在系统偏差较大时不采用积分。
在系统刚开始趋向稳定时,这段时间偏差很大导致积分很大。那么当系统接近稳定时由于积分项很大就会出现超调和较大的震荡,积分起到干扰作用,这时我们可以选择不要积分。
2.C语言实现
C语言实现过程非常简单,设定偏差上限值,当偏差绝对值大于上限时然让积分项输出为0。下面举个例子。
if( abs(ek) > EK_MAX )
index = 0;
else
index = 1;
out = kp*ek + index*ki*sk + kd*(ek-ek_1);
三、抗积分饱和
1.内容讲解
饱和是指PID输出值out超过了最大值,我们知道硬件的实际输出不可能无穷大,所以即便out超过最大值,最终我们还是会让out等于最大值。当out出现单方向饱和时,积分的单方向偏差会累积到很大,这时如果突然要系统反偏,由于积分单方向累积较大,那么积分对于系统起到干扰作用。
举个例子,正方向最大速度旋转的电机,突然要让它反方向旋转,由于积分正方向偏差大,如果积分不进行抗饱和系统反应速度会很慢。
所以我们需要在out饱和时不要将饱和方向的偏差加入到积分项中,只将与饱和方向相反的偏差加入积分项中。
2.C语言实现
在积分分离基础上加入抗积分饱和
if(pid.out > OUT_MAX)
{
if( abs(pid.ek) > EK_MAX ) //积分分离
index = 0;
else
{
index = 1;
if(pid.ek < 0) //积分只累积负值
pid.sk += pid.ek;
}
}
else if(pid.out < OUT_MIN)
{
if( abs(pid.err) > EK_MAX ) //积分分离
index = 0;
else
{
index = 1;
if(pid.ek > 0) //积分只累积正值
pid.sk += pid.ek;
}
}
else //不出现饱和时
{
if( abs(pid.ek) > EK_MAX ) //积分分离
index = 0;
else
{
index = 1;
pid.sk += pid.ek;
}
}
四、变积分
1.内容讲解
上述的积分分离是在偏差达到最大值时不要积分,那么偏差在没有达到最大值但又比较大时可以适当虚弱积分的作用。作用与积分分离一样,防止系统接近稳定由于积分项很大出现超调和较大的震荡。
2.C语言实现
在上述代码基础上加入变积分
if(pid.out > OUT_MAX)
{
if( abs(pid.ek) > EK_MAX ) //积分分离
index = 0;
else
{
if(EK_MID < abs(pid.ek) < EK_MAX) //变积分
index = 0.5;
else
index = 1;
if(pid.ek < 0) //积分只累积负值
pid.sk += pid.ek;
}
}
else if(pid.out < OUT_MIN)
{
if( abs(pid.err) > EK_MAX ) //积分分离
index = 0;
else
{
if(EK_MID < abs(pid.ek) < EK_MAX) //变积分
index = 0.5;
else
index = 1;
if(pid.ek > 0) //积分只累积正值
pid.sk += pid.ek;
}
}
else //不出现饱和时
{
if( abs(pid.ek) > EK_MAX ) //积分分离
index = 0;
else if(EK_MID < abs(pid.ek) < EK_MAX) //变积分
index = 0.5;
else
index = 1;
pid.sk += pid.ek;
}
结语
那么以上就是本篇文章的所有内容了。
本文如果有什么不对的或者需要改进的地方欢迎指出。