3. 飞行模式基础概念:模式的定义、模式切换逻辑、模式与任务(Mission)的关系
好,咱们进入第三章。这一章我打算把飞行模式这个核心概念彻底讲透。很多新手一上来就急着写代码,结果连模式是怎么切换的都没搞明白,最后调试时一脸懵。我当年也踩过这个坑,所以今天咱们把基础打牢。
3.1 模式到底是什么?
说白了,飞行模式就是飞控的一套「行为规则集合」。你切换一个模式,就等于告诉飞控:「从现在开始,按这套规则来干活」。
举个例子:
- Stabilize模式:飞控只管把姿态稳住,你松手它就保持当前角度。不会自己往前飞。
- Loiter模式:飞控不仅要稳住姿态,还要锁定GPS位置。你松手,它悬停在那不动。
- Auto模式:飞控完全接管,按你预先规划好的航点一个个飞过去。
每个模式背后,都对应着一套完整的控制逻辑。在ArduPilot的代码里,每个模式都是一个独立的类,继承自Mode基类。我习惯把模式理解成「飞控的多种人格」——同一个硬件,换了个模式就像换了个人。
核心要点:模式 = 控制逻辑 + 传感器需求 + 用户交互方式 的三位一体。
3.2 模式切换逻辑
模式怎么切?这个问题看似简单,其实门道不少。ArduPilot支持三种切换方式:
- 遥控器通道切换:最常见的方式。通过遥控器上的三段开关或旋钮,映射到飞控的某个RC通道。我在项目中遇到过用户把通道映射搞反了,一拨开关直接切到RTL,飞机往回飞撞树……嗯,所以一定要在地面站里先验证通道映射。
- 地面站指令切换:通过Mission Planner等地面站,发送MAVLink指令
MAV_CMD_DO_SET_MODE。调试时很方便。 - 脚本/代码触发:在自定义模式或任务脚本里,通过
set_mode()函数主动切换。这个我们后面章节会大量用到。
切换时,飞控内部会做几件事:
- 检查当前模式是否允许退出(比如正在执行关键任务)
- 调用旧模式的
exit()方法,清理资源 - 调用新模式的
init()方法,初始化参数 - 更新
control_mode变量
注意:不是所有模式之间都能随意切换。比如从Auto模式切到Stabilize,飞控会丢掉当前任务进度。我曾经遇到过用户在空中误切模式,导致任务中断,飞机直接悬停在那不动了。所以,关键任务阶段建议锁定模式切换。
3.3 模式与任务(Mission)的关系
这是最容易混淆的地方。我直接说结论:模式是「怎么飞」,任务是「飞去哪」。
任务(Mission)是一系列航点(Waypoint)和动作指令的集合。它存储在飞控的EEPROM里,像一个剧本。而模式是执行这个剧本时的「表演风格」。
举个例子你就明白了:
- 你规划了一个任务:从A点飞到B点,然后拍照,再飞到C点降落。
- 如果你在Auto模式下执行这个任务,飞控会严格按照航点飞,速度、高度都按预设来。
- 如果你在Guided模式下执行同一个任务,飞控会允许你随时用地面站或摇杆干预,改变目标点。
- 如果你在Loiter模式下,任务根本不会执行——因为Loiter模式不读取任务队列。
所以,模式和任务是两个维度的东西。任务定义了「做什么、去哪做」,模式定义了「以什么风格做」。我习惯把任务比作乐谱,模式比作演奏风格——同样的乐谱,用古典风格和爵士风格演奏出来完全不同。
我的经验:在自定义模式开发中,你完全可以创建一个新模式,让它读取任务队列但用不同的方式执行。比如我做过一个「安全巡逻模式」,它读取任务航点,但飞行速度自动根据风速调整,遇到障碍物还会绕行。这就是「模式」对「任务」的二次加工。
3.4 模式与任务的状态机关系
为了让你更直观地理解,我画了一张图。这张图展示了模式、任务、飞控主循环之间的核心逻辑关系。
这张图你看懂了吗?核心逻辑是这样的:
- 飞控主循环每4毫秒跑一次,每次都会调用当前模式的
update()方法。 - 模式选择器根据遥控器或地面站的指令,决定当前激活哪个模式。
- 只有Auto模式会主动读取任务队列。其他模式要么忽略任务,要么只读取但不执行(比如Guided模式)。
- 任务队列执行完毕后,会通知模式选择器,触发模式切换(比如切到Loiter或RTL)。
一个小技巧:在自定义模式里,你可以通过
mission.get_current_nav_cmd()随时读取当前任务指令。我做过一个「半自动模式」:飞控按任务飞,但用户可以通过摇杆临时调整高度和速度,松开摇杆后自动回到任务轨迹。这就是模式和任务灵活组合的例子。
3.5 避坑指南
最后,分享几个我实际踩过的坑:
- 模式切换时的瞬态问题:从Loiter切到Auto时,如果飞机当前位置和任务第一个航点距离很远,飞控会猛打油门冲过去。我建议在切换前先检查距离,如果太远就先切到Guided模式慢慢靠近。
- 任务队列为空时切Auto:飞控会直接进入悬停状态,不会报错。你可能会觉得飞机「卡住了」。其实不是卡住,是没任务可执行。
- 模式优先级:有些模式有隐式优先级。比如RTL(返航)模式的优先级高于其他模式。如果你在Auto模式下触发了RTL,飞控会中断任务直接返航。这个逻辑在
AP_Mission.cpp里写得很清楚。
嗯,这一章的内容就到这里。模式和任务的关系,说白了就是「怎么飞」和「飞去哪」的区别。搞懂这个,后面写自定义模式时你就能游刃有余了。
公众号:蓝海资料掘金营,微信deep3321