NMEAとは?GPSが吐き出すデータの読み方
GPS受信機をパソコンやマイコンにつなぐと、こんな文字列が延々と流れてきます。
$GPGGA,085120.00,3540.1234,N,13945.5678,E,1,08,0.9,45.2,M,36.1,M,,*54
意味が分からないと、ただの記号の羅列に見えます。しかしこの一行には、時刻、緯度、経度、測位の品質、使っている衛星の数、標高が、すべて入っています。この形式の名前がNMEAです。
読み方さえ分かれば、市販の受信機でも自作の装置でも、位置の情報を自由に取り出せます。この記事では、NMEAとは何かから始めて、緯度経度の数字を普通の度に直す方法、ログファイルの扱い方、地図で開ける形式への変換まで、順番に説明します。
NMEAとは
NMEAは、位置や航行の情報をやりとりするための取り決めです。米国海洋電子機器協会(National Marine Electronics Association)が定めたもので、名前はその頭文字から来ています。もともとは船の世界の規格でした。船には方位を測る装置、深さを測る装置、位置を測る装置が別々に載っており、それらを同じ配線でつなぐために作られました。
いま一般に「NMEA」と呼ばれているのは、正確にはNMEA 0183という版です。1983年に定められ、四十年以上使われ続けています。GPS受信機がこの形式で出力するため、船とは無関係な用途、たとえばドライブレコーダー、測量機器、スマートフォンの位置ログ、農業機械の自動操舵まで、位置を扱うほとんどの機器がこれを話します。
規格そのものは有償で頒布されていますが、GPS受信機が出す部分は各社の資料に詳細が書かれており、実務では困りません。
NMEA 0183 と NMEA 2000 の違い
検索でよく並ぶこの二つは、名前が似ているだけで中身は別物です。混同すると配線から間違えます。
| NMEA 0183 | NMEA 2000 | |
|---|---|---|
| 送るもの | 文字列 | 数値をまとめた小包 |
| 下地の通信 | シリアル通信(RS-422 / RS-232) | CAN(自動車で使われる通信網) |
| 速さ | 毎秒4800ビットが基本、GPSでは38400ビットも多い | 毎秒25万ビット |
| つなぎ方 | 送る側1台から、受ける側へ一方通行 | 1本の幹線に複数の機器がぶら下がり、双方向 |
| 見分け方 | ドルマークで始まる読める文字列 | PGNという番号で中身を区別する |
| 配線 | 線をはんだ付けするか、USB変換器を使う | 専用のコネクタと分岐器 |
CANは、自動車の中で複数の制御装置をつなぐために作られた通信の仕組みです。1本の線に何台つないでも衝突しないよう調停する仕掛けがあり、船の機器を数珠つなぎにするのに向いています。PGNはParameter Group Numberの略で、この小包が水深なのか位置なのかを示す番号です。
パソコンやマイコンでGPSを扱う場面で出会うのは、ほぼすべて0183のほうです。2000が必要になるのは、船の統合航海システムに機器を追加するときです。両者をつなぐ変換器も市販されています。
センテンスの形
NMEAの一行を、センテンスと呼びます。形は決まっています。
$GPGGA,085120.00,3540.1234,N,13945.5678,E,1,08,0.9,45.2,M,36.1,M,,*54
左から順に、ここから始まるという合図のドルマーク、どの衛星群かを示す2文字、行の種類を示す3文字、カンマ区切りの中身、そして最後に検査の数値が並びます。
先頭のドルマークが行の始まりです。続く2文字は、どの衛星の群れを使ったかを示します。
| 記号 | 意味 |
|---|---|
| GP | アメリカのGPS |
| GL | ロシアのGLONASS |
| GA | 欧州のGalileo |
| GB | 中国のBeiDou |
| GQ | 日本のみちびき |
| GN | 複数の群れを混ぜて測位した |
近年の受信機は複数の衛星群を同時に使うため、GPではなくGNで始まる行が多く出ます。GPしか想定していない古い解析プログラムが、新しい受信機で急に動かなくなる原因はこれです。
次の3文字が、この行の種類です。GGAなら測位の要点、RMCなら最小限の推奨情報、というように決まっています。
末尾のアスタリスクの後ろにある2桁は、検査用の数値です。ドルマークとアスタリスクの間にある全文字を、排他的論理和で順に重ねた結果を16進数で書いたものです。排他的論理和とは、2進数の同じ桁を比べて、違えば1、同じなら0にする計算です。通信の途中で1文字化けると、この数値が合わなくなるので、壊れた行を捨てられます。
行の終わりには、復帰と改行の2文字が入ります。テキストエディタで開いたときに余計な改行に見えるのはこのためです。
緯度経度を普通の度に直す
NMEAでいちばん人をつまずかせるのが、緯度経度の書き方です。先ほどの例の緯度を見てください。
3540.1234,N
これは35.40度ではありません。左から2桁が度、残りが分です。つまり35度40.1234分の北緯という意味です。経度は左から3桁が度になります。13945.5678なら139度45.5678分の東経です。
地図アプリで使う十進の度に直すには、分を60で割って度に足します。
緯度 = 35 + 40.1234 / 60 = 35.66872度
経度 = 139 + 45.5678 / 60 = 139.75946度
南緯や西経のときは、記号がSやWになります。その場合は符号を負にします。
この変換を忘れると、東京の位置が北緯35.40度あたり、実際より約30km南の海の上に出ます。地図に載せたら位置がずれていたという相談の大半は、この一点です。
なお、分の小数点以下は受信機によって桁数が違います。4桁なら約0.2m、5桁なら約0.02mの刻みです。桁が多いからといって、その精度で測れているわけではありません。
主なセンテンスの早見
種類は数十ありますが、GPS受信機が日常的に出すのは限られています。
| 種類 | 何が入っているか |
|---|---|
| GGA | 時刻、緯度経度、測位の品質、衛星数、標高 |
| RMC | 時刻、日付、緯度経度、速度、進行方向 |
| GSA | 測位に使った衛星の番号と、精度の指標 |
| GSV | 空に見えている衛星の一覧と、電波の強さ |
| VTG | 進行方向と速度 |
| GLL | 緯度経度と時刻だけ |
位置だけ欲しいならGGAかRMCの一行で足ります。受信の状態を調べたいならGSAとGSVを見ます。各センテンスの一つ一つの項目については、別の記事にまとめました。
NMEAファイルとは
受信機から流れてくる行を、そのまま保存したものがNMEAファイルです。拡張子は.nmeaのほか、.logや.txtのこともあります。中身はただのテキストなので、メモ帳でも開けます。
このファイルに出会う場面はいくつかあります。ドライブレコーダーの走行記録、スマートフォンの位置記録アプリ、測量機の生ログ、ラジコンやドローンの飛行記録です。動画に位置を重ねる機能を持つドライブレコーダーは、映像の隣にこのファイルを置いていることが多くあります。
再生する、地図で開く
NMEAファイルは、時刻順に並んだ位置の列です。これを地図の上でたどることを、再生と呼びます。方法は大きく三つあります。
一つ目は、受信機メーカーが配る解析ソフトに読ませる方法です。ユーブロックス社のu-centerが代表で、無料で使えます。ファイルを開くと、地図と衛星の配置と電波の強さを、記録したときと同じ順で流し直せます。受信が途切れた瞬間に何が起きていたかを調べるには、これがいちばん確実です。
二つ目は、地図で扱える形式に変換してから開く方法です。詳しくは次の節で説明します。
三つ目は、自分で読む方法です。テキストなので、表計算ソフトにカンマ区切りとして取り込むこともできます。ただし行の種類が混在しているため、GGAの行だけを抜き出す下ごしらえが要ります。
別の形式に変換する
地図で見たい、他のソフトに渡したいという場合は、GPXかKMLに変換します。GPXは位置ログをやりとりするための共通形式で、多くの地図ソフトが読めます。KMLはグーグルアースが読む形式です。
変換にはGPSBabelという道具が広く使われています。無料で、ウィンドウズでもマックでもリナックスでも動きます。画面から操作もできますし、命令行からも呼べます。
gpsbabel -i nmea -f drive.nmea -o gpx -F drive.gpx
前半が入力の形式とファイル、後半が出力の形式とファイルです。nmeaのところをgpxに、gpxのところをkmlに変えれば、他の組み合わせにもなります。
変換で気をつける点が一つあります。NMEAには標高が二種類入っています。楕円体高と、平均海面からの高さです。GGAの9番目の項目が海面からの高さ、11番目がその二つの差です。変換の途中でどちらを採るかによって、日本国内では30mから40mほど値が変わります。
受信機から取り出す
自作の装置でNMEAを読むときは、まず通信の速さを合わせます。多くの受信機は毎秒9600ビットが初期値で、設定で38400や115200に上げられます。速さが合っていないと、文字化けした記号が並ぶだけになります。
出力の間隔は普通は1秒に1回です。受信機によっては5回、10回に増やせます。ただし、増やすほど通信の帯域を食うので、速さを上げないと行が途中で切れます。毎秒10回でGGAとRMCとGSVを全部出すなら、9600では足りません。
不要なセンテンスを止める設定も、たいていの受信機にあります。GSVは見えている衛星の数だけ行が増えるので、位置だけ欲しいなら止めると扱いが楽になります。
プログラムで読む
パイソンで扱うなら、pynmea2という部品が手軽です。
import pynmea2
with open("drive.nmea", encoding="utf-8", errors="ignore") as f:
for line in f:
if not line.startswith("$"):
continue
try:
msg = pynmea2.parse(line)
except pynmea2.ParseError:
continue
if msg.sentence_type == "GGA":
print(msg.timestamp, msg.latitude, msg.longitude, msg.gps_qual)
latitudeとlongitudeは、十進の度に直した値で返ります。度と分の計算を自分で書かずに済みます。gps_qualは測位の品質で、0が測位できていない、1が単独測位、2がディファレンシャル、4がRTKの固定解、5がRTKの浮動解です。
自分で書く場合も、難しくはありません。カンマで切って、必要な位置の項目を取り出すだけです。ただし、項目が空のまま残ることがあります。衛星を捕まえていない間、緯度経度の欄は空になります。カンマが連続する行を、そのまま数値に変換しようとして止まるのが、最初に踏む落とし穴です。
読めると何ができるか
NMEAが読めると、位置を扱う道具を自分の手で組み立てられるようになります。
走行や航行の記録を、自分の欲しい形で残せます。市販のアプリに依存せず、必要な項目だけを抜き出して保存できます。受信の状態を数値で確かめられるので、位置が飛んだときに、衛星の配置が悪かったのか、電波が遮られたのか、装置の設定が原因なのかを切り分けられます。
複数の機器の記録を突き合わせることもできます。同じ時刻の行を並べれば、二台の受信機がどれだけ違う位置を出していたかが分かります。基準局を使った補正の効果を確かめるときに、この比較が効きます。
まとめ
NMEAは、位置の情報を文字列で表す取り決めです。ドルマークで始まり、衛星群の記号と3文字の種類が続き、カンマで区切られた項目が並び、最後に検査の数値が付きます。
つまずきやすいのは緯度経度の書き方で、度と分が混ざった形になっています。60で割って足す一手間を忘れないでください。
保存したファイルはただのテキストなので、解析ソフトで再生することも、GPXやKMLに変換して地図で開くことも、自分で読むこともできます。どれを選んでも、扱っているのは同じ一行の並びです。