3. 指令链设计原则:顺序执行、条件跳转、时间触发、事件触发

指令链,说白了就是让无人机按你预设的剧本一步步走。但剧本怎么写,决定了飞行的可靠性和灵活性。我见过不少项目,指令链写得像一团乱麻,飞着飞着就卡住了。今天咱们把这四种核心设计原则掰开揉碎讲清楚。

3.1 顺序执行——最基础也是最可靠的骨架

顺序执行是指令链的默认模式。每条指令执行完,自动进入下一条。就像排队打饭,一个接一个,不会插队。

核心特征:指令按编号递增依次执行,无分支、无等待、无跳转。

我在早期做测绘无人机时,航点任务几乎全是顺序执行。起飞→爬升到50米→飞向第一个航点→拍照→飞向第二个航点→拍照→……→返航降落。简单直接,不容易出错。

MAVLink里怎么表示顺序执行?其实不需要额外字段。只要MISSION_ITEM的command字段填上MAV_CMD_NAV_WAYPOINT,current字段按顺序递增,飞控自然就按顺序走了。

// 顺序执行示例:三个航点
MISSION_ITEM #0: MAV_CMD_NAV_TAKEOFF, param1=10 (爬升到10米)
MISSION_ITEM #1: MAV_CMD_NAV_WAYPOINT, x=114.05, y=22.55 (第一个航点)
MISSION_ITEM #2: MAV_CMD_NAV_WAYPOINT, x=114.06, y=22.56 (第二个航点)
MISSION_ITEM #3: MAV_CMD_NAV_RETURN_TO_LAUNCH (返航)

但顺序执行有个硬伤——它没有应变能力。如果第二个航点遇到禁飞区,飞控不会自己跳过,只会傻傻地尝试。所以,光有顺序执行是不够的。

3.2 条件跳转——让无人机学会做决定

条件跳转是给指令链装上「大脑」。飞控在执行某条指令后,检查一个条件,满足就跳到指定编号的指令,不满足就继续往下走。

为什么会需要这个?我举个例子。有一次做电力巡检,无人机需要检查三座塔。但天气突变,风力超过6级。如果还是顺序执行,飞机会硬着头皮飞完,风险很大。有了条件跳转,就可以在起飞前加一条「风力检测」指令,超标就直接跳到「返航」。

跳转类型 MAVLink命令 典型场景
无条件跳转 MAV_CMD_DO_JUMP 循环执行某段任务
条件跳转 MAV_CMD_CONDITION_DELAY + DO_JUMP 等待条件满足后跳转
距离条件 MAV_CMD_CONDITION_DISTANCE 飞到离目标一定距离时触发
高度条件 MAV_CMD_CONDITION_ALTITUDE 爬升到指定高度后跳转

注意:条件跳转容易写出死循环。我曾经见过一个案例,条件判断写反了,无人机一直在两个航点之间来回跳,直到电池耗尽。设计时一定要加「最大循环次数」保护。

3.3 时间触发——精确到毫秒的节奏控制

时间触发,就是让指令在预设的时间点执行。不是「做完A再做B」,而是「在T时刻做B」。

这在摄影测量中特别重要。比如做正射影像,需要每隔2秒拍一张照片,保证重叠率。如果用顺序执行,拍照指令执行完才进入下一个,但拍照本身耗时不确定,会导致照片间隔不均匀。

MAVLink里时间触发主要通过MAV_CMD_CONDITION_DELAY实现。它会让飞控暂停执行后续指令,直到延迟时间结束。

// 时间触发示例:每3秒拍一张,共拍5张
MISSION_ITEM #0: MAV_CMD_NAV_WAYPOINT (飞到目标区域)
MISSION_ITEM #1: MAV_CMD_CONDITION_DELAY, param1=3 (等待3秒)
MISSION_ITEM #2: MAV_CMD_IMAGE_START_CAPTURE (拍照)
MISSION_ITEM #3: MAV_CMD_CONDITION_DELAY, param1=3 (再等3秒)
MISSION_ITEM #4: MAV_CMD_IMAGE_START_CAPTURE (再拍)
// ... 重复5次

