主要内容

このページの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。

为每个子系统を使用したアルゴリズムの繰り返し

ブロックとサブシステムをコピーして貼り付けることでブロック線図内でアルゴリズムを繰り返すと,モデルの保守が困難になる可能性があります。個別の信号線およびサブシステムによってブロック線図が過密になり,可読性が低下したり,単純な変更を行うことが困難になる可能性があります。変数がワークスペースに集まり,モデルの移植性が低下する可能性もあります。こうした効率性に関する問題は,設計に対する追加を行うにつれて徐々に蓄積されていきます。

アルゴリズムを繰り返す場合は,配列および構造体にグループ化された信号,サブシステムおよびパラメーターに対して,アルゴリズムを反復させることができます。この例は,非効率的に繰り返し実行する複雑なアルゴリズムを,管理が容易なコンパクトな形式に変換する方法を示します。

モデル例の確認

  1. モデル例ex_repeat_algorithmを開きます。モデルはベース ワークスペース内で約 30 個の変数を作成します。

  2. サブシステムBurner_1_Analysisを検査します。このサブシステムは、ベース ワークスペースの変数をブロック内 (常数および离散时间积分器など)でパラメーターとして使用することでアルゴリズムを実行します。

  3. サブシステムBurner_2_AnalysisおよびBurner_3_Analysisを検査します。3つのサブシステムはすべて同じアルゴリズムを実行しますが、ブロックをパラメーター化するために異なるワークスペース変数を使用します。

  4. 3つのAnalysis_Delayサブシステムを検査します。これらのサブシステムは,分析サブシステム内のアルゴリズムとは別のアルゴリズムを繰り返しています。

  5. モデルの最上位レベルに戻ります。内存ブロックは,Analysis_Delayサブシステムに入力される前に,入力信号を遅延させます。

  6. [コンフィギュレーションパラメーター]ダイアログボックスの[データのインポート/エクスポート]ペインを確認します。モデルは変数SensorsInputおよびtをシミュレーション入力として使用します。

    シミュレーション中は,行列変数SensorsInput内の9つの列それぞれがモデルの最上位レベルにある轮廓尺寸ブロックに入力データを提供します。

バスによる信号線密度の低減

バスを使用して関連する信号をグループ化し,構造化された単一の信号を作成すると,信号線密度を低減したり,モデルの可読性を向上させることができます。

モデル例の各サブシステムには3つの信号入力が必要です。グループごとに3つの信号を組み合わせて,単一のバスを作成することができます。

モデル例のすべてのサブシステムがバスを使用するように変更できます。ただし,一部のサブシステムは同じものであるため,それらのサブシステムを削除し,後で为每个子系统ブロックと置換することができます。

  1. バスエディターを開きます。

    buseditor

  2. 3つの信号要素sensor1sensor2およびsensor3をもつバス型SensorDataを作成します。

  3. 図に示すようにブロックを削除します。残りの2つのサブシステムへの入力として、Burner_1_Sensor1ブロックおよびBurner_1_Delay1ブロックのみを残します。

  4. Burner_1_Sensor1轮廓尺寸ブロックダイアログボックスの[信号属性]タブで,[データ型)を[总线:SensorData]に設定します。

    ブロックの出力は3つの信号要素sensor1sensor2およびsensor3を含むバスです。

  5. Burner_1_Analysisサブシステムを開きます。3つの轮廓尺寸ブロックの出力信号線を削除します。In2ブロックとIn3轮廓尺寸ブロックを削除します。

  6. 三机一体轮廓尺寸ブロックの右側に总线选择器ブロックを追加します。轮廓尺寸ブロックの出力を总线选择器ブロックに接続します。

  7. 总线选择器ブロックダイアログボックスで,信号sensor1sensor2およびsensor3を選択します。

    总线选择器ブロックは,入力バスから3つの信号要素を抽出します。モデル内の他のブロックは抽出された信号要素を使用できます。

  8. サブシステムでは,次のようにブロックを接続します。

  9. サブシステムBurner_1_Analysis_Delayでは,总线选择器ブロックを使用してバス内の信号を抽出します。サブシステムBurner_1_Analysisと同じ手法を使用します。

