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(故障保护)这三个状态,决定了飞控能不能输出油门、要不要执行应急动作。

我画了一张状态机转换图,你看完就明白了:

PX4 状态机核心转换图 DISARMED 上锁 / 待机 ARMED 解锁 / 飞行中 FAILSAFE 故障保护 / 应急 解锁指令 / 安全检查通过 上锁指令 / 落地自动上锁 故障触发 / 遥控器丢失 / 低电量 故障恢复 / 手动上锁 ⚠ 注意: FAILSAFE 状态下,飞控会执行预设的应急动作(如立即降落或返航)。 从 FAILSAFE 恢复到 ARMED 需要手动干预,不会自动恢复。

这张图里,我最想让你记住的是 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 定位在解锁后才开始参与控制。

一句话总结:模式决定「怎么飞」,状态机决定「能不能飞」。排查问题时,先看状态机是否正常,再看模式切换是否合理。顺序搞反了,你可能会在错误的方向上浪费大量时间。