最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

カスタム ブロック ライブラリの作成

MATLAB Function Block ライブラリを使用する場合

Simulink® では、ブロックまたはサブシステムの機能を 1 つ以上のモデルで再利用する一つの方法として、ユーザー独自のブロック ライブラリを作成できます。Simulink モデルで一連の MATLAB® アルゴリズムを再利用するには、MATLAB Function ブロック ライブラリで独自の MATLAB コードをカプセル化します。

他の Simulink ブロック ライブラリ同様、モデル内の MATLAB Function ライブラリ ブロックの各インスタンスを特殊化して、さまざまなデータ型、サンプル時間、その他のプロパティを使用することができます。同じプロパティを継承するライブラリ インスタンスでは生成コードを再利用できます。

カスタム MATLAB Function ブロック ライブラリの作成方法

ここでは、MATLAB Function ブロックを使用したカスタム ブロックの作成の基本的なワークフローを示します。例を使用してこれらの手順を実行するには、例: Custom Signal Processing Filter ブロック ライブラリの作成を参照してください。

  1. ポリモーフィック MATLAB コードを Simulink モデル内の MATLAB Function ブロックに追加します。

    ポリモーフィック コードとは、型、サイズ、実数/複素数などの異なるプロパティのあるデータを処理できるコードのことです。

  2. 特殊化するプロパティを継承するようにブロックを構成します。

    特殊化できるプロパティの一覧については、ライブラリ ブロックのインスタンス間で特殊化できるプロパティを参照してください。

  3. オプションで、マスキングを使用してライブラリ コードをカスタマイズします。

  4. MATLAB Function ライブラリ ブロックのインスタンスを Simulink モデルに追加します。

メモ

MATLAB Function ブロック ライブラリがマスクされている場合、ブロックの内容をマスク初期化コードによって変更することはできません。MATLAB Function ブロック ライブラリでは [マスク] ダイアログ ボックスの [ライブラリ ブロックで内容を変更することを許可] オプションはサポートされません。

例: Custom Signal Processing Filter ブロック ライブラリの作成

学習内容

この単純な例では、カスタム MATLAB Function ブロック ライブラリの作成方法で説明したワークフローに沿って以下の方法を説明します。

  • MATLAB Function ブロックを使用して信号処理フィルター アルゴリズムのライブラリを作成する

  • マスク パラメーターを使用してライブラリ ブロックの 1 つをカスタマイズする

  • フィルター アルゴリズムの 1 つを MATLAB Function ライブラリ ブロックから呼び出せるソース保護された P コードに変換する

フィルター アルゴリズムについて

MATLAB フィルター アルゴリズムには以下のものがあります。

my_fft-  入力信号に対して離散フーリエ変換を実行します。入力は、長さが 2 のべき乗であるベクトル、行列、多次元配列のいずれかです。

my_conv-  2 つの入力ベクトル信号を畳み込みます。マスク パラメーター Shape で指定されたサイズの畳み込みのサブセクションを出力します。

my_sobel-  ソーベル エッジ検出フィルターで 2 次元入力行列を畳み込みます。

