前言
积分饱和现象是指若系统存在一个方向的偏差,PID控制器的输出由于积分作用不断累加而增大,超出执行机构的极限位置。计算机输出的控制量超出正常运行范围而进入饱和区。。
目录
一、抗积分饱和算法
基本思路:在计算控制量时,首先判断上一时刻的控制量是否超出限制范围。若超出最大值,则只进行负偏差的累加;若上一时刻的控制量小于最小值,则只进行正偏差的累加。
二、算法实现
1.结构体定义与参数初始化
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
struct pid
{
float SetSpeed; //设定值
float ActualSpeed; //实际输出值
float err; //偏差值
float err_last; //上一时刻偏差值
float Kp,Ki,Kd; //定义比例系数、积分系数和微分系数
float ut; //定义控制量
float interal; //定义积分项
float umax; //执行机构的最大值和最小值
float umin;
}pid;
void PID_init();
float PID_realize(float speed);
void PID_init() //参数初始化
{
pid.SetSpeed = 0.0;
pid.ActualSpeed = 0.0;
pid.err = 0.0;
pid.err_last = 0.0;
pid.Kd = 0.2;
pid.Ki = 0.1;
pid.Kp = 0.2;
pid.ut = 0.0;
pid.interal = 0.0;
pid.umax = 400;
pid.umin = -200;
}
2.算法实现
float PID_realize(float speed) //本算法实现中未引入实际受控对象,故控制量ut与实际输出值ActualSpeed相等
{
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed;
int index;
if(pid.ut >= pid.umax) // 如果控制量超出执行机构最大值
{
if(pid.err >= 0) // 若偏差为正值,停止积分
{
index = 0;
}
else // 若偏差为负值,执行负偏差的累加
{
index = 1;
pid.interal += pid.err;
}
}
else if(pid.voltage <= pid.umin) // 如果控制量小于执行机构的最小值
{
if(pid.err <= 0) // 若偏差为负值,停止积分
{
index = 0;
}
else // 若偏差为正值,执行正偏差的累加
{
index = 1;
pid.interal += pid.err;
}
}
else // 其他情况下,正常执行积分
{
index = 1;
pid.interal += pid.err;
}
// 抗积分饱和控制规律
pid.ut = pid.Kp*pid.err + index*pid.Ki*pid.interal + pid.Kd*(pid.err - pid.err_last);
//参数更新
pid.err_last = pid.err;
pid.ActualSpeed = pid.ut;
return pid.ActualSpeed;
}
3.主函数
int main()
{
PID_init();
int count;
while(count<1000)
{
float speed = PID_realize(200);
printf("%f\n",speed);
count++;
}
return 0;
}