4. AIS报文解析基础

AIS设备对外输出的并不是“裸”的二进制数据,而是经过两层包装的文本语句:外层是航海电子设备通用的NMEA 0183语句格式,内层才是AIS自定义的六位ASCII编码载荷。要解析一条位置报告,必须先把这两层“剥开”,再按报文类型定义逐字段解码。本节围绕一条典型的A类船载位置报告(报文类型1)展开,讲清结构、字段与可复现的解析步骤。

一、外层:NMEA 0183语句的封装结构

AIS信息通过VHF数据链路(VDL)接收后,由AIS设备以NMEA 0183语句形式经串口或网络输出。常见语句标识有!AIVDM(其他台站发来的VDL报文)和!AIVDO(本船自身信息)。一条语句以!起始,以*加两位十六进制校验和结束,字段之间用逗号分隔:

!AIVDM,1,1,,A,13aG?P0P00PD;88MD5MTDww@2D0S,0*5C

各字段含义依次为:语句标识符AIVDM;片段总数(1);当前片段序号(1);多片段报文时的消息序列号(此处为空);AIS信道(A或B);六位ASCII编码的载荷;填充位数(0表示载荷位数恰为6的整数倍,无需补位);最后是*后的校验和。校验和的计算方法是:对!与*之间的所有字符(不含这两个符号)逐字节做异或,结果以两位大写十六进制表示。接收端应先校验再解析,校验失败说明语句在传输中出错,应丢弃。

当一条AIS报文较长(如类型5静态与航程数据)时,会被拆成多个片段,此时片段总数大于1,接收端需按序列号缓存并拼接载荷后再解码。位置报告报文通常较短,单片段即可承载。

二、内层:六位ASCII编码与位流还原

载荷中的每个字符并不是普通ASCII,而是AIS规定的“六位ASCII”字符集。解码规则是:取字符的ASCII码值减48;若结果大于40,再减8;得到的值即6位二进制数(0~63)。例如字符1(ASCII 49)→ 49−48=1 → 000001;字符W(ASCII 87)→ 87−48=39 → 100111。把所有字符依次展开成6位二进制并串接,就得到AIS报文的原始位流。若语句末尾填充位字段为n,则位流末尾的n位是补齐用的,解码时应剔除。

位流按“从高位到低位、从第0位开始”的顺序,依报文类型定义切分为各字段。字段可能是无符号整数、有符号整数(补码)、布尔值、字符串或特殊编码(如经度纬度以1/10000分为单位)。理解“位偏移+位长度+数据类型”这三要素,是逐字段解码的关键。

AIS位置报告(类型1)解析链路 ① NMEA 0183 外层语句 !AIVDM,1,1,,A,13aG?P0P00PD;88MD5MTDww@2D0S,0*5C 标识符 | 片段总数 | 片段序号 | 序列号 | 信道 | 六位ASCII载荷 | 填充位 | *校验和 校验通过 → 提取载荷 ② 六位ASCII解码:ASCII码 − 48(若 >40 再 −8) 字符 1 → 49−48=1 → 000001 字符 3 → 51−48=3 → 000011 字符 a → 97−48=49>40 → 41 → 101001 字符 G → 71−48=23 → 010111 字符 ? → 63−48=15 → 001111 …… 依次串接为位流 剔除末尾填充位 → 得到完整位流 ③ 按位偏移切分字段(类型1关键字段) 类型 0-5 MMSI 8-37 航行状态 38-41 转向率 42-49 对地航速 50-59 位置精度 60 经度 61-88 纬度 89-115 对地航向 116-127 真航向 128-136 时间戳 137-142 输出:MMSI、经纬度、航速、航向、时间戳等可读字段

三、逐字段解码:以经度、纬度、航速为例

位流切分后,各字段按定义换算为物理量。位置报告中最关键的三个字段换算规则如下:

  • 经度:位偏移61、长度28,有符号整数,单位为1/10000分。解码值除以600000即得度(因为1度=60分,60×10000=600000)。例如解码值为121500000,则经度为121.5°;负值表示西经。
  • 纬度:位偏移89、长度27,有符号整数,单位同为1/10000分,除以600000得度。正值北纬,负值南纬。注意纬度位长比经度少1位,是因为纬度范围只需±90°。
  • 对地航速:位偏移50、长度10,无符号整数,单位0.1节。解码值1023表示“不可用”,1022表示“102.2节及以上”。例如解码值123即12.3节。

此外,航行状态(0=在航、1=锚泊、5=系泊等)、转向率(有符号,单位°/分,−128表示不可用)、对地航向(单位0.1°,3600表示不可用)、时间戳(0~59秒,60表示不可用)等字段也需按各自定义判读。解析时务必区分“数值0”与“不可用标记”,否则会把无效数据误当作真实位置。

四、可复现的解析步骤

  1. 接收并校验:读取以!AIVDM开头的语句,计算!与*之间字符的异或校验和,与语句末尾两位十六进制比对,不一致则丢弃。
  2. 提取载荷与填充位:按逗号分割字段,取第6个字段为载荷,第7个字段为填充位数。
  3. 六位ASCII转位流:逐字符按“减48、大于40再减8”得到6位值,拼接成二进制串,并按填充位数剔除末尾补位。
  4. 读取报文类型:取前6位得类型号,确认是否为位置报告(1、2、3类结构相同)。
  5. 按偏移切字段:依类型定义表,用位偏移和长度截取各字段,按有无符号及单位换算为物理量。
  6. 合理性检查:核对经纬度是否在合法范围、航速航向是否为不可用标记、时间戳是否有效,再交给上层应用显示或存储。
实操建议:初次实现时,可先用一条已知内容的示例语句手工推演位流,再与程序输出逐字段比对。特别注意有符号数的补码处理——例如经度为负时,28位补码需先判断最高位再取反加一,不能直接当无符号数读。
常见错误:把六位ASCII字符直接当普通ASCII解析,或忘记“大于40再减8”这一步,会导致位流整体错位,后续所有字段全部错误;另外多片段报文未拼接就解码,也会得到残缺数据。

掌握上述两层封装与字段换算规则后,任何一条标准位置报告都可以被稳定还原为船位、航速、航向与时间信息,这也是后续实现AIS目标跟踪、避碰辅助与轨迹回放的数据基础。