チャート内での MATLAB 関数のプログラミング
Stateflow® チャートにおける MATLAB® 関数は、アルゴリズム記述用のグラフィカル要素です。アルゴリズムは組み込みの MATLAB 関数を呼び出して簡単に実装できます。このタイプの関数は、グラフィカルな Stateflow 構造よりも MATLAB を使う方が簡単に記述できるアルゴリズムのコード作成に便利です。詳細については、MATLAB 関数の定義による MATLAB コードの再利用を参照してください。
MATLAB 関数内では次のタイプの関数を呼び出すことができます。
MATLAB 関数の本文内で定義されているローカル関数。
チャート内のグラフィカル関数、Simulink® 関数、真理値表関数、およびその他の MATLAB 関数。
コード生成をサポートする MATLAB 組み込み関数。これらの関数は、組み込み環境のメモリとデータ型の要件に準拠したターゲットのビルドに対応する C コードを生成します。
コード生成をサポートしない MATLAB 外部関数。これらの関数はモデルのシミュレーション時に MATLAB ワークスペース内でのみ実行されます。詳細については、Stateflow チャートでの外部 MATLAB 関数の呼び出しを参照してください。
プロパティ証明およびテスト生成のための Simulink Design Verifier™ 関数。このような関数には、以下があります。
sldv.prove
(Simulink Design Verifier)sldv.assume
(Simulink Design Verifier)sldv.test
(Simulink Design Verifier)sldv.condition
(Simulink Design Verifier)
この例では、2 つの MATLAB 関数 (meanstats
と stdevstats
) を呼び出す Stateflow チャートを含むモデルの作成方法を説明します。
meanstats
は、vals
内の値の平均値を計算します。stdevstats
は、vals
内の値の標準偏差を計算します。
モデルの作成
以下の手順に従います。
以下のブロックを含む新しいモデルを作成します。
モデルを
call_stats_function_stateflow
という名前で保存します。モデルで、Chart ブロックをダブルクリックします。
オブジェクト パレットで、MATLAB 関数のアイコン
を使用して、空のチャートに 2 つの関数を追加します。
以下のように、各関数のラベルを設定します。
MATLAB 関数のラベルにはそのシグネチャを含めなければなりません。次の構文を使用します。
[return_val1,return_val2,...] = function_name(arg1,arg2,...)
上記の構文に示すように、複数の戻り値と複数の入力引数を指定できます。戻り値と入力引数として、値のスカラー、ベクトル、または行列を指定できます。
ヒント
戻り値が 1 つのみの MATLAB 関数では、シグネチャ ラベルの大かっこは省略できます。
チャートで、以下の条件アクションを含む終端ジャンクションにデフォルト遷移を描画します。
{ mean = meanstats(invals); stdev = stdevstats(invals); }
チャートは以下のようになります。
ヒント
関数シグネチャの仮引数がスカラーの場合は、関数呼び出しの入力と出力がスカラー拡張のルールに従っていることを確認してください。詳細については、行列のすべての要素への値の代入を参照してください。
[モデル化] タブの [データの設計] で、[モデル エクスプローラー] を選択します。
モデル エクスプローラーの [モデルの階層構造] ペインで、関数
meanstats
を選択します。[コンテンツ] ペインには、入力引数
vals
と出力引数meanout
が表示されます。既定の設定では、両方とも、double
型のスカラーです。サイズ列の下の
vals
行をダブルクリックし、vals
のサイズを4
に設定します。モデル エクスプローラーの [モデルの階層構造] ペインで、関数
stdevstats
を選択し、前のステップを繰り返します。モデル エクスプローラーの [モデルの階層構造] ペインで
Chart
を選択し、以下のデータを追加します。名前
スコープ
サイズ
invals
入力
4
mean
出力
スカラー (変更なし)
stdev
出力
スカラー (変更なし)
これで以下のデータがモデル エクスプローラーに表示されます。
データ
invals
、mean
、およびstdev
をチャートに追加すると、対応する入力端子と出力端子がモデルの Stateflow ブロックに表示されます。Constant ブロックと Display ブロックを Chart ブロックの端子に接続して、モデルを保存します。
MATLAB 関数のプログラミング
関数 meanstats
および stdevstats
をプログラミングするには、次の手順に従います。
モデル
call_stats_function_stateflow
内のチャートを開きます。チャートで、
meanstats
を開きます。関数エディターは、ヘッダーが表示された状態で開きます。
function meanout = meanstats(vals)
この関数のヘッダーは、チャートの関数ラベルから取得されます。エディターで直接ヘッダーを編集すると、エディターを閉じた後にチャートに変更が適用されます。
関数のヘッダーに続く行に以下のコメントを入力します。
%#codegen
%#codegen
コンパイル命令を使用すると、コード生成でサポートされる MATLAB 関数の構文およびセマンティクスのコンパイル時違反を検出できます。行間と以下のコメントを入力します。
% Calculates the statistical mean for vals
以下の行を追加します。
len = length(vals);
関数
length
は、コード生成でサポートされている組み込み MATLAB 関数の例です。この関数を直接呼び出して、引数vals
のベクトルの長さを返すことが可能です。シミュレーション ターゲットをビルドすると、関数 length は生成された C コードで実装されます。コード生成でサポートされている関数の詳細については、C/C++ コードの生成でサポートされている関数およびオブジェクト (MATLAB Coder)を参照してください。変数
len
は、暗黙的に宣言されたローカル データの例です。代入された値と同じサイズと型が設定されます。具体的には、関数length
によって返されたdouble
型のスカラーに該当します。変数の宣言の詳細は、数値型 (MATLAB Coder)を参照してください。MATLAB 関数は暗黙的に宣言されるローカル データを一時的なデータとして扱います。このデータは関数が呼び出される時だけ存在し、関数が終了すると消えます。チャートの MATLAB 関数のローカル データを永続データとして宣言するには、
persistent
構造を使用します。以下の行を入力して、
meanout
の値を計算します。meanout = avg(vals,len);
関数
meanstats
は、vals
の平均値を Stateflow データmeanout
に格納します。これらのデータは親の Stateflow チャートに対して定義されているため、MATLAB 関数で直接使用できます。1 行または 1 列の要素で構成される 2 次元配列は、MATLAB 関数ではベクトルまたは行列として扱われます。たとえば、
meanstats
では、引数vals
は 4 つの要素ベクトルです。このベクトルの 4 番目の要素にアクセスするには、行列表記法vals(4,1)
またはベクトル表記法vals(4)
を使用します。MATLAB 関数は、関数
avg
とsum
を使用して、mean
の値を計算します。sum
はコード生成でサポートされる関数です。avg
は後で定義するローカル関数です。関数名を解決する際には、チャート内の MATLAB 関数は最初にローカル関数、次にコード生成でサポートされる関数を検索します。メモ
コード生成で MATLAB 関数がローカル関数または関数として解決できない関数を呼び出す場合は、その関数を外部関数として宣言しなければなりません。
次に、以下のステートメントを入力します。
coder.extrinsic("plot");
以下の行を入力して、ベクトル インデックスに対する
vals
の入力値のプロットを作成します。plot(vals,"-+");
plot
はコード生成ではサポートされていないため、非組み込み関数にするよう宣言したことに注意してください。MATLAB 関数が非組み込み関数を検出すると、シミュレーション時に MATLAB ワークスペースに対して実行呼び出しを送信します。次に、以下のようにローカル関数
avg
を定義します。function mean = avg(array,size) mean = sum(array)/size;
avg
のヘッダーでは、2 つの引数array
とsize
、および単一の戻り値mean
を定義しています。ローカル関数avg
は、array
内の要素の合計を引数size
の値で除算して、平均を計算します。関数
meanstats
のコードの完成形は、以下のようになります。function meanout = meanstats(vals) %#codegen % Calculates the statistical mean for vals len = length(vals); meanout = avg(vals,len); coder.extrinsic("plot"); plot(vals,"-+"); function mean = avg(array,size) mean = sum(array)/size;
モデルを保存します。
チャートに戻り、関数
stdevstats
を開いて、vals
の値の標準偏差を計算するコードを追加します。このコードの完成形は、以下のようになります。function stdevout = stdevstats(vals) %#codegen % Calculates the standard deviation for vals len = length(vals); stdevout = sqrt(sum(((vals-avg(vals,len)).^2))/len); function mean = avg(array,size) mean = sum(array)/size;
モデルを再び保存します。