4. 条件触发与任务跳转:基于条件(如高度、距离、时间)的任务跳转逻辑,实现动态任务流
各位同学,欢迎来到第四章。
前面几章我们讲了任务规划的基础,航点怎么设,航线怎么画。但说实话,那些都是「死」的任务。飞机按部就班飞完就完事了,对吧?
但实际干活的时候,哪有这么理想?
我举个例子。你让飞机去巡检一条输油管道,飞到一半发现电池电压掉得比预期快。这时候你是让它硬着头皮飞完然后炸机,还是让它立刻跳转到最近的降落点?
答案很明显。这就是我们今天要聊的核心——条件触发与任务跳转。
说白了,就是给任务装上「大脑」。让飞机自己判断:现在该继续,还是该改变计划。
4.1 什么是条件触发?
条件触发,就是设定一个规则。当某个物理量达到阈值,就执行一个动作。
在PX4里,这个「物理量」可以是:
- 高度:比如爬升到50米后,切换下一个动作。
- 距离:比如离目标点还有100米时,提前减速。
- 时间:比如悬停10秒后,开始拍照。
- 电池电量:比如电量低于20%,立刻返航。
- GPS信号质量:比如卫星数少于8颗,暂停任务。
我个人习惯把条件触发分成两类:硬条件和软条件。
| 类型 | 定义 | 典型场景 |
|---|---|---|
| 硬条件 | 不满足就炸机或丢飞机的条件 | 低电量返航、GPS丢失悬停 |
| 软条件 | 为了优化任务效率而设置的条件 | 高度到达后切换速度、时间到后触发拍照 |
嗯,这里要注意。硬条件通常写在飞控的安全机制里(比如COM_FAIL_ACT)。但软条件,才是我们今天任务规划的重点。
4.2 任务跳转的三种基本模式
条件触发了,然后呢?跳转到哪里?
我总结了一下,任务跳转无非三种模式:
- 顺序跳转:满足条件,跳到下一个航点或动作。这是最基础的。
- 条件分支跳转:满足条件A,跳到任务3;满足条件B,跳到任务5。像岔路口。
- 循环/回退跳转:满足条件,跳回之前的某个航点,形成循环。比如盘旋等待。
你想想看,这三种模式组合起来,几乎能覆盖所有动态任务场景。
核心概念:PX4的任务跳转,本质上是修改NAV_CMD队列的指针。你不需要理解底层代码,但你要理解:跳转指令是在当前航点执行完成后才生效的。
4.3 实战:用QGC实现高度触发跳转
我们直接上手。假设一个场景:
飞机从A点起飞,爬升到50米高度后,自动切换到B点执行巡检任务。如果爬升过程中高度低于30米(比如被风吹下去了),就跳转到C点紧急悬停。
在QGC里怎么做?
- 在A点设置起飞动作,目标高度50米。
- 在A点之后插入一个条件航点(Conditional Waypoint)。
- 在条件航点里设置:
高度 >= 50米,跳转到B点。 - 再插入一个条件航点:
高度 < 30米,跳转到C点。 - B点和C点分别设置对应的任务动作。
代码层面,QGC生成的plan文件里,条件跳转对应的MAVLink指令是:
// 条件:高度大于等于50米,跳转到任务序号3
NAV_CMD: MAV_CMD_CONDITION_DELAY
参数1: 0.0 (不延时)
参数2: 0.0
参数3: 0.0
参数4: 0.0
参数5: 50.0 (目标高度)
参数6: 0.0
参数7: 3 (跳转到任务序号3)
注意,这里的参数7是跳转目标的任务序号。这个序号是从0开始数的,别数错了。我曾经有一次把序号写错,飞机直接往反方向飞,吓出一身冷汗。
小技巧:在QGC里,你可以右键点击航点,选择「插入条件航点」。条件航点在列表里会显示为菱形图标,和普通航点不一样,一眼就能认出来。
4.4 时间触发:延时与等待
时间触发是最常用的条件之一。比如:
- 到达目标点后,悬停5秒再拍照。
- 每隔10秒拍一张照片,连续拍10张。
- 等待30秒,让机载传感器完成校准。
在PX4里,时间触发主要通过MAV_CMD_CONDITION_DELAY实现。
举个例子,让飞机在航点2悬停10秒:
// 航点2:悬停,并延时10秒
NAV_CMD: MAV_CMD_NAV_WAYPOINT
参数1: 10 (停留时间,单位秒)
参数2: 0.0
参数3: 0.0
参数4: 0.0
参数5: 纬度
参数6: 经度
参数7: 高度
你看,其实MAV_CMD_NAV_WAYPOINT的第一个参数就是停留时间。但如果你需要更复杂的延时逻辑(比如先延时,再判断),那就得用CONDITION_DELAY。
我个人习惯是:简单的停留用航点参数,复杂的条件逻辑用条件指令。这样plan文件看起来更清晰。
4.5 距离触发:提前预判
距离触发,说白了就是「离目标还有多远」。这个在避障和精准降落里特别有用。
比如:
- 距离目标点还有50米时,切换到低速模式。
- 距离降落点还有10米时,开启降落灯。
- 距离禁飞区边界还有100米时,触发绕飞逻辑。
PX4里距离触发对应的指令是MAV_CMD_CONDITION_DISTANCE。
// 条件:距离目标点小于50米,跳转到任务序号5
NAV_CMD: MAV_CMD_CONDITION_DISTANCE
参数1: 50.0 (距离阈值,单位米)
参数2: 0.0
参数3: 0.0
参数4: 0.0
参数5: 0.0
参数6: 0.0
参数7: 5 (跳转到任务序号5)
这里有个坑,我必须要说。
避坑指南:我曾经在山区测试距离触发,结果飞机一直不触发跳转。排查了半天,发现是GPS高度误差太大,导致水平距离计算偏差。记住,距离触发依赖GPS精度。在峡谷或高楼附近,GPS信号差,距离触发可能失效。建议配合视觉或激光测距使用。
4.6 组合条件:AND与OR的逻辑
单个条件好办,但现实往往是多个条件同时判断。比如:
「高度大于50米 并且 距离目标小于100米」才触发拍照。
或者:
「电池低于20% 或者 风速超过10m/s」就返航。
PX4原生不支持直接的AND/OR逻辑组合。但我们可以通过任务序列的巧妙编排来实现。
方法很简单:
- AND逻辑:把两个条件航点串起来。第一个条件满足后,跳到第二个条件;第二个条件也满足,才跳到目标动作。
- OR逻辑:用两个条件航点指向同一个目标动作。任何一个条件满足,都跳过去。
举个例子,AND逻辑的任务序列:
| 序号 | 指令 | 说明 |
|---|---|---|
| 0 | 起飞到50米 | 初始动作 |
| 1 | 条件:高度 >= 50米 → 跳转到2 | 第一个条件 |
| 2 | 条件:距离目标 < 100米 → 跳转到3 | 第二个条件 |
| 3 | 触发拍照 | 目标动作 |
你看,只有两个条件都满足,飞机才会走到序号3。这就是AND逻辑。
经验之谈:组合条件虽然灵活,但别搞太复杂。我见过有人写了七八个条件航点串在一起,最后自己都搞不清逻辑了。我的建议是:组合条件不超过3层。超过3层,不如用机载计算机(如树莓派)跑外部逻辑,然后通过MAVSDK下发指令。
4.7 动态任务流的完整示例
我们来画一个完整的动态任务流。假设我们要执行一个「智能巡检」任务:
- 起飞到安全高度。
- 飞到巡检区域A。
- 如果电池电量 > 60%,执行A区巡检(10个航点)。
- 如果电池电量 ≤ 60%,直接跳转到最近的降落点。
- 巡检完成后,如果还有时间(任务总时长 < 30分钟),飞到B区继续巡检。
- 否则,返航降落。
这个任务流包含了高度、电量、时间三种条件,以及多次跳转。下面我用SVG画出来,大家感受一下。
这个流程图,说白了就是我今天讲的所有内容的浓缩。你把这个图看懂了,条件触发和任务跳转你就掌握了八成。
4.8 常见坑与调试技巧
最后,我分享几个实战中踩过的坑,以及对应的调试方法。
- 坑1:条件航点不触发
- 原因:阈值设置不合理,或者传感器数据更新频率太低。
- 解决:在QGC的MAVLink Inspector里实时观察传感器数据,确认阈值是否可达。
- 坑2:跳转序号错误
- 原因:任务序号从0开始,但人习惯从1开始数。
- 解决:在QGC里打开任务列表,确认每个航点的序号。我习惯在plan文件里用注释标注序号。
- 坑3:组合条件逻辑混乱
- 原因:条件航点太多,自己都忘了哪个跳哪个。
- 解决:画流程图。就像我上面那张SVG图一样,画出来就清楚了。
- 坑4:跳转后飞机行为异常
- 原因:跳转目标航点的动作参数不兼容(比如跳到了一个没有高度信息的航点)。
- 解决:确保跳转目标航点包含完整的导航信息(经纬度、高度、动作类型)。
调试利器:PX4的mavlink status命令可以实时查看当前任务序号和下一个目标序号。在终端里跑mavlink status | grep mission,就能看到任务执行进度。这个命令我几乎天天用。
好了,第四章就到这里。条件触发和任务跳转,是让无人机从「死飞」变成「智飞」的关键。你回去之后,拿一台测试机,在安全环境下多试试各种条件组合。相信我,试过几次之后,你就会发现——原来任务规划可以这么灵活。