GNU Radio と遊ぶ  2019.4.27




 最初にRFワールド44号を見たときは、GNURadioがMATLABのShimulinkにやっと追いついたのか、遅いぜ!なんてナマ言っていました。この頃はSDR-3にかまけていたためもあって、RFワールド44号は購入もしないで放置してありました。ただ、よくよく考えてみると、MATLABのほうの昨今の流行りは、どうも「ディープラーニング」の方に行ってしまっていて、もう、SDR関連の機能モジュールが盛んに開発されているような雰囲気ではないようなのです。そうです、もう、「金を取るツール」として、MATLAB界隈ではSDRはネタとして見向きもされないということのようです。

 また、MATLABの機能モジュールの中身の記述言語のm−codeですが、これに関する資料は英文でもあまり多くありません。関連のありそうなE-bookを一つDLしてありますが、これはSDRというより、変調・復調・伝搬シミュレーションが主で、なんとなく没入するには敷居が高いです(有名なこれではありません)。大学の研究室等ではMATLABは大変ポピュラーな解析ツールなので、そういったアカデミックフィールドでは、資料が蓄積されているのかもしれませんが、普通の検索ではあまり引っかかってきません。

 それに引き替え、GNURadioは?というと、これも、HAM連中には殆ど知られていないのじゃないかと思います。特にGRCなるグラフィカルユーザインタフェース(GUI)機能が用意されるまでは、PythonとC#を駆使して記述しなければならないので、そのバリアーたるや一般のHAMには大変高いものが有ったのだと思います。要は、趣味レベルでは敷居が高く、学術的な利用に留まっていたのだという認識です(最近、CQ誌に紹介があったのにはびっくりですが、読者層を間違えてないか?:笑)。

 これがGRCなるGUIを具備することで、飛躍的に扱いが楽になったと考えられます。直視的に信号処理系を構築できるので、随分ととっかかるうえでのバリアーは消えています。機能モジュールがブラックボックスと考えても、なんとか処理系が動き出すような感じがします。一方、「中身は一体どうなちょるんじゃー?」という疑問に対しては、モジュールのC#で書かれたプログラムを読めばそれは理解できるのでしょう。ディジタル信号処理を実際に体験し、その中身の「カン」を養うには、いい教材になるのではないでしょうか?

 GNURadioはオープンソースで、ロイヤリティフリーですが、かなり信頼性も高く、商業ベースでなくても成功したLinuxのような物と考えればいいのでしょうか。見識のある方が寄ってたかって機能向上・デバッグをやっていて、結果信頼性も高くなったのだろうという感触です。

 ここまでくると、MATLABをアップデートするのに、個人ユースとはいえ、毎年15K円程度の出費が要るので、GNURadioが使えるようになれば、もう、MATLABのアップデートはしないで済むかもしれないというスケベ心から、GNURadioを試してみようと思い始めました。

 GNURadio用のSDRハードですが、ちょっと前まではUSRPやBladeRFといった、高価〜若干高価なものに限られていたのですが、最近はHackRFoneやRedpitaya、LimeSDR(mini)といった、私の既に所有していて、12〜14ビットのそれもHAMが使うにもFamiliarなSDRが対応しているようなので(RedpitayaとLimeはGNURadioで未検証ですが、そのうちトライしたいと思っています)、なんだかわくわくしてきます。

 本音を吐くと、実は、MATLABはPlutoSDRやBladeRFとかのSDRがメインで、若干私好みではありません。もちろん、GNUとMATLABもRTL-SDR(ドングル)には対応していますが、ま、ドングルでは大したことが出来ないので(勉強するにはいいのですがね)、やっぱりGNURadioかなぁ?と思ってしまいます。特にRedpitayaは噂では近く大きな性能改善が有りそうで、こうなると、尚更GNURadioがいいかなぁ?と思ってしまいますね。

 前置きはこのくらいにして、どのように体制を立ち上げるか考えないといけません。RFワールドの記事を読むと、Linux機でGRCを動かすのが良さそうです(Windows環境は制限が多すぎるし、検証レベルも低いといわれています。使えれば使ってね!レベルでしょうか?)。なんせ、こんな事態を想定して、2年前にUbuntuの16年ヴァージョンを開発機にwindowsとデュアルインストールしてありましたので、らっくしょーでしょう?なんて考えたのが運の尽きで、少々苦労することになります。

 というのも、Ubuntuは既に18年ヴァージョンが出ているのですが、再インストールが面倒だったので、16年ヴァージョンのアップデートを行ったら、途中で、なにやらエラーがでてそこでアップデートが終了してしまいました。まぁ、それでもGRCを動かすのに、支障が無ければ関係ないだろ?と思ってそのまま、GRCをダウンロードして、単独では動いているかに見えました。なので、気を良くして、ここで購入した、HackRFonem「もどき」を接続して動作させようとしたのですが、うんともすんとも言いません。ドライバーあたりをしつこく確認したのですが、結局動作せずに撃沈されました。ま、こんなことは良くある話で、いちいちめげていたら先に進めません。

 さて、次のアプローチは?というと、一丁、Linux専用機を作ろうかなぁ?と思ったの「も」運の尽きでした(笑)。オクを見ていると、Windows10を搭載した、法人ユースのデスクトップPCは、結構安値でたたき売られています。型遅れになって償却されたPCを法人からタダ同然で引っ張ってきて、そこにW10を再インストールしたもののように見えます。W10の大量ディスカウントパッケージ?が1台あたりいくらかかるのか知りませんが、オクを見ているとえらく安い機体もありますね。もっとも、法人用ならば、すでに5年は酷使されていて、寿命の尽きる直前のものと見た方がいいのかもしれませんが。

 結局、CPUはCeleron、メモリー4GB、HDDは500GBの型落ちでW10をクリーンインストールしてあった富士通のデスクトップが、送料込で4K円!で買えました。これなら、どう使おうと、最悪、壊れても全く惜しくありません。最初はこれのパーティション分割を行い、RFワールドお勧めのXubuntu(コンパクトなパッケージ)をインストールしようとしたのですが、まっさらなパーティションには、なんだがインストールを嫌がる反応をするので、ええい、ままよ、とフル書き替え(W10は廃棄)してしまいました。この機種では、CPUの能力上、W10の動きが結構トロイのは分かっていたので、コイツでW10を動かす気はなかった(メイン機と開発機で十分)というのが理由です。

 そのあと、GRCとHackRFもどきに必要なドライバーをインストールして、一応の動作に漕ぎ着けました。

 しか〜〜〜〜し、問題発生です。

 HackRFもどきでFM受信機を作ってみたのですが、どうやら、感度が偉く悪いのです。−20dBm以下は受信しないというショック状態に陥りました。HackのRF,IFゲインを変えても変化がありません。まさに

 なんじゃこりゃ?

 状態というわけです。こうなると少々困ったことになりました。何が原因なのか、良くわからないのです。もともとLinuxは軽いので、劣悪なPCでも動くのが「ウリ」ですが、それに甘えきって、安物PCを購入したのですが、もしかして、Liunx OSは動作が軽くても、その上のGRCは重いので、うまく動作しないのか?なんてちょっとぶっ飛んだ感覚になってしまいました。

 ただ、何もしないではことが進まないので、とえりあえず、PCの能力アップを企図してみます。といっても、Linux専用機にハイパフォーマンスのPCを宛がう気も起きません。なので、以前にUbuntuを分割インストールしてあった開発機(Corei−5)の領域に、Xubuntuを上書きができないかトライしてみました。すると、今度は、全部書き換えるか、Ubuntuのみを書き換えるか聞いて来たので、Ubuntu16年ヴァージョンを殺して上書きしています。このあとは、同じようにGRCをインストールし、HACKRFを動かすわけですが、今度はなんとかまともに動いています。−70dBmくらいまで、FMが受信できていますから、普通に動作をしている様子です。ということは、さっきのXubuntu専用機との差は、CPUやメモリーの能力差だけですから、結局、それが原因で、先のプアPCではまともに動かなかったということになるのでしょうか?このあたりは良く分かりません。


 さて、GRCとHackRFoneの組み合わせで、いろいろとRFワールドNo44の事例をなぞり始めました。例題をやっていてもあまり面白くないので、GRCの中で提供される機能ブロックについての「動き」を想像しながら、パラメータを変えて、その変化を見ています。このツールが思った通りに動かせるようになるためには、例題をいくらこなしてもダメなのじゃないかと思っています。というのも、フローグラフを本文の通り結線して、結果が得られても、それは単に、著者が原稿に書いた事例を「なぞっているだけ」に過ぎないからです。なので、ずっとそこに留まっているなら、応用ができないということになります。こんなことを書くと炎上しそうですが、このHPにはコメ欄がないので大丈夫です(大笑)。


 とりあえず、ハードでも動いたので、その「動作の正しさ?」について見て行きましょう。まずは簡単なところで、FM変調器の事例を取り上げてみてみます。シグナルフローは以下の通りです。





