注册会员
- 积分
- 26
- 威望
- 18
- 贡献
- 6
- 兑换币
- 5
- 注册时间
- 2015-7-26
- 在线时间
- 1 小时
- 毕业学校
- 西安电子科技大学
|
一般形式:
Up=P*E;
Ui=i*(E+E_1+E_2+...) E_n为之前的第n次误差.
Ud=i*(E-E_1)
U=Up+Ui+Ud; U为PID控制输出量.
上式中Ui的计算不太方便,长时间单方向的累加将可能出现溢出,于是将上式改为如下所示的增量形式:
??
Up=p*(E-E_1) 比例项增量
Ui=i*(E-2*E_1+E_2) 微分项增量
Ud=i*E 积分项增量
U=Uout_1+Up+Ui+Ud U为PID控制输出量,Uout_1为前次PID输出值
Uout=U 保存本次值
对于上面的公式或理论,便可得到相应的C语言程序:
//======================定义PID结构=========================
static float MinValue; //最大值限制
static float MaxValue; //最小值限制
static float CurrentValue; //当前采样值
static struct PID{
float Ki; //定义积分常数
float Kp; //定义比例常数
float Kd; //定义微分常数
float E_2; //存储前前次误差
float E_1; //存诸前次误差
float E; //存储本次误差
float OutPut; //本次输出量
float ValueSet; //设定值或期望值
}Control;
//===========================PID计算函数=====================
void PidWork() {
float Up,Ud,Ui;
Control.E=CurrentValue-Control.ValueSet; //得到本次误差
Up =Control.Kp*(Control.E-Control.E_1); //得到比例项
Ud=Control.Kd*(Control.E-2*Control.E_1+Control.E_2); //得到微分项
Ui=Control.Ki*Control.E; //得到积分项
Control.E_2=Control.E_1; //历史存储
Control.E_1=Control.E;
Control.OutPut+=Up+Ud+Ui; //计算增量和
if(Control.OutPut<MinValue)Control.OutPut=MinValue; //值域限制
else if(Control.OutPut>MaxValue)Control.OutPut=MaxValue;
}
??
//==========================初始化速度=========================
void PidInit() {
MinValue=0;
MaxValue=1000;
CurrentValue=0;
Control.Kp=-6;
Control.Ki=-1.5;
Control.Kd=-0.5;
Control.E=0;
Control.E_2=0;
Control.E_1=0;
Control.ValueSet=100;
Control.OutPut=0;
}
----------------------------------------------------------------------------------
不知道到这个模板能不能用到控制小车的速度上,那么如果用来控速的话,那么程序中ValueSet为所期望的PWM的值还是期望的小车速度值,然后CurrentValue当前采样值是利用测速模块所测得的速度么,那如果CurrentValue采样的是PWM的话,是如何用硬件实现采集实际PWM的值的呢。或者ValueSet与CurrentValue都为速度值,那么如何利用所得求出的增量Control.OutPut来实现对PWM的控制的呢。新手没用过PID,所以问题比较多,见谅
|
|