飞控算法从入门到精通 · 108 · 实时性分析:任务执行时间与抖动
从一次炸机说起
去年夏天,我在调试一架四轴穿越机。PID参数调得差不多了,悬停稳得像钉在天空里。然后我加了一段“看起来很酷”的航点跟踪逻辑——在控制循环里插了个EKF更新、一个路径平滑、还有一个串口日志打印。飞起来三秒,电机突然啸叫,飞机翻了个跟头栽进草丛。
事后复盘,那段代码在正常工况下跑完大约1.2ms,但偶尔会跳到3.8ms。而我的控制周期是2ms。当任务执行时间超过周期,下一个控制输出就晚了,电机指令滞后,姿态失控。这就是实时性崩溃的典型症状——不是算力不够,是抖动把时序打碎了。
任务执行时间:你以为的“稳定”是假象
很多初学者喜欢用micros()或者clock_gettime()在代码里打点测时间,然后看到“平均执行时间0.5ms”就放心了。别这样写。平均时间骗人,最坏情况才是杀手。
飞控里的任务执行时间由三部分构成:
- 确定性部分:固定循环、查表、简单算术。这部分时间基本不变。
- 数据依赖部分:比如根据传感器读数做分支判断,不同分支耗时不同。气压计更新时做一次卡尔曼滤波,和只做一次滑动平均,时间差可能翻倍。
- 中断干扰部分:高优先级中断(比如DMA传输完成、定时器溢出)会抢占当前任务,导致执行时间被“拉长”。