狭帯域FM変調器のシグナルフローグラフ


 ここで、Signal Sourceの信号振幅を0.1としてみたスペクトラムを示します。さて、この状態でSSGから同じような信号を出してみます。最大周波数偏移は10kHzに対してAudio信号が0.1ということは周波数偏移は1kHzということになるのでしょうか? その写真が以下の通りとなります。




上:RF変調信号のスペクトラム(中心周波数は50MHzに設定) 下:変調信号(1kHz)




実際のHACKRFoneのFM変調スペクトラム

周波数が若干ずれているのはご愛敬です(Hackのほうがずれている)
第二側帯波のレベルは、シグナルフローグラフで示した周波数偏移1kHzで変調指数0.1の様子に等しい(ようだ)





SSGからのFM変調スペクトラム

最大周波数偏移は1kHzなのでGRCで設定されたパラメータと等価になるはず
第二側帯波のレベルがHack RF Oneと1dB程度異なるがほぼ同じレベル


 このとおり、シグナルフローグラフで設定したスペクトラム、HackRFOneからの出力スペクトラム、またSSGで同じパラメータはを設定したときのスペクトラムは全て(ほぼ)一致しますので、GNC及び、HackRFoneがパラメータ設定を含めて正しく動いていることが分かります。ただ、今まではRedpitayaで14ビットの波形を見てたので、今度のHackRFの8ビットでは随分と「Dレンジのせせこましい」波形(Dレンジが狭いのでノイズフロアが高い)になってしまいますね。ここまで、意外とすんなり動いたのですが、MATLABに較べて、直感的に操作しやすいように思えます。確かに、各機能モジュールの設定パラメータの説明が良くわからない部分もあるので、これらを完全に理解しない限り、「動作が分かった!」とはならないのですが、取り掛かりのバリアーは意外と低いのかもしれません。



