MATLABのAppDesignerでGUIアプリを作る (5)座標軸
こんにちは。
今回もAppDesignerの基本的な使い方を抑えるための備忘録です。
第4回の前回は「スライダー」の使い方を解説しました。
taekwongineer.hatenablog.jp
今まで年1回更新するかしないかだったのによくここまで続いているなと思います(;^_^A
さて、第5回の今回は
座標軸
です。
GUIアプリを使ってグラフとか描けるとだんだん面白くなってきますね♪
では早速行きましょう。
(今回の記事もほぼ過去の使いまわしですがご容赦ください(;^_^A)
●この記事の目次
1.GUI部品の配置
いつもと同様、まずはAppDesignerを起動し、空のWindow画面に座標軸のGUI部品をドラッグ&ドロップで配置します。
今回は動作確認用に前回解説したスライダーも使用します。(図1)
図1 座標軸部品の配置
2.とにかくまずはグラフを描いてみる
座標軸の細かい設定とかはとりあえず置いといて、まずは座標軸上にグラフを描いてみることにします。
スライダーのValueChangingFcnのコールバック関数を追加し、スライダーの値が振幅となるSIN関数を描くこととします。(図2)
図2 コールバック関数にSIN関数の波形描画のコードを追記
コールバック関数を記述したら早速動かしてみましょう!
youtu.be
スライダーの値に応じてSIN関数の振幅が変わるグラフの描画を確認できました。
3.座標軸の表示範囲を固定する
先ほどのグラフでは、SIN関数の振幅の大きさに応じてY軸の表示範囲が変わってしまいました。X軸もアプリ起動時は0~1の範囲の表示でしたが、グラフの表示後は0~10に変わっていました。
今度は座標軸の表示範囲を固定してみます。
座標軸の表示範囲を固定するには、座標軸のルーラーのプロパティにて、XLimMode、YLimModeの値をautoからmanualに変更します。
また、座標軸の表示範囲を変更するには、XLim、YLimに表示範囲を最小値、最大値をそれぞれ入力します。(図3)
図3 ルーラーのプロパティの修正
修正が完了したらまた動かしてみましょう。
youtu.be
SIN関数の振幅が変化しても、Y軸の表示範囲が変化せずに固定されるようになりましたね。
4.座標軸の目盛表示を変更する。
これまでの例では、X軸、Y軸の値の範囲は指定しましたが、目盛の間隔は自動設定となっていました。
今度は目盛の間隔や表示方法についても変更していきたいと思います。
今回はX軸の目盛の表示を
0, 2, 4, 6, 8, 10
から
に変更します。
X軸の目盛を修正するには、座標軸のXTickのプロパティを変更します。(図4)
0 : π/2 : 3π
と入力すると簡単です。
図4 XTickの値の変更
入力が完了すると、X軸の目盛の表示が図5のようになります。
図5 XTickの値変更後のX軸の表示
うん・・・
間違ってはいないですが、小数値で表示されるのはあまり美しくないですね・・・
今度はこれを文字式πを使った形式に書き換えていきたいと思います。
目盛の値の表示方法を指定するには図7のように、XTickLabelModeをmanualにし、XTickLabelに
と1つずつ値を手入力していきます。
(ここでは0 : π/2 : 3πのような簡易入力はできません・・・(;^_^A)
入力が完了すると、X軸の目盛の値の表示が小数からπを使った文字式の形式に変化します。
図7 XTickLabelとXTickLabelModeの変更
こちらもせっかくなので動かしてみましょう。
(目盛の位置でSIN関数の値が-1、0、+1となるようにスライダーのコールバック関数の式を少しいじりました。)
youtu.be
MATLABのAppDesignerでGUIアプリを作る (4)スライダー
こんにちは。
今回もAppDesignerの基本的な使い方を抑えるための備忘録です。
第3回の前回は「ラジオボタングループ」の使い方を解説しました。
taekwongineer.hatenablog.jp
第4回の今回は
スライダー
です。
では早速行きましょう。
(今回の記事もほぼ過去の使いまわしですがご容赦ください(;^_^A)
●この記事の目次
1.GUI部品の配置
いつもと同様、まずはAppDesignerを起動し、空のWindow画面にスライダーのGUI部品をドラッグ&ドロップで配置します。(図1)
図1 スライダー部品の配置
ちょっとサイズを大きくしておきます。(図2)
図2 サイズを拡大
更に動作確認のために、ラベルを2つ配置します。(図3)
図3 ラベル部品を2つ配置
2.コールバック関数の定義
次にスライダーのGUI部品用に用意されているコールバック関数の使い方を確認していきたいと思います。
スライダーのコールバック関数は図4のように
・ValueChangingFcn
・ValueChangedFcn
の2種類が定義されています。
「テキストエリア」の時と同様、
・ValueChangingFcn:スライダーの値の変更中に呼び出せる関数
・ValueChangedFcn:スライダーの値の変更後に呼び出される関数
となります。
図4 スライダーのコールバック関数
次にこれらのコールバック関数のデフォルトのコードを見てみましょう。(図5)
図5 スライダーのコールバック関数のコード
ValueChangingFcnについては、「SliderValueChanging」という関数が追加されており、
changingValue = event.Value;
という式がデフォルトで記述されています。このchangingValueには現在のスライダーの値が格納されます。
ValueChangedFcnについては、「SliderValueChanged」という関数が追加されており、
という式がデフォルトで記述されています。このvalueにも同様に現在のスライダーの値が格納されます。
では、このデフォルトのコールバック関数に動作確認用のコードを追記していきましょう。(図6)
図6 スライダーのコールバック関数の修正後コード
今回は、2つのラベルに呼び出されている関数と現在のスライダーの値を表示するようにしました。
5.まとめ
今回は「スライダー」の使い方を解説しました。
次回は「座標軸」の予定です。
パッと見た感じではなかなか使い方が難しそう…
MATLABのAppDesignerでGUIアプリを作る (3)ラジオボタングループ
こんにちは。
今回もAppDesignerの基本的な使い方を抑えるための備忘録です。
第2回の前回は「テキストエリア」の使い方を解説しました。
taekwongineer.hatenablog.jp
第3回の今回は
です。
では早速行きましょう。
●この記事の目次
1.GUI部品の配置
前回同様、まずはAppDesignerを起動し、空のWindow画面にラジオボタングループのGUI部品をドラッグ&ドロップで配置します。(図1)
今回は更に動作確認のために、前回解説したテキストエリアも配置します。(図2)
図2 テキストエリア部品の配置
2.コールバック関数の定義
次にラジオボタングループのGUI部品用に用意されているコールバック関数の使い方を確認していきたいと思います。
ラジオボタングループのコールバック関数は図3のように
・SelectionChangedFcn
・SizeChangedFcn
・ButtonDownFcn
の3種類が定義されています。
SelectionChangedFcnはその名のとおりラジオボタンの選択が変更されたときに呼び出されます。
SizeChangedFcnは何かのサイズが変更されると呼び出される関数のようですが、使い方がよくわかりませんでした・・・
ButtonDownFcnはラジオボタングループの枠をクリックすると呼び出される関数のようです。
次にこれらのコールバック関数のデフォルトのコードを見てみましょう。(図4)
SelectionChangedFcnについては、「ButtonGroupSelectionChanged」という関数が追加されており、
selectedButton = app.ButtonGroup.SelectedObject
という式がデフォルトで記述されています。このselectedButtonには、選択されたラジオボタンの表示名や座標情報が記録されるようです。(図5)
図5 sellectedButtonの中身
では、このデフォルトのコールバック関数に動作確認用のコードを追記していきましょう。(図6)
今回はラジオボタンを選択すると、テキストエリアに選択されたボタンの名称を表示するようにしました。
また、ラジオボタングループの枠内をクリックすると、ButtonGroupButtonDown関数が呼び出され、同じテキストエリアに「uttonGroupButton is selected.を表示するようにしました。
MATLABのAppDesignerでGUIアプリを作る (2)テキストエリア
こんにちは。
今回もAppDesignerの基本的な使い方を抑えるための備忘録です。
第1回の前回は「ボタン」の使い方を解説しました。
taekwongineer.hatenablog.jp
第2回の今回は
テキストエリア
です。
では早速行きましょう。
●この記事の目次
1.GUI部品の配置
前回同様、まずはAppDesignerを起動し、空のWindow画面にテキストエリアのGUI部品をドラッグ&ドロップで配置します。(図1)
図1 テキストエリア部品の配置
テキストエリア部品を置くと、空のテキストエリアとテキストエリアのタイトル等を示すためのラベル(TextArea)がセットで配置されます。
更に今回は動作確認のために前回解説した「ボタン」も使用します。(図2)
図2 ボタンも設置
そして、テキストエリアには初期値のテキストを入力しておきます。(図3)
図3 テキストエリアに初期値を入力
次にコードビューで「テキストエリア」のオブジェクト定義のコードを見てみましょう。(図4)
図4 オブジェクト定義のコード
テキストエリアのGUI部品を設置すると、オブジェクトとしてはTextAreaとTextAreaLabelの2つが定義されるようです。
2.コールバック関数の定義
次にテキストエリアのGUI部品用に用意されているコールバック関数の使い方を確認していきたいと思います。
テキストエリアのコールバック関数は図5のように
・ValueChangingFcn
・ValueChangedFcn
の2種類が定義されています。
その名の通り、ValueChangingFcnはテキストエリアの編集開始時に呼び出され、ValueChangedFcnはテキストエリアの編集完了後に呼び出される関数となります。
図5 テキストエリアのコールバック関数
次にこれらのコールバック関数のデフォルトのコードを見てみましょう。(図6)
図6 テキストエリアのコールバック関数のコード
それぞれの関数にデフォルトでchangingValue、valueという変数が定義されていますが、これらには関数呼び出し時のテキストエリアに書き込まれているテキストの内容が格納されます。
では、このデフォルトのコールバック関数に動作確認用のコードを追記していきましょう。(図7)
図7 テキストエリアのコールバック関数のコード
今回はテキストエリアの編集を開始すると、TextAreaValueChanging関数が呼びされ、テキストエリアのラベルに「Changing」を表示し、テキストエリアの編集完了後には、TextAreaValueChanged関数が呼び出され、テキストエリアのラベルに「Changed」を表示するようにしました。
また、Button1およびButton2のクリック時には、テキストエリアに「Good Morning!!」、「Hello World!!」をそれぞれ表示するようにしました。
3.動作確認
ここまで作成が完了したら早速動作確認してみましょう。
youtu.be
テキストエリアの編集時にラベルの表示が変化するのが確認できます。
またボタンのクリックによってもテキストエリアの内容が変わるのが確認できますね。
4.まとめ
今回は「テキストエリア」の使い方を解説しました。
今回もそんなに難しくはありませんでしたね(;^_^A
次回は何にしようかはまだ検討中です。
決まったらブログ更新します。(;^_^A
MATLABのAppDesignerでGUIアプリを作る (1)ボタン
こんにちは。
また1年以上ぶりの更新となってしまいました(;^_^A
今までGUIアプリの開発はVisual Studioを使うことが多かったのですが、最近はMATLABを使う機会が増えてきたので、MATLABのAppDesignerを使ったGUIアプリの作成方法を覚えていくことにしました。
ある程度まとまった機能を持つGUIアプリを作成する前に、まずはGUI部品1つ1つの基本的な使い方から抑えていこうと思います。
というわけで、初回の今回はタイトルにもある通り
ボタン
です。
●この記事の目次
1.App Designerの起動
初回なので、まずはApp Designerの起動方法を備忘録として書き留めておきます。
まず筆者の環境ですが、MATLAB 2023a Home版ですので、これを全体に説明します。
MATLABを起動後、「アプリ」タブをクリックすると、図1のような画面表示になるので、一番左にある「アプリの設計」ボタンをクリックします。
図1 App Designerの起動アイコン
ボタンをクリックすると、図2の画面が表示されます。
テンプレートがいくつか用意されているようですが、今回は「空のアプリ」を選択します。
図2 App Designerの起動画面
「空のアプリ」を選択すると、図3のようなGUIの編集画面が表示されます。
画面中央に空のキャンバスが表示され、左側のコンポーネントライブラリには、各種GUI部品が表示されます。
この画面構成はVisual Studioともよく似ていますね。
以降、主要(だと筆者が勝手に思っている)GUI部品の使い方を書いていきます。
一度にいくつも書くと大変なので、1つの記事で1~2個程度にしておこうと思います(;^_^A
2.ボタンの使い方
さて、ようやく本題です。
App Designerのボタン部品には「ボタン」と「状態ボタン」の2つがあるようです。
前者の「ボタン」はクリックするたびに同じイベントの動作が発生します。
後者の「状態ボタン」はその名のとおり「ON/OFF」の2通りの状態を持ち、クリックするたびに状態が入れ替わり、状態に応じた動作の切替を行うことができます。
(便宜上、状態名をここでは「ON」、「OFF」と定義しました。)
2.1 ボタン
まずは「ボタン」の使い方です。
図4の示すように、コンポーネントライブラリの中から「ボタン」をクリックし、GUIウィンドウの中心にドラッグ&ドロップします。
デフォルトのボタンのテキスト表示は「Button」です。
図4 ボタンの部品をウィンドウ上に配置
ボタンのアイコンをダブルクリックすると、図5のように「Button」にハッチがかかり、任意の表示に編集することができます。
図5 ボタンのテキスト表示を編集
今回はシンプルにカタカナで「ボタン」と変更しました。(図6)
図6 ボタンのテキスト表示を「ボタン」に変更
次に図7のように、ボタン部品をクリックした状態で、コンポーネントブラウザの「コールバック」をクリックし、更に関数名の隣の「▼」をクリックして表示される「ButtonPushedFcnコールバックの追加」をクリックします。
図7 コールバック関数を追加
コールバック関数の追加を実行すると、画面が「設計ビュー」から「コードビュー」に切り替わり、コード上にボタンクリック時に実行されるコールバック関数「ButtonPushed」が追加されます。(図8)
この段階ではまだコールバック関数の中身は空なので、ここに処理を追記していきます。
図8 コールバック関数のコード
今回はごくシンプルにボタンがクリックされると、MATLABのコマンドウィンドウ上に「Hello World!!」が表示されるように、
disp("Hello World!!");
を追記します。(図9)
ここまで作成したら一度ファイルを保存します。
AppDesignerの編集ファイルは「.mlapp」という拡張子で保存されるようです。
図10 ファイルを保存
保存が完了したらF5をクリックして、プログラムを実行してみましょう。
設計したボタンが1つだけ配置されたGUIアプリが起動し、ボタンをクリックすると、コマンドウィンドウ上に「Hello World!!」と表示されることが確認できます。(図11)
(図11の例ではボタンを3回クリックしています。)
図11 実行結果
ボタンの基本的な使い方はこんな感じです。
ちなみに今回配置したボタンは、コードビュー上では、図12のように定義されるようです。
ボタンに表示されるテキストは
app.Button.Text
で定義されるようなので、コード上でこの値を変更することで、プログラムの動作中にボタンの表示を切り替えることも可能です。
図12 「ボタン」オブジェクト定義のコード
2.2 状態ボタン
次は「状態ボタン」です。
2.1の「ボタン」とほとんど違いがないのと、2.1でだいぶ細かく説明したのでこちらは手抜きます(;^_^A
まずは2.1と同様、コンポーネントライブラリから「状態ボタン」を選択し、GUIウィンドウ上にドラッグ&ドロップします。(図13)
次にコールバック関数を追加します。
図13 「状態ボタン」部品の設置
コールバック関数を追加すると、コードビュー上に「ButtonValueChanged」という関数が追加されます。(図14)
2.1の「ボタン」と比べると、「状態ボタン」のコールバック関数は空ではなく、
というコードがデフォルトで記述されています。
このコードは変数valueにボタンの押下状態(1:ON/0:OFF)を格納するためのものようです。
図14 「状態ボタン」のコールバック関数
今回はシンプルな例として、valueの0/1の値に応じてif文で処理を分岐し、コマンドウィンドウに表示させるテキストを切り替えてみます。(図15)
コードを追記したらファイルを保存し、プログラムを実行してみます。
実行結果は図16です。ボタンをクリックするたびにコマンドウィンドウに表示されるテキストが切り替わっていることが確認できます。
図16 実行結果
3.まとめ
今回はAppDesignerの起動から「ボタン」、「状態ボタン」の使い方についてシンプルな例を交えて説明しました。
長々と書いた割にはとても簡単でしたね(;^_^A
次回は「テキストエリア」部品の使い方について書こうと思います。
次はまた1年後・・・とはならないように1週間後くらいには更新できるように頑張ります(;^_^A
ではでは・・・
MATLAB/SimulinkでQPSK変調のBER測定をシミュレーションしてみる
こんにちは。
前回、MATLABによるQPSK変調のBER測定のシミュレーションを行いました。
今回もMATLABですが、mファイルのスクリプトではなく、SimulinkによるモデルベースでのQPSK変調のBER測定のシミュレーションをやってみようと思います。
●この記事の目次
1.シミュレーションに用いるライブラリ
この記事で説明するSimulinkのシミュレーションでは、
Communications Toolbox
のライブラリを使用しています。
0,1のデータ生成、各種変復調、フィルタ処理、BER測定、スペクトラム解析などなど、通信システムの解析に必要な機能が盛りだくさんで大変便利なライブラリです。
オプション扱いなので、MATLABやSimulinkの本体に加えてHome版では4,490円かかりますが、Proffessional版と比べたら1/50くらいなので破格のお値段かと思います(;^_^A
(何だかMathWorksの回し者みたいだな・・・(;^_^A)
2.QPSK変調のBER測定のSimulinkモデルとシミュレーション実行のmファイルスクリプト
QPSK変調のBER測定のSimulinkモデルを図2-1に示します。
今回のシミュレーションでは、前回のmファイルのスクリプトによるシミュレーションの処理内容に合わせて、QPSK変調後のRaised Cosineフィルタによる帯域制限の処理は省略しているので、とてもシンプルな構成のモデルとなっています。
Raised Cosineフィルタも含めたシミュレーションについては、また別の機会に掲載したいと思います。
次に、図2-1のモデルによるBER測定のシミュレーションをSNRを変化させながら実施し、結果をグラフ表示するためのmファイルスクリプトを以下に示します。
close clc % 初期パラメータの定義 SNdBvec = 0:0.5:15; BER_sim = zeros(1, length(SNdB)); BER_theory = zeros(1, length(SNdB)); for index = 1:length(SNdBvec) % Simulinkモデルの実行 SNdB = SNdBvec(index); sim("QPSKsim"); % Simulinkモデルの実行結果の取り出し BER_sim(index) = BER(1); % BER理論値の計算 SN = 10^(SNdB/10); BER_theory(index) = erfc(sqrt(SN/2))/2; % 計算結果の表示 disp("SNdB=" + SNdB + " BER=" + BER_sim(index)); disp("SNdB=" + SNdB + " BER_theory=" + BER_theory(index)); end %%%%% グラフにプロット %%%%% semilogy(SNdBvec, BER_sim,"o", SNdBvec, BER_theory); % 片対数表示 legend("シミュレーション", "理論値"); % 凡例の表示 xlabel("SNR[dB]"); % 横軸ラベルの表示 ylabel("BER"); % 縦軸ラベルの表示 grid on;
QPSKの変復調処理やBERの計算等は、全てSimulinkのモデル内で実行されるため、mファイル側で実施するのは、はSNRを変化させるforループと、BERのシミュレーション結果のグラフへのプロットのみとなります。
シミュレーション結果のグラフを図2-2に示します。
図2-2 BER測定のシミュレーション結果
以後、Simulinkのモデルの内容の詳細について説明していきます。
3.Simulinkモデルの内容について
本章では、図2-1に示したSimulinkモデルの各ブロックの設定内容や簡単な使い方について触れていきます。
MathWorksのドキュメントを読んでも英語を日本語に直訳しただけで、なかなか意味が分かりづらいことが多いので、やっぱり自分で触ってみてあれこれ試行錯誤しながら使い方を覚えていく必要があるなと思います。
(1)0,1のランダムデータの生成
0,1のデータ生成には、Communications Toolboxに含まれる「Bernoulli Binary Generator」ブロックを使用します。
図3-1 Bernoulli Binary Generatorブロック
今回のシミュレーションで使用したBernoulli Binary Generatorブロックのブロックパラメーターの設定を図3-2に示します。
図3-2 Bernoulli Binary Generatorブロックパラメーター
この「Sample per frame」は、Bernoulli Binary Generatorブロックが、0,1のランダム数値列をベクトルとして一度に出力するサンプル数を示しています。
無線フレームを構成するようなシミュレーションでは、この値が数十~数百、大きければ数千といったオーダーの値になるかと思いますが、ここでは単純なBERの懸賞であるため、シミュレーション時間短縮のため、10^7と大きな値を設定しています。
(MATLABでは繰り返し処理をforループを使わずに、できるだけ行列演算の形式で記述する方が処理時間が早くなるのと同じです。)
Sample timeは、1サンプルあたりの時間(単位:秒)を示しており、デフォルト値は1秒に設定されています。
つまり「1bps」です。
これは近年の5GのようなGbps級の無線通信システムに比べると猛烈に遅い値ですが、今回のシミュレーションではスペクトラム解析を行うわけではないので、1秒のままで特に支障はありません。
(2)QPSKの変復調処理
QPSKの変調、変復調の処理には「QPSK Modulator Baseband」ブロック、「QPSK Demodulator Baseband」ブロックをそれぞれ使用します。
図3-3 QPSK Modulator Basebandブロック/QPSK Demodulator Basebandブロック
QPSK Modulator Basebandブロックのブロックパラメーター設定を図3-4に示します。
図3-4 QPSK Modulator Basebandブロックパラメーター
Input typeはデフォルトでは「Integer」に設定されていますが、これを「Bit」に変更します。
Integerの場合は、「0~3」の整数値を入力として使用する場合に設定しますが、今回のシミュレーションでは、Bernoulli Binary Generatorの出力をそのまま入力するため、「0,1」のビット列を入力する場合の「Bit」を設定します。
「View Constellation」をクリックすると、図3-5のように入力ビット列に対するシンボルマッピングを確認することができます。
00が入力された場合は、(+1+i)/√2
01が入力された場合は、(-1+i)/√2
10が入力された場合は、(+1-i)/√2
11が入力された場合は、(-1-i)/√2
がそれぞれ出力されます。
1ビット目が虚部、2ビット目が実部の符号を決定していることが分かりますね。
次に、QPSK Demodulator Basebandブロックのブロックパラメーター設定を図3-6に示します。
図3-6 QPSK Demodulator Basebandブロックパラメーター
こちらもQPSK Modulator Basebandブロックと同様で、Output typeがデフォルトでは「Integer」に設定されていますが、これを「bit」に変更します。
その他のパラメーターについてはデフォルト値のままにしておきます。
(Decision typeトカヨクワカリマセン・・・(T_T))
(3)AWGN雑音の生成
AWGN雑音の生成には「AWGN Channel」ブロックを使用します。
図3-7 AWGN Channelブロック
AWGN Channelブロックのブロックパラメーター設定を図3-8に示します。
図3-8 AWGN Channelブロックパラメーター設定
「Mode」はデフォルトでは、「Signal to noise ratio(Eb/No)」が設定されていますが、今回は「Signal to noise ratio(SNR)」を選択します。
そして、「SNR(dB)」はデフォルトでは「10」が設定されていますが、ワークスペースから読み込む変数として、「SNdB」を入力します。
「input signal power, referenced to 1ohm(watts)」はデフォルトの「1」のままにしておきます。
(QPSK Modulator Basebandの出力の平均電力が「1」なので、デフォルト値のままで問題ありません。)
(4)BER(Bit Error Rate)の算出
BERの測定には「Error Rate Calculation」ブロックを使用します。
図3-9 Error Rate Calculationブロック
TxのポートにはBernoulli Binary Generatiorブロックの出力を、RxのポートにはQPSK Demodulator Basebandブロックの出力をそれぞれ接続します。
Error Rate Calculationブロックのブロックパラメーター設定を図3-10に示します。
図3-10 Error Rate Calculationブロックパラメーター設定
「Output data」を「Workspace」に設定することで、BERの計算結果をワークスペースに出力することができます。
(デフォルトで選択済)
「Variable name」にはワークスペースにBERの計算結果を出力する際の変数名を入力します。
デフォルトでは、「ErrorVec」と入力されていますが、今回は「BER」と入力します。
(特に意味はありません、ただの好みです(;^_^A)
BERには、ビット誤り率、ビット誤り数、送信シンボル数の3つの値がベクトルとして格納されます。
そして、「Stop Simulation」にチェックを入れ、シミュレーションの停止条件となる「Target number of errors」(エラービットの上限数)及び「Maximum number of symbols」(送信シンボル数の上限)をそれぞれ入力します。
今回は、Target number of errorsに1000、Maxinum number of symbolsに10^7をそれぞれ入力します。
Bernoulli Binary Generatorから一度に出力される0,1のランダムビットの系列長が10^7なので、Bernoulli Binary GeneratorからQPSK Demodulator Basebandまでの処理が一巡すると、そこでシミュレーションが終了します。
シミュレーションの終了時間に「inf」を設定した状態で、Stop simulationにチェックを入れずにシミュレーションを実行すると、永久に終わらなくなってしまうので要注意です(;^_^A
また、「Receive delay」には今回はデフォルト値の0を設定しますが、QPSK Modulator Basebandブロックの出力の後に、レイズドコサインフィルタ等の帯域制限処理を加えると、フィルタ処理の遅延が発生してくるため、発生した遅延分をここに入力する必要があります。
フィルタ処理の遅延時間の確認方法については、また別の機会に開設したいと思います。
(5)ワークスペースからのSimulinkモデルの実行
sim("Simulinkモデル名")
で実行することができます。
今回は上記のサンプルコードの14行目にて
sim("QPSKsim");
と記述しています。
Simulinkモデルの拡張子「.slx」は書いても、書かなくても大丈夫です。
そしてSimulinkモデルがワークスペースに出力したシミュレーション結果であるBERから、
BER_sim(index) = BER(1);
と記述し、BERの値を取り出します。
BER(2)、BER(3)にはそれぞれビット誤り数、送信シンボル数が格納されていますが、今回のシミュレーションでは特に使用しません。
forループ毎にSNdBの値が更新され、各SNdBの値の条件のもとで「sim("QPSKsim");」が実行されます。
(6)まとめ
今回の記事では、SimulinkによるQPSK変調のBER測定シミュレーションについて説明しました。
今回のシミュレーションでは、mファイルによるforループのスクリプトでBER曲線を描いていますが、Communications Toolboxの一機能である「bertool」を使用することで、mファイルのスクリプトの記述一切なしでBER曲線を描くことも可能です。
ただ、bertoolを使用した場合のグラフは横軸はEb/Noに限定されてしまうため、今回はmファイルのスクリプトを用いたシミュレーションを行いました。
次回は、レイズドコサインフィルタによる帯域制限も含めたシミュレーションを実施したいと思います。
MATLABでQPSK変調のBER測定をシミュレーションしてみる
こんにちは。
最近MATLABを購入しました。
MATLABというと、昔は大変高価なもので、とても一個人で購入できるような代物ではなかったのですが、何年か前から個人利用向けの安価なバージョンであるMATLAB Homeが販売されているようです。
さて、以前pythonによるBPSK変調のBER計算のシミュレーションを行いましたが、今回はMATLABを使って、QPSK変調のBER計算のシミュレーションを実施してみたいと思います。
MATLABは高いから頑張ってpythonで信号処理のシミュレーション組めるようにしよう!と以前は意気込んでいましたが、やっぱMATLABの方が楽でいいです(;^_^A
●この記事の目次
1.この記事で説明しないこと
MATLABの使い方を説明することが主目的であるため、BPSK、BERといったディジタル無線通信関連の専門用語の内容についてはこの記事では説明しません。
2.QPSK変調のBER測定シミュレーションのサンプルコード
ではさっそくMATLABによるQPSK変調のBER測定シミュレーションのmファイルのサンプルコードを以下に示します。
clear; close; clc; % 初期パラメータ Ns = 10^7; % 送信ビット数 SNdB = 0:0.5:15; % SNRのベクトル BER = zeros(1, length(SNdB)); % BERのシミュレーション結果を格納するベクトル BER_theory = zeros(1, length(SNdB)); % BERの理論値を格納するベクトル % SNRを変化させながら、BERを計算 for index = 1:length(SNdB) %%%%% 送信ビット列の生成 %%%% TxData = randi([0, 1], 2, Ns/2); %%%%% QPSK変調 %%%%% % 00:1+i, 01:1-i, 11:-1-i, 10:-1+i % Ichの信号生成 Ich = TxData(1, :); Ich(find(Ich == 1)) = -1; Ich(find(Ich == 0)) = 1; Ich = Ich / sqrt(2); % Qchの信号生成 Qch = TxData(2, :); Qch(find(Qch == 1)) = -1; Qch(find(Qch == 0)) = 1; Qch = Qch / sqrt(2); % IQ信号の複素信号の生成 QPSKMod = Ich + Qch*i; %%%%% AWGN信号の生成 %%%%% % ノイズ電力の真値を計算 Pn = 10^(-SNdB(index)/10); % AWGN信号の生成 Noise = (randn(1, Ns/2) + randn(1, Ns/2)*i) * sqrt(Pn/2); %%%%% 受信信号の計算 %%%%% RxSig = QPSKMod + Noise; %%%%% 復調処理 %%%%% % オールゼロの行列を生成 DemodData = zeros(2, Ns/2); % 実部および虚部が負値になっている箇所を1に書き換え DemodData(1, find(real(RxSig) < 0)) = 1; DemodData(2, find(imag(RxSig) < 0)) = 1; % BERの計算 BER(index) = sum(sum(abs(TxData - DemodData))) / Ns; % BER理論値の計算 SN = 10^(SNdB(index)/10); BER_theory(index) = erfc(sqrt(SN/2))/2; % 計算結果の表示 disp("SNdB=" + SNdB(index) + " BER=" + BER(index)); disp("SNdB=" + SNdB(index) + " BER_theory=" + BER_theory(index)); end %%%%% グラフにプロット %%%%% semilogy(SNdB, BER,"o", SNdB, BER_theory); %片対数表示 legend("シミュレーション", "理論値"); %凡例の表示 xlabel("SNR[dB]"); %横軸ラベルの表示 ylabel("BER"); %縦軸ラベルの表示 grid on;
BERのグラフ表示は以下のようになります。
図1-1 SN[dB] 対 BERグラフ
3.ディジタル変復調のシミュレーションで覚えておきたい関数
(1)randi([A, B], X, Y)
0,1のランダムデータ列の生成には、randi()関数を使用します。
上記の引数により、AからBの範囲のランダムな整数を含むX行Y列の行列を生成します。
ここでは、randi([0, 1], 2, Ns/2)とすることで、2行5×10^6列の行列を生成しています。
(2)randn(X, Y)
AWGN信号の生成には、randn()関数を使用します。
上記の引き数により、X行Y列の標準正規分布の乱数データ列を生成します。
(3)find(条件式)
ベクトルまたは行列に対する条件式を入力すると、条件式に対して結果が真となる要素のインデックス番号を返します。
文章だけだとわかりづらいので、具体的な実行結果を↓に例示します。
(要素のインデックス番号は1行1列目(左上)から列方向(下)にカウントされている点に注意)