はじめに
ソフトウェア無線(SDR: Software Defined Radio)をご存知でしょうか?ソフトウェア無線とは、ハードウェアを変更せずに、制御ソフトウェアにより、無線通信方式を変更できる技術と説明されています。送信側は、法令で規制されているため、気安く試すわけには行きませんが、受信側でソフトウェア無線を試すのは比較的容易です。USBドングル形状の、ソフトウェア無線用受信機は安価で販売され、ARM 64-bit 対応のデバイスドライバも提供されているので、Jetson Nano でも利用することができます。おまけに、Jetson Nano 上の GPU で、ソフトウェア無線のデジタル信号処理も高速に実行できます。
ハードウェア
ソフトウェア無線用受信機とアンテナが必要です。私は、RTL-SDR BLOG V.3 とアンテナのセットを購入しました。アマゾンにて5千円程度の価格で購入できます。
この受信機はUSBドングルとしては少し大きいので、他の USB ポートと干渉します。そのため、この写真のとおり、USB エクステンダーケーブルを介して、Jetson Nano と接続しています。
ソフトウェア
Python でプログラミングできるようにするため、以下のパッケージを利用しました。
-
RAPIDS cuSignal
- GPU を利用したデジタル信号処理ライブラリ
- Scipy Signal 互換 API
-
SoapySDR
- ベンダーに依存しないソフトウェア無線サポート・ライブラリ
- ライブラリ内部で、RTL-SDR 用ライブラリ librtl-sdr を呼び出している
ソフトウェアのインストール
cuSignal, SoapySDR の順で、インストールを行います。この2つに依存関係は存在しないのですが、cuSignal は Anaconda 環境が標準なので、その環境構築が最初という意味で、この順序でのインストールに帰結します。
両方共に、配布元のドキュメントに沿ってインストールできますが、少し面倒なところもあったので、ここに記録します。
cuSignal のインストール
cuSignal の GitHub リポジトリ に Jetson 用のインストール手順 が記載されているので、基本的にはこの手順に従います。
注意点は、CuPy のビルド時に、GPU の Compute Capability を指定することです。これを行わないと、いつまでたってもビルドが完了しません。
Anaconda 環境の構築
まず最初に、Anaconda 環境を構築します。ドキュメントに記載どおり、Miniforge をインストールします。Linux aarch64 (arm64) Miniforge3-Linux-aarch6 を利用しました。インストーラーを実行するだけでインストールできます。最後に conda init を実行するかどうか問われますので、この後の作業のために、そこで Yes とします。
cuSignal のインストール
export CUSIGNAL_HOME=$(pwd)/cusignal
git clone https://github.com/rapidsai/cusignal.git $CUSIGNAL_HOME
cd $CUSIGNAL_HOME
以下の環境変数設定が非常に重要です。Jetson Nano の Compute Capability は 5.3 なので以下のように設定します。これを行わないとすべての Compute Capability に対応できるよう CuPy がビルドされるので、いつまでたってもビルドが完了しません。(私は半日放置してビルドが終わらなかったので諦め、Compute Capability を指定してのビルドへ切り替えました。)
export CUPY_NVCC_GENERATE_CODE="arch=compute_53,code=sm_53"
conda env create -f conda/environments/cusignal_jetson_base.yml
conda activate cusignal-dev
CUDA Toolkit へパスを通しておかないと、CuPy のビルドに失敗します。
PATH="$PATH":/usr/local/cuda/bin
./build.sh
cd python
cuSignal が正しくインストールできたかテストします。いくつかのワーニングが出ましたが、エラーは出なかったので、良しとしました。
pytest -v
SoapySDR のインストール
基本的には、SoapySDR BuildGuide と Building Soapy RTL-SDR のとおり。
RTL-SDR と オーディオ関連のライブラリをインストール
sudo apt install rtl-sdr librtlsdr-dev portaudio19-dev
pyrtlsdr と pyaudio は conda install で見つからなかったので、pip でインストールしました。
pip install pyrtlsdr pyaudio
ほとんどの RTL-SDR デバイスで libdvb ドライバをブラックリスト登録してロードをされないようにする必要があるらしいです。Please note, for most rtlsdr devices, you'll need to blacklist the libdvb driver in Linux.
sudo vi /etc/modprobe.d/blacklist.conf
最後の行に、blacklist dvb_usb_rtl28xxu を追加。それを反映させるため、リブート。
sudo reboot
swig をインストールしておかないと、SoapySDR の Python パッケージがビルドされないので。
conda install swig
後々、サンプルの Jupyter Notebook を実行するので。
conda install jupyter
SoapySDR のインストール
git clone https://github.com/pothosware/SoapySDR.git
cd SoapySDR
mkdir build
cd build
Anaconda 環境に関する理解が不足しているため、ここが苦労したところ。普通に cmake .. とやると、通常の Python パスに SoapySDR の Python パッケージがインストールされて、Anaconda 環境からは見えなくなってしまう。そのため Anaconda 環境のパスを指定。PYTHON_INSTALL_DIR と PYTHON3_INSTALL_DIR の両方に指定したが、PYTHON3_INSTALL_DIR だけで良いのかも知れない。
cmake -DPYTHON_INSTALL_DIR=`python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"` -DPYTHON3_INSTALL_DIR=`python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"` ..
make -j4
sudo make install
sudo ldconfig
以下のコマンドで SoapySDR がインストールできたことを確認。
SoapySDRUtil --info
以下のように出力されれば成功。
######################################################
## Soapy SDR -- the SDR abstraction library ##
######################################################
Lib Version: v0.8.0-gab626068
API Version: v0.8.0
ABI Version: v0.8
Install root: /usr/local
Search path: /usr/local/lib/SoapySDR/modules0.8
Module found: /usr/local/lib/SoapySDR/modules0.8/librtlsdrSupport.so (0.3.2-53ee8f4)
Available factories... rtlsdr
Available converters...
- CF32 -> [CF32, CS16, CS8, CU16, CU8]
- CS16 -> [CF32, CS16, CS8, CU16, CU8]
- CS32 -> [CS32]
- CS8 -> [CF32, CS16, CS8, CU16, CU8]
- CU16 -> [CF32, CS16, CS8]
- CU8 -> [CF32, CS16, CS8]
- F32 -> [F32, S16, S8, U16, U8]
- S16 -> [F32, S16, S8, U16, U8]
- S32 -> [S32]
- S8 -> [F32, S16, S8, U16, U8]
- U16 -> [F32, S16, S8]
- U8 -> [F32, S16, S8]
SoapyRTLSDR のインストール
git clone https://github.com/pothosware/SoapyRTLSDR.git
cd SoapyRTLSDR
mkdir build
cd build
cmake ..
make
sudo make install
最後に RTL-SDR デバイスが認識できているか確認。Jetson Nano 起動前から RTL-SDR デバイスが USB ポートに刺さっている必要があるようです。
SoapySDRUtil --probe
以下のように表示されれば、めでたし、めでたし。
######################################################
## Soapy SDR -- the SDR abstraction library ##
######################################################
Probe device
Found Rafael Micro R820T tuner
[INFO] Opening Generic RTL2832U OEM :: 00000001...
Found Rafael Micro R820T tuner
----------------------------------------------------
-- Device identification
----------------------------------------------------
driver=RTLSDR
hardware=R820T
index=0
origin=https://github.com/pothosware/SoapyRTLSDR
----------------------------------------------------
-- Peripheral summary
----------------------------------------------------
Channels: 1 Rx, 0 Tx
Timestamps: YES
Time sources: sw_ticks
Other Settings:
* Direct Sampling - RTL-SDR Direct Sampling Mode
[key=direct_samp, default=0, type=string, options=(0, 1, 2)]
* Offset Tune - RTL-SDR Offset Tuning Mode
[key=offset_tune, default=false, type=bool]
* I/Q Swap - RTL-SDR I/Q Swap Mode
[key=iq_swap, default=false, type=bool]
* Digital AGC - RTL-SDR digital AGC Mode
[key=digital_agc, default=false, type=bool]
* Bias Tee - RTL-SDR Blog V.3 Bias-Tee Mode
[key=biastee, default=false, type=bool]
----------------------------------------------------
-- RX Channel 0
----------------------------------------------------
Full-duplex: NO
Supports AGC: YES
Stream formats: CS8, CS16, CF32
Native format: CS8 [full-scale=128]
Stream args:
* Buffer Size - Number of bytes per buffer, multiples of 512 only.
[key=bufflen, units=bytes, default=262144, type=int]
* Ring buffers - Number of buffers in the ring.
[key=buffers, units=buffers, default=15, type=int]
* Async buffers - Number of async usb buffers (advanced).
[key=asyncBuffs, units=buffers, default=0, type=int]
Antennas: RX
Full gain range: [0, 49.6] dB
TUNER gain range: [0, 49.6] dB
Full freq range: [23.999, 1764] MHz
RF freq range: [24, 1764] MHz
CORR freq range: [-0.001, 0.001] MHz
Sample rates: [0.225001, 0.3], [0.900001, 3.2] MSps
Filter bandwidths: [0, 8] MHz
最後に
Jetson Nano でもソフトウェア無線を気軽に試すことができることは、先人達の努力によるもので、感謝しかありません。但し、Windows 10 や x64 Linux プラットフォームの場合ほど、Jetson Nano で試す際の情報は充実していません。私自身、このインストール手順を見出すのに何日もかかり、それが、記事にした動機です。誰かのお役に立てば幸いです。
ところで、インストール作業をもっと簡単にするため、Dockerfile の作成を考えたのですが、Anaconda を使わないで CuPy をインストールすることが難しくて断念しました。(x64 向けは サポート されているようです。)
本記事は、動作確認編 へ続きます。