PocketSDRすごい(pocket_trk編)
はじめに
東京海洋大学の高須知二先生が、新しいPocketSDRのコードとサンプルデータを提供されました。これは、測位衛星の信号を追捕しながら、その航法データを復号するものです。
このコードはPythonで書かれていますが、今回、利用するpocket_trk.py
はC言語で書かれたRTKLIBとLIBFECの共有ライブラリを呼び出しています。PocketSDRには、これらの64ビットWindows用とLinux用の共有ライブラリも同梱されています。
私の利用しているMacbook Air(Intel CPU)でも、その航法データ復号コードを実行してみたいと思い、自らで必要な共有ライブラリをコンパイルしてみました。
ここでは、RTKLIBやLIBFECのmacOS上での共有ライブラリ作成手順と、pocket_trk.py
実行例を示します。もうひとつのサンプルコードpocket_acq.py
が実行できていること、パッケージマネージャHomebrewがインストールされて、C言語での開発環境が整っていることを前提にしています。
Mac上でのRTKLIBとLIBFECの共有ライブラリ作成
RTKLIBは、高須知二先生が公開されている、測位衛星利用に関するC言語ライブラリとアプリケーションです。一方、LIBFECは、昔からのアマチュア無線家ならばご存知かもしれないKA9Q、Phil Karn氏が公開されている、前方誤り訂正(FEC: forward error correction)のC言語ライブラリ(のクローン)です。
以下は、ターミナルで操作します。私は、より使いやすいiTerm2をHomebrewにてインストールし、それを利用しています(brew install iterm2
)。
はじめに、RTKLIBをGitHubからチェックアウトして、共有ライブラリ作成用のディレクトリを作成します。
git clone https://github.com/tomojitakasu/RTKLIB -b rtklib_2.4.3 rtklib
cd rtklib/app/consapp/
mkdir -p dylib/gcc/
現在のmacOSでは、シリアルポートのボーレートが230,400 bit/sまでですので、src/stream.c
の348行目や361行目付近にある、460800や921600の文字をコメントアウトします。
そして、例えばstr2str/gcc
にあるmakefile
をdylib/gcc/
にコピーして、共有ライブラリが作成されるよう、先頭部分を次のように書き換えました。
# makefile for str2str
BINDIR = /usr/local/bin
SRC = ../../../../src
# for beagleboard
#CTARGET= -mfpu=neon -mfloat-abi=softfp -ffast-math
CTARGET=
OPTION = -DENAGLO -DENAGAL -DENAQZS -DENACMP -DENAIRN -DTRACE -DNFREQ=3 -DNEXOBS=3
#OPTION = -DENAGLO -DENAGAL -DENAQZS -DENACMP -DENAIRN -DTRACE -DNFREQ=5 -DNEXOBS=3 -DSVR_REUSEADDR
CFLAGS = -Wall -O3 -ansi -pedantic -fno-common -I$(SRC) $(OPTION) $(CTARGET) -g
LDLIBS = -lm -lpthread #-lrt
all: librtk.dylib
librtk.dylib: stream.o rtkcmn.o solution.o sbas.o geoid.o
librtk.dylib: rcvraw.o novatel.o ublox.o ss2.o crescent.o skytraq.o javad.o
librtk.dylib: nvs.o binex.o rt17.o rtcm.o rtcm2.o rtcm3.o rtcm3e.o preceph.o
librtk.dylib: streamsvr.o septentrio.o
librtk.dylib :
$(CC) -dynamiclib -o librtk.dylib $(CFLAGS) \
stream.o rtkcmn.o solution.o sbas.o geoid.o \
rcvraw.o novatel.o ublox.o ss2.o crescent.o skytraq.o javad.o \
nvs.o binex.o rt17.o rtcm.o rtcm2.o rtcm3.o rtcm3e.o preceph.o \
streamsvr.o septentrio.o
stream.o : $(SRC)/stream.c
$(CC) -c $(CFLAGS) $(SRC)/stream.c
macOSにて共有ライブラリを作成するためには、コンパイル時に-fno-common
オプションを、リンク時に-dynamiclib
オプションを指定すればよいようです(PowerPC CPUでの方法がIntel CPUでも利用できました)。
ここでmake
を実行すると、このディレクトリにlibrtk.dylib
が作成されます。これをPocketSDRのlibディレクトリにコピーします。
次に、LIBFECの共有ライブラリを作成します。LIBFECをGitHubからチェックアウトし、configure
スクリプトを実行して、make
コマンドを実行します。ターゲットCPUの自動判定に失敗するようですので、configure
スクリプトにはターゲットCPUを指定するオプションが必要です。
git clone https://github.com/quiet/libfec
cd libfec
./configure --target=x86
make
最後に、ローダーコマンドの実行に失敗した旨のメッセージ(ld: unknown option: -soname=libfec.so)が現れます。そこで、手作業で共有ライブラリを作成します。
gcc -dynamiclib -o libfec.dylib cpu_mode_unknown.o fec.o viterbi27.o viterbi27_port.o viterbi29.o viterbi29_port.o viterbi39.o viterbi39_port.o viterbi615.o viterbi615_port.o encode_rs_char.o encode_rs_int.o encode_rs_8.o decode_rs_char.o decode_rs_int.o decode_rs_8.o init_rs_char.o init_rs_int.o ccsds_tab.o encode_rs_ccsds.o decode_rs_ccsds.o ccsds_tal.o dotprod.o dotprod_port.o peakval.o peakval_port.o sumsq.o sumsq_port.o -lc
ここで、libfec.dylib
が作成されますので、これもPocketSDRのlibディレクトリにコピーします。
最後に、PocketSDRのpythonディレクトリにある、sdr_rtk.py
とsdr_fec.py
の先頭部分を修正して、ここで作成した共有ライブラリをpocket_trk.py
にて読み込めるようにします。
sdr_rtk.py
# load RTKLIB ([1]) ------------------------------------------------------------
dir = os.path.dirname(__file__)
#try:
# librtk = cdll.LoadLibrary(dir + '/../lib/win32/librtk.so')
#except:
# librtk = cdll.LoadLibrary(dir + '/../lib/linux/librtk.so')
librtk = cdll.LoadLibrary(dir + '/../lib/librtk.dylib')
sdr_fec.py
# load LIBFEC ([1]) ------------------------------------------------------------
dir = os.path.dirname(__file__)
#try:
# libfec = cdll.LoadLibrary(dir + '/../lib/win32/libfec.so')
#except:
# libfec = cdll.LoadLibrary(dir + '/../lib/linux/libfec.so')
libfec = cdll.LoadLibrary(dir + '/../lib/libfec.dylib')
pocket_trk.pyの実行
PocketSDRのsampleディレクトリにある、link拡張子のファイルを参照して、サンプルデータをダウンロードし、unzipコマンドで展開しておきます。観測時間が30秒程度は必要だからです。
ここまでできたら、PocketSDRのpythonディレクトリにあるpocket_trk.py
を試すことができます。高須先生のホームページに多数の実行例がありますが、私が特に楽しいと思ったのは、DLL(delay locked loop)にて衛星信号を追尾しながら、信号を復号するものです。一例として、PRN16のGPS L1 C/A信号を追尾しながら、その航法データを復号します。
python3 pocket_trk.py L1_20211226_082212_12MHz_I.bin -prn 16 -f 12 -fi 3 -p
その動画をキャプチャーしてみました。信号追尾、信号空間ダイヤグラム、逆拡散後の波形、そして、しばらく待つと航法データの復号結果が表示されます。
これはとても楽しいです。色々な衛星信号を見てみたいです。PocketSDRに添付されているPythonコードは、L1 C/A信号だけでなく、みちびきのL1S信号や新信号のL1 C/B信号をはじめとする多数の多数の信号を追尾でき(sdr_code.py
)、LNAV(legacy navigation message、航空機の航法LNAVとは別ものです)、CNAV(civil navigation message)、I/NAV(integrity navigation message)、F/NAV(free navigation message)、SBAS(satellite-based augmentation system)の航法メッセージを復号できます(sdr_nav.py
)。
pocket_trk.py
の使い方や関数仕様は、そのソースコード中に丁寧に記述されています。分厚いマニュアルよりも、ソースコード中のコメントの方が、検索しながら読むことができて、ずっと嬉しいです。
もし私が汎用的なライブラリを作ることがあるならば、その共有ライブラリとPythonラッパーも提供しようと思います。
まだ、M1 CPUのMacでは試していません。LIBFECは、特定CPUの利用を想定しているようですので、その共有ライブラリ作成は困難かもしれません。
Apple Silicon CPUでのpocket_trk
(2022-01-07追記)
Apple M1 CPUのMacでも試しました。RTKLIBの共有ライブラリは、上述の手順により作成できました。また、LIBFECについては、configure
スクリプト実行時のCPUアーキテクチャを指定することなく、make
コマンド実行だけで、簡単に共有ライブラリが作成できました。
前述の実行では、Macbook Air 13-inch Early 2015, Intel Core i7-5650U 2.2 GHz, 8 GB 1600 MHz DDR 3, macOS Big Sur 11.6.2を使いました。
一方、この実行では、Mac mini M1 2020, Apple M1 3.2 GHz, 16 GB LPDDR 4 unified memory, macOS Monterey 12.0.1を使いました。
PocketSDRすごいです。私もPocketSDRハードウェアを作成すべく、MAX2771とFX2LPの獲得競争に参加しようと思います。これからリフロー炉を準備して、使い方を学びます。
macOS用共有ライブラリダウンロード
私の作成した共有ライブラリは以下の通りです。ご自由にご利用ください。自己責任でお願いします。Intel CPU向けと、M1 CPU向けとがあります。
librtkfec-intel.ziplibrtkfec-m1.zip
pocketsdr_maclib.zipをお使いください。
(2022-02-19更新: PocketSDR version 0.7に合わせて更新しました。)
関連記事
- Pocket SDRすごい(リアルタイム測位機能) 13th October 2024
- Pocket SDRを用いたGalileo E6B信号の受信 27th January 2023
- リフローでやらかしました 19th January 2023
- Pocket SDRハードウェア製作(第3報) 30th September 2022
- Pocket SDRハードウェア製作(第2報) 14th September 2022
- Pocket SDRハードウェア製作(第1報) 4th September 2022
- PocketSDRすごい(パーツ購入編) 9th April 2022
- PocketSDR APにてbladeRFを使いたい(その2) 16th March 2022
- PocketSDR APにてbladeRFを使いたい 5th March 2022
- PocketSDRすごい(スナップショット測位編) 23rd February 2022
- PocketSDRすごい(FFTWによる高速化) 19th February 2022
- PocketSDRすごい(L6信号デコード編) 19th January 2022
- PocketSDRすごい(pocket_acq編) 4th December 2021