GNSS SDRを用いたGPS信号の受信

categories: gnss
tags: sdr

GNSS-SDR

無線電波をコンピュータに取り込み、信号処理によりその無線信号を復調するソフトウェア無線(SDR: software defined radio)があります。その信号形式が変わっても、ソフトウェア更新により同じハードウェアが利用可能です。

以前に参加した測位航法学会の全国大会で、テレビ放送受信用USBドングルによりGPS信号を復調するハンズオンに参加しました。ソフトウェアGNSS-SDRLIBを用いましたが、そのソフトウェアの著者である鈴木太郎先生に講習していただきました。

今回は、別のソフトウェアGNSS-SDRを用いて、遠隔で収集したGPS信号の復調と測位を試しました。結局、測位はできませんでしたが、もうすこしで出来そうです。

構成

装置は、屋上にあるGPSアンテナ、USBドングル、およびRaspberry Pi 2からなります。Raspberry Pi 2は、GPS受信電波をパケットに変換し、学内イーサネットにてその信号を伝送します。この信号を研究室PC上のソフトウェアGNSS-SDRにてリアルタイム復調します。

GNSS-SDRは、プログラム言語PythonとC++で記述されたプラットフォームであるGNU Radio上で動作します。このGNSS-SDRのソースコードは公開されており、改変することも可能です。GNU RadioをLinux以外のOSで利用するときには、ライブラリのバージョンを合わせるなどの、様々なノウハウが必要です。このGNSS-SDRにはコンテナでも動作するdocker版も公開されていますので、例えばMac上でも比較的容易かつ安定に動作させることができます。

GPS電波受信部

Raspberry Piに、USBドングル、GPSアンテナ、電源、イーサネットケーブルを接続して、apt-getコマンドなどでrtl-sdrをインストールします。この中に含まれるrtl_tcpを利用して、GPS受信信号を研究室PCに伝送します。この手順により、ディジタル化されたGPS L1無線信号パケットがイーサネット上に流れます。

ほとんど全てのGPSアンテナには、低雑音増幅器(LNA: low noise amplifier)が内蔵されています。このLNAに電源を供給しなければなりませんが、このドングルはLNAに電源供給のできる「バイアスティ」がついています。そこで、このドングルに電源供給を指示するためのソフトウェアrtl_biastをインストールします。rtl_biastに必要なlibusb-1.1-0はすでにインストールされているはずです。その古いバージョンlibusb-0.1-4がインストールされていれば、アンインストールします。または、

# rmmod dvb_usb_rtl28xxu

として、不要なカーネルモジュールをはずします。

そして、このUSBドングルで受信した信号をイーサネットに流します。私は次のシェルスクリプトを作りました。

rtl_biast -d 1 -b 1 && \
rtl_tcp -a 0.0.0.0 -f 1575420000 -g 0 -s 2000000 \
    > /dev/null 2>&1 &

これでGPS受信部の準備はできました。このRaspberry PiのIPアドレスとポート番号1234にアクセスするとGPS信号を得ることができます。

測位計算部

この受信信号を復調して測位を行うために、デスクトップPC(私はMacを使いました)にdockerをインストールしました。GNSS-SDRをインストールして起動する作業はdockerが自動的にしてくれます。任意のディレクトリに次のようなGNSS-SDRに動作を指示する設定ファイルを、たとえばosmosdr.confなどとして保存します。

このSignalSource.addresにある[IPアドレス]はGPS電波受信部のRaspberry PiのIPアドレスに置き換えてください。そして、次のようなシェルスクリプトをgnss-sdr.shなどとして保存しておきます。毎回、dockerコマンドの長い引数を入力したくないからです。

# https://hub.docker.com/r/carlesfernandez/docker-gnsssdr
docker run -it --rm \
    -v $(PWD):/home \
    --net=host \
    carlesfernandez/docker-gnsssdr

さらに、docker内のシェルからGNSS-SDRを起動するためのシェルスクリプトをstart-in-docker.shなどとして作成します。

gnss-sdr --config_file=./osmosdr.conf

準備ができたら、シェルスクリプトgnss-sdr.shを起動します。コンテナが起動してプロンプトが出たら、シェルスクリプト./start-in-docker.shを実行してGNSS SDRを起動します。dockerのオプションでカレントディレクトリをマウントしていますので、このシェルスクリプトがコンテナ内で見えます。

結果

すぐに衛星信号が受信され、コンソール上に例えば次のようにその様子が表示されます。

Tracking of GPS L1 C/A signal started on channel 7 for satellite GPS PRN 19 (Block IIR)
Current receiver time: 5 min 51 s
Current receiver time: 5 min 52 s
Loss of lock in channel 0!
Tracking of GPS L1 C/A signal started on channel 0 for satellite GPS PRN 01 (Block IIF)
Current receiver time: 5 min 53 s
Current receiver time: 5 min 54 s
Current receiver time: 5 min 55 s
Loss of lock in channel 4!
Tracking of GPS L1 C/A signal started on channel 4 for satellite GPS PRN 26 (Block IIF)
Current receiver time: 5 min 56 s
Loss of lock in channel 6!
Tracking of GPS L1 C/A signal started on channel 6 for satellite GPS PRN 27 (Block IIF)
Loss of lock in channel 6!
Tracking of GPS L1 C/A signal started on channel 6 for satellite GPS PRN 27 (Block IIF)
Current receiver time: 5 min 57 s
Loss of lock in channel 3!

私の環境では、GPS信号を捕捉できるのですが、測位に必要な衛星数の信号を受信する前に信号を見失っているようです。RTL_TCPを使わずに、GPS電波受信部で直接、測位を行うべきかもしれません。もう少し頑張ってみます。