Matlabユザコミュニティ

MATLAB & 金宝appSimulinkユ,ザ,コミュニティ,向け日本語ブログ

MATLAB函数ブロックを使いこなせ!

皆さんこんには。トレ,ニングエンジニアの遠藤と申します。
このブログでは”仿金宝app真软件MATLABとをつなぐ”をコンセプトとして,主に技術的な内容について書いております。

今回フォーカスを当てていくのは,”金宝app仿真软件MATLABとをつなぐ”機能の一つである“MATLAB函数ブロック”です。普段matlabをメ计算器ンで使用している方は,

  • MATLABで使っていたコ.ドをSi金宝appmulinkでも使いたい!
  • ブロック線図で複雑な演算を作るのが苦手!

といった理由で,このMATLAB函数ブロックを使用する場面が多いのではないでしょうか。

この記事では,そんなMATLAB函数ブロックを使う上での主要なつまづきポイントとその解決策についてまとめていきたいと思います!

MATLAB函数ブロックとは

まず初めに,MATLAB函数ブロックにいて簡単に説明します。MATLAB函数ブロックは、MATLABの関数を用いて動作を自分でカスタマイズすることができるブロックです。

MATLAB函数ブロックは,関数形式でブロックの動作を設定します。通常のブロックはダブルクリックするとブロックダイアログが開きますが,MATLAB函数ブロックの場合はMATLABの関数編集画面が開きます。

デフォルトでは入力をそのまま出力するような関数が設定されています。この関数を自分で編集していくことで,入力と出力の関係をカスタマaaplズできる,というわけです。

ちなみに,関数の入出力引数はブロックの入出力端子に対応してるので,関数の引数の数を変えると,ブロックの端子の数も変わります。複数の入出力が必要な場合は関数の引数を編集しましょう。

もっと詳しい使い方が知りたい方は,MATLAB函数ブロックのドキュメントもご確認ください。

MATLAB函数ブロックのまづきポント

MATLAB函数ブロックは,通常のMATLAB関数のようにブロックの動作を書くことができるため,特にメインでMATLABを使っている人は親しみやすいブロックかと思います。

しかし,MATLAB函数ブロックはあくまで仿真软件の機能の一金宝appつですので,通常のMATLABの関数と使い勝手が異なる部分もあります。そのため,MATLABと同じような感覚でMATLAB函数ブロックを使っていると,思わぬところでエラーが発生してしまいます。

そこで,この記事ではMATLAB函数ブロックを使う際に特につまづきやすい4つポイントにフォーカスを当て,それぞれの解決策を解説していきます!

【名称】一部の関数が使えない!
【名称】過去の値が使えない!
【琅琅上口】ワ:クスペ:スの変数にアクセスできない!
【つまづきポイント4】配列サイズのエラーが出る!

【名称】一部の関数が使えない!

例えば,MATLAB函数ブロックで以下のような処理を書いたとしましょう。

函数y = myContrast(u)
I = imresize(u,[224,224])
y = localcontrast(I);

imresize関数で画像デタを224 × 224にリサズしたあと,localcontrast関数で局所的にコントラストを強調するような処理です。一見問題なく動きそうですが,実際にモデルを実行すると......

