こんにちは、カヲルです!
本記事ではMATLABのスクリプトでSimulinkのブロックを配置する方法について紹介します。
決められたルールで多数のブロックを自動作成したい場合や設定ファイルの情報をもとに動的な配置をしたい時などに使えるかと思います。
ブロック配置
ライブラリからブロックを配置する
ブロックをマウス操作により配置する場合はSimulinkのメイン画面(モデル ブラウザー)から「ライブラリ ブラウザー」を開き、ドラッグ&ドロップで配置するかと思います。
これとは対照的にスクリプトで配置する場合はadd_block関数を用います。
まず、ブロックを配置する先のファイルをload_system関数で読み込みます。
下記の例ではあらかじめ「Test01.slx」と言う名前の空のSimulinkモデルを作成しておき、そちらを読み込みます。また、保管場所はmファイルと同じフォルダであるとします。
なお、文字を括るシングルクォーテーションマークですが、表示の都合上で上向きのチョンになってますが、最初と最後の両方で下向きのチョンに読み替えてください。
load_system(‘Test01’);
つぎにadd_block関数を使ってライブラリからブロックを配置します。配置するブロックは「ライブラリ ブラウザー」から確認します。
例題ではConstantブロックを追加します。ライブラリ ブラウザーを開くと下記の構造のツリーが表示されます。
∨ Simulink
Commonly Used Blocks
Continuous
・・・
Sources
・・・
Sourcesを開くとConstantブロックがあることが確認できます。これを参考にConstという名前でTest01に追加します。
add_block(‘simulink/Sources/Constant‘, ‘Test01/Const‘);
ここで上記命令を複数記載して実行するとエラーになります。対応としてはConstantブロックの名前を変えることで解決します。
もしくは連番でよければ、下記の自動連番のオプションを追加します。
add_block(‘simulink/Sources/Constant’, ‘Test01/Const’, ‘MakeNameUnique’, ‘on’);
add_block関数の出力引数(戻り値)はハンドルになっているよ。あとの項で説明するけど、このハンドルを使ってプロパティを変更できるよ。
もし、add_block関数を複数回実行し、一つしか表示されていない場合はぴったり重なっている可能性があるので、重ならないようにプロパティで座標を指定ないとダメですね。
自分で作成したサブシステムを配置する
サブシステムとその中身をモデル ブラウザーでマウス操作により作成し、そのサブシステムをスクリプトで配置することもできます。
まず上記と同様にサブシステムを配置する先のファイルをload_system関数で読み込みます。
つぎに空のサブシステムをadd_block関数で追加します。この例ではSubsysというサブシステムを作成し、関数の出力引数(戻り値)をhandleという変数に格納します。
そしてTest01と入力しSimulinkを起動して空のサブシステムが作成できているか確認します。
load_system(‘Test01’);
handle = add_block(‘built-in/Subsystem’, ’Test01/Subsys’);
Test01;
上記を入力すると空のサブシステムがTest01に追加されていると思います。
このサブシステムにあらかじめ作成しておいたサブシステムをコピーしたいと思います。
まず、コピー対象元のファイルをload_systemで開きます。例題ではmファイルと同じ位置にlibraryというフォルダがあり、BasedSystem01.slxがあるものとします。
次にSimulink.BlockDiagram.copyContentsToSubsystem関数を用いてサブシステムをコピーします。
(上記例題の3命令では複数回実行できないのでモデルブラウザーを保存せずに閉じ、一旦、Simulinkモデルを解放してください。)
load_system(‘Test01’);
handle = add_block(‘built-in/Subsystem’, ’Test01/Subsys’);
load_system(‘library/BasedSystem01’);
Simulink.BlockDiagram.copyContentsToSubsystem(‘BasedSystem01’, ‘Test01/Subsys’);
Test01;
上記2命令を追加することでSubsysにBasedSystem01がコピーされたと思います。
ここで位置やサイズを変更したい場合は取得したハンドルを使ってプロパティ設定できます。
ここでは例として、x = 50, y = 20の位置に幅150, 高さ50のサブブロックになるように設定します。プロパティはset関数を用いて設定できます。
load_system(‘Test01’);
handle = add_block(‘built-in/Subsystem’, ’Test01/Subsys’);
load_system(‘library/BasedSystem01’);
Simulink.BlockDiagram.copyContentsToSubsystem(‘BasedSystem01’, ‘Test01/Subsys’);
x = 50; y = 20; w = x + 150; h = y + 50;
sizeSys = [x;y;w;h];
set(handle, ‘Position’, sizeSys);
Test01;
もし、一回一回モデル ブラウザーを閉じるのが面倒な場合はclose_system関数を用います。保存していないモデルは閉じれないので合わせてsave_system関数も用います。
例題では上書き保存しないようにわざと別ファイル名にしています。
close_system;
load_system(‘Test01’);
handle = add_block(‘built-in/Subsystem’, ’Test01/Subsys’);
load_system(‘library/BasedSystem01’);
Simulink.BlockDiagram.copyContentsToSubsystem(‘BasedSystem01’, ‘Test01/Subsys’);
x = 50; y = 20; w = x + 150; h = y + 50;
sizeSys = [x;y;w;h];
set(handle, ‘Position’, sizeSys);
Test01;
save_system(‘Test01’, ‘Test01_bak’);
ブロックやサブシステムの配置の基本の流れは以上になるよ。あとは制御文などを使ってモデルを配置してみよう!
例題は下に示すよ。
close_system;
load_system(‘Test01’);
x = 50; y = 20; w = x + 150; h = y + 50;
for idx = 1:1:5
SysName = strcat(‘Test01/Subsys’, num2str(idx));
handle(idx,1) = add_block(‘built-in/Subsystem’, SysName);
load_system(‘library/BasedSystem01’);
Simulink.BlockDiagram.copyContentsToSubsystem(‘BasedSystem01’,SysName);
sizeSys = [x;y;w;h];
set(handle(idx,1), ‘Position’, sizeSys);
y=y+80; h=h+80;
end
Test01;
save_system(‘Test01’, ‘Test01_bak’);
ラインによる接続
ブロックが配置できたらラインで接続してみましょう。
ラインを追加するのはadd_line関数を用います。では例題として上記の制御文を使った例題にてSubsys1の出力1からSubsys2の入力2とSubsys3の入力2へラインを引いてみます。
close_system;
load_system(‘Test01’);
x = 50; y = 20; w = x + 150; h = y + 50;
for idx = 1:1:5
SysName = strcat(‘Test01/Subsys’, num2str(idx));
handle(idx,1) = add_block(‘built-in/Subsystem’, SysName);
load_system(‘library/BasedSystem01’);
Simulink.BlockDiagram.copyContentsToSubsystem(‘BasedSystem01’,SysName);
sizeSys = [x;y;w;h];
set(handle(idx,1), ‘Position’, sizeSys);
y=y+80; h=h+80;
end
add_line(‘Test01’, ‘Subsys1/1’, ‘Subsys2/2’, ‘autorouting’, ‘on’);
add_line(‘Test01’, ‘Subsys1/1’, ‘Subsys3/2’, ‘autorouting’, ‘on’);
Test01;
save_system(‘Test01’, ‘Test01_bak’);
ここでオプションで付けた‘autoroutiong’, ‘on’はなくても動きますが、ブロックを避けて比較的綺麗に結線してくれるので追加したほうが良いオプションかと思います。
同様の手順でadd_line関数でラインを追加していけば一つのSimulinkモデルを完成させることが出来ます。
add_line関数の出力引数(戻り値)もハンドルになっているのでもしプロパティを設定したい場合はハンドルを取得して、set関数で設定しよう。
さいごに
スクリプトでブロックを配置するのはモデルブラウザにてマウス操作で配置するのに比べ手軽さは劣るものの手順自体は簡単ですね。
この記事ではMATALBの基本機能となる行列演算、ファイル操作、制御文、グラフ表示などを扱ってませんが、さらにMATLABを使いこなしたい方は書籍を読みながら学習を進めてみてはいかがでしょうか。