2. 飞控系统架构:从传感器到电机,PID在飞控链路中的位置
做飞控这么多年,我经常被问到同一个问题:“PID到底在飞控里扮演什么角色?”
很多人一上来就调PID,结果越调越乱。为什么?因为你不清楚整个飞控链路是怎么跑的。传感器数据从哪来,经过哪些处理,最后怎么变成电机的转速——这些搞不明白,调参就是瞎蒙。
今天我就带你走一遍这条链路。说白了,就是搞清楚“谁在干活,活是怎么干的”。
2.1 飞控系统的“五层架构”
我习惯把飞控系统拆成五层。你想想看,一架四旋翼飞起来,从你推油门到它真的往上窜,中间经历了什么?
- 传感器层:感知物理世界(IMU、磁力计、GPS、气压计)
- 状态估计层:把传感器数据融合成姿态、位置、速度
- 控制层:计算期望姿态/位置与实际值的偏差,输出控制量
- 混控层:把控制量分配到各个电机
- 执行层:电机响应,产生力和力矩
嗯,这里要注意:PID就住在第三层——控制层。它既不是最底层,也不是最顶层。
核心认知:PID不是飞控的全部,它只是控制层里的一个“计算单元”。但它是整个链路里最容易被调崩的一环。
2.2 一张图看懂飞控链路
我画了一张图,把整个链路串起来。你看完就明白PID到底在哪了。
这张图我画了好几次才满意。你看,PID控制层是整个链路的“大脑”——它接收状态估计层算出来的姿态和位置,跟遥控器给的期望值做比较,然后算出该给电机多少力。
2.3 PID在控制层里的具体位置
控制层内部其实还有讲究。我见过不少新手,以为PID就是一层。实际上,飞控里通常是串级PID。
什么叫串级?就是外环套内环。拿四旋翼的横滚控制举个例子:
- 外环(位置环):期望横滚角 vs 实际横滚角 → 输出期望角速率
- 内环(角速率环):期望角速率 vs 实际角速率 → 输出电机控制量
为什么会这样设计?因为角速率环响应更快,能先把飞机的“抖动”压住,外环再慢慢把角度调准。我在项目里遇到过,如果只用单环PID,飞机稍微受点风就晃得跟筛子似的。
实战经验:调参时永远先调内环(角速率环),再调外环(角度环)。内环稳了,外环才有意义。我曾经有一次把顺序搞反了,结果飞机在地上疯狂抽搐,差点把桨打碎。
2.4 传感器数据是怎么“喂”给PID的?
你可能会问:PID怎么知道飞机当前的角度?答案是——它不知道,它只负责算。
传感器数据经过状态估计层处理后,变成了PID能理解的“实际值”。这个过程我简单说一下:
| 传感器 | 原始数据 | 状态估计输出 | PID使用 |
|---|---|---|---|
| 陀螺仪 | 角速度(°/s) | 滤波后的角速度 | 内环PID输入 |
| 加速度计 | 三轴加速度(m/s²) | 姿态角(横滚、俯仰) | 外环PID输入 |
| 磁力计 | 磁场强度 | 偏航角 | 偏航外环PID |
| GPS | 经纬度、高度 | 位置、速度 | 位置/速度PID |
说白了,PID就是个“比较器+计算器”。它不关心数据怎么来的,只关心“期望值 - 实际值 = 偏差”,然后根据偏差算输出。
2.5 一个典型的控制循环代码
我写一段伪代码,你看完就明白PID在循环里是怎么跑的:
// 飞控主循环(400Hz,每2.5ms执行一次)
while(flight_armed) {
// 1. 读取传感器原始数据
raw_gyro = read_gyroscope();
raw_accel = read_accelerometer();
// 2. 状态估计(卡尔曼滤波)
attitude = kalman_filter(raw_gyro, raw_accel);
angular_rate = lowpass_filter(raw_gyro);
// 3. PID控制(串级)
// 外环:角度PID
angle_error = target_roll - attitude.roll;
target_rate = angle_pid.update(angle_error);
// 内环:角速率PID
rate_error = target_rate - angular_rate.roll;
control_output = rate_pid.update(rate_error);
// 4. 混控:分配到4个电机
motor_pwm = mixer(control_output, throttle);
// 5. 输出PWM给电调
write_pwm(motor_pwm);
// 6. 等待下一个控制周期
wait_for_next_cycle();
}
你看,PID在整个循环里只占了两步。但就是这两步,决定了飞机是稳如磐石还是乱晃乱抖。
避坑指南:我曾经在调试一架大四旋翼时,发现PID输出一直在震荡。查了半天,结果是传感器数据更新频率跟控制频率不匹配——传感器100Hz,控制跑400Hz,PID每次算的都是旧数据。后来我把控制频率降到跟传感器同步,问题就解决了。
2.6 为什么PID调参会影响到整个链路?
这个问题很关键。你调PID的时候,其实是在调整整个控制链路的“响应特性”。
- P太大:控制量过冲,飞机来回晃
- D太大:对噪声敏感,电机高频抖动
- I太大:积分饱和,飞机反应迟钝
但你知道吗?有时候问题不在PID本身。我遇到过好几次,用户说“PID调不好”,结果一看——传感器安装有振动,IMU数据本身就带噪声,PID再努力也白搭。
所以我的建议是:调参之前,先确认传感器数据是干净的。你可以在飞控的日志里看看角速度曲线,如果毛刺很多,先解决减震问题,再来调PID。
2.7 小结:记住这三句话
这一章的内容,你只需要记住三句话:
- PID在控制层,控制层在飞控链路的中间——前面是传感器和状态估计,后面是混控和电机
- 串级PID是标配——内环管角速率,外环管角度/位置,调参先内后外
- PID不是万能的——传感器数据质量、控制频率、混控逻辑都会影响最终效果
下一章,我会带你深入PID的三个参数——P、I、D到底在干什么,以及它们各自对飞行的影响。嗯,到时候我会拿我踩过的坑给你当反面教材。