手順 1: フィルター アルゴリズムの MATLAB Function ライブラリ ブロックへの追加

  1. Simulink で、ライブラリ モデルを作成します。[シミュレーション] タブで、[新規][ライブラリ] を選択します。

  2. 3 つの MATLAB Function ブロックを Simulink ライブラリ ブラウザーの [User-Defined Functions] セクションからモデルにドラッグし、以下のように名前を付けます。

    • my_fft_filter

    • my_conv_filter

    • my_sobel_filter

  3. ライブラリ モデルを my_filter_lib として保存します。

  4. my_fft_filter という名前の MATLAB Function ブロックを開き、テンプレート コードを次のコードで置き換え、ブロックを保存します。

    function y = my_fft(x)
    
    y = fft(x);
    

  5. my_conv_filter ブロック内のテンプレート コードを次のコードで置き換え、ブロックを保存します。

    function c = my_conv(a, b)
    
    c = conv(a, b);

  6. my_sobel_filter ブロック内のテンプレート コードを次のコードで置き換え、ブロックを保存します。

    function y = my_sobel(u)
    
    %% "my_sobel_filter" is a MATLAB function
    %%  on the  MATLAB path.
    y = my_sobel_filter(u);

    関数 my_sobel は、コード生成パス上の MATLAB 関数 my_sobel_filter を呼び出すラッパーとして機能します。my_sobel_filter は、ソーベル エッジ検出フィルターを使用して 2 次元行列を畳み込むアルゴリズムを実行します。MATLAB Function ブロックにコードを直接インライン化する代わりに関数を呼び出すことにより、アルゴリズムを MATLAB コードとして、および Simulink モデル内で再利用できます。次に my_sobel_filter を作成します。

  7. 次のコードを使用して、my_filter_lib を作成したものと同じフォルダーに新しい MATLAB 関数 my_sobel_filter を作成します。

    function y = my_sobel_filter(u)
    
    % Sobel edge detection filter
    h = [1     2     1;...
         0     0     0;...
        -1    -2    -1];
    
    y = abs(conv2(u, h)); 
    

    ファイルを my_sobel_filter.m として保存します。

ステップ 2: 特殊化するプロパティを継承するブロックの構成

この例では、信号処理フィルター アルゴリズムのデータは、Simulink モデルからサイズ、型、実数/複素数を継承しなければなりません。既定では、MATLAB Function ブロック内のデータはこれらのプロパティを継承します。プロパティを継承するように、データを明示的に構成するには次の手順に従います。

  1. MATLAB Function ブロックを開き、[データの編集] を選択します。

  2. [端子とデータの管理] の左ペインで、目的のデータを選択します。

  3. 右ペインで、Simulink からプロパティを継承するようにデータを構成します。

    継承対象指定する項目
    サイズ[サイズ] フィールドに -1 と入力します。
    実数/複素数コンテキスト メニューから [継承] を選択します。
    データ型[継承: Simulink と同じ] を [データ型] メニューから選択します。

たとえば、[端子とデータの管理] で MATLAB Function ブロック my_fft_filter を開き入力 x のプロパティを見ると、既定の設定でサイズ、タイプ、実数/複素数が継承されるのがわかります。

メモ

設計に特別な要件または制約がある場合、Simulink から継承せずに、これらのプロパティの値を入力できます。たとえば、アルゴリズムが複雑な入力を処理できない場合は、[実数/複素数][オフ] に設定します。

ステップ 3: マスキングを使用したライブラリのカスタマイズ

