3. 飞控软件架构:RTOS基础、任务调度与优先级
各位同学,咱们今天聊聊飞控的“大脑”——软件架构。说白了,飞控就是一块跑着实时操作系统的单片机。我刚开始接触飞控时,总觉得不就是个嵌入式程序嘛,后来被炸机教训了几次才明白:飞控软件的核心,是实时性。
你想想看,飞机在天上飞,传感器数据晚来1毫秒,控制指令晚到1毫秒,结果可能就是炸机。所以,飞控必须用实时操作系统(RTOS),而不是Linux那种分时系统。
3.1 实时操作系统(RTOS)基础
RTOS和普通操作系统的最大区别,就是确定性。普通系统“尽量”在规定时间内完成任务,RTOS是“必须”在规定时间内完成。我习惯用FreeRTOS,PX4和ArduPilot底层都基于它。
核心概念:
- 任务(Task):一个无限循环的函数,有自己的栈空间和优先级。
- 调度器(Scheduler):决定哪个任务在什么时候运行。
- 临界区(Critical Section):不允许被打断的代码段,通常用关中断实现。
举个例子,一个典型的飞控任务长这样:
void sensor_task(void *param) {
while(1) {
// 读取IMU数据
imu_read(&accel, &gyro);
// 等待下一个周期
vTaskDelay(pdMS_TO_TICKS(1)); // 1ms周期
}
}
嗯,这里要注意:vTaskDelay不是精确延时,它只是让任务挂起。真正的定时靠硬件定时器中断。
3.2 任务调度与优先级
RTOS的调度策略,说白了就是谁急谁先跑。飞控里最常见的调度方式是抢占式优先级调度:高优先级任务可以打断低优先级任务。
我曾经在项目里犯过一个低级错误:把姿态控制任务的优先级设得比传感器采集任务还高。结果呢?传感器数据还没读完,控制任务就抢跑了,用的全是上一帧的旧数据。飞控直接震荡,差点炸机。
避坑指南:
我曾经见过一个团队,把10个任务全设成同一个优先级。结果调度器按时间片轮转,关键任务经常被非关键任务打断。飞控在天上忽忽悠悠的,跟喝醉了似的。
我的建议是:优先级不要超过5级,每级只放1-2个任务。
典型的飞控任务优先级分配如下:
| 优先级 | 任务名称 | 周期 | 说明 |
|---|---|---|---|
| 最高 | IMU采集 | 1ms | 必须最快响应 |
| 高 | 姿态控制 | 4ms | 依赖最新传感器数据 |
| 中 | 位置控制 | 10ms | 可以容忍少量延迟 |
| 低 | 日志记录 | 100ms | 优先级最低,有空才跑 |
3.3 飞控固件的模块划分
ArduPilot和PX4虽然代码风格不同,但模块划分思路大同小异。我两个都用过,个人更喜欢PX4的模块化设计,每个模块独立编译,调试起来方便。
咱们以PX4为例,核心模块包括:
- 传感器驱动层:负责IMU、磁力计、气压计、GPS的原始数据读取。
- 状态估计模块:EKF(扩展卡尔曼滤波)融合多传感器数据,输出姿态、位置、速度。
- 控制模块:包括角度控制、角速度控制、位置控制,输出电机混控指令。
- 导航模块:航线规划、避障、返航逻辑。
- 通信模块:MAVLink协议,地面站和遥控器数据交互。
我的经验:
模块划分时,一定要遵循单一职责原则。一个模块只做一件事,比如传感器采集模块只管读数据,别在里面写控制逻辑。否则后期维护会想哭。
3.4 传感器数据采集与滤波任务
传感器采集是飞控的“眼睛”。我习惯把采集任务分成两级:
- 硬件中断级:IMU数据通过SPI或I2C中断读取,保证最低延迟。
- 任务级:在任务中做数据预处理和滤波,比如低通滤波、滑动平均。
为什么需要滤波?因为传感器噪声很大。我测过MPU6000,静止状态下加速度计噪声就有±0.05g。如果不滤波,控制量会抖得像筛糠。
一个简单的低通滤波实现:
// 一阶低通滤波
float low_pass_filter(float input, float prev_output, float alpha) {
return alpha * input + (1.0f - alpha) * prev_output;
}
// 使用示例
float filtered_accel = low_pass_filter(raw_accel, prev_filtered, 0.2f);
这里alpha值越小,滤波越平滑,但延迟越大。我一般取0.1~0.3之间,具体看传感器采样率。
核心要点:
传感器采集任务必须保证时间确定性。我曾经用FreeRTOS的vTaskDelayUntil来实现固定周期采集,比vTaskDelay更精确。因为vTaskDelayUntil会补偿任务执行时间,保证唤醒间隔恒定。
最后,咱们用一张图总结本章的知识体系:
好了,这一章的内容就这些。记住一句话:飞控软件没有“差不多”,只有“精确”和“炸机”。下一章咱们深入传感器驱动,聊聊怎么把原始数据变成可用的姿态信息。
公众号:蓝海资料掘金营,微信deep3321