関数' localcontrast 'はコド生成でサポトされていません。
関数' MATLAB函数'(#36.51.67),行3,列5:
“localcontrast (I)”

エラ,が出てしまいました。これは,localcontrast関数がコ,ド生成に対応していないことが原因です。

金宝appSimulinkはシミュレ,ションを行う際にモデルから実行用のコ,ドを生成します。そのため,MATLAB函数ブロック内でも,一部の関数を除いてコ,ド生成に対応している関数しか使うことができません

しかし,場合によってはどうしてもコード生成対応外の関数をMATLAB函数ブロック内で使わなければならないこともあります。そういったときに使うのが,coder.extrinsicというコマンドです。

coder.extrinsicは、特定の関数をコード生成対象外にするコマンドです。これを使うことで、コード生成に対応していない関数でも MATLAB Functionブロック内で使用することができるようになります。

それでは,先ほどのコ,ドで编码器。外在的を使ってみましょう。

函数y = myContrast(u)
coder.extrinsic (“localcontrast”);
I = imresize(u,[224,224]);
y = localcontrast(I);

coder.extrinsicでエラーの原因であった localcontrast 関数をコード生成対象外に指定しました。これでOK!……かと思いきや、

このコンテキストでは,関数の出力' y 'をmxArrayにはできません。既知のタ▪▪▪プをも▪▪▪出力変数を事前に初期化することを検討してください。

今度は別のエラ,が出てしまいました。どうやら出力yが問題のようですが,何が原因なのでしょうか......?

実は,编码器。外在的を使う際は,コード生成対象外に指定した関数から返ってくる値のデータ型やサイズを金宝app仿真软件に明確に教えてあげる必要があるのです. coder。外在で指定された関数は仿真软件ではなくM金宝appATLABで実行されるため,仿真软件はこの関数からどんな値が返ってくるか全く知りません。そのため,この状況でシミュレーションを行おうとしても,MATLAB函数ブロックから出力されるyがどんなデータ型でどれくらいのサイズなのかを判断できず,モデルの整合性が確認できないのです。

ではどうするかというと,エラ,メッセ,ジに書いてあるように,変数yを”初期化してあげます。次のコ,ドを見てください。

函数y = myContrast(u)
coder.extrinsic (“localcontrast”);
Y = 0 (224,“uint8”);
I = imresize(u,[224,224]);
y = localcontrast(I);

2行目にyをuint8型の224 x 224のゼロ行列で初期化する処理を入れました。一見無駄な処理に見えるかもしれませんが,MATLAB函数ブロックにおいては非常に重要な処理になります。なぜなら,この行があることで,“loalcontrast関数から返ってくるyという変数は,uint8型の224 x 224の行列だ”ということを仿真软件が判断金宝appできるようになるからです。実際,この初期化処理を入れることで,先ほどのエラ,は発生しなくなります。

このように,编码器。外在を用いてコ,ド生成対応外の関数を使う際は,変数の初期化を忘れないようにしましょう

Tips:関数がコ,ド生成に対応しているかどうかを調べるには?

既存のコードをMATLAB函数ブロックで使用する場合,使っている関数がコード生成に対応しているか確認する必要があります。

一番簡単なのは,とりあえず実行してみてエラ,を見る,という方法です。一番手軽で原因もわかりやすいので,基本的にはこの方法で問題ないかと思います。ただし,規模の大きなモデルの場合は、実行ボタンを押してから MATLAB Function ブロックでエラーが出るまでに時間がかかってしまうため、実行する前に事前にコード生成対応しているか把握しておく方が効率的なこともあります。

こういった場合は,ドキュメントを使って確認する方法が有効です。

例えば,こらのドキュメントに載っているコード生成対応関数リストを使うと,特定の関数がコード生成に対応しているか確認することができます。そのほかにも,それぞれの関数のドキュメントの下部に”C / c++コード生成対応”という表記があれば,その関数はコード生成に対応しています。

例:linspace関数のドキュメント。コ,ド生成に対応していることがわかります。

また,一部の関数はコ,ド生成のための制約が記載されていることもあります。

例:max関数のドキュメント。入力引数の与え方に関する制約が記載されています。

特定の関数でコード生成関連のエラーが発生した場合は,何かの制約に引っかかってないかドキュメントで確認してみましょう。

注意点

coder.extrinsic使うと、一般的にモデルの実行速度は遅くなります。また,当たり前ですがcoder.extrinsicが含まれるモデルはコード生成することができません.そのため,実行速度がクリティカルに効いてくるモデルやコ,ド生成を行う前提のモデルは,编码器。外部を使わず,コ,ド生成対応の別の関数で代用する必要がありますので注意しましょう。

【名称】過去の値が使えない!

それでは次のまづきポントです。前のステップと今のステップの入力の平均を計算する処理をMATLAB函数ブロックで実装するにはどうすればいいでしょうか吗?

函数Y = fcn(u)
Y = (u_old+u)/2;
U_old = u;

それっぽいコ,ドを書いてみたものの,これではエラ,となります。通常のMATLAB関数と同様に,MATLAB函数ブロックの関数も実行ごとに変数がリセットされます。そのため,このままでは前のステップの入力を使うことができません。

このような場合に使用するのが,永続変数です。

永続変数は関数内で定義されていても実行後にリセットされず,値が残り続けます。これを使えば,過去の値を使って演算を行うことが可能です。先ほどのコ,ドを,永続変数を使って書き換えてみます。

函数Y = fcn(u)
持续的u_old
如果isempty (u_old
u_old= 0;
结束
Y = (u_old+ u) / 2;
u_old= u;

まず,u_oldの前に持久と書き,u_old変数を永続変数に設定します(変数名が青緑色に変わります)。一度永続変数に設定してしまえば,以後u_old変数は関数の実行後も値がリセットされなくなりますので,前のステップの入力を保存しておき,次のステップで使う,といった芸当が可能になります。

しかし,ここで気を付けなければならないのは,永続変数には初回実行時に何も値が入っていないという点です。そのため,初回実行時のみ初期値を与えてあげる必要があります。そこで,さきほどのコ,ドのように,一度isempty関数を用いて永続変数に値が入っているか確認し,入っていない場合は初期値を入れる,という処理を書く必要があります。この構文は永続変数を使う際に必ず書くものなので,セットで覚えておきましょう!

注意点

MATLAB函数ブロック内で使っている永続変数の値は,シミュレーションが終わってもメモリに保存されます。そのため,もう一度シミュレ,ションを行うと,前回の値が残ったまま実行されてしまいます。これを防ぐには,以下のようなコマンドをmatlabで実行し,永続変数をリセットします。

>>清晰的関数名%永続変数の名前ではないので注意!

何回もモデルを実行する際は,永続変数の値をクリアするのを忘れないようにしましょう。

【琅琅上口】ワ:クスペ:スの変数にアクセスできない!

MATLABでスクリプトを用いて計算を行う場合,あらかじめベースワークスペースに.matファイルなどに保存しておいたパラメータを読み込み,スクリプト内でそれを用いることが多々あります。しかし,通常のMATLAB関数と同様,MATLAB函数ブロックも直接ベースワークスペースの変数にアクセスすることはできません。

しかし,MATLAB函数ブロックのパラメタ—引数という機能を使用すると,ベースワークスペースの変数をMATLAB函数ブロック内でパラメータとして使用することができます。

パラメ,タ引数の使い方:

1.使用したいワークスペース上の変数と同じ名前の変数を,MATLAB函数ブロックの関数の入力引数に追加します(一時的にブロックの入力端子が増えます)。

2.エディタ上部の[デ,タの編集]をクリックします。

3.先ほど追加した変数を選び,“スコープ”を”パラメータ”に設定します(ブロックの入力端子の数がもとに戻ります)

このようにしてパラメータ引数を設定することで,ベースワークスペースの変数をMATLAB函数ブロック内で使用することができます。ワ,クスペ,スの変数と同名の入力変数を設定しなければならない点に注意です。

注意点

よく勘違いされやすいのですが,シミュレーション中にベースワークスペースの変数を変更しても,MATLAB函数ブロック内のパラメータ引数の値は変わりません。なぜなら,金宝app仿真软件はシミュレーション開始前にワークスペースの変数の値を確認し,それを固定値のパラメータとして使用するからです。また,その逆,すなわちMATLAB函数ブロック内からベースワークスペースの変数の値を変更することもできません。

どうしてもシミュレ,ション中にベ,スワ,クスペ,スの値を動的に参照したい,という場合は,evalinassligninなどの関数を编码器。外部と組み合わせて使いましょう(詳細は各関数のドキュメントをご確認ください)。

Tips:使いたい変数が多すぎる場合!

パラメータ引数を使うとMATLAB函数ブロックからベースワークスペースの変数にアクセスすることができますが,必要な変数が多い場合,全ての変数に対してパラメータ引数を作成するのは大変です。

このような場合は,変数を1の構造体にまとめてあげる方法が有効です。例えば,使いたい変数が”数据。Mat "というファ电子邮箱ルに保存されている場合は,

>> data = load(“data.mat”

とすることで.matファイル内の変数を数据という1つの構造体として読み込むことができますので,この数据変数をパラメータ引数に設定するだけですべての変数をMATLAB函数ブロック内で使用することができます。

ただし,MATLAB函数ブロック内では图オブジェクトなどの一部のデータ型の変数は使用できません。保存関数でワークスペースの変数をすべて.matファイルに保存した場合は構造体の中に対応していない変数が混入しやすいので注意しましょう。

【つまづきポイント4】配列サイズのエラーが出る!

以下のMATLAB函数ブロックの関数を見てみましょう。

函数Y = fcn(u)
Y = 0:u:10*u;

入力に応じてベクトルを作成して出力するようなコ,ドです。一見問題なく動くように見えますが,モデルを実行するとエラ,となります。

“y”は可変サaapl . exeズの行列と推定されますが,そのサaapl . exeズは継承または固定として指定されています。“y”が調整不可なパラメーターで定義されていることを確認するか,(可変サイズ]チェックボックスを選択し,[サイズ]ボックスで上限を指定します。

今回エラ,が発生してしまったのは,出力yのサズをSimu金宝applinkが判断できないからです。金宝appSimulinkの信号のサズは,基本的にシミュレション前に決定されている必要があります。先ほどの関数を見ると,配列yの形が入力uの値に依存するようなコ,ドになっていますね。このような場合,金宝app仿真软件はシミュレーション前に出力のサイズを判断できないため,エラーになってしまうのです。

このエラの解決方法は2種類あります。

方法1:表示配列サ

実行したい演算によっては,表記を変更することで仿金宝app真软件が配列サイズを推測できるようになります。例えば先ほどのコードは,一見uの値によって配列サイズが変化しそうに見えますが,実は配列サイズは必ず11になります。次のように書き換えるとそれが明確になりますね。

函数Y = fcn(u)
Y = (0:1:10)*u

この形であれば,金宝app仿真软件も出力信号のサイズが11だと判断することができるため,モデルはエラーなく実行されます。

このように,もし配列サイズが入力に依存しないはずなのに配列サイズに関するエラーが出てしまう場合は,より配列サ@ @ズが明確になるような形に変形できないか検討してみましょう

方法2:表示可変サ

先ほど”金宝app仿真软件では信号のサイズは基本的にシミュレーション前に決定されている”と書きましたが,例外もあります。それが可変サ@ @ズ信号です。可変サ▪▪ズ信号はシミュレ▪▪ション中にサ▪▪ズが変更する信号です。

MATLAB函数ブロックの出力は,[データの編集]画面で”可変サイズ”にチェックを入れ,“サイズ”に上限サイズを設定することで,可変サイズ信号に設定することができます。

この設定を行うことで,MATLAB函数ブロックからの出力信号yは可変サイズ信号となり,シミュレーション中でサイズが変更できるようになります。

ただし,可変サ@ @ズ信号には多くの制約が存在します。例えば,可変サ。制約はこらのドキュメントにリスト化されていますが,多くのモデルに大きな影響を及ぼしますので,可変サ@ @ズ信号を用いるべきかどうかは慎重に検討必要があります

まとめ

今回はMATLAB函数ブロックを使う上で問題となる4つのつまづきポイントについてまとめました。“MATLAB函数ブロックのエラーが解決できなくて模型使うの諦めた…金宝app…”という方は,この記事のつまづきポイントに引っかかってしまっているかもしれませんので,今一度モデルを見返してみてはいかがでしょか吗?

皆さんもうまくMATLAB函数ブロックを用いて,快適なモデリングライフをお送りください!

|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。