我个人习惯把时间触发和顺序执行配合使用。时间触发管「节奏」,顺序执行管「流程」。但要注意,CONDITION_DELAY是阻塞的——飞控在这段时间里不会做其他事。如果延迟太长,飞机会悬停等待,耗电很快。

小技巧:如果需要在等待期间保持飞行(比如绕圈),可以在CONDITION_DELAY之前加一个MAV_CMD_NAV_LOITER_TIME,让飞机边盘旋边等。

3.4 事件触发——对外部变化做出响应

事件触发是最高级的玩法。指令链不再按固定时间或顺序走,而是等某个「事件」发生才执行。这个事件可以是传感器数据、遥控器信号、甚至是另一架飞机的MAVLink消息。

我做过一个集群编队项目,5架无人机需要保持队形。如果其中一架掉队了,其他飞机不能傻等,必须触发「重新编队」事件。这就是典型的事件触发。

MAVLink里事件触发没有专门的命令,但可以通过组合实现:

  • 距离事件:MAV_CMD_CONDITION_DISTANCE——飞到离目标xx米时触发
  • 高度事件:MAV_CMD_CONDITION_ALTITUDE——爬升/下降到xx米时触发
  • 自定义事件:通过MAV_CMD_DO_SET_MISSION_CURRENT动态跳转

举个例子,你想让无人机在发现某个目标(比如红色气球)时自动切换任务。地面站检测到目标后,发送MISSION_SET_CURRENT消息,把当前指令指针跳到「跟踪模式」的起始编号。飞控收到后立即中断当前任务,开始执行新指令链。

// 事件触发流程(地面站侧)
1. 飞控执行常规航点任务
2. 地面站图像识别检测到目标
3. 地面站发送:MISSION_SET_CURRENT(seq=10)
4. 飞控跳转到第10条指令(跟踪模式)
5. 开始执行跟踪指令链

避坑指南:我曾经在事件触发上栽过跟头。事件触发后,原来的指令链状态(比如已经飞了几个航点)全部丢失。如果你需要恢复原任务,一定要在跳转前保存上下文。我的做法是在跳转前插入一条MAV_CMD_DO_SET_MISSION_CURRENT记录当前序号,存到飞控的参数里。

3.5 四种原则的协同与选择

实际项目中,这四种原则很少单独使用。我画了一张图,帮你理清它们的关系:

指令链设计原则协同框架 MAVLink指令链 顺序执行 条件跳转 时间触发 事件触发 实际任务中,四种原则通常混合使用:顺序执行做骨架,条件跳转做分支,时间触发做节奏,事件触发做应急 基础航点任务 避障/绕飞/循环 定时拍照/采样 集群/应急响应 设计建议 1. 优先用顺序执行,简单可靠 2. 条件跳转要加循环次数限制 3. 时间触发注意电池消耗 4. 事件触发记得保存上下文 5. 混合使用时画好状态机

你看,这四种原则不是互斥的。我一般这样选:

  • 简单任务(如单点拍照):只用顺序执行就够了
  • 巡检任务(如多塔检测):顺序执行 + 条件跳转(遇到障碍就跳过)
  • 测绘任务(如正射影像):顺序执行 + 时间触发(定时拍照)
  • 复杂任务(如集群编队):四种全上,但事件触发做最高优先级

我的经验:设计指令链时,先画状态机图,再写MAVLink指令。状态机里每个状态对应一组指令,状态之间的转换就是条件跳转或事件触发。这样逻辑清晰,不容易漏掉边界情况。

嗯,这四种原则是指令链设计的基石。理解透了,后面讲具体指令组合和优化时,你就能明白为什么有些设计是「好」的,有些是「坑」的。记住一点:没有万能的原则,只有适合场景的设计。