3. 飞行模式基础概念:模式的定义、模式切换逻辑、模式与任务(Mission)的关系

好,咱们进入第三章。这一章我打算把飞行模式这个核心概念彻底讲透。很多新手一上来就急着写代码,结果连模式是怎么切换的都没搞明白,最后调试时一脸懵。我当年也踩过这个坑,所以今天咱们把基础打牢。

3.1 模式到底是什么?

说白了,飞行模式就是飞控的一套「行为规则集合」。你切换一个模式,就等于告诉飞控:「从现在开始,按这套规则来干活」。

举个例子:

  • Stabilize模式:飞控只管把姿态稳住,你松手它就保持当前角度。不会自己往前飞。
  • Loiter模式:飞控不仅要稳住姿态,还要锁定GPS位置。你松手,它悬停在那不动。
  • Auto模式:飞控完全接管,按你预先规划好的航点一个个飞过去。

每个模式背后,都对应着一套完整的控制逻辑。在ArduPilot的代码里,每个模式都是一个独立的类,继承自Mode基类。我习惯把模式理解成「飞控的多种人格」——同一个硬件,换了个模式就像换了个人。

核心要点:模式 = 控制逻辑 + 传感器需求 + 用户交互方式 的三位一体。

3.2 模式切换逻辑

模式怎么切?这个问题看似简单,其实门道不少。ArduPilot支持三种切换方式:

  1. 遥控器通道切换:最常见的方式。通过遥控器上的三段开关或旋钮,映射到飞控的某个RC通道。我在项目中遇到过用户把通道映射搞反了,一拨开关直接切到RTL,飞机往回飞撞树……嗯,所以一定要在地面站里先验证通道映射。
  2. 地面站指令切换:通过Mission Planner等地面站,发送MAVLink指令MAV_CMD_DO_SET_MODE。调试时很方便。
  3. 脚本/代码触发:在自定义模式或任务脚本里,通过set_mode()函数主动切换。这个我们后面章节会大量用到。

切换时,飞控内部会做几件事:

  • 检查当前模式是否允许退出(比如正在执行关键任务)
  • 调用旧模式的exit()方法,清理资源
  • 调用新模式的init()方法,初始化参数
  • 更新control_mode变量
注意:不是所有模式之间都能随意切换。比如从Auto模式切到Stabilize,飞控会丢掉当前任务进度。我曾经遇到过用户在空中误切模式,导致任务中断,飞机直接悬停在那不动了。所以,关键任务阶段建议锁定模式切换。

3.3 模式与任务(Mission)的关系

这是最容易混淆的地方。我直接说结论:模式是「怎么飞」,任务是「飞去哪」

任务(Mission)是一系列航点(Waypoint)和动作指令的集合。它存储在飞控的EEPROM里,像一个剧本。而模式是执行这个剧本时的「表演风格」。

举个例子你就明白了:

  • 你规划了一个任务:从A点飞到B点,然后拍照,再飞到C点降落。
  • 如果你在Auto模式下执行这个任务,飞控会严格按照航点飞,速度、高度都按预设来。
  • 如果你在Guided模式下执行同一个任务,飞控会允许你随时用地面站或摇杆干预,改变目标点。
  • 如果你在Loiter模式下,任务根本不会执行——因为Loiter模式不读取任务队列。

所以,模式和任务是两个维度的东西。任务定义了「做什么、去哪做」,模式定义了「以什么风格做」。我习惯把任务比作乐谱,模式比作演奏风格——同样的乐谱,用古典风格和爵士风格演奏出来完全不同。

我的经验:在自定义模式开发中,你完全可以创建一个新模式,让它读取任务队列但用不同的方式执行。比如我做过一个「安全巡逻模式」,它读取任务航点,但飞行速度自动根据风速调整,遇到障碍物还会绕行。这就是「模式」对「任务」的二次加工。

3.4 模式与任务的状态机关系

为了让你更直观地理解,我画了一张图。这张图展示了模式、任务、飞控主循环之间的核心逻辑关系。

飞控主循环 (250Hz) 模式选择器 Stabilize 模式 姿态稳定,无位置控制 Loiter 模式 GPS位置锁定悬停 Auto 模式 执行任务队列 任务队列 (Mission) 读取航点 任务完成/失败通知 遥控器通道 地面站指令 脚本/代码触发 set_mode() 控制流 数据流 模式实例

这张图你看懂了吗?核心逻辑是这样的:

  • 飞控主循环每4毫秒跑一次,每次都会调用当前模式的update()方法。
  • 模式选择器根据遥控器或地面站的指令,决定当前激活哪个模式。
  • 只有Auto模式会主动读取任务队列。其他模式要么忽略任务,要么只读取但不执行(比如Guided模式)。
  • 任务队列执行完毕后,会通知模式选择器,触发模式切换(比如切到Loiter或RTL)。
一个小技巧:在自定义模式里,你可以通过mission.get_current_nav_cmd()随时读取当前任务指令。我做过一个「半自动模式」:飞控按任务飞,但用户可以通过摇杆临时调整高度和速度,松开摇杆后自动回到任务轨迹。这就是模式和任务灵活组合的例子。

3.5 避坑指南

最后,分享几个我实际踩过的坑:

  • 模式切换时的瞬态问题:从Loiter切到Auto时,如果飞机当前位置和任务第一个航点距离很远,飞控会猛打油门冲过去。我建议在切换前先检查距离,如果太远就先切到Guided模式慢慢靠近。
  • 任务队列为空时切Auto:飞控会直接进入悬停状态,不会报错。你可能会觉得飞机「卡住了」。其实不是卡住,是没任务可执行。
  • 模式优先级:有些模式有隐式优先级。比如RTL(返航)模式的优先级高于其他模式。如果你在Auto模式下触发了RTL,飞控会中断任务直接返航。这个逻辑在AP_Mission.cpp里写得很清楚。

嗯,这一章的内容就到这里。模式和任务的关系,说白了就是「怎么飞」和「飞去哪」的区别。搞懂这个,后面写自定义模式时你就能游刃有余了。


公众号:蓝海资料掘金营,微信deep3321