1. 株式会社PALTEK
  2. TECHブログ
  3. 技術情報
  4. MATLAB®スクリプトでSimulink®モデルを修正してみた【第3回】実際にモデルを修正してみた

TECHブログ

MATLAB®スクリプトでSimulink®モデルを修正してみた【第3回】実際にモデルを修正してみた

MATLAB®スクリプトでSimulink®モデルを修正してみた【第3回】実際にモデルを修正してみた

このブログでは、自動車業界で普及している、モデルベース設計ツールのMathWorks社のSimulink®で作成したモデルを、MATLAB®スクリプトで修正することを試みます。

今回は全3回のうちの第3回目で「実際にモデルを修正してみた」と題して、Simulink® APIを使用してSimulink®モデルの修正を行い、シミュレーションを実行する、一連の流れを説明します。

なお、全3回の内容は以下の通りです。

第1回:Simulink® APIの基本1(基礎の基礎)
第2回:Simulink® APIの基本2(モデル編集のAPI)
第3回:実際にモデルを修正してみた

実行した環境は以下の通りです。

OS Microsoft Windows 10 Pro
MathWorks社製 MATLAB® バージョン 9.9 (R2020b)
Simulink® バージョン 10.2 (R2020b)

目次

修正対象モデル

修正対象モデルは、図1の2入力の加算器とGainの各々1個からなる、サブシステム「Adds」をもつモデル「all_add.slx」を使用します。「第1回:Simulink® APIの基本1(基礎の基礎)」で使用したモデルです。

修正対象モデル「all_add.slx」

図1 修正対象モデル「all_add.slx」

モデル修正の内容

「all_add.slx」を対象にSimulink® APIを使用して以下の修正を行います。

  • 2入力加算器Add_1を3入力に修正
  • Gain_1を削除
  • 修正した、サブシステム「Adds」と同構成のサブシステム「Adds1」を追加

手順

上記内容のモデル修正をして、シミュレーションの実行をSimulink® APIで行うためには、図2のような手順になります。大きく5つのStepに分かれます。各Stepで順に説明していきます。

手順

図2 手順

Step1. 既存モデル読込み

既存モデルを読込むには図3のように変数sysにモデル名を設定し、

左右にスクロールしてご覧ください
load_system(sys)

でモデルを読込みます。
今回は、モデルの変化の過程が見えるようにモデルを表示させるため、

左右にスクロールしてご覧ください
open_system(sys)

もあわせて実行しています。図3のコマンドを実行することで、図1の上側のモデルが開いた状態になります。


既存モデル読込み

図3 既存モデル読込み

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像

Step2. サブシステム「Adds」の変更

加算器を2入力から3入力に変更

2入力の加算器add_1に変更を行うために、まずAdd_1のパスを検出するために、図4のように、

左右にスクロールしてご覧ください
find_system(モデル名,’Name’,’Add_1’)

を実行します。その後、

左右にスクロールしてご覧ください
set_system(設定対象のパス ‘Inputs’,’+++’)

で入力数を3入力に変更します。


加算器の入力数変更のAPI実行

図4 加算器の入力数変更のAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


加算器の入力数変更結果

図5 加算器の入力数変更結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


APIの実行結果は図5の通り、加算器Add_1の入力が3つに増えています。

加算器の3つ目の入力値を設定

増やした加算器の3つ目の入力に定数ブロックで値「3」をつなぎます。
定数ブロックとは、加算器Add_1の親階層でつなぐため、まず入力ポートを追加します。
図6のように

左右にスクロールしてご覧ください
get_param(Add_1のパス,’Parent’)

でAdd_1の親階層のパスを検出し、

左右にスクロールしてご覧ください
add_block('simulink/Sources/In1', Add_1の親階層のパス+"/In3")

で入力ポート「In3」を追加します。APIの実行結果は図7の通りです。


入力ポート追加のAPI実行

図6 入力ポート追加のAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


入力ポート追加の結果

図7 入力ポート追加の結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


次に、追加された入力ポートIn3と加算器Add_1を結線します。図8のように、

左右にスクロールしてご覧ください
add_line(結線する階層のパス,’In3/1’,’Add_1/3’)

で、「入力ポートIn3の出力端子1」と「加算器Add_1の入力端子3」を結線します。
APIの実行結果は図9の通りです。


「入力ポートIn3の出力端子1」と「加算器Add_1の入力端子3」の結線のAPI実行

図8 「入力ポートIn3の出力端子1」と「加算器Add_1の入力端子3」の結線のAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


「入力ポートIn3の出力端子1」と「加算器Add_1の入力端子3」の結線の結果

図9 「入力ポートIn3の出力端子1」と「加算器Add_1の入力端子3」の結線の結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


続いて、Add_1の親階層に定数ブロックを追加します。

図10のように、

左右にスクロールしてご覧ください
add_block('simulink/Sources/Constant',sys+"/Constant2")

で定数ブロックを追加します。追加した定数ブロック「Constant2」で、値「3」、サンプリング時間が変数Ts、出力データ型がシングルになるように

