はじめに
仕事の関係で飛行機によく乗る友人から,HND-ITM(羽田-伊丹)便で記録したGPSデータをいただきました.というか,キャビン内でうまく受信できるのか?という興味があったのと,別用途でも使いたかった(データを見てみたかった)ので,録ってきて!!とお願いしたら二つ返事で録ってくれました(感謝!).
受信機で測位演算する前のいわゆるRawデータと,測位結果が記録されたNMEAデータを頂きました.そのうち,NMEAデータの方から位置情報を取り出してLeafletでOpen Street Map上にプロットしたものと,高度の時系列をプロットしたものが下の図になります.結構きれいに録れていると思います.離陸時と着陸時の高度変化の違いが面白いです.
データ解析ツールは探せば何だかんだ出てきますが,DIYがこのブログの趣旨なので,まずはNMEAデータを読んでいきます.今回はNMEAフォーマットについての備忘録です.
ちなみに,上に示したデータで,羽田空港を離陸した直後の21時39分59秒(UTC)には以下のように記録されていました.
$GPZDA,213959.00,23,12,2021,,*60
$GPDTM,W84,,00.0000000,N,00.0000000,E,00.0000000,W84*5F
$GPRMC,213959.00,A,3522.5012666,N,13942.1022598,E,312.1,230.1,231221,7.5,W,A*2E
$GPGGA,213959.00,3522.5012666,N,13942.1022598,E,1,20,0.9,4174.8064,M,39.6262,M,,*5A
$GNGNS,213959.00,3522.5012666,N,13942.1022598,E,AAAA,20,0.9,4174.8064,39.6262,,*6E
$GPVTG,230.12,T,237.66,M,312.15,N,578.09,K,A*20
$GPGSA,A,3,02,06,07,13,20,30,,,,,,,1.6,0.9,1.3*3E
$GPGSA,A,3,69,79,,,,,,,,,,,1.6,0.9,1.3*3F
$GPGSA,A,3,07,13,26,,,,,,,,,,1.6,0.9,1.3*3F
$GPGSA,A,3,01,03,04,16,24,25,26,28,33,,,,1.6,0.9,1.3*30
$GPGST,213959.00,3.434,2.280,0.960,296.304,1.327,2.088,3.095*55
$GPGBS,213959.00,8.940,13.120,18.379,03,0.0001,5.334,6.383*57
$GPGRS,213959.00,1,0.2,0.3,0.7,-0.5,0.0,0.3,,,,,,*66
$GPGRS,213959.00,1,1.2,-1.5,,,,,,,,,,*61
$GPGRS,213959.00,1,-0.3,1.1,-1.2,,,,,,,,,*65
$GPGRS,213959.00,1,2.6,5.3,2.4,4.3,-4.9,-5.2,-4.2,-2.5,-3.4,,,*47
$GPGSV,3,1,11,20,67,046,45,06,17,147,44,29,27,281,,07,24,051,40*7D
$GPGSV,3,2,11,15,32,247,32,11,56,151,,30,41,080,48,05,59,332,26*76
$GPGSV,3,3,11,02,64,173,45,13,66,237,41,18,01,320,*45
$GLGSV,3,1,10,84,51,199,29,79,21,090,43,78,12,039,20,70,44,293,*6C
$GLGSV,3,2,10,85,48,309,,69,42,027,40,80,06,145,,68,03,060,35*65
$GLGSV,3,3,10,71,06,259,23,86,07,336,*64
$GAGSV,2,1,08,26,67,190,43,19,19,245,,13,17,155,42,33,51,307,25*6E
$GAGSV,2,2,08,07,55,038,43,08,07,055,31,30,04,090,39,12,03,324,*67
$BDGSV,4,1,16,33,63,014,41,24,28,102,45,25,14,160,40,02,20,250,*67
$BDGSV,4,2,16,26,15,054,41,27,29,304,,09,17,214,29,06,28,215,31*6F
$BDGSV,4,3,16,04,44,147,42,16,37,214,40,13,52,323,24,03,40,225,37*6F
$BDGSV,4,4,16,14,44,053,,01,49,172,42,28,48,237,43,08,60,332,24*6F
$GQGSV,1,1,04,193,86,009,,199,47,201,36,195,46,200,42,194,07,171,35*75
NMEAフォーマットの構造
National Marine Electronics Association (NMEA;米国海洋電子機器協会) のフォーマットで,GNSS以外にも海洋関連の計測システムの情報伝達に使われるフォーマットが規定されています.正式な規定は販売されていますが大変高価で日曜DIYには手が出ません.しかし,GNSS関連部分については,色々なGNSS受信機のマニュアルやオープンソースのソフトウェア等を見ると,その内容が分かります.
センテンスの構造
(例)$GPRMC,213959.00,A,3522.5012666,N,13942.1022598,E,312.1,230.1,231221,7.5,W,A*2E
- 1つのセンテンスは,「$」ではじまり,改行コード「\r\n; CR LF; 0x0d 0x0a」で終わる.
- センテンス内のデータはカンマ「,」区切り
- 最後の2文字(*より後ろ)はチェックサム
Talker ID
(例)$GPRMC,213959.00,A,3522.5012666,N,13942.1022598,E,312.1,230.1,231221,7.5,W,A*2E
- $に続く2文字(例では,GP)をTalker IDといい,どのGNSSシステムに関するデータであるかを特定する手がかりとなる.Talker IDの種類は以下の通り.
Talker ID | GNSSシステム | 備考 |
---|---|---|
GP | GPS | ver2.3以上 |
GL | GLONASS | ver2.3以上 |
GA | Galileo | ver4.10以上 |
GB | BeiDou | ver4.11以上 |
GQ | QZSS | ver4.11以上(4.10以下ではGPが使われる) |
GN | 上記の組合せ |
- Talker IDの後ろ3文字(例ではRMC)でセンテンスの種類を表す.
チェックサムの計算方法
(例)$GPRMC,213959.00,A,3522.5012666,N,13942.1022598,E,312.1,230.1,231221,7.5,W,A*2E
- チェックサムは「$」の後ろから「*」までの範囲に対して計算する
- 0x00を初期値として,左から右へ,各文字コードのXORをとったものがチェックサムとなる
- チェックサムの値を16進表記した文字列がセンテンスの末尾に記録されている(例では2E)
- サンプルプログラム(C#)を以下に示す.実行すると2Eが表示される
string sentence = "GPRMC,213959.00,A,3522.5012666,N,13942.1022598,E,312.1,230.1,231221,7.5,W,A*";
byte[] data = System.Text.Encoding.ASCII.GetBytes(sentence);
byte cs = 0x00;
for (int i = 0; i < data.Length - 1; i++)
{
cs ^= data[i];
}
Console.WriteLine(string.Format("{0:X2}", cs));
NMEAメッセージのフォーマット
RMCメッセージ(Recommended minimum data)
(例)$GPRMC,213959.00,A,3522.5012666,N,13942.1022598,E,312.1,230.1,231221,7.5,W,A*2E
番号 | 例 | 意味 | 読み取り結果 | |
---|---|---|---|---|
1 | 213959.00 | hhmmss.ss | UTC時刻 | 21時39分59.00秒 |
2 | A | char | 測位状況ステータス A: Valid,V: Invalid | Valid |
3 | 3522.5012666 | ddmm.mmmmmmm | 緯度(補足1) | 35度22.5012666分 |
4 | N | char | 北緯(North)/南緯(S) | 北緯 |
5 | 13942.1022598 | dddmm.mmmmmmm | 経度(補足1) | 139度42.1022598分 |
6 | E | char | 東経(E)/西経(W) | 東経 |
7 | 312.1 | numeric | 対地速度(knots) | 312.1ノット |
8 | 230.1 | numeric | 対地方位(度) | 230.1度 |
9 | 231221 | ddmmyy | 日付(UTC) | 21年12月23日 |
10 | 7.5 | numeric | 磁気偏角(真北と磁北のずれ)(度) | 7.5度 |
11 | W | E/W | 磁気偏角の方向 | 西 |
12 | A | char | 測位モードステータス N:No fix, E:Estimated/Dead Reckoning, F:RTK Float(ver4.10以降) R:RTK Fixed(ver4.10以降) A/D:GNSS Fix バージョン間で若干意味が異なる部分がある. 必要に応じて確認する | |
13 | 2E | string | チェックサム | 0x2E |
14 | \r\n | char | センテンス終端 |
緯度,経度は受信機の測地系設定に依存する.通常,デフォルトではWGS84になっているはずなので,そのままGoogleEarthや地理院地図等で利用可能.
GGAメッセージ(Global positioning system fix data)
(例)$GPGGA,213959.00,3522.5012666,N,13942.1022598,E,1,20,0.9,4174.8064,M,39.6262,M,,*5A
番号 | 例 | 意味 | 読み取り結果 | |
---|---|---|---|---|
1 | 213959.00 | hhmmss.ss | UTC時刻 | 21時39分59.00秒 |
2 | 3522.5012666 | ddmm.mmmmmmm | 緯度(補足1) | 35度22.5012666分 |
3 | N | char | 北緯(North)/南緯(S) | 北緯 |
4 | 13942.1022598 | dddmm.mmmmmmm | 経度(補足1) | 139度42.1022598分 |
5 | E | char | 東経(E)/西経(W) | 東経 |
6 | 1 | 1digit | 測位モードステータス 0:No Fix 1:GNSS Fix 2:DGPS Fix 4:RTK Fix 5:RTK Float 6:Estimated or Dead reckoning Fix | GNSS Fix |
7 | 20 | numeric | 使用衛星数 | 20 |
8 | 0.9 | numeric | HDOP(水平方向精度劣化指標) | 0.9 |
9 | 4174.8064 | numeric | 高度(平均海水面からの高さ) | 4174.8064 |
10 | M | char | 上記高度の単位 | m(メートル) |
11 | 39.6262 | numeric | ジオイド高 準拠楕円体からのジオイド(平均海水面)高さ ジオイド高+(9)の高度=楕円体高 | 39.6262 |
12 | M | char | 上記ジオイド高の単位 | m(メートル) |
13 | 空白 | numeric | Differential補正値のage 最後の有効な補正値受信からの時間[秒] DGPSモードで無い場合は空白 | |
14 | 5A | string | チェックサム | 0x5A |
15 | \r\n | char | センテンス終端 |
(注)緯度,経度は受信機の測地系設定に依存する.
ZDAメッセージ(Time and date)
(例)$GPZDA,213959.00,23,12,2021,,*60
番号 | 例 | 意味 | 読み取り結果 | |
---|---|---|---|---|
1 | 213959.00 | hhmmss.ss | UTC時刻 | 21時39分59.00秒 |
2 | 23 | dd | 日付(UTC) | 23日 |
3 | 12 | mm | 月(UTC) | 12月 |
4 | 2021 | yyyy | 年(UTC) | 2021年 |
5 | null | hh | ローカルタイムオフセット(時)-13–13 | 記録無し |
6 | null | mm | ローカルタイムオフセット(分)0–59 | 記録無し |
7 | 60 | string | チェックサム | 0x60 |
8 | \r\n | char | センテンス終端 |
DTMメッセージ(Datum reference)
(例)$GPDTM,W84,,00.0000000,N,00.0000000,E,00.0000000,W84*5F
番号 | 例 | 意味 | 読み取り結果 | |
---|---|---|---|---|
1 | W84 | string | 測地系 W84:WGS84 P90:PZ90 999:ユーザ定義 | WGS84 |
2 | null | 空フィールド | ||
3 | 00.0000000 | numeric | 緯度オフセット(分) | 0.0分 |
4 | N | char | N/S(緯度オフセットの方向) | N |
5 | 00.0000000 | numeric | 経度オフセット(分) | 0.0分 |
6 | E | char | E/W(経度オフセットの方向) | E |
7 | 00.0000000 | numeric | 高度オフセット(m) | 0.0m |
8 | W84 | string | 基準とする測地系のコード | WGS84 |
9 | 5F | string | チェックサム | 0x5F |
8 | \r\n | char | センテンス終端 |
VTGメッセージ(Course over ground and ground speed)
(例)$GPVTG,230.12,T,237.66,M,312.15,N,578.09,K,A*20
番号 | 例 | 意味 | 読み取り結果 | |
---|---|---|---|---|
1 | 230.12 | numeric | 方位(度) | 230.12度 |
2 | T | char | 上記方位の単位,T:真方位 | |
3 | 237.66 | numeric | 方位(度) | 237.66度 |
4 | M | char | 上記方位の単位,M:磁方位 | N |
5 | 312.15 | numeric | 対地速度 | 312.15 |
6 | N | char | 上記速度の単位,N:Knots | ノット |
7 | 578.09 | numeric | 対地速度 | 578.09 |
8 | K | char | 上記速度の単位,K:km/h | km/h |
9 | A | char | 測位モードステータス N:No fix E:Estimated/dead reckoning fix A:GNSS fix D:Differential GNSS fix F:RTK float R:RTK fixed | |
9 | 5F | string | チェックサム | 0x5F |
8 | \r\n | char | センテンス終端 |
GSAメッセージ(GNSS DOP and active satellites)
(例)$GPGSA,A,3,02,06,07,13,20,30,,,,,,,1.6,0.9,1.3*3E
番号 | 例 | 意味 | 読み取り結果 | |
---|---|---|---|---|
1 | A | char | 2D/3D測位切り換えモード M:手動切り換え A:自動切り換え | 自動 |
2 | 3 | digit | 測位ステータス 1:No fix 2:2D fix 3:3D fix | 3D fix |
3 | 02 | numeric | 衛星番号の1番目(補足2) | 02 |
3~14まで衛星番号を12回繰り返す | ||||
14 | null | numeric | 衛星番号の12個目 | なし |
15 | 1.6 | numeric | PDOP(3D位置精度劣化指標) | |
16 | 0.9 | numeric | HDOP(水平位置精度劣化指標) | |
17 | 1.3 | numeric | VDOP(垂直位置精度劣化指標) | |
18 | XX | numeric | システム識別番号(補足3),ver4.10以降で記録 この例では記録されていない | |
18 | 3E | string | チェックサム | 0x3E |
19 | \r\n | char | センテンス終端 |
測位演算に使用された衛星番号が記録される.1センテンス12衛星まで記録なので,複数回にわたって送信されてくることもある.埋まらない場合はempty.衛星番号は(補足2)を参照.
GSVメッセージ(GNSS satellites in view)
(例)$GPGSV,3,1,11,20,67,046,45,06,17,147,44,29,27,281,,07,24,051,40*7D
番号 | 例 | 意味 | 読み取り結果 | |
---|---|---|---|---|
1 | 3 | digit(1-9) | 送信されるGSVメッセージの数 | 3 |
2 | 1 | digit | このメッセージの番号 | メッセージ総数3の内の 1番目のメッセージ |
3 | 11 | numeric | Talker IDとSignal ID(下記のX番)に対する 可視衛星数 | 11機 |
4 | 20 | numeric | 衛星番号(補足3) | 20 |
5 | 67 | numeric | 仰角(度,0-90) | 仰角67度 |
6 | 046 | numeric | 方位角(度,0-359) | 方位角46度 |
7 | 45 | numeric | 信号強度(C/N0値,0-99)[dBHz] | 45 |
4~19 | 4~7の内容を4衛星分繰り返す | |||
20 | XX | numeric | Signal ID(補足4),ver4.10以降で記録 この例では記録されていない | |
18 | 7D | string | チェックサム | 0x7D |
19 | \r\n | char | センテンス終端 |
衛星数に応じて,複数のTalker IDで複数のメッセージが送信されてくる.GSAメッセージと見比べると,信号補足は出来ているが測位に使用していない衛星が分かる.
補足1(緯度,経度の表示について)
(例)$GPGGA,213959.00,3522.5012666,N,13942.1022598,E,1,20,0.9,4174.8064,M,39.6262,M,,*5A
の場合,以下のような読みになります.
- 北緯35度22.5012666分,東経139度42.1022598分
ちなみに,1度は60分,1分は60秒なので,「度」や,「度・分・秒」で表示したければ以下のようにできます.
- 「度」で表示したければ,分の部分を60で割って足す
- 度,分,秒で表現したければ,分の小数部分に60を掛けて秒で表示する
北緯 35 + (22.5012666 / 60) = 35.37502111 [度]
東経 139 + (42.1022598 / 60) = 139.70170433[度]
北緯 35度22分(0.5012666 * 60)秒 = 35度22分30.075996秒
東経 139度42分(0.1022598*60)秒 = 139度42分6.135588秒
分解能について
日本付近では,だいたい緯度方向1秒が30m,経度方向1秒が25mくらいです(詳細な数値や計算方法は理科年表や国土地理院さんのサイトで紹介されています).したがって,緯度,経度方向の1分の距離は,1800mと1500m程度になります.
つまり,「分」の小数第3位までで緯度方向1.8m,経度方向1.5m程度の分解能です.
小数第4位で18cmと15cm
小数第5位で1.8cmと1.5cm
小数第6位で1.8mmと1.5mm
になります.通常の受信機では第5位くらいまで出力していると思いますが,高精度測位の場合は桁数を増やして出力しないと正確な評価が出来ない可能性があります.
補足2(衛星番号)
NMEA Ver. | GPS | GLONASS | Galileo | QZSS | BeiDou | SBAS |
---|---|---|---|---|---|---|
ver.2.3-4.0 | 1-32 | 65-96 | 301-336 | 193-202 | 401-437 | 33-64 152-158 |
ver4.10 | 1-32 | 65-96 | 1-36 | 193-202 | 1-37 | 33-64 152-158 |
ver.4.11 | 1-32 | 65-96 | 1-36 | 1-10 | 1-37 | 33-64 152-158 |
補足3(システム識別番号)
NMEA Ver. | GPS | GLONASS | Galileo | QZSS | BeiDou | SBAS |
---|---|---|---|---|---|---|
ver.2.3-4.0 | 1 | 2 | N/A | N/A | N/A | 1 |
ver4.10 | 1 | 2 | 3 | N/A | N/A | 1 |
ver.4.11 | 1 | 2 | 3 | 5 | 4 | 1 |
補足4(Signal ID)
Signal | NMEA Ver. 4.10 System ID | NMEA Ver. 4.10 Signal ID | NMEA Ver.4.11 System ID | NMEA Ver.4.11 Signal ID |
---|---|---|---|---|
GPS L1 C/A | 1 | 1 | 1 | 1 |
GPS L2 CL | 1 | 6 | 1 | 6 |
GPS L2 CM | 1 | 5 | 1 | 5 |
SBAS L1 C/A | 1 | 1 | 1 | 1 |
Galileo E1C | 3 | 7 | 3 | 7 |
Galileo E1B | 3 | 7 | 3 | 7 |
Galileo E5B I | 3 | 2 | 3 | 2 |
Galileo E5B Q | 3 | 2 | 3 | 2 |
BeiDou B1I D1 | — | — | 4 | 1 |
BeiDou B1I D2 | — | — | 4 | 1 |
BeiDou B2I D1 | — | — | 4 | 11 |
BeiDou B2I D2 | — | — | 4 | 11 |
QZSS L1 C/A | — | — | 5 | 1 |
QZSS L1S | — | — | 5 | 4 |
QZSS L2 CM | — | — | 5 | 5 |
QZSS L1 CL | — | — | 5 | 6 |
GLONASS L1 | 2 | 1 | 2 | 1 |
GLONASS L2 | 2 | 3 | 2 | 3 |