<GNU Radio でRedpitayaを使う> 【2019.8.4】

 前回、さわりをアップしましたが、このGNURadioというSDRシミュレーションソフトは本当に素晴らしいと思います。少し弄っただけで、MATLABを完全に「亡きもの=廃棄」にできると確信しました。ただし、扱いはまだまだ難しいところも多く、一般的な解説書は、RFワールドNo44くらいしかないので、いろいろ弄りこんで、自分で体得していかなければならないのでしょう。

 実は、最近、SDRに関して少し意識が変わってきたことが有りますので、ちょっとメモしておくことにします。

 以前は、慣れのために、多くのSDRとその制御ソフトを弄っていましたが、なんとなく既製品のリグを弄るのとなにが違うのか?なんて天邪鬼な感覚を払拭できないでいました。よく考えると、自分で手を加える余地が殆どないから、そう感じていたようです。ハード&ソフトがブラックボックスで「何をやっているのかよーわからん」てな状態ですよね。

 それを脱しようと、TRX−305とかの動作解説の理解に努め、SDRが分かったような気になっていましたが、別に詳細な処理を行うコードを見るでもなく、特にFPGAベースTRX305の解析は、まるで歯が立たなくて撃沈されました。ここで、FPGAの処理は、信号処理を行う上での多くのテクニックが必要で、理解するだけで、年を重ねてしまいそう(重ねても理解できないかも?:笑)なので、趣味で弄るのは敷居が極めて高そうだとFPGAは諦めました。

 その後SDR-3という良く練られたSDRのTRXキットも入手し、これはソースコードがCなので、比較的とっつきやすく、ハマルかと思ったのですが、なんとなく弄りから疎遠になっています。おじさん工房のBBSではソースを弄っていろいろ機能追加をされている例があり、大変アクティビティが高く、これは素晴らしいことですね。私も、開発環境を構築して、ソース変更&コンパイル&ロードができるようにしていますが、ちょっと弄っただけで止まっています。

 そういえば、昔にDSPを弄っていたころ、Cでいろいろ書いて、DSPに実装し、実際に動作をさせていたのですが、ま、ハードからデータが取得できれば、処理のソフトは「こんな感じで動くんだ」ととりあえず理解は出来ていました。なので、SDR-3のSDP処理部分のソースを細かく見て、理解したうえで、何かしら改造するという「労力を厭う気持ち」がでてきてしまったようです。あまり、DSPで遊んだ処理と変わるところはないのかな?というところでした。

 で、Redpitayaですが、これはお気に入りのSDRで、14ビット版でさえもPowerSDRと組合せると、けっこうな高性能が体験できます。世に出ているSDRは、携帯やGPSやWiFiその他の遊びができるように、高い周波数のチューナを持ったものが多く、HAMにはあまり魅力的ではないように私的には映っています。その点、Redpitayaは120Msps以上のサンプルレートを持ち、HF〜50MHzまでダイレクトサンプルできるので、極めてHAM好みのSDRになっていると思います。ビット数が14〜16というのも、高い周波数のSDR(8〜12ビット)と違って、高性能を実現している大事な要素でもあります。

 これがGNURadioで、いろいろな動作ファンクションを簡単に定義することができ、リアルにその動作を確認できるとなると、これはもう大変な魅力で一杯です。SDRやDSPのコードを書いて、実働させるのは、とんでもなく高いスキル、正確さ、忍耐が必要となり、趣味としては「ちょっとしんどいなぁ」と思っています。どうせ苦労して書いても、場合によったら使い物にならない(苦笑)し、ハードがそもそもプアでは、結果もプアで、苦労して没入する気にもならないと、私としては思っていました。それが、特性のいいRedpitayaをGNURadioで使う(機能を記述できる)事ができるとなると、「これはちょっと違うかも!」と見直しているのです。

 まだ、やっとGNURadioで動いただけなので、こんなに褒め倒して、そのあと結果がでてこないと恥ずかしいのですが、まぁ、それはおいおい書いて行くとして、まずはGNURadio+Redpitayaに至るまでのプロセスを書いておきましょう。

 実はその本題に入る前に、少しびっくりしたことを記しておきます(前置きが長そうだ:笑)。それは、Linux用のPCのことです。以前に、HackRFOneでGNURadioを弄り始めたときに、古い世代のPCじゃ、もう力不足?で動かなかった?くだりをUPしましたが、これは大きな間違いでした。ここではパワー不足で動かんよーーと騒いでいたのですが、時間を置いて再度チェックしてみると、なんとガンガンに動いているではありませんか。