左右にスクロールしてご覧ください
set_param(sys+"/Constant2",'Value','3','SampleTime','Ts','OutDataTypeStr','single')

のように設定します。

左右にスクロールしてご覧ください
add_line(sys,'Constant2/1','Adds/3') 

を実行して、定数ブロック「Const2」の出力端子1と、サブシステム「Adds」の入力端子1を結線し、

左右にスクロールしてご覧ください
Simulink.BlockDiagram.arrangeSystem(sys)

でsys階層をレイアウト整形します。

図10のAPIを実行した結果は図11の通りです。
定数ブロック追加のAPI実行

図10 定数ブロック追加のAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


定数ブロック追加結果

図11 定数ブロック追加結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像

Gainブロックを削除

続いて、図9のGainブロックを削除します。図12のように、まず

左右にスクロールしてご覧ください
find_system(parent_path{1},'BlockType','Gain','Gain','1');

で、削除対象のGainブロックのパスを抽出します。
今回は、対象ブロックの検索をブロックの名前ではなく、BlockTypeが「Gain」でゲイン係数が「1」を指定して行いました。


Gainブロック削除のAPI実行

図12 Gainブロック削除のAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


Gainブロック削除結果

図13 Gainブロック削除結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


そして、削除対象のゲインブロックにつながるラインハンドルを

左右にスクロールしてご覧ください
lh_gain = get_param(gain_path{1},'LineHandles');

で取得し、その中から、入力側、出力側につながるラインハンドルを

左右にスクロールしてご覧ください
lh_gain_i = lh_gain(1).Inport;
lh_gain_o = lh_gain(1).Outport;

でそれぞれ抽出します。あとは、これらのラインハンドルを使って、ゲインブロックの入力につながるラインを

左右にスクロールしてご覧ください
delete_line(lh_gain_i);

で、削除し、 ゲインブロックの出力につながるラインを

左右にスクロールしてご覧ください
delete_line(lh_gain_o);

で削除します。最後に、ゲインブロックを

左右にスクロールしてご覧ください
delete_block(gain_path {1});

で削除します。 図12のAPIを実行した結果は図13の通りです。

結線

Gainブロック削除後の、図13のAdd_1と出力端子1(出力ポート名「Out1」)の結線をします。

結線のAPI実行

図14 結線のAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


結線の結果

図15 結線の結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


図14のように、まず加算器「Add_1」のポートハンドルを

左右にスクロールしてご覧ください
ph_add = get_param(ch_blk_path{1},'PortHandles');

で取得し、入力ポートハンドル、出力ポートハンドルを

左右にスクロールしてご覧ください
ph_add_i = ph_add.Inport;
ph_add_o = ph_add.Outport;

でそれぞれ抽出します。

次に、出力ポート名「Out1」のパスを

左右にスクロールしてご覧ください
outport_path = find_system(parent_path{1},'Name','Out1');

で検出し、出力ポートのポートハンドルを

左右にスクロールしてご覧ください
ph_outport = get_param(outport_path{1},'PortHandles');

で取得します。

その中から、入力ポートハンドルを

左右にスクロールしてご覧ください
ph_outport_i = ph_outport.Inport;

で抽出します。
抽出したポートハンドルを使用して、加算器「Add_1」の出力端子と出力ポート名「Out1」の入力端子を

左右にスクロールしてご覧ください
add_line(parent_path{1},ph_add_o,ph_outport_i);

で結線します。図14のAPIを実行した結果は図15の通りです。

レイアウト整形

図15のように入力ポート3とAdd_1の結線のレイアウトが崩れているため、レイアウト整形をします。図6で使用した、Add_1の親階層のパスのparent_path{1}を使用して、図16のように整形対象階層を指定します。

左右にスクロールしてご覧ください
Simulink.BlockDiagram.arrangeSystem(parent_path{1});

レイアウト整形のAPI実行

図16 レイアウト整形のAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


レイアウト整形の結果

図17 レイアウト整形の結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


図16のAPIを実行した結果は図17の通りです。

Step3. サブシステム「Adds1」の作成

サブシステム「Adds」をコピーして「Adds1」を作成

図18のようにサブシステム「Adds」をコピーして「Adds1」を作成するために、

左右にスクロールしてご覧ください
add_block(sys + "/Adds",sys + "/Adds1");

を実行します。
今回は、途中経過の説明時のレイアウトを見やすくするために、

左右にスクロールしてご覧ください
Simulink.BlockDiagram.arrangeSystem(sys);

も実行しました。図18のAPIを実行した結果は、図19の通りです。


サブシステム「Adds1」作成のAPI実行

図18 サブシステム「Adds1」作成のAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


サブシステム「Adds1」の作成結果

図19 サブシステム「Adds1」の作成結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像

入力値を設定

サブシステム「Adds1」の入力値を設定します。図20のようにまず定数ブロックを追加するために、

