AISのNMEA(AIVDM)を解析してみよう

# はじめに
　前回は船舶の位置情報を取得して地図上に表示してみました。
[低予算・簡単構築で船の位置を受信してみよう](https://qiita.com/messyu4/items/526992a9c5263a676145)

今回はAISのNMEAのAIVDMの解析方法を紹介します。
AIVDMにデータには27種類存在していますが、そのうち位置情報に関するデータを1つだけ紹介します。

# 用語
説明中にいくつか用語が出てきます。
分からない用語があれば参考にして下さい。

- NMEA
 GPS、GLONSSなどの情報を示す時に使用するプロトコルです。
また、船舶、航空機などの情報を示すときにも使用されています。

- AIVDM
 船舶の情報が記載されている。

- クラスA、クラスB
 AISにはClass分けされています。
>
| 種類    | SOLASS                    | 通信間隔|
|:-------|:--------------------------|:-------|
| Class A| SOLASSで搭載義務となっている船舶| 2-10秒 |
| Class B| 非SOLASS対象の船舶　　　　　　| 30-3分 |
参考：[簡易型ＡＩＳの概要](https://www.soumu.go.jp/main_sosiki/joho_tsusin/policyreports/joho_tsusin/kaijo_musen/pdf/071018_1_si50-4-5.pdf)

- チェックサム
 NMEAの内容が正しいかをチェックする機能のこと。
*の後の16進数がそれに当たる。

- ITU(International Telecommunication Union:国際電気通信連合)
 >国際電気通信連合（こくさいでんきつうしんれんごう、フランス語: Union internationale des télécommunications; UIT、英語: International Telecommunication Union; ITU）は、国際連合の専門機関の一つである。
1865年5月17日にフランスのパリで設立された万国電信連合（フランス語: Union internationale du télégraphe、英語: International Telegraph Union）に端を発しているため、ITUは世界最古の国際機関とみなされている。国際電気通信連合憲章に基づき、無線通信と電気通信分野において各国間の標準化と規制の確立を図っている。
参考：["Wikipedia"](https://ja.wikipedia.org/wiki/%E5%9B%BD%E9%9A%9B%E9%9B%BB%E6%B0%97%E9%80%9A%E4%BF%A1%E9%80%A3%E5%90%88)

# AIVDMのNMEA
前回と同様に以下のNMEAを例にして説明します。
>!AIVDM,1,1,,A,13u?etPv2;0n:dDPwUM1U1Cb069D,0*24
参考：[https://rl.se/aivdm](https://rl.se/aivdm)

# データの誤り検出
AISのNMEAは上記のように構成されていますが、そのデータが誤っている可能性があります。
データの誤りの有無をチェックする仕組みとしてチェックサムがあります。
チェックサムは`*`の後の16進数`24`がそれにあたります。
`!`から`*`の間の`AIVDM,1,1,,A,13u?etPv2;0n:dDPwUM1U1Cb069D,0`の整合性は以下の手順で確認できます。

1. 各文字をASCIIコード表を元に10進数に変換する  
2. 各10進数をすべてXORする
3. XORした物を16進数にしてチェックサムと一致するか比較する

１のステップは、以下のようになります。

```
# 生データ
['A', 'I', 'V', 'D', 'M', ',', '1', ',', '1', ',', ',', 'A', ',', '1', '3', 'u', '?', 'e', 't', 'P', 'v', '2', ';', '0', 'n', ':', 'd', 'D', 'P', 'w', 'U', 'M', '1', 'U', '1', 'C', 'b', '0', '6', '9', 'D', ',', '0']
# ASCIIコード表を元に10進数したもの
[65, 73, 86, 68, 77, 44, 49, 44, 49, 44, 44, 65, 44, 49, 51, 117, 63, 101, 116, 80, 118, 50, 59, 48, 110, 58, 100, 68, 80, 119, 85, 77, 49, 85, 49, 67, 98, 48, 54, 57, 68, 44, 48]
```

# AIS情報をデコードする
 AISの情報は`13u?etPv2;0n:dDPwUM1U1Cb069D`にあたります。
これをデコードする際に大きく3回のステップを踏む必要があります。

1. 各文字を以下の表を元に6桁の2進数に変換する
>分かりやすい表があったので、こちらを参照してください。
<details>
![スクリーンショット 2020-03-13 0.06.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181903/f3f4ce20-c905-523b-9749-2bc9e68042c1.png)
</details>
参考：[AIVDM/AIVDO protocol decoding](https://gpsd.gitlab.io/gpsd/AIVDM.html)


2. 2進数の頭から6桁分を10進数に変換するして、AISのデータの種類を特定する。
>データの種類が分かりやすくまとめてあるところがあったので、こちらを参照して下さい。
<details>
![スクリーンショット 2020-03-13 0.16.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181903/5a14a65e-6671-730d-de8e-7ce4f7109f2a.png)
</details>
参考：[U.S. Coast Guard Navigation Center](https://www.navcen.uscg.gov/?pageName=AISMessages)

3. AISのデータの種類に合わせて区切る。

ステップ１は、以下のようになります。

```
# 生データ
['1', '3', 'u', '?', 'e', 't', 'P', 'v', '2', ';', '0', 'n', ':', 'd', 'D', 'P', 'w', 'U', 'M', '1', 'U', '1', 'C', 'b', '0', '6', '9', 'D']
# 表を元に10進数にしたもの
[1, 3, 61, 15, 45, 60, 32, 62, 2, 11, 0, 54, 10, 44, 20, 32, 63, 37, 29, 1, 37, 1, 19, 42, 0, 6, 9, 20]
# 表を元に2進数にしたもの
['000001', '000011', '111101', '001111', '101101', '111100', '100000', '111110', '000010', '001011', '000000', '110110', '001010', '101100', '010100', '100000', '111111', '100101', '011101', '000001', '100101', '000001', '010011', '101010', '000000', '000110', '001001', '010100']
# 上記を一列にしたもの
000001000011111101001111101101111100100000111110000010001011000000110110001010101100010100100000111111100101011101000001100101000001010011101010000000000110001001010100
```

ステップ2で先頭が`000001`なのでAISメッセージは`１`の船舶の位置に関するデータであると分かります。
また、AISメッセージが`1`であることから、以下の表のとおりに分割します。
><details>
<img width="529" alt="スクリーンショット 2020-03-13 13.51.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181903/8b266b2b-c7b5-049d-b8a2-111012eee300.png">
</details>
参考：[U.S. Coast Guard Navigation Center](https://www.navcen.uscg.gov/?pageName=AISMessagesA)


最終的に解析したら、以下のことが分かりました。

| name               | value                 |
|:-------------------|:----------------------|
| AIS Message        | 1                     |
| Repeat Indicator   | Zero                  |
| MMSI               | 265547250             |
| Navigational Status| INDER_WAY_USING_ENGINE|
| Rote Of Turn       | -2                    |
| Speed Over Ground  | 13.9                  |
| Position Accuracy  | LOW                   |
| Longitude          | 11.832976666666667    |
| Latitude           | 57.66035333333333     |
| Course Over Ground | 40.4                  |
| True Heading       | 41                    |
| Time Stamp         | 53                    |
| Maneuvre Indicator | NOT_AVAILABLE         |
| RAIM flag          | NOT_IN_USE            |
| Sync State         | UTC_DIRECT            |
| Slot Time Out      | 0                     |
| Sub Message        | 8788                  |


# まとめ
今回は、AIVDMの解析の一部を紹介しました。
もっと詳しく知りたい方は、以下の資料を参考にすることをお勧めします。
[Technical characteristics for an automatic identification system using time-division multiple access in the VHF maritime mobile band](https://www.itu.int/rec/R-REC-M.1371-5-201402-I/en)