富士通のDTP PC


 動かなかった当時、タスクマネージャーでパフォ―マンスを見ていれば、即座に分かったのかもしれませんが、GNURadioの要求CPUリソースはそう多くないようです。ターミナルモードのモニタを見ていると、FM受信機動作を実行しているとき、しきりに“UUUUUU”が連発していたので、当時の「動作が重い」原因は、PCとHackRFOneとの信号授受で同期が外れかけていた状態という「オチ」だったのかもしれません。時間を置いた再度の実行時は、何事も無かったように、Corei5のPCと同じようなCPU使用率で動いています。いったいこの現象はなんだったのかとは思いましたが、4000円のWin10(結局、Xubuntuで全部上書きしてしまいましたが)のPCが「十分使い物になる」と分かったので、これはこれで大きな収穫でした。

 ただ、メモリーを2GBしか積んでいなかったので、ブラウザを開くとFireFOXでさえ1MB以上消費してしまうので、新品の4GB(ジャスト2000円)を追加して、合計6GBのメモリーで運用しています。これだと、メモリースワップもまったく起きず、ソフトをたくさん開いても問題ないです。この手のPCは法人向けのリースアップなのか、大量に安くオクに出ていますね。

 実は、GNURadioだけでなくて、ブラウザ、メーラ、印刷、ドキュメントソフト利用とか、普通の事務PCと同じような動作もさせているのですが、Celeronとは思えないような軽快さです。すでに5年くらい経った、もともとWin-7/8のオフィスPCにW-10を載せ替えてオクに出してあったものですから、まったく動作速度は期待していなかったのですが、殆どWin-10のメインPCと同じよう(あるいは少し速いか?)に使えるので、これが送料込で4K円とは、本当にお買い得だと思ってしまいます。

 X−ubuntuは、小さなパッケージで小回りが利くのですが、ここまで軽快だとは思いませんでした。“生活に必要な”ソフトも殆どオリジナルでパッケージされていますし。但し、PCの寿命については未知数ですね。いきなり壊れてしまうかもしれませんから。実は、Win-7にupgradableなWin-XPを載せたHP社のPCもいまだに有りますが、こちらも好調で、壊れそうなそぶりは有りません・・・なんて書くと“言霊”じゃなくて“書き霊”で、壊れてしまわないか心配ですが(笑)。

 さて、側道から戻って、RedpitayaのGNURadioの動作設定です。

 最初はこんなの簡単だろうと思っていたのですが、ここでも少し手こずりました。

 有名なPavel-DeminさんのRedpitaya NotesのSDR tranceiverの項目をフォローすれば、「出来てしまいますよ」という情報が有ったので、その通り実施してみました。Pavelさんの該当箇所を借用してきます。





Redpitayaを起動する場合のインストラクション(Pavel-deminのSDR tranceiver)


 この通り実行すると、redpitayaというディレクトリのなかに、cloneで動作環境が構築されるようです。

 実際起動してみると、お?ちゃんとam_trxがGNURadioで起動できるぞ!と喜んだ(RedpitayaのSource/Sinkが見える)のですが、それも束の間でした。なんと、実行してみると、すぐに×マークが表示されてプログラムは終了してしまい、当然、Redpitayaは反応しません。モニターを見ているとsocket-errorと出ているので、Redpitayaへのデータ送受信のところで引っかかっているようです。

 DHCPで与えられたRedpitayaのローカルアドレス(Win-10のコマンドラインからarp -aで確認済み)へXubuntuのターミナルからpingを打つと、ちゃんと返事が返ってきます。あれー?繋がってるのになぁと思うも、実際にはRedpitayaが動きません。一方、XubuntuからはRedpitayaのローカルアドレスが確認できません。なので、ここで考え込んでしまいました。

 数日トライするも進展が無いので、困った時のネット検索です。RedpitayaとGNURadioで検索すると、なんとこちらのサイトで実働している情報があることが分かりました。そちらに問い合わせてみると、

「Redpitaya本体のサーバにブラウザでアクセスして、中のSDR Tranceiverを叩くと動作し始めますよ」と教えて戴きました。いままで、これに類する動作はしていたのですが、叩いていたのがSDR Tranceiver compatible with HPSDR だったのが間違いだったようです。この動作がRedpitayaのFPGAへ書き込むトリガーになると聞きましたが、どうも書き込むデータが異なっていたのでしょうか?




シグナルフローの様子TRX AM



 いずれにしても、この操作の後に、GNURadioを起動して、さらにRedpitayaのローカルIPアドレスを設定することで、無事に動作を開始できることが分かりました。アドバイス戴いたノイテック店主様には大変感謝しております。

 ということで、一応動くことが確認できたので、このPCから、HackRFOneとRedpitayaを同じシグナルフローグラフで動かして、その特性差を見てみることにしましょう。





シグナルフロー  SSB 2-トーンによるHACKとRedpitayaの比較



 上図は7MHz帯でSSB変調した2-トーン信号を発生させるシグナルフローです。Sinkには2つのSDRをパラレルで繋いであり、これで、双方のSDRから、上記信号が生成させるのだから、比較するにはこの上なく便利です。まずは、Hackから見ていきましょう。




HACK-RFONeによるSSBの2-トーン


 これを見ると、なんだかさえないスペクトラムですねぇ。送信8ビットの限界が見えると思います。200段のヒルベルト変換器では逆サイドバンド、漏えいキャリアがたっぷりあり、また、ノイズフロアも結構目立っています。同じシグナルフローで、Redpitayaの方は?というと