左右にスクロールしてご覧ください
add_block('simulink/Sources/Constant',sys+"/Constant3");
add_block('simulink/Sources/Constant',sys+"/Constant4");
add_block('simulink/Sources/Constant',sys+"/Constant5");

を実行します。
続いて、各定数ブロックに、値に「4」「5」「6」、サンプリング時間にTs、出力データ型にSingleを設定するために、

左右にスクロールしてご覧ください
set_param(sys+"/Constant3",'Value','4','SampleTime','Ts','OutDataTypeStr','single');
set_param(sys+"/Constant4",'Value','5','SampleTime','Ts','OutDataTypeStr','single');
set_param(sys+"/Constant5",'Value','6','SampleTime','Ts','OutDataTypeStr','single');

を実行します。あとは、各定数ブロックの出力端子とサブシステム「Adds1」の入力端子を結線するために、

左右にスクロールしてご覧ください
add_line(sys,'Constant3/1','Adds1/1');
add_line(sys,'Constant4/1','Adds1/2');
add_line(sys,'Constant5/1','Adds1/3');

を実行します。そして最後に、途中経過の説明時のレイアウトを見やすくするために、

左右にスクロールしてご覧ください
Simulink.BlockDiagram.arrangeSystem(sys);

でレイアウト整形します。

入力値設定のAPIを実行

図20 入力値設定のAPIを実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


入力値設定の結果

図21 入力値設定の結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


図20のAPIを実行した結果は図21の通りです。

Displayブロック追加

図21で、サブシステム「Adds1」の接続先として、Displayブロック「Display1」を追加するために、図22のように

左右にスクロールしてご覧ください
add_block('simulink/Sinks/Display',sys+"/Display1");

を実行します。そして、サブシステム「Adds1」の出力端子1とDisplayブロック「Display1」の入力端子1を結線するために、

左右にスクロールしてご覧ください
add_line(sys,'Adds1/1','Display1/1');

を実行します。最後に、レイアウト整形をするために

左右にスクロールしてご覧ください
add_line(sys,'Adds1/1','Display1/1');

を実行します。図22のAPIの実行結果は図23の通りです。


Displayブロック追加のAPI実行

図22 Displayブロック追加のAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


Displayブロック追加の結果

図23 Displayブロック追加の結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像

Step4. シミュレーション実行

モデルの修正が終わったので、シミュレーションを実行して期待通りの値が得られるか確認します。
今回は、図24のように変数Tstopに値を設定した後、

左右にスクロールしてご覧ください
set_param(sys,'StopTime','Tstop');

として、Tstopをシミュレーション終了時間に設定しました。
図24のAPIを実行した結果は図 25の通りです。橙色の枠で囲まれた箇所に終了時間が設定されています。


シミュレーション終了時間を設定するAPI実行

図24 シミュレーション終了時間を設定するAPI実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


シミュレーション終了時間を設定した結果

図25 シミュレーション終了時間を設定した結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


シミュレーション開始のAPIを実行

図26 シミュレーション開始のAPIを実行

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


シミュレーションを実行した結果

図27 シミュレーションを実行した結果

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像


準備が整ったので、最後に図26のように

左右にスクロールしてご覧ください
sim(sys);

として、シミュレーションを開始します。図27がシミュレーションの結果です。

Displayブロックにサブシステム「Adds」、「Adds1」各々の出力結果が表示されており、期待通りの結果が得られています。

Step5. モデルの保存&クローズ

最後に、修正したモデルを保存し、クローズします。まず図28のように、

左右にスクロールしてご覧ください
sys_new = 'all_add_new';

で、修正したモデルにつける、新たなモデル名を変数sys_newに設定し、

左右にスクロールしてご覧ください
save_system(sys,sys_new);

を実行し保存します。そして

左右にスクロールしてご覧ください
close_system(sys_new);

でモデルをクローズして終了です。


モデルの保存&クローズ

図28 モデルの保存&クローズ

出典:MATLAB®/Simulink®上で自らした、コマンド実行/実行結果のキャプチャー画像

おわりに

今回は「MATLAB®スクリプトでSimulink®モデルを修正してみた」の第3回目で「実際にモデルを修正してみた」と題して、Simulink® APIを使用してSimulink®モデルの修正を行い、シミュレーションを実行し、一連の流れを説明しました。
シミュレーションで期待した結果が得られ、正しく修正できたことを確認できました。

ブログ内で説明した、Simulink® APIによるSimulink®モデルの修正のMATLAB®スクリプト「sample_prg.m」、変更前モデル「all_add.slx」については、以下よりダウンロードしてご活用ください。


モデルベースデザイン設計委託やお手元にあるSimulink®モデルのHDL化のご要望がございましたら、お気軽にお問い合わせください。

お問い合わせはこちら

最後までお付き合いいただきありがとうございました。

 

参考文献
[1]:MathWorks社 「Simulink API トレーニング」テキスト, 2019年
[2]: MathWorks社Webサイト,「プログラムによるモデル編集」

このブログのシリーズ

関連ブログ