- 相关推荐
PID算法的C语言实现:抗积分饱和的PID优化
导语:C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。下面我们来看看PID算法的C语言实现:抗积分饱和的PID优化,希望对大家有所帮助。
积分饱和通俗讲就是系统在一个偏差方向上的饱和,比如一个系统设定了输出不会超过100,但因为出现一个方向上的偏差积分使得输出超过了100,此时达到了饱和状态,如果继续在这个方向上积分会导致PID控制超过100系统却运行在100,相当于积分调节对系统输出没有作用,就出现失控的状态,这是系统不能接受的,而且饱和积分越深,退出饱和就越久。上面是在正向的饱和,负向的饱和类似!
为了解决这个问题,我们采用抗积分饱和算法,其思路就是:如果上一次的输出控制量超过了饱和值,饱和值为正,则这一次只积分负的偏差,饱和值为负,则这一次只积分正的偏差,从而避免系统长期留在饱和区!
下面我以位置型+抗积分饱和+积分分离的PID控制算法C语言来观察调节结果:
//位置型+抗积分饱和+积分分离 PID控制算法
struct _pid{
float SetSpeed;
float ActualSpeed;
float Err;
float Err_Last;
float Kp,Ki,Kd;
float Voltage;
float Integral;
float Umax; //最大正饱和上限值
float Umin; //最大负饱和下限值
}pid;
void PID_Init(void)
{
printf("PID_Init begin! ");
pid.SetSpeed = 0;
pid.ActualSpeed = 0;
pid.Err = 0;
pid.Err_Last = 0;
pid.Kp = 0.2;
pid.Ki = 0.1; //增大了积分环节的值
pid.Kd = 0.2;
pid.Voltage = 0;
pid.Integral = 0;
pid.Umax = 400; //正饱和值为400
pid.Umin = -200; //负饱和值为-200
printf("PID_Init end! ");
}
float PID_Cal(float Speed)
{
unsigned char index;
pid.SetSpeed = Speed;
pid.Err = pid.SetSpeed - pid.ActualSpeed;
if(pid.ActualSpeed>pid.Umax) //如果上一次输出变量出现正向的饱和
{
if(abs(pid.Err)>200)
{
index = 0;
}
else
{
index = 1;
if(pid.Err<0)
{
pid.Integral += pid.Err; //正饱和只积分负偏差
}
}
}
else if(pid.ActualSpeed {
if(abs(pid.Err)>200)
{
index = 0;
}
else
{
index = 1;
if(pid.Err>0)
{
pid.Integral += pid.Err; //负饱和只积分正偏差
}
}
}
else
{
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*(pid.Err - pid.Err_Last);
pid.Err_Last = pid.Err;
pid.ActualSpeed = pid.Voltage*1.0;
return pid.ActualSpeed;
}
int main(void)
{
int count = 0 ;
printf("SYSTEM BEGIN! ");
PID_Init();
while(count<1000)
{
float speed = PID_Cal(200.0);
printf("-%d-%f-",count,speed);
count++;
}
return 0;
}
【PID算法的C语言实现:抗积分饱和的PID优化】相关文章:
PID算法的C语言实现07-19
C语言中实现KMP算法实例08-09
C语言实现归并排序算法实例09-18
C语言程序的实现09-27
C语言的HashTable简单实现10-12
C语言中递归算法的剖析08-15
C语言冒泡排序算法实例06-15
关于字符串的组合算法问题的C语言实现攻略10-21
C#实现协同过滤算法的实例代码06-19
如何实现C语言画图教程08-08