RedpitayaによるSSBの2-トーン


 これが、あっさり「漏えい成分」が消えています。HACKと比べると雲泥の差ということになりますね。同じ処理系を使っているので、この性能差は処理ビット数の差になるのでしょうか?だとすると8ビット(Hack)と14ビット(Redpitaya)の差はかくも大きいということになります。Redpitayaの波形を見ると、とってもHackは使う気にはなりませんね。受信に関しても大きな差があるのだろうと思います。

 そのうち、16ビットのRedpitayaもGNURadioで使える「はず」ですから、トライしてみたいですね。そうなると、GNURadioの信号処理が、送信と受信を対向させて実行できるようになるので、いといろな応用が効くようになるでしょう。もっとも、Redpitaya単体でも送受信が同時にできるので、送信信号をRedpitayaの外部でなにがしかの処理を行い、同じRedpitayaで受信すれば、等価なことが出来るようにも思います。いずれにしても、「いじりがい」のあるオモチャを手に入れることができました(笑)



<SSB受信機4題> 【2019.8.24】

 GNURadio をいじり始めて少し時間が経ちました。ただ、集中的にではなく、気が向いたときにいじっているので、なかなかまとまった話になっていません。一方、このシミレーションソフトは、シグナルフロー例を単に結線するだけでは、それで終わってしまい、まったく応用力がつきません。なので、遊びたい事例の枯渇とともに、飽きてしまう運命にあると考えられます。それを回避するためには、シグナルフローが「どういう動作をしているのか」理解することが必要となります。

 実は、SDRを理解するためのは、「複素信号処理」を理解しないといけないのですが、これが、アマチュア自作家にとっては大きなバリアーになっていると考えられます。いままでアナログの無線機を語るときは、受信機にしても送信機にしてもその構成要素を説明するには「実信号処理」で十分でした。例えば、複素信号処理の扱いが直感的に見える「イメージリジェクトミクサー」にしても、Sin Cosの乗算と加法定理で説明できてしまいます。なので、複素信号なんて、まったく考えもしなくても、なんとなく構成要素とその実動作が「直観的に」一致しますので、あまり深く考える必要も無かったわけです。

 ところが、SDRの内部処理へは、全てがI/Q処理で複素信号を扱うことになります。あらゆる変復調もI/Q信号に変換され、複素信号処理されますので、これを「体感」として理解しないと、GNURadioを弄ることは出来なくなってしまいます。私も、正直言うと、正確に理解しているというわけではないのですが、ネットを漁っていると複素信号処理に関しては、大学の講義録や、アナデバとかのA/Dコンバータの参考文献とかに、けっこう詳しいチュートリアルがありますので、そのあたりをじっくり読み込んでからの方が、GNURadioを弄るうえで、バリアーがなくて進みが早いと思います。

 ということで、少し、I/Q信号処理を意識しながら、GNURadioのシグナルフローを弄ってみます。

 まずは、Redpitayaから入出力される信号ですが、どんな形でGNURadioにインターフェースされるのか考えてみましょう。RedpitayaやHackRFOne等のハードウェアからは物理インターフェース(イーサやUSB)を介して、I/Q信号として取り込まれます。以下は私の理解なので、もしかしたら、正確ではないかもしれませんが、以下のような形で扱われているのではないかと推測しています。





Redpitaya Source




Redpitaya Sink


 この部分がRedpitaya のSource(受信)とSink(送信)になっていると考えることが出来ます。このSourceとSinkを使っていろいろな変調方式を作ることができ、Source のインプット(アナログ信号)とSinkのアウトプット(アナログ信号)を結べば、ループテスト(送受信)ができますし、それらの間に実伝送路を作る(アンテナをつないで送受信する)なんてこともできます。また、Source、Sinkを用いないで変復調回路の間を、GNURadioで伝送路(チャネル)シミュレーションすることも可能です。なので、ものすごく柔軟なSDRを実験できるのが、GNURadioとRedpitayaの組み合わせということになります。

 こういったハードを用いて、さらに複素信号処理の入門実験をするには、SSBは結構面白い材料になります。その面白さはこのあと述べるとして、まずは複数の方式でSSBを受信してみることにします。送信に関しては、まずは前回作ったPhase−Shiftタイプを使います。

(1)Phase Shiftタイプ
 最初に、一番簡単そうな、Phase−Shiftタイプの受信機を作ってみましょう。HJ44ではSSB受信機としてWeaverタイプが紹介されていて、その中では「Phase−Shiftタイプの受信機を作るのは、ちょっと面倒」という記述がありました。最初はどうしてかな?と疑問に思ったのですが、Phase−Shifterのブロックを見て、その意味が理解できました。用意されるPhase−Shifter(ヒルベルトフィルタ)は、インプットが実数で出力が複素数の固定になっているのです。このことは、送信側(変調器)には使い易いが、受信側では面倒な操作を強いられるということになります。

まずは、Phase-ShiftタイプのSSB受信機である、「イメージリジェクトミクサー」を作ると以下のようになります。



Image Reject Mixer


 ところで、アナログの世界ではポピュラーな「ダイレクトコンバージョン受信機」では2周波数受信(LSBもUSBもいっしょくたに受信)になるので、とてもSSB受信機とは呼べず、実用性にも乏しいので、これは鼻から検討対象外とします。一方、イメージリジェクトミクサーは1周波受信で、受信サイドバンドと反対のサイドバンドは抑圧する構成です。

 さて、RedpitayaのSourceを見ると、このイメージリジェクトミクサーの形式を持っていることが分かります。そうです、I/Q出力を有するのは、Redpitayaの内部でNCU(数値制御発振器)と2つのミクサー(乗算器)がゼロ周波数のI/Q信号(複素信号)を作り出してくれるのです。

 このあとは、ヒルベルト変換器(Phase−Shifter)を通して、I/Qの複素信号を合成して実信号に変換すれば、イメージリジェクトミクサーを用いたSSB受信機が出来上がるはずです。

 と簡単に考えたのですが、なんと先に述べたように、移相器を構成するヒルベルト変換器の入力が、びっくりすることに「実数に固定」のようなのです。これには参りました。複素入力ならば、一発でSSB受信機が構成できるのにーーーと悔やんでも仕方がありません。

 さて、どうするか?で、泥くさい方法を考えてみました。以下のシグナルフローをご笑覧(まさに笑っちまう)ください。