この演習では、出力する畳み込みのサブセクションを指定するカスタム パラメーター shape を使用するように畳み込みフィルター my_conv を変更します。独自のライブラリ用にこのアルゴリズムをカスタマイズするには、my_conv_filter ブロックをマスク サブシステムの下に配置し、マスク パラメーターとして shape を定義します。

  1. ブロクックをマスク サブシステムに変換します。

    1. my_conv_filter ブロックを右クリックし、[サブシステムとモデル参照][選択からサブシステムを作成] を選択します。

      my_conv_filter ブロックが Subsystem ブロックに変わります。

    2. サブシステムの名前を my_conv_filter に変更します。

    3. my_conv_filter サブシステムを右クリックし、コンテキスト メニューから [マスク][マスクの作成] を選択します。

      [アイコンと端子] タブが開いた状態のマスク エディターが表示されます。

    4. [アイコンを描画するコマンド] テキスト ボックスに入力します。

      disp('my_conv');
      port_label('output', 1, 'c');
      port_label('input', 1, 'a');
      port_label('input', 2, 'b');

    5. [パラメーターとダイアログ] タブを選択します。

    6. [ダイアログ ボックス] ペインで [パラメーター] 行項目を強調表示します。

    7. [コントロール] ペインの [パラメーター] リストで [ポップアップ] をクリックしてポップアップ タイプのパラメーターを追加します。

      新しいパラメーターがダイアログ ボックス ペインに表示されます。

    8. [プロパティ エディター] ペインで、[プロパティ] を設定します。

      プロパティ
      名前shape
      full
      プロンプトshape
      データ型popup
      データ型オプションデータ型オプション エディターを開いて入力します。
      full
      same
      valid
    9. [プロパティ エディター] ペインで [属性][ダイアログ] および [レイアウト] のプロパティを設定します。

      属性、ダイアログおよびレイアウトの項目
      属性
      • [評価]: オン

      • [調整可能]:オフ

      • [読み取り専用]: オフ

      • [非表示]: オフ

      • [保存しない]: オフ

      ダイアログ
      • [有効]: オン

      • [表示]: オン

      • [コールバック]: エントリなし

      レイアウト
      • [項目の場所]: グレー表示

      • [プロンプトの場所]: 左

    10. [OK] をクリックします。

      サブシステムは次のようになります。

  2. コードの再利用のためにサブシステム プロパティを設定します。

    1. my_conv_filter サブシステムを右クリックし、コンテキスト メニューから [ブロック パラメーター (サブシステム)] を選択します。

    2. [サブシステム パラメーター] ダイアログ ボックスにおいて、[Atomic サブシステムとして扱う] チェック ボックスを選択します。

      ダイアログ ボックスが拡張され新しいフィールドが表示されます。

    3. 再利用可能な関数を生成するには、[コード生成] タブを選択して [関数のパッケージ化] フィールドのドロップダウン メニューで [再利用可能な関数] を選択します。

      メモ

      これはこの例で必要なオプションのステップです。既定の設定である [自動] のままにすると、コード生成ソフトウェアでは内部ルールを使用して関数をインライン化するかどうかを決定します。

    4. [OK] をクリックします。

  3. MATLAB 関数 my_convshape パラメーターを定義します。

    1. my_conv_filter サブシステムを右クリックし、コンテキスト メニューから [マスク][マスク内を表示] を選択します。

      マスク サブシステムの下に my_conv_filter ブロックを含むブロック線図が表示されます。

    2. 端子ブロックの名前を以下のようにデータ名と一致する名前に変更します。

      変更する名前目的
      In1a
      In2b
      Out1c
    3. my_conv_filter ブロックをダブルクリックして MATLAB Function ブロック エディターを開きます。

    4. MATLAB Function ブロック エディターで、[データの編集] を選択します。

    5. [端子とデータの管理] で [追加][データ] を選択します。

      新しいデータ要素がプロパティのダイアログと共に選択された状態で表示されます。

    6. 以下のプロパティを入力します。

      プロパティ指定するもの
      名前shape」と入力します。
      スコープ[パラメーター] を選択します。
      調整可能チェック ボックスをオフにします。

    7. [サイズ][実数/複素数]、および [タイプ]ステップ 2: 特殊化するプロパティを継承するブロックの構成で説明したように継承された値 (既定の設定) のままにします。

    8. [適用] をクリックして [端子とデータの管理] を閉じ、MATLAB Function ブロック エディターに戻ります。

  4. shape パラメーターを使用して、出力する畳み込みのサイズを決定します。

    1. MATLAB Function ブロック エディターで正しい形状の conv を呼び出すために関数 my_conv を変更します。

      function c = my_conv(a, b, shape)
      if shape == 1
          c = conv(a, b, 'full');
      elseif shape == 2
          c = conv(a, b, 'same');
      else
          c = conv(a, b, 'valid');
      end
    2. 変更内容を保存して、MATLAB Function ブロック エディターを閉じます。

ステップ 4: MATLAB ライブラリ ブロックのインスタンスの Simulink モデルへの追加

