Main Content

チャート内での MATLAB 関数のプログラミング

Stateflow® チャートにおける MATLAB® 関数は、アルゴリズム記述用のグラフィカル要素です。アルゴリズムは組み込みの MATLAB 関数を呼び出して簡単に実装できます。このタイプの関数は、グラフィカルな Stateflow 構造よりも MATLAB を使う方が簡単に記述できるアルゴリズムのコード作成に便利です。詳細については、MATLAB 関数の定義による MATLAB コードの再利用を参照してください。

MATLAB 関数内では次のタイプの関数を呼び出すことができます。

  • MATLAB 関数の本文内で定義されているローカル関数。

  • チャート内のグラフィカル関数、Simulink® 関数、真理値表関数、およびその他の MATLAB 関数。

  • コード生成をサポートする MATLAB 組み込み関数。これらの関数は、組み込み環境のメモリとデータ型の要件に準拠したターゲットのビルドに対応する C コードを生成します。

  • コード生成をサポートしない MATLAB 外部関数。これらの関数はモデルのシミュレーション時に MATLAB ワークスペース内でのみ実行されます。詳細については、Stateflow チャートでの外部 MATLAB 関数の呼び出しを参照してください。

  • プロパティ証明およびテスト生成のための Simulink Design Verifier™ 関数。このような関数には、以下があります。

この例では、2 つの MATLAB 関数 (meanstatsstdevstats) を呼び出す Stateflow チャートを含むモデルの作成方法を説明します。

  • meanstats は、vals 内の値の平均値を計算します。

  • stdevstats は、vals 内の値の標準偏差を計算します。

モデルの作成

以下の手順に従います。

  1. 以下のブロックを含む新しいモデルを作成します。

    Simulink model that contains a Stateflow chart, a constant block, and two display blocks.

  2. モデルを call_stats_function_stateflow という名前で保存します。

  3. モデルで、Chart ブロックをダブルクリックします。

  4. オブジェクト パレットで、MATLAB 関数のアイコン を使用して、空のチャートに 2 つの関数を追加します。

  5. 以下のように、各関数のラベルを設定します。

    Stateflow chart with two MATLAB functions called meanstats and stdevstats.

    MATLAB 関数のラベルにはそのシグネチャを含めなければなりません。次の構文を使用します。

    [return_val1,return_val2,...] = function_name(arg1,arg2,...)

    上記の構文に示すように、複数の戻り値と複数の入力引数を指定できます。戻り値と入力引数として、値のスカラー、ベクトル、または行列を指定できます。

    ヒント

    戻り値が 1 つのみの MATLAB 関数では、シグネチャ ラベルの大かっこは省略できます。

  6. チャートで、以下の条件アクションを含む終端ジャンクションにデフォルト遷移を描画します。

    {
    mean = meanstats(invals);
    stdev = stdevstats(invals);
    }

    チャートは以下のようになります。

    Stateflow chart with a transition that calls the two MATLAB functions.

    ヒント

    関数シグネチャの仮引数がスカラーの場合は、関数呼び出しの入力と出力がスカラー拡張のルールに従っていることを確認してください。詳細については、行列のすべての要素への値の代入を参照してください。

  7. [モデル化] タブの [データの設計] で、[モデル エクスプローラー] を選択します。

  8. モデル エクスプローラーの [モデルの階層構造] ペインで、関数 meanstats を選択します。

    Model Explorer showing the input an output variables for MATLAB function meanstats.

    [コンテンツ] ペインには、入力引数 vals と出力引数 meanout が表示されます。既定の設定では、両方とも、double 型のスカラーです。

  9. サイズ列の下の vals 行をダブルクリックし、vals のサイズを 4 に設定します。

  10. モデル エクスプローラーの [モデルの階層構造] ペインで、関数 stdevstats を選択し、前のステップを繰り返します。

  11. モデル エクスプローラーの [モデルの階層構造] ペインで Chart を選択し、以下のデータを追加します。

    名前

    スコープ

    サイズ

    invals

    入力

    4

    mean

    出力

    スカラー (変更なし)

    stdev

    出力

    スカラー (変更なし)

    これで以下のデータがモデル エクスプローラーに表示されます。

    Model Explorer showing data for chart.

    データ invalsmean、および stdev をチャートに追加すると、対応する入力端子と出力端子がモデルの Stateflow ブロックに表示されます。

    Simulink model that contains a Stateflow chart with one input and two output ports.

  12. Constant ブロックと Display ブロックを Chart ブロックの端子に接続して、モデルを保存します。

    Completed Simulink model.

MATLAB 関数のプログラミング

関数 meanstats および stdevstats をプログラミングするには、次の手順に従います。

  1. モデル call_stats_function_stateflow 内のチャートを開きます。

  2. チャートで、meanstats を開きます。

    関数エディターは、ヘッダーが表示された状態で開きます。

    function meanout = meanstats(vals)

    この関数のヘッダーは、チャートの関数ラベルから取得されます。エディターで直接ヘッダーを編集すると、エディターを閉じた後にチャートに変更が適用されます。

  3. 関数のヘッダーに続く行に以下のコメントを入力します。

    %#codegen

    %#codegen コンパイル命令を使用すると、コード生成でサポートされる MATLAB 関数の構文およびセマンティクスのコンパイル時違反を検出できます。

  4. 行間と以下のコメントを入力します。

    % Calculates the statistical mean for vals
  5. 以下の行を追加します。

    len = length(vals);

    関数 length は、コード生成でサポートされている組み込み MATLAB 関数の例です。この関数を直接呼び出して、引数 vals のベクトルの長さを返すことが可能です。シミュレーション ターゲットをビルドすると、関数 length は生成された C コードで実装されます。コード生成でサポートされている関数の詳細については、C/C++ コードの生成でサポートされている関数およびオブジェクト (MATLAB Coder)を参照してください。

    変数 len は、暗黙的に宣言されたローカル データの例です。代入された値と同じサイズと型が設定されます。具体的には、関数 length によって返された double 型のスカラーに該当します。変数の宣言の詳細は、数値型 (MATLAB Coder)を参照してください。

    MATLAB 関数は暗黙的に宣言されるローカル データを一時的なデータとして扱います。このデータは関数が呼び出される時だけ存在し、関数が終了すると消えます。チャートの MATLAB 関数のローカル データを永続データとして宣言するには、persistent 構造を使用します。

  6. 以下の行を入力して、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 関数は、関数 avgsum を使用して、mean の値を計算します。sum はコード生成でサポートされる関数です。avg は後で定義するローカル関数です。関数名を解決する際には、チャート内の MATLAB 関数は最初にローカル関数、次にコード生成でサポートされる関数を検索します。

    メモ

    コード生成で MATLAB 関数がローカル関数または関数として解決できない関数を呼び出す場合は、その関数を外部関数として宣言しなければなりません。

  7. 次に、以下のステートメントを入力します。

    coder.extrinsic("plot");
  8. 以下の行を入力して、ベクトル インデックスに対する vals の入力値のプロットを作成します。

    plot(vals,"-+");

    plot はコード生成ではサポートされていないため、非組み込み関数にするよう宣言したことに注意してください。MATLAB 関数が非組み込み関数を検出すると、シミュレーション時に MATLAB ワークスペースに対して実行呼び出しを送信します。

  9. 次に、以下のようにローカル関数 avg を定義します。

    function mean = avg(array,size)
    mean = sum(array)/size;

    avg のヘッダーでは、2 つの引数 arraysize、および単一の戻り値 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;
  10. モデルを保存します。

  11. チャートに戻り、関数 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;
  12. モデルを再び保存します。