Phase-Shift方式SSB受信機


 なんと、せっかく複素信号で出力されているRedpitayaのSourceの出力を一回実信号に変換してしまいます。ちなみにシグナルフローの中で、ブロックの入出力の色が青は複素信号、橙色は実信号の処理です。ここを理解していないと始まりません。で、わざわざ実信号に戻したあとに、ヒルベルト変換器を通して、その複素信号出力を抽出して、実はもう一度実信号に直してそれらを合成して、SSBの復調信号を生成させています。なんともはや、泥臭さの極致です。これが、ヒルベルト変換器に複素入力が選択できれば、こんな馬鹿なことをしなくて済むのですが、仕方がありませんね。ただ、原理図通りの動作をソフト(GNURadio)とハード(Redpitaya)を用いて実現できたわけです。

 ここまで見てきて、気が付いたと思いますが、複素信号に指定されているシグナルフロー図の信号経路の場合、概念的には、I/Q信号の「2本」が通っていると考えると直感的に納得がいきます。ブロック図間が複素信号の場合の「→」はそのような意味を持ってると理解してしまいます。実際には二つの系統の信号を演算しているだけなのですが。

 さて、動作の様子を以下のスペクトラムで示しておきましょう。 





送信スペクトラム


 は、SSB送信機で実際に2-トーンを発生させた状態です。これは、以前の実際のスペアナで見たスペクトラムと一緒ですが、7.1MHzということで、一応、LSBにしています(以前の図は7MHzでUSBでした:笑)。方法は簡単で複素共役を計算するだけです。これを下記のように、RedpitayaのTX1とRx1をステップアッテネータで繋いで、信号のループ回路を作っています。





Redpitaya一台で送受信


 さて、この状態で、Sinkから吐き出される受信信号のスペクトラムは以下の図の通りです。ひずみのないきれいな信号ですね。



受信スペクトラム

ひずみも少なく良好な特性


 念のために、不要サイドバンドであるUSB(シングルトーン)を受信した場合のスペクトラムを以下に記します。まずは、7.099MHzの信号をSSGからぶち込んで、復調信号の時間波形と周波数スペクトラムを見てみます。時間波形のほうは、希望受信帯がLSBなので、I/Qのチャネルの信号が同相になって、まったく重なって見えます(CH1とCH2で2信号)。このあと加算すれば、振幅が2倍になります。




LSB信号の受信

I/Q信号は同相
SSGからの信号は狭帯域ではphase noiseが多いのがわかる


 受信周波数を7.101MHzにしてみます。そうなると、イメージリジェクト効果で、I/Qの時間領域信号はその移相が互いに180度異なるので、加え合わせるとゼロになるはずです。ただし、スペクトラムを見ると、LSB受信に比べて、−60dBくらいのようです。





USB信号の受信

I/Q信号は逆相なので加算そて消滅


 上図のようにように若干の不要サイドバンドの漏れが認められますが、まぁ、これは上記のような冗長な構成で実現したので、いろいろ不完全性が重なった結果でしょう。サイドバンドサプレッションは、キャリアから1kHz離れで−58dB、2kHz離れで−60dB、10kHz離れで−65dBとなりました。ちょっとこの値には不満が残りますね。もっともアナログ方式だと、一回チューンできても、温度、経年変化ですぐに劣化するとは思いますが。

 ということで、ヒルベルト変換器を「無理やり」使ったPhase-ShiftタイプのSSB受信機が出来上がりました。

(2)Weaver方式によるSSB受信機
 これは、HJ44でも紹介のあったSSB受信機を構成する「標準的方法」のようです。この方式は古くはSSBハンドブックにも掲載されています。アナログ方式では、その不完全性(ミクサーのキャリア&サイドバンドサプレッション)ゆえに、全く実用的では無かったのが、ディジタル化によって、その欠点を補うことができ、実用的な回路になった典型例ですね。まさに実信号をI/Q分離して、「直交性」を利用することによって、混濁した信号を分離・合成する見事な回路構成です。

 まずは実信号を用いた、アナログチックな回路構成を見てみましょう。まずはWeaver変調器です。





Weaver変調器


 まず、この図で「アナログ的に」sin/cosで記述しておきたいと思います。

@変調(復調)信号:cosωmt
AI相サブキャリア: cosωst   BQ相サブキャリア: sinωst

CI相BMサブキャリア出力
cosωst*cosωmt =(cos(ωs+ωm)t+cos(ωs-ωm)t)/2
DQ相BMサブキャリア出力
sinωst*sinωmt =(sin(ωs+ωm)t+ sin(ωs-ωm)t)/2

EI相LPF出力: (cos(ωs-ωm)t)/2
FQ相LPF出力: (sin(ωs-ωm)t)/2

