3. 航点数据结构:航点属性与任务指令

航点数据结构,说白了就是无人机听得懂的“指令清单”。我刚开始接触这个领域时,以为只要给个经纬度飞机就能飞过去——结果第一次试飞,飞机在天上转圈圈,就是不执行任务。后来才明白,每个航点背后藏着十几个参数,少写一个都可能出问题。

这一章,咱们把航点数据拆开揉碎。你掌握了这个,后面写自动化脚本就顺了。

3.1 航点核心属性

一个完整的航点,至少包含下面这些字段。我习惯把它们分成两组:位置属性和行为属性。

属性类别 字段名 说明 典型值
位置属性 latitude 纬度,WGS-84坐标系 39.9042
longitude 经度,WGS-84坐标系 116.4074
altitude 海拔高度(米),相对起飞点或椭球面 100.0
行为属性 speed 到达该点后的飞行速度(m/s) 5.0
heading 机头朝向(度),0=正北,顺时针 90
gimbal_pitch 云台俯仰角(度),负值向下 -45
我的习惯:写经纬度时,小数点后至少保留6位。4位精度误差约11米,6位精度约0.1米。航拍任务差几米,构图就全歪了。

3.2 任务指令:让飞机干活

光有位置还不够。你想想看,飞机飞到那个点要干嘛?拍照?悬停?变焦?这些就是任务指令。

我整理了一份常用指令清单,你在项目里大概率都会用到:

  • 拍照指令:触发相机快门。可以单拍、连拍、全景拼接。
  • 悬停指令:到达航点后停留指定时长(秒)。常用于等待云台稳定或避开障碍。
  • 变焦指令:调整相机焦距(倍率)。比如从广角切到2倍光学变焦。
  • 开始/停止录像:控制视频录制。
  • 云台角度预设:快速切换云台俯仰/偏航角度。

避坑指南:我曾经在巡检项目里,给每个航点都加了拍照指令。结果飞机每飞一米就拍一张,飞了200米拍了200张——全是废片。后来我改成“每5个航点拍一张”,数据量降了80%,有效照片反而更多。

3.3 数据格式:JSON vs XML

现在主流无人机SDK都支持JSON和XML两种格式。我个人更倾向JSON,原因很简单:轻量、易读、好解析。但有些老系统还在用XML,咱们都得会。

3.3.1 JSON 示例

{
  "mission": {
    "name": "巡检任务-01",
    "waypoints": [
      {
        "index": 1,
        "latitude": 39.904200,
        "longitude": 116.407400,
        "altitude": 100.0,
        "speed": 5.0,
        "heading": 90,
        "gimbal_pitch": -45,
        "actions": [
          { "type": "photo", "params": { "mode": "single" } },
          { "type": "hover", "params": { "duration": 3 } }
        ]
      },
      {
        "index": 2,
        "latitude": 39.905000,
        "longitude": 116.408000,
        "altitude": 120.0,
        "speed": 3.0,
        "heading": 180,
        "gimbal_pitch": -60,
        "actions": [
          { "type": "zoom", "params": { "level": 2.0 } },
          { "type": "photo", "params": { "mode": "burst", "count": 3 } }
        ]
      }
    ]
  }
}

3.3.2 XML 示例

<?xml version="1.0" encoding="UTF-8"?>
<mission>
  <name>巡检任务-01</name>
  <waypoints>
    <waypoint index="1">
      <latitude>39.904200</latitude>
      <longitude>116.407400</longitude>
      <altitude>100.0</altitude>
      <speed>5.0</speed>
      <heading>90</heading>
      <gimbal_pitch>-45</gimbal_pitch>
      <actions>
        <action type="photo">
          <param name="mode">single</param>
        </action>
        <action type="hover">
          <param name="duration">3</param>
        </action>
      </actions>
    </waypoint>
  </waypoints>
</mission>
注意:XML的标签闭合很容易出错。我见过一个项目,因为少写了一个 </waypoint>,整个任务链解析失败,飞机直接原地降落。建议用工具校验格式后再上传。

3.4 航点数据结构总览图

下面这张图,把航点数据结构的全貌画出来了。你可以把它当作“航点数据字典”来用。

航点数据结构总览图 航点任务 (Mission) 元数据 (Metadata) 航点列表 (Waypoints) 任务名称 创建时间/版本 位置属性 行为属性 纬度/经度 高度 速度 朝向 (heading) 云台俯仰 任务指令 (Actions) 拍照 / 录像 悬停 / 变焦 每个航点可绑定 多个指令

3.5 常见坑与经验

嗯,这里有几个我踩过的坑,你提前知道能省不少时间:

  • 高度基准要统一:有的SDK用相对高度(离起飞点),有的用绝对海拔。混用的话,飞机可能一头扎进地里。我习惯在任务文件头部加一个 altitude_mode 字段,明确标注。
  • 朝向不要写0:很多新手把朝向写成0,以为就是正北。但有些飞控把0当作“不控制朝向”,飞机会保持当前朝向。我一般写1到360之间的值。
  • 指令顺序影响执行:先变焦再拍照,和先拍照再变焦,结果完全不同。我建议把“稳定类指令”(悬停、云台调整)放在前面,把“采集类指令”(拍照、录像)放在后面。

一个小技巧:写自动化脚本时,我习惯先输出一个“空壳”JSON,只包含经纬度和高度。等飞机实际飞一遍,确认路径没问题,再往里填指令参数。这样调试效率高很多。

航点数据结构,说白了就是“位置+行为+指令”的三层组合。你把这个结构吃透了,后面写自动化生成脚本,就是往模板里填数据的事。