3、姿态PID控制器设计:内环与外环、角度环与角速度环
好,咱们今天聊点硬核的。姿态PID控制器,说白了就是让无人机“站稳”的核心。很多新手一上来就调PID,结果飞机乱抖甚至翻跟头。为什么?因为没搞明白内环和外环的关系。
我个人习惯把姿态控制拆成两层:角度环(外环)和角速度环(内环)。这两层各有各的活,千万别混着调。
3.1 为什么需要内外环?
你想想看,无人机要控制姿态,最终靠的是电机转速变化。但电机转速变化直接产生的是角加速度,不是角度。所以我们需要一个“翻译”过程:
- 外环(角度环):负责把期望角度和实际角度的偏差,转成期望角速度。
- 内环(角速度环):负责把期望角速度和实际角速度的偏差,转成电机控制量。
我在项目中遇到过一个问题:有人只用一个角度环,结果飞机反应特别迟钝,稍微有点风就晃。为什么?因为角度环输出的是角速度期望,但实际角速度变化很快,单环根本跟不上。加上内环后,响应速度明显提升。
核心结论:内环负责“快”,外环负责“准”。内环频率通常是外环的5-10倍。
3.2 内环:角速度环设计
角速度环是姿态控制的“肌肉”。它直接面对陀螺仪数据,响应最快。
我一般这样设计角速度环的PID:
// 角速度环PID结构体
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
float integral; // 积分累计
float prev_error; // 上次误差
float output_limit; // 输出限幅
} PID_Controller;
// 角速度环计算函数
float AngularRatePID_Update(PID_Controller *pid, float target, float actual) {
float error = target - actual;
// 比例项
float p_out = pid->Kp * error;
// 积分项(带限幅)
pid->integral += error * dt;
pid->integral = constrain(pid->integral, -pid->output_limit, pid->output_limit);
float i_out = pid->Ki * pid->integral;
// 微分项(注意:这里用角速度变化率,不是误差变化率)
float d_out = pid->Kd * (error - pid->prev_error) / dt;
pid->prev_error = error;
// 输出限幅
float output = p_out + i_out + d_out;
output = constrain(output, -pid->output_limit, pid->output_limit);
return output;
}
经验之谈:角速度环的Kd我一般设得很小,甚至为0。因为陀螺仪数据本身就有噪声,微分项容易放大噪声。我曾经在调试时把Kd设大了,结果飞机高频抖动,差点炸机。
3.3 外环:角度环设计
角度环是“大脑”,它告诉内环“该往哪个方向转多快”。
角度环通常只用P控制就够了。为什么?因为角度误差本身就有积分效果——你一直偏着,误差就一直存在,内环就会一直纠正。
// 角度环计算(输出给内环作为目标角速度)
float AnglePID_Update(float target_angle, float actual_angle) {
float error = target_angle - actual_angle;
// 角度环一般只用P
float p_out = angle_Kp * error;
// 限幅:最大角速度不能超过内环能处理的范围
p_out = constrain(p_out, -max_angular_rate, max_angular_rate);
return p_out; // 这个值就是内环的目标角速度
}
嗯,这里要注意:角度环的输出限幅很关键。如果你设的max_angular_rate太大,内环可能跟不上,导致超调。我一般设成内环最大输出能力的60%-70%。
3.4 内外环的配合与调参顺序
调参顺序很重要。我见过有人上来就调角度环,结果怎么调都不对。正确的顺序是:
- 先调内环(角速度环):让飞机能快速响应角速度指令,不震荡。
- 再调外环(角度环):让飞机能准确跟踪角度指令。
具体步骤:
| 步骤 | 操作 | 现象 |
|---|---|---|
| 1 | 内环P从0慢慢增大 | 飞机开始有阻力感,推杆回中后能停住 |
| 2 | 内环I适当加入 | 消除稳态误差,悬停更稳 |
| 3 | 内环D(可选) | 抑制超调,但注意噪声 |
| 4 | 外环P从0增大 | 飞机响应角度指令,回中迅速 |
避坑指南:我曾经在调内环时,发现飞机有低频振荡。检查了半天,发现是外环P太大,导致内环目标角速度频繁跳变。解决办法:降低外环P,或者给外环输出加一个低通滤波。
3.5 实际工程中的注意事项
说几个我在实际项目中踩过的坑:
- 积分饱和:内环积分项一定要限幅。否则飞机长时间偏转后,积分累计太大,回中时会猛冲过去。
- 控制频率:内环至少200Hz,外环50Hz以上。我习惯内环400Hz,外环100Hz。
- 死区处理:陀螺仪在小角速度时有零偏,可以加一个死区,比如角速度小于0.5°/s时不做控制。
你想想看,如果内环频率太低,外环输出一个角速度指令,内环要等5ms才响应一次,那飞机肯定晃。所以频率匹配很重要。
最后总结一下:内环管快,外环管准;先调内环,再调外环;内环用PID,外环用P。 记住这个口诀,姿态控制就成功了一半。
个人习惯:我一般在调试时,先用一个简单的角度环P参数让飞机能勉强悬停,然后专心调内环。内环调好了,外环稍微调一下就能飞得很稳。别急着一步到位,慢慢来。