MATLABプログラミング Simulink基礎編(4)
MATLABプログラミング Simulink基礎編4回目です。
これまでは、対象となるモデルやブロックの名前が分かっている状態で、それらのパラメータを読み書きしていました。
しかしたとえば、「モデルの中にあるConstantブロックの値をすべて列挙したい」というような場合はどうでしょう。そもそもモデル中のどこにConstantブロックがあるのか?すらわかっていない状況では、パラメータを読み込むどころではありません。そう、まずはConstantブロックがどこにあるのかを探さないといけません。
このように、「モデル中にある○○ブロックをすべて列挙したい」というのが今回のテーマです。
find_systemコマンド
ブロックを探すには、find_system コマンドを使用します。このfind_systemというコマンドは、モデル中にある「ブロック」「信号線」「注釈」を検索してくれるものです。
使い方についてはこれから詳しくご説明しますが、今すぐ詳細を知りたいという方はMATLABコマンドプロンプトにて、
doc find_system
と入力していただければヘルプを見ることができます。
基本形:Constantブロックを探し、その値を列挙する
まず始めに、「find_systemコマンドにてConstantブロックを探し、その値を列挙する」という流れを「基本形」としてご紹介します。
というのも、もちろんfind_systemはConstantブロックを探す以外にも多様な検索が行えるのですが、それらはすべてこの「基本形」をチョコチョコ修正するだけで実現可能だからです。
さて、その「基本形」ですが、find_systemコマンドの引数に「検索条件」を渡すと「検索結果(ハンドル配列)」が返ります。その「検索結果」を「ループで処理」するという流れを持っています。
コードとしては次のようになります。
hModel = get_param( 'モデル名', 'Handle' ); hConstant = find_system( hModel, 'BlockType', 'Constant' ); for i = 1:length( hConstant ) get_param( hConstant( i ), 'Value' ) end
さっそく演習という形で試してみましょう。
演習:Constantブロックを探し、その値を列挙する
事前準備
モデル ex1_7.mdl を作成し、そこにConstantブロックを3つ置きます。そして、それぞれの値を1,2、ON とします。
手順1
手順1:MATLABコマンドウィンドウにて、モデル ex1_7 のハンドルを取得します。
>> hModel = get_param( ‘ex1_7’, ‘Handle’ )
結果1:モデル ex1_7 のハンドルが取得できました
手順2
手順2:MATLABコマンドウィンドウにて、Constantブロックを検索し、そのハンドルを取得します。
>> hConstant = find_system( hModel, ‘BlockType’, ‘Constant’ )
結果2:Constantブロックのハンドルが取得できました
Constantブロックは3つあるので、ハンドルも3つあります。
手順3
手順3:MATLABコマンドウィンドウにて、各ConstantブロックのValueを取得します。
>> for i = 1:length( hConstant ), get_param( hConstant( i ), ‘Value’ ), end
結果3:各Constantブロックの値が表示されました
ここでのポイントは、 length( hConstant ) と、 hConstant( i ) です。
find_systemはハンドルの配列を返すのですが、その配列の要素数こそが見つかったブロックの数になります。そのため、 length( hConstant ) とすることで要素数を取得します。
そして、それぞれのブロックに1つずつアクセスするには、 hConstant( i ) というように配列要素を1つずつ取り出しては操作(get_paramの引数にするとか)を行います。
ふりかえり
Constantブロックを検索するのに、find_system( hModel, ‘BlockType’, ‘Constant’ ) というコマンドを使用しましたが、これの引数について見てみましょう。
まず第一引数の hModel ですが、これは「どのモデルを検索するのか?」という指定です。
そして第二、第三引数の ‘BlockType’, ‘Constant’ ですが、これは2つで1つの意味を成します。すなわち、パラメータ「BlockType」が、「Constant」という値をもつものを検索しなさいという意味になります。
そう、Constantブロックにはパラメータ「BlockType」というものがあって、その値が「Constant」なのです。その他のブロックにもパラメータ「BlockType」があるため、’Constant’の部分を変えれば別のブロックを検索する事が出来ます。
Constantブロックの「BlockType」パラメータは’Constant’
オマケの課題
このコード、Constantブロックが0個、もしくは1個の時にもちゃんと動くのだろうか?と疑問に思われた方もいらっしゃるでしょう。物はためし、実際にやってみてください。
まとめ
ブロックを検索するには find_system コマンドを使用します。検索条件をfind_systemに渡すと、見つかったブロックのハンドルを返してくれるため、あとはforループで処理するなり何なり好きに利用すれば良いというのが今回の話でした。
次回は、この「基本形」をどのように変更する事で、どのような応用ができるのかご紹介します。
備考
今回の話を読んで、「ちょっと待て。自分の知っている find_system の使い方と違うぞ」と思われた方もいらっしゃるでしょう。その方に向けて、釈明(?)をしておきます。
Constantブロックを検索するにあたり、こうされる方もいらっしゃるでしょう。
>> listConstant = find_system( ‘ex1_7’, ‘BlockType’, ‘Constant’ )
これを実行すると次のように「Constantブロック名」のセル配列が返ります。
ポイントは第一引数です。今回の記事ではワザワザ get_param でモデルのハンドルを取得していましたが、ここでは ‘ex1_7’ というモデル名を直接指定しています。
find_systemは、第一引数に何を渡すかによって戻り値の型が変わります。
ハンドルを渡す → ハンドル配列が返る
文字列(モデル名)を渡す → セル配列が返る
という関係にあります。
ではなぜハンドルにこだわっているのか?というと、そこには2つほど意図があります。
意図その1:基礎編(2)でご紹介したように、ブロック名に特殊文字が入っている場合でもハンドルであれば問題が起きませんが、セル配列(=文字列のあつまり)では問題となってしまいます
意図その2:find_systemではブロックだけではなく信号線、注釈も検索できるのですが、これらの結果は強制的にハンドルで返ってきます。ブロックと信号線とで取り扱いを変えるのも面倒(だし、プログラミング上の安全性が下がる)ため、ハンドルでの統一を推奨する事にしました。
もちろん、これは私の個人的な好みによる所が大きいため、絶対に「文字列を渡してセル配列を受け取る」というパターンを使っちゃいけないわけではありません。