GI相キャリア: cosωct      HQ相キャリア:  sinωct

II相BM出力:
(cosωct *cos(ωs-ωm)t)/2= (cos(ωc+ωs-ωm)t+ cos(ωc-ωs+ωm)t)/4

JQ相BM出力:
(sinωct * sin(ωs-ωm)t)/2=(cos(ωc-ωs+ωm)t- cos(ωc+ωs-ωm)t)/4

これらを加算すると

KRF出力:(cos(ωc-ωs+ωm)t)/2
が得られます。これはωmなる変調周波数を持つ信号がωc-ωs+ωmなる周波数に変換されることを示しています。

ここで
ωc-ωs+ωm=ωr(=受信周波数)
とすると
ωm=ωr-ωc+ωs
となります。

 周波数関係は後で参照できるようにメモしておきました。「アナログ的」にはきれいにSSBができていることがわかります。

 ここでは分かりやすいように変調器を考えましたが、この回路は双方向性があるので、変調器を逆から辿ると、復調器になります。ここでは、受信周波数からキャリアを引いてサブキャリア周波数を加えた周波数が復調周波数になります。ここで着目したいのは、90度位相回路を持ったI/Qミクサーの二組でLPFで挟んだ形になっているということです。これは、まさに複素信号処理を行っているに等しいのです。

 さて、Weaver方式がなんとなくわかったので、これをシグナルフロー図に落としていきます。なお、先の図はMODですが、右から逆に辿れば、DEMOになりますので、Weaver方式の受信の場合はそのように考えてください。





Weaver方式のシグナルフロー



 良く見ると、この場合、最初のミクサーはRedpitaya Sourceそのもの(Weaver変調器の図の赤点線内)です。実は受信機では、LPFを0〜サブキャリア周波数以上にするために周波数シフトを行います。これがRedpitayaのSinkの後についているFrequency-Xlating Fir Filterというブロックです。ここに周波数シフト量を入れると、受信周波数を、Frequency Xlating FIR FilterのブロックのCenter周波数だけ変化させることができるようです。ここでは、0〜ωs(Hz)でLPFを動作させたいので、-ωsなるシフト量(ここでは-1.2kHz)を設定します。





Weaver方式におけるサブキャリア周波数シフト



 これでWeaver方式のLPFまでたどり着きました。このあとは、サブキャリアのωsを乗じて、実信号に戻せば、それで復調が完了します。HJ44では、サブキャリア周波数を1.5kHz、周波数シフト量を98.5kHzとして、結果的に7.1MHzの受信機にしています。この周波数シフトの様子を上図に示します。但し、Redpitayaの受信周波数は7.0MHzになっていて、これがさきのFrequency-Xlating Fir Filterの周波数シフト動作になるようですね。今回はRedpitaya Sourceの受信周波数を7.1MHzにし、周波数シフト量を−1.2kHzにして同様の動作を行わせます。

 このWeaver方式というのは、I/Qのディジタル信号処理に似た動作を、いままではアナログで行っていたわけですが、アナログ回路が不完全であるために、キャリアサプレッションや、I/Q系列のゲイン変動が、通過帯域のビート(サブキャリア由来)や、不要サイドバンドサプレッションの発生になり、なかなかまともなSSBを生成(あるいは受信)できなかったのでしょう。多分、Weaverさんは机上で三角関数を弄り回していて、「お?SSBがLPFだけで生成できるじゃん!」と喜んだのでしょうねぇ。でも、それを実用的に実現できる技術が当時は無かったということなのでしょうか。USパテントを見ると、Weaverさんの書いたおぞましいアナログ回路が載っていましたが(笑)。

 さて、当然のごとく、これで1信号のSSB受信ができます。Phase Shift方式と比べると、「ヒルベルト変換器」の替りに「簡易なLPFとミクサー2個」が必要になります。ま、回路規模では複素入力のヒルベルト変換器があれば、両方式に大差はないのでしょう。



(3)複素BPF方式によるSSB受信機
 いままで、Weaver方式にしろ、Phase−Shift方式にしろ、IQ信号を用いて、原理図通りにSDRを構成してきましたが、NETを漁っていて、もっと簡単な方法があることを見つけてしまいました。その際たるものが複素BPFを用いて、DSBからどちらか一方のサイドバンドを取り出す方法です。良く考えると、この方式はアナログで言うところのフィルター方式そのものです。もちろんアナログSSB用のフィルタは、クリスタルフィルタなり、MFなりを中間周波数で用いるので、この例とは周波数的には全然異なる形にはなりますが。

 しかし、「なんだ、こんな方法があるなら、最初から紹介しろよ!」と言われそうですね。、まぁ、そう言わずに、原理と信号処理を体感できるように、(1)と(2)を弄ってみたと思って下さい。

 この方式のシグナルフローグラフを以下に示します。参考にしたのはここです。





複素BPF方式によるSSB受信機




