4、飞行模式与状态机:PX4飞行模式详解、模式切换日志分析、状态机转换
飞行模式,说白了就是飞控的「性格切换」。同一个架飞机,在手动模式它就是个愣头青,你推杆它就冲;到了定高模式,它就开始自己管油门了;切到任务模式,它完全按航线飞,你动杆子它都不理你。
我刚开始带飞手培训时,发现很多人把模式切换当成「换个手感」那么简单。直到有一次,一个学员在降落前从任务模式切回自稳,结果飞机直接砸地——因为他忘了自稳模式不会自动保持高度。嗯,从那以后,我每次讲飞行模式都会先强调一句:模式切换,本质上是状态机的状态转移。
4.1 PX4飞行模式全景
PX4 的模式体系,我习惯把它分成三大类:
| 类别 | 典型模式 | 核心特征 |
|---|---|---|
| 手动模式 | 自稳(Stabilized)、特技(Acro)、手动(Manual) | 飞手直接控制姿态/油门,飞控只做基础增稳 |
| 辅助模式 | 定高(Altitude)、定点(Position)、返航(RTL) | 飞控接管部分自由度,飞手控制剩余通道 |
| 全自动模式 | 任务(Mission)、降落(Land)、起飞(Takeoff) | 飞控完全自主飞行,飞手只做监控和干预 |
你想想看,这三种模式对应的是完全不同的控制回路。手动模式走的是角速度环,辅助模式加了速度环和位置环,全自动模式还要叠加导航逻辑。模式切错了,控制回路就断了。
关键认知:模式切换不是「换个手感」,而是「换一套控制律」。飞控在切换瞬间会重新初始化控制器状态,如果切换时机不对(比如大姿态下切模式),飞控可能产生剧烈响应。
4.2 模式切换日志分析
日志里怎么看模式切换?我一般直接搜 commander 模块的 NAV_STATE 变化。在 PX4 的 .ulog 文件里,模式切换会记录在 vehicle_status 主题中。
举个例子,这是我从一次炸机日志里截取的关键片段:
# 时间戳 nav_state arming_state
0:01.234 5 (Auto.Loiter) 2 (Armed)
0:01.567 3 (Auto.RTL) 2 (Armed) ← 触发返航
0:01.890 2 (Auto.Land) 2 (Armed) ← 进入降落
0:02.100 2 (Auto.Land) 1 (Disarmed) ← 落地解锁
那次炸机的原因很简单:飞手在远距离触发 RTL,但返航点没更新,飞机直接往起飞点飞,撞上了中途的高压线。日志里 NAV_STATE 从 Loiter 切到 RTL 那一下,时间戳和 GPS 坐标都对得上,但高度设置有问题。
我的排查习惯:拿到日志后,先用 ulog_info 看 vehicle_status 的更新频率。如果模式切换间隔小于 0.5 秒,说明飞手在频繁切模式,或者 RC 通道有抖动。我曾经遇到过遥控器三段开关接触不良,导致模式在自稳和定点之间来回跳,飞机在天上跟抽风一样。
4.3 状态机转换:ARM / DISARM / FAILSAFE
状态机是飞控的「生死线」。ARM(解锁)、DISARM(上锁)、FAILSAFE(故障保护)这三个状态,决定了飞控能不能输出油门、要不要执行应急动作。
我画了一张状态机转换图,你看完就明白了:
这张图里,我最想让你记住的是 FAILSAFE 到 DISARMED 那条路径。很多人以为故障解除了飞机就能继续飞,其实不是。飞控一旦进入 FAILSAFE,执行完应急动作后就会上锁,你必须重新解锁才能起飞。
我曾经踩过的坑:有一次测试,飞机在空中触发低电量 RTL,落地后自动上锁。我换完电池想继续飞,结果怎么解锁都解不开。查了半天才发现,FAILSAFE 触发后,飞控会把 arming_state 锁死在 DISARMED,必须通过地面站发送 arm_disarm 指令才能恢复。后来我在所有测试流程里都加了一条:FAILSAFE 触发后,先检查状态机,再换电池。
4.4 日志中状态机转换的实战排查
日志里看状态机转换,我一般关注三个字段:
arming_state:0=初始化,1=上锁,2=解锁,3=故障保护nav_state:当前导航状态(对应具体飞行模式)failsafe:故障保护标志位,0=正常,1=触发
举个例子,有一次用户反馈飞机在空中突然掉高。我拿到日志后,先画了状态机时间线:
时间轴:
0:00.000 arming_state=2 (Armed) nav_state=4 (Auto.Mission)
0:05.200 arming_state=2 (Armed) nav_state=3 (Auto.RTL) ← 触发返航
0:05.210 failsafe=1 ← 故障标志置位
0:06.800 arming_state=2 (Armed) nav_state=2 (Auto.Land) ← 进入降落
0:07.500 arming_state=1 (Disarmed) ← 落地上锁
问题出在哪?failsafe 在 0:05.210 置位,但 nav_state 在 0:05.200 就已经切到 RTL 了。说明故障触发和模式切换几乎同时发生。再查 RC 信号,发现遥控器在 0:05.200 那一瞬间丢失了信号——原来是飞手飞到了遮挡区。
排查技巧:如果日志里 arming_state 在飞行中突然从 2 跳到 1,别急着怀疑飞控。先看 failsafe 有没有置位,再看 battery_status 的电压曲线。我遇到过好几次,其实是电池电压瞬间掉到保护阈值以下,飞控主动上锁保命。
4.5 模式与状态机的联动关系
模式和状态机不是独立的。同一个模式,在不同状态机阶段表现完全不同。我整理了一张对照表:
| 模式 | DISARMED 状态 | ARMED 状态 | FAILSAFE 状态 |
|---|---|---|---|
| 自稳 (Stabilized) | 飞控输出零油门,电机不转 | 飞手控制姿态,飞控增稳 | 执行 FAILSAFE 动作(默认降落) |
| 定点 (Position) | 同上,GPS 定位不生效 | 飞控保持位置和高度 | 执行 FAILSAFE 动作(默认返航) |
| 任务 (Mission) | 任务航点已加载,但不执行 | 按航点自动飞行 | 中断任务,执行 FAILSAFE |
你看,同一个定点模式,在 DISARMED 状态下 GPS 定位是不起作用的。我见过有人在地面站上看到 GPS 锁星了,就以为定点模式能用了,结果一解锁飞机直接飘走——因为 GPS 定位在解锁后才开始参与控制。
一句话总结:模式决定「怎么飞」,状态机决定「能不能飞」。排查问题时,先看状态机是否正常,再看模式切换是否合理。顺序搞反了,你可能会在错误的方向上浪费大量时间。