この演習では、my_conv_filter ライブラリ ブロックの特殊なインスタンスを単純なテスト モデルに追加します。

  1. 新しい Simulink モデルを開きます。

    この演習の目的上、シミュレーションのために次のコンフィギュレーション パラメーターを設定します。

    ペインセクション指定する項目
    ソルバーソルバーの選択
    • [タイプ][固定ステップ] を選択

    • [ソルバー][離散 (連続状態なし)] を選択

    • [固定ステップ サイズ]"1" を入力

    データのインポート/エクスポートファイル保存オプション[形式][構造体]

  2. my_conv_filter ブロックの 2 つのインスタンスを my_filter_lib ライブラリからモデルにドラッグします。

  3. ConstantOutport および Display ブロックを追加します。モデルは以下のようになります。

    両方のライブラリ インスタンスは、それぞれ入力 ab のサイズ、タイプ、実数/複素数を共有します。

  4. 各ライブラリ インスタンスをダブルクリックします。

    shape パラメーターの既定の設定はどちらのインスタンスでも [full] です。

  5. モデルのシミュレーションを実行します。

    各ライブラリ インスタンスは、同じ結果 (2 次元の完全な畳み込み) を出力します。

  6. shape パラメーターの値を [same] に設定し、2 番目のインスタンス my_conv_filter1 を特殊化します。

  7. ここでモデルを再度シミュレートします。

    今回は、出力のサイズが異なります。my_conv_filter3 は 2 次元の完全な畳み込みを出力しますが、my_conv_filter1 は畳み込みの中央部分を a と同じサイズである 1 行 2 列のベクトルとして表示します。

  8. ここで、my_conv_filter1 をコピーして 3 番目のインスタンスを追加します。新しいインスタンス my_conv_filter2 を特殊化して、最初の 2 つのインスタンスと同じサイズ入力を継承しないようにします。

  9. モデルを再度シミュレートします。

    今回は、my_conv_filter1my_conv_filter2 はそれぞれ畳み込みの中央部分を表示しますが、それぞれ異なるサイズの入力 a と一致するため、出力サイズは異なります。

ライブラリ ブロックでのコードの再利用

MATLAB Function ライブラリ ブロックのインスタンスが同じプロパティを継承する場合、ステップ 4: MATLAB ライブラリ ブロックのインスタンスの Simulink モデルへの追加に基づく例に示したとおり、生成されたコードを再利用できます。

このモデルでは、ライブラリ インスタンスの my_conv_filtermy_conv_filter1 は各入力について同じサイズ、タイプ、実数/複素数を継承します。各インスタンスでは、入力 a は 1 行 2 列のベクトル、入力 b は 1 行 5 列のベクトルです。比較すると、my_conv_filter2 の入力は、異なるサイズを継承します。どちらも 1 行 3 列のベクトルです。

さらに、各ライブラリ インスタンスには shape というマスク パラメーターがあり、出力する畳み込みのサブセクションはこのパラメーターによって決定されます。shape の値は各インスタンスで同じであると想定します。

