初级会员
- 积分
- 50
- 金钱
- 50
- 注册时间
- 2017-3-4
- 在线时间
- 7 小时
|
本帖最后由 keysking 于 2017-5-5 18:16 编辑
对PID算法的愚见
PID算法名字中的三个字母其实是此算法的三个核心系数:
​ P: 比例系数
​ I : 积分系数
​ D: 微分系数
比例系数
在只有比例系数的控制下,如果我们要让四旋翼悬浮在100cm高度,那么由于误差,它可能在90或者110等位置停下
积分系数
加入积分系数控制后,四旋翼飞到110cm的时候,发现不对,便向下飞,又飞过了,就又向上飞,上上下下,最终可能稳定.但是每次上下的速度是相同的.
微分系数
因为上上下下每次速度相同,所以极有可能飞过,所以加入微分系数,当距离目标位置越近时,速度就放的越缓,达到稍微调整就能准确的悬浮到目标位置的目的.
程序
刚刚写了一个通用的(耦合度极低)PID函数,使用的是增量式PID算法.自我感觉这个算法并不是准确的PID计算公式,只是简化计算后的计算方法,适合计算能力较弱的单片机等使用.
[mw_shl_code=c,true]//PID.h
typedef struct {
int shuzhi[3]; //保存本次和之前两次的设定值与实际测量值的差值
char KP; //比例系数
char KI; //积分常数
char KD; //微分常数
int PID;//PID输出值
int SET;//设定值
int CUR;//实际值
int THR;//阀值
int MAX;//全力输出
} PID_Value;
void PID_Operation(PID_Value *PID);[/mw_shl_code]
[mw_shl_code=c,true]//PID.c
//增量法PID算法:
// PID=U(k)+KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)]
#include "PID.h"
void PID_Operation(PID_Value *PID){
int temp[3]={0}; //用于辅助计算的临时变量
if(PID.SET-PID.CUR>PID.THR){ //当设定值与实际值的差值大于阀值时,直接全力输出
PID.PID=MAX;
return ;
}
if(PID.CUR-PID.SET>PID.THR){ //当设定值与实际值的差值大于阀值时,直接全力输出
PID.PID=0-MAX;
return ;
}
PID.shuzhi[2]=PID.shuzhi[1];
PID.shuzhi[1]=PID.shuzhi[0];
PID.shuzhi[0]=PID.SET-PID.CUR; //差值.E(k)
//=====PID=U(k)+KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)]==================
temp[0]=PID.shuzhi[0]-PID.shuzhi[1]; //E(k)-E(k-1)
temp[2]=PID.shuzhi[1]*2;
temp[2]=PID.shizhu[0]+PID.shuzhi[2]-temp[2]; //E(k)-2E(k-1)+E(k-2)
temp[0]=PID.KP*temp[0];
temp[1]=PID.KI*PID.shuzhi[0];
temp[2]=PID.KD*PID.temp[2];
PID.PID=PID.PID+temp[0]+temp[1]+temp[2];
}[/mw_shl_code]
|
|