飞控系统核心原理:飞控硬件架构与算法
飞控系统,说白了就是无人机的“小脑”。它负责感知姿态、计算偏差、输出指令。我最早接触飞控时,总觉得它很神秘。后来拆了几块板子,跑了几个算法,才明白核心就那几样东西。
这一章,我们聊聊飞控的硬件架构和核心算法。你搞懂了这些,后面调参、排故都会顺手很多。
飞控硬件架构:MCU/IMU/GPS/气压计
一块典型的飞控板,上面集成了几个关键器件。我习惯把它们分成三类:大脑、感官、执行。
| 类别 | 器件 | 作用 | 常见型号 |
|---|---|---|---|
| 大脑 | MCU(微控制器) | 运行算法,处理数据,输出控制信号 | STM32F4/F7、K66、F103 |
| 感官 | IMU(惯性测量单元) | 测量加速度和角速度,感知姿态 | MPU6000、ICM-20602、BMI088 |
| 感官 | GPS(全球定位系统) | 提供位置、速度、航向(需磁罗盘辅助) | UBLOX M8N/M9N、NEO-8M |
| 感官 | 气压计 | 测量大气压强,推算高度 | MS5611、BMP280、SPL06 |
| 执行 | PWM输出(电调接口) | 将控制量转为电机转速 | —— |
嗯,这里要注意:IMU 是飞控最核心的传感器。它内部包含三轴加速度计和三轴陀螺仪。加速度计测重力方向,陀螺仪测旋转角速度。两者互补,才能算出准确的姿态。
姿态解算算法:互补滤波 vs 卡尔曼滤波
传感器数据不能直接用。加速度计有高频噪声,陀螺仪有低频漂移。怎么办?融合。
姿态解算,就是把加速度计和陀螺仪的数据揉在一起,得到一个可靠的姿态角(横滚、俯仰、偏航)。
互补滤波
互补滤波的思路很简单:陀螺仪数据做短时积分,加速度计数据做长时修正。说白了,就是相信陀螺仪的瞬时变化,但用加速度计来拉回长期漂移。
公式长这样:
// 互补滤波核心代码(简化版)
angle = 0.98 * (angle + gyro * dt) + 0.02 * acc_angle;
0.98 和 0.02 是权重系数。系数怎么定?我一般先设 0.98,然后看悬停时姿态是否稳定。如果漂移大,就加大加速度计权重(比如 0.95/0.05)。
缺点:动态响应慢,有滞后。剧烈机动时容易跟丢。
卡尔曼滤波
卡尔曼滤波就高级一些。它用状态空间模型,结合预测和观测,给出最优估计。我当年啃《卡尔曼滤波原理》时,看了三遍才搞懂那五个公式。
核心步骤就五步:
- 预测状态:根据上一时刻状态和陀螺仪数据,预测当前状态。
- 预测协方差:估计预测的不确定性。
- 计算卡尔曼增益:决定相信预测还是相信观测。
- 更新状态:用加速度计观测值修正预测值。
- 更新协方差:为下一轮迭代做准备。
代码实现(一维角度卡尔曼滤波示例):
// 卡尔曼滤波核心(一维角度)
float kalman_filter(float angle_meas, float gyro_rate, float dt) {
// 预测
angle_pred = angle_est + (gyro_rate - bias_est) * dt;
P_pred = P_est + Q;
// 更新
K = P_pred / (P_pred + R);
angle_est = angle_pred + K * (angle_meas - angle_pred);
P_est = (1 - K) * P_pred;
// 更新偏差
bias_est += K * (angle_meas - angle_pred) * dt;
return angle_est;
}
两种算法怎么选?我个人的习惯是:
- 玩具级/低成本飞控:互补滤波,够用且省算力。
- 竞赛/工业级飞控:卡尔曼滤波,精度高,动态好。
- 视觉/激光SLAM辅助:扩展卡尔曼或粒子滤波,能融合多传感器。
PID控制原理
姿态解算完了,得到当前角度。接下来要算:当前角度和目标角度差多少?怎么让电机转才能纠正这个差?
这就是 PID 的事。
PID 三个字母分别代表:
- P(比例):偏差越大,输出越大。简单粗暴,但会有静差。
- I(积分):累积偏差,消除静差。但积分过头会超调。
- D(微分):预测偏差变化趋势,抑制震荡。但噪声会被放大。
飞控里最常用的是串级 PID:内环控制角速度,外环控制角度。
为什么用串级?你想想看,角度变化慢,角速度变化快。外环输出作为内环的目标值,内环快速响应。这样既稳又快。
// 串级PID伪代码
// 外环:角度环
angle_error = target_angle - current_angle;
target_rate = Kp_angle * angle_error + Ki_angle * angle_error_integral;
// 内环:角速度环
rate_error = target_rate - current_rate;
output = Kp_rate * rate_error + Ki_rate * rate_error_integral + Kd_rate * (rate_error - last_rate_error);
PWM信号与电机控制
PID 算出来的输出值,怎么变成电机的转速?答案是 PWM(脉冲宽度调制)。
飞控的 MCU 输出 50Hz 的 PWM 信号,脉宽在 1000μs 到 2000μs 之间。1000μs 对应电机停转,2000μs 对应满油门。电调(ESC)解读这个脉宽,驱动无刷电机旋转。
这里有个坑:不同电调的 PWM 频率和脉宽范围可能不同。我遇到过用 400Hz 频率驱动老款电调,结果电机嗡嗡响但不转。后来改成 50Hz 才正常。
| 参数 | 典型值 | 说明 |
|---|---|---|
| PWM 频率 | 50Hz(标准) | 周期 20ms,兼容大多数电调 |
| 脉宽范围 | 1000μs - 2000μs | 1000=停转,2000=满油门 |
| 油门校准 | 上电时发送最大/最小脉宽 | 让电调记住行程范围 |
| OneShot125 | 125μs - 250μs | 高速协议,延迟更低 |
电机控制还有个关键:混控器。四旋翼有四个电机,每个电机的转速变化会影响多个轴。混控器把横滚、俯仰、偏航、油门四个通道的指令,映射到四个电机上。
举个例子,X 型四旋翼的混控矩阵:
// X型四旋翼混控(简化)
Motor[0] = Throttle + Roll_Pitch - Yaw; // 右前
Motor[1] = Throttle - Roll_Pitch + Yaw; // 左后
Motor[2] = Throttle - Roll_Pitch - Yaw; // 左前
Motor[3] = Throttle + Roll_Pitch + Yaw; // 右后
嗯,这里要注意:混控器的输出要限幅,不能超过 2000μs 或低于 1000μs。否则电调会进入异常状态。
这张图把飞控的核心流程串起来了。从传感器到姿态解算,再到 PID 和混控器,最后输出 PWM。你把这个链路搞清楚了,飞控对你来说就不再是黑盒子。