この例のコードを生成するには、次の手順に従います。

  1. ライブラリ ブロックのコードの再利用を有効にします。

    1. ライブラリで MATLAB Function ブロック my_conv_filter を右クリックし、コンテキスト メニューから [ブロック パラメーター (サブシステム)] を選択します。

    2. [関数ブロック パラメーター] ダイアログ ボックスで次のパラメーターを設定します。

      • [Atomic サブシステムとして扱う] チェック ボックスをオンにします。

      • [関数のパッケージ化] フィールドのドロップダウン メニューで [再利用可能な関数] を選択します。

  2. コードを生成するためにモデルを設定します。

    この演習の目的上、次のコンフィギュレーション パラメーターを設定します。

    ペインセクション指定する項目
    コード生成ターゲットの選択System target file として ert.tlc を入力
    コード生成レポート [コード生成レポートを作成] チェック ボックスを選択
  3. モデルを作成します。

    このモデルを作成する場合、my_conv_filter ライブラリ インスタンスと my_conv_filter1 ライブラリ インスタンスは同じ入力プロパティを継承するため、生成された C コードではそれらのロジックが再利用されます。

    /*
     * Output and update for atomic system:
     *    '<Root>/my_conv_filter'
     *    '<Root>/my_conv_filter1'
     */
    void sp_algorithm_tes_my_conv_filter(const real32_T rtu_a[2], const real32_T
      rtu_b[5], rtB_my_conv_filter_sp_algorithm *localB)
    {
      int32_T jA;
      int32_T jA_0;
      real32_T s;
      int32_T jC;
    
      /* MATLAB Function Block: '<S1>/my_conv_filter' */
      /* MATLAB Function 'my_conv_filter/my_conv_filter': '<S4>:1' */
      /* '<S4>:1:4' */
      for (jC = 0; jC < 6; jC++) {
        if (5 < jC + 2) {
          jA = jC - 4;
        } else {
          jA = 0;
        }
    
        if (2 < jC + 1) {
          jA_0 = 2;
        } else {
          jA_0 = jC + 1;
        }
    
        s = 0.0F;
        while (jA + 1 <= jA_0) {
          s += rtu_b[jC - jA] * rtu_a[jA];
          jA++;
        }
    
        localB->c[jC] = s;
      }
    
      /* end of MATLAB Function Block: '<S1>/my_conv_filter' */
    }

    ただし、my_conv_filter2 に対して別個の関数が生成されます。

    /* Output and update for atomic system: '<Root>/my_conv_filter2' */
    void sp_algorithm_te_my_conv_filter2(const real_T rtu_a[3], const real_T rtu_b[3],
      rtB_my_conv_filter_sp_algorit_h *localB)
    {
      int32_T jA;
      int32_T jA_0;
      real_T s;
      int32_T jC;
    
      /* MATLAB Function Block: '<S3>/my_conv_filter' */
      /* MATLAB Function 'my_conv_filter/my_conv_filter': '<S6>:1' */
      /* '<S6>:1:4' */
      for (jC = 0; jC < 5; jC++) {
        if (3 < jC + 2) {
          jA = jC - 2;
        } else {
          jA = 0;
        }
    
        if (3 < jC + 1) {
          jA_0 = 3;
        } else {
          jA_0 = jC + 1;
        }
    
        s = 0.0;
        while (jA + 1 <= jA_0) {
          s += rtu_b[jC - jA] * rtu_a[jA];
          jA++;
        }
    
        localB->c[jC] = s;
      }
    
      /* end of MATLAB Function Block: '<S3>/my_conv_filter' */
    }
    

メモ

このモデルの C コードの生成には、Simulink Coder™ ライセンスまたは Embedded Coder® ライセンスが必要です。

MATLAB Function ライブラリ ブロックのデバッグ

任意の MATLAB Function ブロックをデバッグするのと同じように、MATLAB Function ライブラリ ブロックをデバッグします。ただし、ライブラリ ブロックでブレークポイントを追加すると、そのブレークポイントはすべてのインスタンスで共有されます。実行を続ける際、デバッガーは各インスタンスのブレークポイントで停止します。

ライブラリ ブロックのインスタンス間で特殊化できるプロパティ

Simulink から以下のプロパティを継承できるようにして、MATLAB Function ライブラリ ブロックのインスタンスを特殊化できます。

プロパティ既定で継承?継承の指定方法
タイプはいデータ型のプロパティを [継承: Simulink と同じ] に設定します。
サイズはいデータ サイズのプロパティを -1 に設定します。
実数/複素数はいデータの実数/複素数のプロパティを [継承] に設定します。
制限範囲いいえ最小値と最大値を Simulink パラメーターに指定します。
たとえば、最小値 = aParam で最大値 = aParam + 3 の場合、MATLAB Function ライブラリ ブロックの異なるインスタンスを使用して、親マスク サブシステムで定義されたさまざまな aParam パラメーターに解決できます。
サンプリング モード (入力)はいMATLAB Function ブロックの入力端子は常にサンプリング モードを継承します。
固定小数点データのデータ型オーバーライド モードはいデータ型オーバーライドのプロパティを [継承] に設定します。
サンプル時間 (ブロック)はいブロックのサンプル時間のプロパティを -1 に設定します。

関連するトピック