アルゴリズムの繰り返し

为每个子系统ブロックは入力信号を分割し,各パーティションに対して順番にアルゴリズムを実行します。たとえば,サブシステムへの入力が6つの信号の配列である場合,その6つの信号それぞれに対して同じアルゴリズムを実行するようにサブシステムを設定することができます。

为每个子系统を使用すると,アルゴリズムを反復形式で繰り返すことができます。このアプローチによって、モデルの可読性が向上し、繰り返し実行されるアルゴリズムを容易に変更することができます。

  1. 2つの为每个子系统ブロックをモデルに追加します。サブシステムの1つにBurner_Analysisという名前を付けます。もう一方のサブシステムにBurner_Analysis_Delayという名前を付けます。

  2. サブシステムBurner_1_AnalysisのコンテンツをサブシステムBurner_Analysisにコピーします。ブロックを貼り付ける前に、为每个子系统内の轮廓尺寸ブロックと外港ブロックを削除します。

  3. Burner_Analysisサブシステムの为每一个ブロックダイアログボックスで,チェックボックスをオンにして入力三机一体を分割します。

  4. サブシステムBurner_1_Analysis_DelayのコンテンツをサブシステムBurner_Analysis_Delayにコピーします。

  5. Burner_Analysis_Delayサブシステムの为每一个ブロックダイアログボックスで,チェックボックスをオンにして入力三机一体を分割します。

  6. モデルの最上位レベルで,サブシステムBurner_1_AnalysisBurner_1_Analysis_Delayを削除します。新しい为每个子系统ブロックを所定の場所に接続します。

  7. Burner_1_Sensor1の轮廓尺寸ブロックダイアログボックスの[信号属性]タブで,(端子の次元)3.に設定します。

    ブロックの出力はバスの3要素配列です。モデルの为每个子系统は,配列内の3つのバスそれぞれに対してアルゴリズムを繰り返し実行します。

  8. 轮廓尺寸ブロックがシミュレーションデータをインポートするために使用できる金宝appSimulink.SimulationData.Datasetオブジェクトを作成します。次のコードを使用すると,オブジェクトを作成し,そのオブジェクトを変数SensorsInputに保存することができます。

    首先,创建一个结构数组,其中的字段值为% timeseries对象i = 1:3%燃烧器数量%传感器1eval ([“tempInput(1)”num2str(我)”)。sensor1 = '...timeseries (SensorsInput (:,num2str(3 *(张)+ 1)”),t),“])%传感器2eval ([“tempInput(1)”num2str(我)”)。sensor2 = '...timeseries (SensorsInput (:,num2str(3 *(张)+ 2)”),t),“])%传感器3eval ([“tempInput(1)”num2str(我)”)。sensor3 = '...timeseries (SensorsInput (:,num2str(3 *(张)+ 3)”),t),“])结束%创建数据集对象。SensorsInput = 金宝appSimulink.SimulationData.Dataset;SensorsInput = addElement (SensorsInput tempInput,element1的);清晰的tempInputt

    コードはまず3つの構造体の配列を含む変数tempInputを作成します。各構造体には、バス型SensorDataの信号要素に対応する3つのフィールドがあり,各フィールドはMATLAB®timeseriesオブジェクトを格納します。各timeseriesオブジェクトは,各センサーのシミュレーション入力データを保存している変数SensorsInputの9つのデータ列のいずれかを保存します。

    その後,コードは新しい金宝appSimulink.SimulationData.DatasetオブジェクトでSensorsInputを上書きし,オブジェクトの要素としてtempInputを追加します。

  9. [入力]コンフィギュレーションパラメーターをSensorsInputに設定します。

    SensorsInputはシミュレーション入力データをtimeseriesオブジェクトの形式で提供するため,時間データを含む変数を指定する必要はありません。

  10. 残りの内存ブロックを初期化し,その配列を変数initForDelayに保存する構造体の配列を作成します。既存の初期化変数(initDelay_1_sensor1など)の値を使用して構造体フィールドを指定します。

    i = 1:3%燃烧器数量%传感器1eval ([“initForDelay(”num2str(我)”)。sensor1 = '...“initDelay_”num2str(我)“_sensor1;”])%传感器2eval ([“initForDelay(”num2str(我)”)。sensor2 = '...“initDelay_”num2str(我)“_sensor2;”])%传感器3eval ([“initForDelay(”num2str(我)”)。sensor3 = '...“initDelay_”num2str(我)“_sensor3;”])结束

    新しい変数initForDelayの内容を表示するには,ベースワークスペースで変数名をダブルクリックします。変数には3つの構造体の配列が含まれており,各構造体には3つのフィールド(sensor1sensor2およびsensor3)があります。

  11. 内存ブロックのダイアログボックスで,[初期条件]initForDelayに設定します。

    内存ブロックの出力は,初期化が必要なバス配列です。バス配列内にある各信号要素は,構造体の配列内にある対応するフィールドから初期値を取得します。

パラメーターを構造体の配列に再構成

ベースワークスペースにはモデル例がブロックパラメーター用に使用する多くの変数が含まれています。ワークスペース変数の数を削減するには,変数をパッケージ化して構造体の配列を作成し,個々の構造体フィールドを使用してブロックパラメーターを指定します。

为每个子系统ブロックは,マスクパラメーターとして指定する値の配列を分割できます。サブシステムの各反復では、配列の単一のパーティションを使用してブロック パラメーターを指定します。パラメーターを構造体の配列として指定する場合、サブシステムの各反復は配列内の構造体のうちの 1 つを使用することができます。

  1. Burner_Analysis为每个子系统をパラメーター化し,その配列を変数paramsNormalに保存する構造体の配列を作成します。gainNormal_1offsetNormal_1initDelayed_1といった既存のパラメーター変数の値を使用して,構造体フィールドを指定します。

    I = 1:3 eval([“paramsNormal(”num2str(我)”)。获得= gainNormal_ 'num2str(我)“;”eval ()) (“paramsNormal(”num2str(我)”)。抵消= offsetNormal_ 'num2str(我)“;”eval ()) (“paramsNormal(”num2str(我)”)。我nit = initNormal_'num2str(我)“;”])结束

    変数には3つの構造体の配列が含まれており,各構造体には3つのフィールド(获得抵消および初始化)があります。

  2. モデルで,Burner_Analysis为每个子系统を右クリックし,[マスク][マスクの作成)を選択します。

  3. ダイアログボックスの[パラメーターとダイアログ]ペインの[パラメーター]で,[エディット]をクリックします。新しいマスク パラメーターの[プロンプト]参数结构[名前]paramStructに設定します。(好的)をクリックします。

  4. Burner_Analysisサブシステムのマスクで,[パラメーター構造体)paramsNormalに設定します。

  5. サブシステムを開きます。为每一个ブロックダイアログボックスの[パラメーターの分割)ペインで,チェックボックスをオンにしてパラメーターparamStructを分割します。[分割次元]2に設定します。

  6. サブシステム内のブロックに対して,次のパラメーターを設定します。

    ブロック パラメーター名 パラメーター値
    获得 ゲイン paramStruct.gain
    离散时间积分器 初期条件 paramStruct.init
    常数 定数値 paramStruct.offset

  7. Burner_Analysis_Delay为每个子系统をパラメーター化し,その配列を変数paramsForDelayに保存する構造体の配列を作成します。

    I = 1:3 eval([“paramsForDelay(”num2str(我)”)。获得= gainDelayed_ 'num2str(我)“;”eval ()) (“paramsForDelay(”num2str(我)”)。抵消= offsetDelayed_ 'num2str(我)“;”eval ()) (“paramsForDelay(”num2str(我)”)。我nit = initDelayed_'num2str(我)“;”])结束

  8. モデルの最上位レベルで,Burner_Analysis_Delay为每个子系统を右クリックし,[マスク][マスクの作成)を選択します。

  9. ダイアログボックスの[パラメーターとダイアログ]ペインの[パラメーター]で,[エディット]をクリックします。新しいマスク パラメーターの[プロンプト]参数结构[名前]paramStructに設定します。(好的)をクリックします。

  10. 为每个子系统ブロックのマスクで,[パラメーター構造体)paramsForDelayに設定します。

  11. サブシステムを開きます。为每一个ブロックダイアログボックスの[パラメーターの分割)ペインで,チェックボックスをオンにしてパラメーターparamStructを分割します。[分割次元]2に設定します。

  12. サブシステム内のブロックに対して,次のパラメーターを設定します。

    ブロック パラメーター名 パラメーター値
    获得 ゲイン paramStruct.gain
    离散时间积分器 初期条件 paramStruct.init
    常数 定数値 paramStruct.offset

  13. 不要な変数をベースワークスペースからクリアします。

    %清除你替换的旧参数变量%带有结构数组清晰的正则表达式_%清除迭代变量清晰的

    このモデルはベースワークスペースの変数をあまり必要としません。

変換されたモデルの検証

新しい信号とサブシステムの構成を表示するには,ブロック線図を更新します。

モデルの入力は3つのバスの配列です。モデルは2つの为每个子系统を使用し,入力配列内の3つのバスそれぞれに対して2つのアルゴリズムを実行します。

ベースワークスペースでは,構造体の配列によって,モデルで使用した多くの変数が置換されます。数学的には,構造体の配列には従来のすべての変数の値が含まれているため,変更されたモデルの動作は開始時の動作と変わりません。

ヒント

为每个子系统の非バス信号をログに記録できます。ただし,对于每个子系统内からのバスまたはバス配列に対して信号ログを使用することはできません。总线选择器ブロックを使用してログを記録するバス要素信号を選択するか,サブシステムの外に外港ブロックを追加してその信号のログを記録します。詳細については,为每个子系统における信号のログ記録を参照してください。

为每个子系统の操作例

为每个子系统を使用してアルゴリズムをベクトル化

この例では,ベクトル化されたアルゴリズムのモデル化を簡略化する方法を示します。ここでは,为每个子系统ブロックを使用して,3つの同じ转移Fcnブロックで3つの入力信号をフィルターするモデルを簡略化します。また,サブシステムの反復ごとに係数を変えてフィルターをより細かく制御する方法も示します。

このモデルでは,同じ转移Fcnブロックを使用して入力正弦波信号の各要素を個別に処理します。向量连接ブロックは,結果として得られる出力信号を連結します。この反復処理はグラフ的に複雑であり、維持するのは困難です。信号に別の要素を追加するには、モデルを大幅に変更する必要も生じます。

反復処理を1つの为每个子系统ブロックに差し替えることで,このモデルを簡略化することができます。

この为每个子系统ブロックには1つの为每一个ブロックと1つのモデルが含まれています。このモデルは,差し替えた3つの转移Fcnブロックのアルゴリズムを表したものです。为每一个ブロックで,入力信号ベクトルを個別要素に分割する方法と,処理された信号を連結して出力信号ベクトルを形成する方法を指定しています。状態をもつ各ブロックは所定の実行ステップで処理される入力要素ごとに独立した状態セットを維持します。

この例では,分割対象として入力信号が選択されています。为每个ブロックの[分割次元]パラメーターと[分割幅]パラメーターはどちらも入力に対して1に設定されています。

对于每个块参数对话框,输入分区选项卡的截图

この方法を拡張すれば,モデルを大きく変更しなくても信号を追加していくことができます。この方法は拡張が簡単なうえ,グラフ的にもシンプルになります。

モデルの構造を変えずにパラメーターの変化をモデル化-この例では,アルゴリズムのパラメーターの変化をモデル化する方法を示します。ここでは,上記の例からの For Each Subsystem 分割モデルを使用して、モデルを複雑にすることなく入力信号ごとに異なるフィルターを作成します。フィルター係数の配列が、分割対象としてマークしたマスク パラメーターとして为每个子系统ブロックに送られます。为每个子系统ブロックの各反復で,フィルター係数の配列の分割が转移Fcnブロックに送られます。

  1. モデルex_ForEachSubsystem_Partitioningを開きます。为每个子系统ブロックのマスクを作成し,編集可能なマスクパラメーターを追加します。名前をFilterCoeffsに設定し,プロンプトを滤波器系数矩阵に設定します。マスクパラメーターの追加方法については,簡単なマスクの作成を参照してください。

  2. 为每个子系统ブロックを開きます。サブシステム内で为每一个ブロックのダイアログボックスを開きます。

  3. [パラメーターの分割)タブで,(FilterCoeffs)パラメーターの横にあるチェックボックスをオンにして,このパラメーターの分割を有効にします。[分割幅]パラメーターと[分割次元]パラメーターについては,既定値の1のままにします。

    “每个块参数”对话框的“参数分区”页签的截图

  4. 为每个子系统ブロックをダブルクリックし,各行が各入力信号のフィルター係数となる行列を入力します。たとえば。”[0.0284 0.2370 0.4692 0.2370 0.0284;-0.0651 0 0.8698 0 -0.0651;0.0284 -0.2370 0.4692 -0.2370 0.0284“と入力して入力信号ごとに異なる4次フィルターを実装します。

  5. 为每个子系统ブロックで转移Fcnブロックをダブルクリックし,[分母係数]パラメーターにFilterCoeffsと入力します。これにより,係数がマスクパラメーターから取得されるようになります。

为每个子系统ブロックにより,入力パラメーターが幅1の水平分割にスライスされます。これは1行の係数に対応します。係数のパラメーターは,次のような1つの配列で表されます。

これが次のような3行のパラメーターに変換されます。

为每个子系统を使用したコードの再利用の向上-この例では,同じ为每个子系统ブロックが複数ある場合にコードの再利用を高める方法を示します。次のモデルrtwdemo_foreachreuseを考えます。

3つのサブシステム向量,SS2向量,向量SS3で,同じ処理をベクトル信号の各スカラー要素にそれぞれの入力で適用することを目的としています。これら3つのサブシステムは同じ処理を実行するため,このモデルのために生成されたコード内の3つのサブシステムすべてに対して1つの共输出有関数(と更新関数)を生成することが望ましいでしょう。たとえば,矢量SS3サブシステムには次のブロックが含まれています。

3つのサブシステムに1つの共有関数を生成するには,入力信号に対して実行する分割の構成が同じでなければなりません。矢量魔法石,第1章とSS3では,このコンフィギュレーションは簡単です。分割の次元と幅を1に設定できるからです。ところが、Vector SS2 も入力信号を次元 1 で分割するためには、数学函数ブロックを挿入して1行8列の行ベクトルを8行1列の列ベクトルに転置しなければなりません。その後,[転置]演算子に設定された2番目の数学函数ブロックを使用して,サブシステムの出力を1行8列のベクトルに戻すことができます。

Ctrl + Bキーを押してコードを生成すると,結果のコードでは単一の出力関数が使用されます。この関数は3つすべての为每个子系统インスタンスで共有されます。

/* *迭代器系统的输出和更新:* '/Vector SS1' * '/Vector SS2' * '/Vector SS3' */ void VectorProcessing(int32_T numiter, const real_T rtu_In1[], real_T rty_Out1[], rtDW_VectorProcessing *localDW)

関数には入力パラメーターNumItersがあります。これは,各为每个子系统が処理することになる独立スカラーの数を示します。この関数は,パラメーターNumItersが10 8および7に設定されて,3回呼び出されます。

このモデルの残り2つのサブシステムは,为每个子系统ブロックを使用して処理される行列信号に対しても再利用可能なコードが生成される方法を示します。ここでも同様にCtrl + Bキーを押してコードを生成すると,単一の関数のコードを再利用できるようになります。

参考

オブジェクト

ブロック

関連するトピック