【AIロボットカー Phase 1-4】JetsonでCLAS/GNSSログを取る



AIロボットカー開発記録 ・ CLAS / GNSS / Jetson

🛰️ JetsonでCLAS/GNSSログを取る

u-centerで見ていたF9Pの測位状態を、Jetson側でCSVログとして残せるようにした記録。ロボット自身が「位置をどれだけ信じてよいか」を判断するための第一歩。

CLAS GNSS ZED-F9P NEO-D9C Jetson Python

Result

JetsonでUBX-NAV-PVT取得 CSV保存成功 diffSoln=1 確認 Float 確認 Fixed 確認 hAcc ≈ 0.038m まで低下 diffSoln=1でも精度悪化あり

今回の目的は、u-center上で確認できていたF9Pの測位状態を、Jetson側でもログとして残せるようにすることです。

ロボットカーで使うなら、画面で見るだけでは足りません。ロボット自身が「今の位置情報をどれくらい信じてよいか」を判断できる必要があります。

D9CでCLAS L6補正を受信し、F9PへUARTで渡します。F9Pが測位計算を行い、その結果をUSB経由でJetsonへ送ります。

みちびき (QZSS / L6) TOPGNSS AN-168GL アンテナ PS-GNSS-2 スプリッター D9XC (NEO-D9C) ZED-F9P D9C → F9P UART直結(CLAS補正) USB Jetson /dev/ttyACM0 → Python → CSV保存

構成② 分配(スプリッター経由)— D9CとF9Pがアンテナを共有し、F9Pの測位結果をJetsonで保存する

屋外検証時の実機。GNSSアンテナ(白)と、透明ケースに収めたD9C・ZED-F9P・Jetson・モバイルバッテリー

屋外検証時の実機。白いGNSSアンテナを石の上に設置し、透明ケースにD9C・ZED-F9P・Jetson・モバイルバッテリーをまとめて持ち運んだ。Wi-Fiなしでもログを取れるよう、すべて単体で完結する構成にしている。

ここで大事なのは、Jetsonが直接読む対象はD9CではなくF9Pだということです。D9Cは補正を受信してF9Pへ渡す役割。F9Pはその補正を使って測位し、JetsonはF9Pの測位結果を保存します。

最初、JetsonにはNMEA形式のデータだけが来ていました。NMEAでも緯度・経度・時刻・衛星数などは取れます。ただし今回確認したいのは単なる現在地ではありません。

見たいもの:
CLAS補正がF9Pの測位に反映されたかどうか。これにはu-blox独自形式の UBX-NAV-PVT が必要です。
形式 見える情報 今回の用途
NMEA 緯度・経度・時刻・衛星数・測位状態など 位置確認には使えるが、補正状態の詳細確認には足りない
UBX-NAV-PVT fixType / gnssFixOk / diffSoln / carrSoln / hAcc / numSV CLAS補正がどう効いているかを見るために必要

特に重要なのは、次の3つです。

diffSoln  = 差分補正が使われているか
carrSoln  = Float / Fixed などのキャリア解状態
hAcc      = 水平精度の推定値

Jetson側では、最初に /dev/ttyACM0/dev/ttyUSB0/dev/ttyUSB1 が見えていました。確認した結果、/dev/ttyACM0 がF9P USB、/dev/ttyUSB0/dev/ttyUSB1 はUART系と判断しました。

最初にUART系ポートで確認したところ、NMEAは来ていましたが、UBXは来ていませんでした。

初回 raw-debug 結果

NMEA '$' starts     : 266
UBX sync 0xB5 0x62  : 0
NAV-PVT records     : 0

→ NMEAは来ている。でもUBXはゼロ。CLAS確認はできない。

F9PのUSBから UBX-NAV-PVT を出すには、まずUSB側の出力プロトコルで UBX が有効になっている必要があります。

誤解しやすいポイント:
Protocol out は必ずしも UBX + NMEA + RTCM3 である必要はありません。Jetsonで UBX-NAV-PVT を読む目的なら、少なくともUSB側で UBX が有効であることが重要です。NMEARTCM3 は用途に応じて有効・無効が変わります。

今回の設定では、USB側の Protocol outUBX + NMEA + RTCM3 でした。この中で、Jetsonログ取得に最低限必要だったのは UBX です。

Protocol outを確認する場所

u-centerでF9Pに接続する。
メニューから View → Configuration View を開く。
左側の一覧から PRT (Ports) を選ぶ。
Target または PortUSB を選ぶ。
Protocol out 欄で、USB出力に UBX が含まれているか確認する。

USB側の Protocol outUBX が有効でも、それだけで UBX-NAV-PVT が自動で出るとは限りません。

Protocol out と MSG 出力設定は別です。
Protocol out は「UBX形式を出してよい」という許可。MSG 設定は「どのUBXメッセージを、どのポートへ、どの頻度で出すか」という設定です。

UBX-NAV-PVTをUSBへ出す設定

u-centerで View → Configuration View を開く。
左側の一覧から MSG (Messages) を選ぶ。環境によっては UBX → CFG → MSG から開く。
メッセージ一覧から UBX-NAV-PVT を選択する。
出力先の USB1 に設定して Send する。
CFG → Save current configurationBBRFlash に保存する。

これで、電源を切ってもF9P USBから UBX-NAV-PVT が出続ける状態になります。