LSBを選択


 Redpitayaから出力されるゼロ周波数のI/Q信号に対して、USB(例えば0.3〜3kHz)か、あるいはLSB(−3〜−0.3kHz)を選択できるBPFが有るのです。これは実信号処理だと、単なるダイレクトコンバージョンとなってしまいますので、2信号受信になり話になりませんが、複素信号処理だと不要な側のサイドバンドは受信することが有りません。マイナスの周波数のBPFでLSBを選ぶというのが、なんとなく「直感が拒否したがります」が、ここは複素信号領域ですので、マイナスの周波数での処理は、しょっちゅう起きますから、これは、「そういうもの」と考えてておいてください。

 この場合、フローグラフ内の複素BPFですが、ゼロ周波数に対して+の周波数領域をBPFとして設定すれば、USB受信、−の周波数領域をBPFとして設定すればLSB受信となります。実際にSSGで周波数を変化させて、Redpitayaに設定した、中心周波数の周りの+/-の周波数を変化させると、設定がUSBならば、LSBは受信せず、その逆もしかりです。なので、SSB受信機として動作していることが分かります。


(4)FFTフィルタ方式によるSSB受信機

 最後にFFTフィルタとやらを用いたSSB受信機を見てみます。これはPavel−deminさんの例にあったように思いますが、URLを失念してしまいました。まずはシグナルフローグラフです。




 
FFTフィルタを用いたSSB受信機


 ここの肝は「FFTフィルタ」というブロックです。

 FFTフィルタとは、入力信号にFFTをかけて周波数領域に変換したうえ帯域制限をかけてしまって、そのあとIFFT(逆FFT)で時間領域に戻すということのようです。FFTのサンプリング数は2^Nが一般的ですが、これを1処理単位として、周波数領域に変換して、そこで、ばっさりと成分を「ぶった切ることで」フィルターとして動作させているようです。「ぶった切る」という操作は、ある周波数における振幅を算術的に増減させるだけですから、とんでもなく急峻なフィルタを簡単に実現できるはずです。

 例えば、X(Hz)では振幅=1だったのがX+1(Hz)では振幅=0というような矩形に近いフィルタも、掛け算一発でできるはずです。多分、処理の大半はFFT演算に費やされるのじゃないかと思いますが、この形式のフィルタは、いままで、DSPでも弄ったことがないので、あまり直感が働きません。NET上にも詳細な動作の説明が見つからないので、確かなことは言えないのですが、GNURadioのブロックとして用意されているので、この方式のフィルタも、ディジタル信号処理の世界ではポピュラーなのでしょう。

 ということで、さきの複素BPF方式のシグナルフローグラフの中のフィルタをFFTフィルタに交換すれば、同じように動作が可能です。但し、設定パラメータが面倒で、ブロックのパラメータのうち、「Tap」の項目に、以下のごとくおまじないを入れます。

firdes.complex_band_pass(1, 1250000, -3000, -300, 100, firdes.WIN_HAMMING )

 このパラメータの(内)の説明が、GNURadioのTutorialを見ても良くわからなかったのですが、いろいろ弄ってみた結果(利得、サンプリング周波数、低域カットオフ周波数、高域カットオフ周波数、遷移周波数幅、窓関数種類)ではないかと思うようになりました。ここでも、USBの場合の通過帯域は300〜3000、LSBは−3000〜−300と周波数を決めてやれば、複素BPFと同じように動作をさせることが出来ます。

 ところで、今、気が付いたのですが、このおまじないパラメータの「firdes.complex_band_pass」ってなんなのだろう?FFTフィルタというからには、周波数領域に変換してフィルタリングしているはずなので、まさか複素BPF(complex_band_passの文字があるので)を動作させているとは思いたくなくて、フィルタの特性が、パラメータで決めたcomplex_band_passと同等の特性になっているということなのだろうか???よくわからないので、このあと調べることにします。

 さて、いろいろな方式でSSB受信をトライしてきました。教材としてはけっこう楽しめたのではないでしょうか?

 GNURadioを弄る場合、このように各機能ブロックがどのような動作をするのかを理解しながら進んでいくのがいいのではないかと思います。その際にサンプリングレート変換は大切です。この役目を果たすのが、Rational Resamplerというブロックで、インターポーレーション(サンプルレートアップ)とデシメーション(サンプルレートダウン)のいずれもができるブロックです。このブロックはサンプルレート変換が必要なあちこちで使われています。

 実は、昔にTIのDSPでディジタルシグナルプロセッシングをかじっていた時、サンプルレートと各種機能の実現性能は、CPUの処理速度にもよりますが、微妙な関係があることを経験しています。例えば、高いサンプルレートで、低い周波数のフィルタを作ると、場合によっては不安定になるとか・・・・動作しないとか・・・・このあたりは、理論上導かれるものではなく、ハードやソフト処理の制約に拠るものが大きいです。この「程度感」は、実際に弄ってみないと分からない部分もあり、「動かない」場合は、シグナルフローがまずいのか、あるいは、先に書いたような「動作条件」を逸脱しているのか、切り分けが必要になります。

 なので、一気にシグナルフローを仕上げるのではなく、機能ブロックごとに、スペクトラム機能やオシロ機能をつかって、「動作確認」しながら進めるのがいいのではないかと思います。そうすることで、機能ブロックの「くせ」も分かるので、これをマスターした感覚が得られます。もちろん、C++で書かれた機能ブロックのソースファイルを読み込んで、これが理解できれば、より深い理解が得られることは言うまでもありません(が、私はそこまで突っ込まない可能性が高いです:笑)。

 次は、これらの方式毎の「特性」について深堀りしてみたいと思います。単に、シミュレーションソフト上のFFT解析で満足せず、実際のスペアナで見たいと思います。また、HackRFoneと比較したり、ここで作ったTRXとも比較するのも面白そうです。