以下内容转自阿莫论坛,写得很详细,是调试大四轴的。小四轴调试也可参照着调。
PID调试心得
本人不是自动化出身,也没有受过专业训练,都是自己摸索,在这里浅述一下自己的PID参数整定心得。所言之物皆由实践及自己的理解得出,如有不当之处还请指正。
首先例举第一个例子,我调的第一台四轴飞行器,十字型四轴飞行器,讲下配置:
网上一百多的650机架,好赢20A电调,新西达2212 1000kV,1045的桨,2200mah电池。
主控是STM32F103
这是第一个四轴的帖子
http://www.amobbs.com/thread-5539270-1-1.html
采用位置式PID控制,位置式PID公式如下
PID的基本意义我在次就不作阐述了,我只讲我的设计,我以姿态角作为被控制对象,所以
e(k) = 期望-测量 = 给定值-测量姿态角
对于微分项D,我做了一点改变,标准PID的微分项D=kd*(e(k)-e(k-1)),我在实践过程中因为角度的微分就是角速度,而陀螺仪可以直接测出角速度,
所以我没有将微分项作为偏差的差而是直接用D=kd*Gyro
实现代码如下
float pidUpdate(pidsuite* pid, const float measured,float expect,float gyro)
{
float output;
static float lastoutput=0;
pid->desired=expect; //获取期望角度
pid->error = pid->desired - measured; //偏差:期望-测量值
pid->integ += pid->error * IMU_UPDATE_DT; //偏差积分
if (pid->integ > pid->iLimit) //作积分限制
{
pid->integ = pid->iLimit;
}
else if (pid->integ < -pid->iLimit)
{
pid->integ = -pid->iLimit;
}
// pid->deriv = (pid->error - pid->prevError) / IMU_UPDATE_DT; //微分 应该可用陀螺仪角速度代替
pid->deriv = -gyro;
if(fabs(pid->error)>Piddeadband) //pid死区
{
pid->outP = pid->kp * pid->error; //方便独立观察
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = (pid->kp * pid->error) +
(pid->ki * pid->integ) +
(pid->kd * pid->deriv);
}
else
{
output=lastoutput;
}
pid->prevError = pid->error; //更新前一次偏差
lastoutput=output;
return output;
}
我这么做的原因是因为,如果使用传统的D的形式,在我快速打舵时会产生输入的设定值变化频繁且幅度较大,四轴飞行器会迅速回到新的期望点,说白了就是非常灵活,四轴回复很猛,也许造成系统的振荡,对PID参数要求较高。如果用角速度代替的话,那怕你打舵非常快,四轴会较平稳的回到新位置,运动较柔和。对于我这种操作菜鸟来说无疑后面一种会更合适,所以我选择了D=kd*Gyro的方式。