3. 航路点任务描述与文件格式

航路点任务是AUV自主航行的“行程单”。它要回答四个问题:去哪里、下潜多深、以多快速度通过、到达后是否停留。把这四类信息按统一规范写进任务文件,AUV的任务管理器才能逐条解析、装订成航路,再交给航迹控制器执行。本节围绕航路点的字段定义、三种常见任务文件格式的解析方法,以及任务脚本的编写规范展开。

一、航路点由哪些字段构成

一个完整的航路点通常包含位置、深度、速度和停留时间四组参数。位置用经纬度表示,单位是度(°),建议统一保留小数点后6位,约合0.1米分辨率;深度用米(m)表示,正值向下,与AUV常用的“深度向下为正”约定一致;速度用米每秒(m/s)表示,指该航路点之后一段航线的期望对地速度;停留时间用秒(s)表示,为0表示不悬停、直接转向下一点。此外还应给出航路点编号和可选的到达半径(m),到达半径决定“是否算已到达”的判定门限。

需要特别说明坐标系约定:经纬度为WGS-84大地坐标,深度为相对水面(海平面)的深度,速度为正表示前进。全文与图示均采用这一约定,若任务中改用相对海底高度,必须在文件头显式声明,避免控制器误判。

二、三种常见任务文件格式

XML格式结构清晰、可嵌套、便于携带元数据,适合任务较复杂、需要描述航段属性的场景。解析时按元素树逐层读取,注意属性与子元素的区分。

<mission name="survey_A" frame="WGS84" depthref="#" aria-disabled="true" data-keke-missing-local-link="1" onclick="return false">
  <waypoint id="1" lat="30.512300" lon="114.302100"
            depth="10.0" speed="1.2" hold="0" radius="3.0"/>
  <waypoint id="2" lat="30.512800" lon="114.303500"
            depth="15.0" speed="1.0" hold="30" radius="3.0"/>
</mission>

JSON格式轻量、易被脚本生成,适合程序化批量生成航路点。解析时先取顶层元数据,再遍历waypoints数组,逐项校验字段是否齐全、数值是否在合理范围。

{
  "mission": "survey_A",
  "frame": "WGS84",
  "depthRef": "surface",
  "waypoints": [
    {"id":1,"lat":30.512300,"lon":114.302100,"depth":10.0,"speed":1.2,"hold":0,"radius":3.0},
    {"id":2,"lat":30.512800,"lon":114.303500,"depth":15.0,"speed":1.0,"hold":30,"radius":3.0}
  ]
}

CSV格式最便于用表格软件编辑和人工核对,适合航路点数量多、字段固定的测绘任务。解析时按表头映射列名,逐行读取并做类型转换,注意跳过空行与注释行。

id,lat,lon,depth,speed,hold,radius
1,30.512300,114.302100,10.0,1.2,0,3.0
2,30.512800,114.303500,15.0,1.0,30,3.0

三种格式表达的是同一份任务语义,差别在于可读性、可编程性与元数据承载能力。工程上常见做法是:用CSV做人工编辑与评审,用脚本转换为JSON下发,XML则用于需要携带航段属性的复杂任务。

航路点任务:从文件到航迹的数据流 XML 任务文件 元素树 / 属性 JSON 任务文件 对象 / 数组 CSV 任务文件 表头 / 行记录 任务解析器 字段映射 类型转换 范围校验 坐标系检查 航路点序列 WP1 深度10m 1.2m/s WP2 深度15m 1.0m/s 停留30s 半径3m → 装订为航路 航迹控制器 航向/深度 速度指令 到达判定 悬停计时 解析校验要点 经纬度范围:纬度[-90,90]、经度[-180,180];深度≥0;速度>0;到达半径>0;id 唯一且递增

三、解析实现的关键细节

无论哪种格式,解析流程都可以归纳为“读取—映射—校验—装订”四步。读取阶段要处理编码与空行;映射阶段把文件字段对应到内部结构体,例如把CSV的hold列映射为停留时间;校验阶段检查经纬度是否越界、深度是否为负、速度是否为零、id是否重复;装订阶段把航路点按id排序,生成带航段属性的航路表。

以Python为例,CSV解析的核心代码如下,注意显式指定字段类型并捕获异常:

import csv
wps = []
with open("mission.csv", newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        if not row["id"]:
            continue
        wp = {
            "id": int(row["id"]),
            "lat": float(row["lat"]),
            "lon": float(row["lon"]),
            "depth": float(row["depth"]),
            "speed": float(row["speed"]),
            "hold": float(row["hold"]),
            "radius": float(row["radius"]),
        }
        assert -90 <= wp["lat"] <= 90 and -180 <= wp["lon"] <= 180
        assert wp["depth"] >= 0 and wp["speed"] > 0 and wp["radius"] > 0
        wps.append(wp)
wps.sort(key=lambda w: w["id"])

JSON解析可直接用json.load得到字典,再遍历waypoints数组;XML解析可用xml.etree.ElementTree,通过root.findall("waypoint")取节点,用elem.get("lat")读属性。三种格式的校验逻辑应复用同一套函数,避免不同入口产生不一致的判定。

四、任务脚本编写规范

任务脚本是AUV实际执行的“程序”,规范编写能显著降低现场排障成本。建议遵循以下约定:

  • 文件头声明元数据:任务名、坐标系、深度基准、创建时间、版本号,缺一不可。
  • 字段命名统一:经纬度用lat/lon,深度用depth,速度用speed,停留用hold,到达半径用radius,不混用别名。
  • 单位显式标注:在文件头或注释中写明“度、米、米每秒、秒”,避免单位混用。
  • id连续递增:从1开始,不跳号,便于日志定位与断点续航。
  • 首末点特殊处理:首点通常为下潜点,末点通常为回收点,速度可适当降低。
  • 注释与版本管理:CSV用#开头行写注释,XML/JSON用元数据字段记录版本,任务变更留痕。
建议在任务下发前用解析器做一次“干跑”(dry run):只解析、校验、打印航路表,不驱动推进器。确认航路点数量、深度剖面和速度剖面符合预期后,再正式执行。
常见错误包括:经纬度写成“度分”格式导致位置偏差数公里;深度填负值被误判为水面;停留时间单位误用分钟;id重复导致装订时覆盖。解析器应把上述情况作为硬性错误直接拒绝任务,而不是静默修正。