1. raw-debugで確認

cd ~/jetson-clas-logger

python3 src/clas_log.py --port /dev/ttyACM0 --baud 115200 --raw-debug --duration 5

設定後の出力

UBX sync 0xB5 0x62  : 6
UBX frames          : 6
bad checksum        : 0

hex dump:
b5 62 01 07 5c 00 ...

b5 62 = UBX開始
01    = NAV class
07    = PVT message
5c 00 = payload length 92 bytes

→ UBX-NAV-PVTが来ている

2. debugモードで確認

python3 src/clas_log.py --port /dev/ttyACM0 --baud 115200 --debug

debug 出力例

[debug] UBX-NAV-PVT  (92B)
fix=3D
ok=1
diff=0
RTK=None
SV=15
hAcc=2.733m
室内確認のポイント:
室内では diff=0 でも正常です。ここで重要なのは、UBX-NAV-PVTがJetsonで読めていて、CSVに保存できることです。

3. 通常ログ取得

python3 src/clas_log.py --port /dev/ttyACM0 --baud 115200

この時点で、Jetson上でCLAS判定に必要なログ取得基盤ができました。

屋外では、JetsonにWi-Fiがなくても動くように、Jetson単体でログを保存する方式にしました。

10分間だけログを取る場合

timeout 600 python3 src/clas_log.py --port /dev/ttyACM0 --baud 115200

SSHが切れても続けたい場合

tmux new -s clas
python3 src/clas_log.py --port /dev/ttyACM0 --baud 115200

屋外検証では、「室内 → 開けた屋外 → 待機 → 遮蔽あり → 建物近く」という環境変化を含めたルートで記録しました。重要なのは、GNSSにとって環境が大きく変わることです。

1. 室内・建物近く
diffSoln=0 hAcc大きめ

遮蔽やマルチパスの影響を受けやすく、補正は安定しにくい。

2. 開けた屋外へ移動
diffSoln=1

衛星数が増え、F9Pが差分補正ありとして扱い始めた。

3. 屋外で待機
Float Fixed hAcc ≈ 0.038m

キャリア解が安定し、hAccが数cm級まで低下した。

4. 移動再開
Float / DiffOnly

移動・遮蔽物・アンテナ姿勢の変化により、Fixedが維持されにくくなった。

5. 建物近くへ戻る
diffSoln=1 hAcc悪化

補正ありのままでも、環境が悪くなるとhAccは大きく悪化した。

重要:
diffSoln=1 は「補正あり」を意味しますが、それだけで高精度とは言えません。hAcccarrSoln も一緒に見る必要があります。

屋外ログでは、3D Fixがほぼ全期間OK、diffSoln=1 を多数確認、最大衛星数32を記録しました。特に重要なのは、次の状態が出たことです。

diffSoln=1
carrSoln=1 / Float
carrSoln=2 / Fixed

これは、F9P側で差分補正が反映され、さらにキャリア解も安定した状態に入ったことを示します。

約0.038m = 約3.8cm
Fixed状態のhAcc中央値。ただし、これは実測誤差そのものではなく、F9Pが出している水平精度の推定値です。

「実際に3.8cmしかズレていなかった」と断定するものではありません。正確には「F9Pのログ上では、Fixed状態でhAccが3〜4cm級まで低下した」と言うのが適切です。

FINDING 1

JetsonでUBX-NAV-PVTを取得できた

F9P USBを /dev/ttyACM0 として読み、CSV保存できた。u-center不要のログ基盤ができた。

FINDING 2

開けた屋外ではCLAS補正が反映された

diffSoln=1、Float、Fixedをログで確認。D9C→F9Pの補正パスが機能している。

FINDING 3

hAccが数cm級まで改善した

Fixed状態のhAcc中央値は約0.038m。ただしこれは推定値。

FINDING 4

diffSoln=1だけでは不十分

補正ありでも、環境が悪ければhAccは大きく悪化した。複合的な信頼度判定が必要。

今回のログから、位置情報をそのまま信じるのではなく、状態に応じて信頼度を変える必要があると分かりました。

状態 信頼度 ロボット側の判断
Fixed + hAcc < 0.2m 位置を強く信じてよい
Float + hAcc < 0.7m 低速走行なら使える可能性
diffSoln=1 + hAcc < 1.5m 注意 補正あり。ただし慎重に扱う
diffSoln=1 + hAcc > 5m 補正ありでも位置を信じすぎない
diffSoln=0 GNSS単独 IMU・カメラ・停止判断を優先
F9P USBをJetsonに接続する。
u-centerでUSB側の Protocol out を確認する(UBX が有効になっていること)。
u-centerでUSB側に UBX-NAV-PVT を出力設定する(CFG → MSG)。
設定を BBR / Flash に保存する(電源を切っても残る)。
Jetsonで /dev/ttyACM0 から読み取る。
PythonでCSVに保存する。
屋外でログ取得し、diffSoln / carrSoln / hAcc の変化を確認する。

屋外検証では、開けた場所でCLAS補正が反映され、FloatやFixedまで確認できました。一方で、遮蔽物のある環境や建物近くでは、補正ありでもhAccが悪化することが分かりました。

CLASは効く。
でも「効いているかどうか」だけでは足りない。
ロボットに使うなら、位置の信頼度を常に見る必要がある。