1. 四旋翼控制就像骑自行车
第一次飞四旋翼无人机的感觉,就像小时候刚学自行车——明明想往前,车子却总往两边倒。这种不稳定的特性,恰恰是四旋翼最有趣的地方。通过四个螺旋桨的转速差,我们不仅能控制飞行高度,还能实现前后左右移动甚至空中翻转。今天我们就来拆解这个"空中自行车"的控制核心:PID算法。
在智慧城市应用中,无人机常被用于巡检、测绘等任务。我曾参与过一个桥梁检测项目,无人机需要在强风中保持稳定悬停。当时我们花了整整两周时间调整PID参数,最终实现了厘米级定位精度。这个经历让我深刻体会到:理解PID不仅仅是会调参数,更要明白每个环节的物理意义和控制逻辑。
2. 动力学模型:无人机的"牛顿定律"
2.1 力与运动的数学表达
四旋翼的动力学模型可以用牛顿-欧拉方程描述,简单来说就是"力怎么产生运动"。看这段核心代码:
python复制def dynamics_update(self):
# 机体坐标系到世界坐标系的转换
rotation_matrix = self.euler_to_rotation_matrix()
thrust_body = np.array([0, 0, self.total_thrust])
gravity = np.array([0, 0, -self.mass * 9.81])
acceleration = (np.dot(rotation_matrix, thrust_body) + gravity) / self.mass
self.velocity += acceleration * self.dt
这里有几个关键点:
rotation_matrix将螺旋桨推力从机体坐标系转换到世界坐标系total_thrust是四个电机的总拉力,方向始终垂直于机体平面- 重力加速度恒定为9.81m/s²,方向向下
注意:实际飞行中,螺旋桨推力方向并非绝对垂直,会有轻微偏移。我们在智慧城市巡检项目中,就曾因忽略这个细节导致定位漂移。
2.2 力矩与旋转的关系
角运动由力矩控制,计算公式为:
code复制τ = I·α + ω×(I·ω)
其中:
- τ:总力矩
- I:转动惯量矩阵
- α:角加速度
- ω:角速度
这个方程解释了为什么快速旋转的无人机会出现"陀螺效应"——当你想改变其姿态时,会产生额外的耦合力矩。
3. 级联PID:控制回路的"套娃"结构
3.1 内环(姿态环)实现细节
姿态控制是飞行稳定的关键。来看这段角速度环PID代码:
c复制float PID_att_rate_update(PID_Instance* pid, float setpoint, float measurement) {
float error = setpoint - measurement;
pid->integral += error * pid->dt;
// 积分抗饱和处理
if(pid->integral > pid->i_max) pid->integral = pid->i_max;
else if(pid->integral < -pid->i_max) pid->integral = -pid->i_max;
// 微分项用测量值微分
float derivative = (measurement - pid->prev_measurement) / pid->dt;
float output = pid->kp * error + pid->ki * pid->integral - pid->kd * derivative;
pid->prev_measurement = measurement;
return output;
}
几个值得注意的实现技巧:
- 微分项使用测量值而非误差值,避免设定值突变导致的输出抖动
- 积分项做了抗饱和处理,防止"积分windup"
- 采用欧拉积分法,计算量小适合嵌入式系统
3.2 外环(位置环)设计要点
位置环输出的是姿态设定值,其参数整定需要特别注意:
| 参数 | 建议值 | 调整原则 |
|---|---|---|
| Kp | 0.5-2.0 | 太大导致震荡 |
| Ki | 0.01-0.1 | 必须很小 |
| Kd | 0.1-0.5 | 抑制超调 |
在智慧城市巡检项目中,我们发现位置环积分增益过大时,无人机会像"喝醉酒"一样画龙。解决方法是将积分时间常数设为5秒以上。
4. 参数整定的实战技巧
4.1 调参步骤指南
-
角速率环先调:
- 目标:阶跃响应时间<0.2秒
- 方法:给阶跃输入,观察响应
- 参数范围:
- Kp:0.1-1.0
- Ki:0.5-5.0
- Kd:0.01-0.1
-
角度环其次:
- 目标:超调量<10%
- 技巧:先设Kd=0,调Kp到临界震荡点后减半
-
位置环最后调:
- 关键:积分时间必须足够大
- 经验:从Kp=0.5开始,每次增加0.2
4.2 常见问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 高频震荡 | 微分增益过大 | 降低Kd |
| 稳态误差 | 积分增益不足 | 增加Ki |
| 响应迟缓 | 比例增益不足 | 增加Kp |
| 超调严重 | 微分增益不足 | 增加Kd |
5. 电机混控:从指令到执行
四个电机的转速分配由混控矩阵决定:
code复制| ω₁ | | 1 1 1 1 | | T |
| ω₂ | = | 1 -1 -1 1 | | τx |
| ω₃ | | 1 1 -1 -1 | | τy |
| ω₄ | | 1 -1 1 -1 | | τz |
其中:
- T:总推力
- τx,τy,τz:三轴力矩
- ω₁-ω₄:四个电机转速
在桥梁检测项目中,我们曾遇到电机响应不一致的问题。解决方法是在混控前加入电机特性校准:
python复制def motor_mixing(self, thrust, tau_x, tau_y, tau_z):
# 电机校准系数
k1, k2, k3, k4 = self.motor_calibration_factors
# 混控计算
w1 = (thrust + tau_x + tau_y + tau_z) * k1
w2 = (thrust - tau_x - tau_y + tau_z) * k2
w3 = (thrust + tau_x - tau_y - tau_z) * k3
w4 = (thrust - tau_x + tau_y - tau_z) * k4
return [w1, w2, w3, w4]
6. 仿真与实飞的经验之谈
经过多个智慧城市项目的积累,我总结出几点关键经验:
-
仿真先行:先用Gazebo或MATLAB仿真,可以快速验证算法而不用担心炸机。我们团队开发的仿真环境能模拟风速变化,大大缩短了开发周期。
-
参数冻结:找到一组中等性能但鲁棒的参数,不要在每次飞行前都调整。在巡检项目中,我们固定使用两套参数:一套用于常规飞行,一套用于抗风模式。
-
安全机制:必须实现以下保护:
- 积分项清零当误差过大
- 输出限幅
- 传感器失效检测
-
记录分析:飞行数据记录至关重要。我们曾通过分析日志发现,GPS更新延迟是导致位置环震荡的主因。
调参就像中医把脉,需要观察"症状"(响应曲线)、分析"病因"(参数失调)、开出"药方"(参数调整)。记得有次为了调出完美的悬停效果,我连续三天泡在飞场,最终发现将角速率环的Kd提高20%就能显著改善抗风性。这种实践经验,是任何教科书都给不了的。