//20170510
//By Bruce.Duan [email protected] QQ:371818594
//最近在学习PID算法,虽然原理简单,但是实际应用起来并不容易,也有不同//的办法去实现,这是我根据网上找的资料,把多种实现方法写在了同一个程//序里面,希望和大家一起学习
//PID Algorithm in C.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct
{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际输出值
float err; //定义偏差值
float err_next;//定义上一个偏差值
float err_last;//定义最上前一个的偏差值
float kp,ki,kd;//定义比率,积分,微分系数
float voltage; //定义输出值
float integral;//定义积分值
float incrementSpeed;//定义增量值
float umax; //定义积分上限值
float umin; //定义积分下限值
}PID_Struct;
PID_Struct pid;
void PID_Init(void)
{
printf("pid initialize begin\n");
pid.SetSpeed=0.0;
pid.ActualSpeed=0.0;
pid.err=0.0;
pid.err_next=0.0;
pid.err_last=0.0;
pid.integral=0.0;
pid.voltage=0.0;
pid.kp=0.2; //设定比例积分微分系数,系数可调整 默认kp=0.2,变积分Kp=0.4
pid.ki=0.2; //位置型和增量型ki=0.015,积分分离型Ki=0.04,抗饱和积分型ki=0.1,变积分型ki=0.2
pid.kd=0.2;
pid.umax=400.0;
pid.umin=-200;
printf("pid initialize end\n");
}
float PID_realize0(float Speed) //位置型PID算法实现函数
{
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.err-pid.err_last);
pid.err_last=pid.err;
pid.ActualSpeed=pid.voltage;
return pid.ActualSpeed;
}
float PID_realize1(float Speed)//增量式PID算法实现
{
pid.SetSpeed=Speed;
pid.err=pid.SetSpeed-pid.ActualSpeed;
pid.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+=pid.incrementSpeed;
pid.err_next=pid.err;
pid.err_last=pid.err_next;
return pid.ActualSpeed;
}
float PID_realize2(float Speed) //积分分离PID算法实现函数
{
int index;
pid.SetSpeed=Speed;
pid.err=pid.SetSpeed-pid.ActualSpeed;
if(fabs(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;
return pid.ActualSpeed;
}
float PID_realize3(float Speed) //抗饱和积分PID算法实现函数
{
int index;
pid.SetSpeed=Speed;
pid.err=pid.SetSpeed-pid.ActualSpeed;
if(pid.ActualSpeed>pid.umax)
{
if(fabs(pid.err)>200)
{
index=0;
}else
{
index=1;
if(pid.err<0)
{
pid.integral+=pid.err;
}
}
}else if(pid.ActualSpeed<pid.umin)
{
if(fabs(pid.err)>200)
{
index=0;
}else
{
index=1;
if(pid.err>0)
{
pid.integral+=pid.err;
}
}
}
else
{
if(fabs(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.integral/2
pid.err_last=pid.err;
pid.ActualSpeed=pid.voltage;
return pid.ActualSpeed;
}
float PID_realize4(float Speed) //变积分PID算法实现函数,更快
{
int index;
pid.SetSpeed=Speed;
pid.err=pid.SetSpeed-pid.ActualSpeed;
if(fabs(pid.err)>200)
{
index=0;
}else if(fabs(pid.err)<180)
{
index=1;
}else
{
index=(200-fabs(pid.err))/20;
}
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;
return pid.ActualSpeed;
}
int main(void)
{
//printf("PID Algorithm begin!\n");
float SetSpeed=0.0;
float count=1;
int nums=0;
PID_Init();
while(count>0.0001)
{
//SetSpeed=PID_realize0(200.0);//位置型PID
//SetSpeed=PID_realize1(200.0); //增量式PID
//SetSpeed=PID_realize2(200.0); //积分分离型
//SetSpeed=PID_realize3(200.0); //抗饱和积分+梯形积分
SetSpeed=PID_realize4(200.0); //变积分型PID控制
printf("%f\n",SetSpeed);
count=fabs(SetSpeed-200);
nums++;
//count++;
}
printf("计算次数:%d次\n",nums);
printf("PID算法测试结束!\n");
return 0;
}
评论0