3. 航点数据结构:坐标、动作与参数
航点,说白了就是无人机在天空中要踩的一个个「脚印」。但光有位置还不够——飞机到了那个点要干什么?飞多快?停多久?这些信息都得打包进一个数据结构里。
我最早接触航点数据时,用的是大疆的 Waypoint Mission 格式。那时候踩过不少坑,比如动作参数写错了,飞机在航点上空转圈就是不降落。嗯,今天咱们就把这个数据结构彻底拆开讲清楚。
3.1 航点坐标:经纬度与海拔
每个航点最核心的信息就是位置。通常用三个值表示:
- 纬度(Latitude):范围 -90° 到 +90°,北正南负
- 经度(Longitude):范围 -180° 到 +180°,东正西负
- 海拔(Altitude):单位米,通常指相对起飞点的高度(相对高)或 WGS84 椭球高(绝对高)
关键点:海拔类型一定要提前约定。我见过一个项目,飞控用相对高,地面站用绝对高,结果飞机在山区直接撞山。血的教训。
坐标精度方面,一般保留 6-7 位小数就够了。再多也没意义,因为民用 GPS 的精度也就那样。
// 一个典型的航点坐标结构
{
"latitude": 39.9042, // 北纬 39.9042°
"longitude": 116.4074, // 东经 116.4074°
"altitude": 50.0, // 相对起飞点 50 米
"altitudeType": "relative" // relative 或 absolute
}
3.2 航点动作:到了点要干什么
飞机飞到航点后,可以执行一系列动作。我个人习惯把动作分成三类:
| 动作类型 | 典型动作 | 说明 |
|---|---|---|
| 云台动作 | 俯仰、偏航、回中 | 控制相机朝向 |
| 拍照/录像 | 单拍、连拍、开始录像、停止录像 | 数据采集核心 |
| 飞行器动作 | 悬停、降落、返航、设置航向 | 改变飞行状态 |
动作的执行顺序也很重要。我一般建议:先调整云台,再拍照,最后做飞行器动作。为什么?因为云台稳定需要时间,拍完照再动飞机,画面不会糊。
小技巧:如果你做测绘,每个航点建议加一个「云台俯仰 -90°」的动作,保证相机正对地面。我曾经漏了这个参数,飞了 200 个航点,回来发现一半照片是天空。
// 航点动作示例
"actions": [
{
"actionType": "gimbalPitch",
"actionParam": -90, // 云台俯仰 -90°(正对地面)
"actionDelay": 1 // 动作执行前等待 1 秒
},
{
"actionType": "takePhoto",
"actionParam": 0, // 单拍
"actionDelay": 0
}
]
3.3 航点参数:速度、高度与悬停时间
这部分是航点任务的「调性」所在。同样的航线,参数不同,飞出来的效果天差地别。
3.3.1 速度
速度分两种:航段速度和航点速度。
- 航段速度:飞机从一个航点到下一个航点的飞行速度
- 航点速度:飞机到达航点后,执行动作时的速度(通常为 0,即悬停)
我建议航段速度控制在 5-15 m/s 之间。太快了,照片容易模糊;太慢了,电池扛不住。
注意:转弯处的速度要单独处理。我曾经设了 12 m/s 的航段速度,结果在 90° 转弯处飞机差点侧翻。后来我加了转弯半径参数,才把问题解决。
3.3.2 高度
高度参数可以每个航点单独设置,也可以整条航线统一。我个人习惯:
- 平坦地形:统一高度,省事
- 起伏地形:每个航点单独设高度,跟随地形
高度变化率也要注意。一般不超过 5 m/s,否则飞控容易触发高度保护。
3.3.3 悬停时间
悬停时间,就是飞机在航点停留的秒数。这个参数直接影响任务总时长。
举个例子:
// 悬停时间参数
"hoverTime": 2 // 单位:秒,范围 0-3600
如果每个航点悬停 2 秒,100 个航点就是 200 秒。再加上飞行时间,总时长很容易超过电池极限。所以,非必要不悬停。
3.4 完整航点数据结构示例
把上面所有东西拼起来,一个完整的航点数据大概长这样:
{
"waypoints": [
{
"latitude": 39.9042,
"longitude": 116.4074,
"altitude": 50.0,
"altitudeType": "relative",
"speed": 10.0, // 航段速度 10 m/s
"hoverTime": 2, // 悬停 2 秒
"headingMode": "auto", // 航向模式:auto/fixed/target
"actions": [
{
"actionType": "gimbalPitch",
"actionParam": -90,
"actionDelay": 1
},
{
"actionType": "takePhoto",
"actionParam": 0,
"actionDelay": 0
}
]
}
// ... 更多航点
],
"globalParams": {
"defaultSpeed": 12.0, // 默认航段速度
"defaultHoverTime": 0, // 默认悬停时间
"finishAction": "hover", // 任务结束动作:hover/return/land
"exitOnRCLost": "return" // 遥控器信号丢失后:hover/return/land
}
}
核心原则:全局参数作为兜底,航点参数作为覆盖。如果某个航点没设 speed,就沿用全局的 defaultSpeed。这样既灵活又简洁。
3.5 知识体系总览
下面这张图把航点数据结构的核心逻辑串起来了。你一看就明白:
3.6 避坑指南
最后,分享几个我踩过的坑:
- 坐标系统一:整个任务必须用同一个坐标系。WGS84 和 GCJ02 混用?飞机直接飞偏。
- 海拔检查:相对高要确保起飞点海拔正确。我在高原飞过一次,忘了调基准面,飞机差点撞山。
- 动作超时:每个动作最好设一个超时时间。比如云台俯仰,如果 5 秒没到位,直接跳过。否则飞机一直等,电池耗光。
- 悬停时间别太长:超过 30 秒的悬停,建议拆成多个航点。为什么?因为风大的时候,飞机悬停会飘,影响后续航线精度。
我的习惯:每次写航点任务前,先画一张数据结构的草图。把坐标、动作、参数列清楚,再动手编码。这样能避免 80% 的 bug。
好了,航点数据结构就讲到这里。你只要把坐标、动作、参数这三个维度理清楚,剩下的就是填参数的事了。记住:结构清晰,任务才稳。