3

【R2024a新機能紹介】”simulation” オブジェクトで MATLAB からのシミュレーションも...

 1 week ago
source link: https://blogs.mathworks.com/japan-community/2024/04/10/simulation-object/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

皆さんこんにちは、トレーニングチームの遠藤です。普段は「MATLAB と Simulink を繋ぐ」をテーマに技術記事を書いています。

さて、先日 MATLAB の最新バージョンである R2024a がリリースされましたね!面白い新機能はついつい時間も忘れて弄ってしまうので、この時期は時間管理が大変です……。

そして、今回の R2024a では、私がこのブログでテーマとしている「MATLAB と Simulink を繋ぐ」に関連する新しい機能が追加されました。その名も「simulation オブジェクト」です!

今回の記事では、この simulation オブジェクトについて紹介していきたいと思います。

1 simulation オブジェクトとは?

simulation オブジェクトは、MATLAB から Simulink のモデルをシミュレーションするためのオブジェクトです。R2023b 以前では、MATLAB からモデルをシミュレーションする方法として

  • sim 関数を使う
  • set_param 関数で SimulationCommand パラメータを設定する

の 2 つの方法がありましたが、R2024a では新たに simulation オブジェクトを使うことでもシミュレーションできるようになりました。

simulationMethods-1024x181.png

Run Simulations Programmatically のドキュメントから抜粋)

simulation オブジェクトの基本的な使い方はとっても簡単。まずは simulation 関数にモデル名を渡し、simulation オブジェクトを作ります。

>> sm = simulation("myModel");

オブジェクトを作ったら、あとは start 関数を実行するだけでモデルのシミュレーションが行われます。

>> start(sm);

シミュレーションの実行が終わると、simulation オブジェクトの “SimulationOutput” プロパティの中にモデルの出力が保存されます。

SimulationOutput-300x128.png

特にクセもなくシンプルな仕様になっていますね。

2 simulation オブジェクトのここがスゴイ!

それでは、以前のバージョンから存在していた 2 つの方法と、今回追加された simulation オブジェクトは何が違うのでしょうか?

結論から言うと、simulation オブジェクトは「シミュレーションの制御」や「シミュレーション中のモデルに対する操作」が必要となる場合に便利なシミュレーション方法となります。いくつか関連する機能をピックアップしてみましたので、早速見ていきましょう。

2.1 シミュレーションの実行の制御

simulation オブジェクトには、前述した start 関数などのシミュレーションの実行を制御する関数がいくつか用意されています。その中でも特に目を引くのが、特定の時間までシミュレーションを進めることができる step 関数です。

>> step(sm, "PauseTime", 4);
step-1-1024x826.png

もう一度時間を指定すれば、さらにその時間まで進んでくれます。

>> step(sm, "PauseTime", 8);
step2-1-1024x826.png

sim 関数は一度実行したらシミュレーションが完了するまで何もできず、set_param 関数の場合も Start, Pause, Continue 程度しか制御できないため、こういった細かな制御ができるのは simulation オブジェクトの利点の一つと言えますね。

2.2 シミュレーションで使用するパラメータの変更

simulation オブジェクトの set*** 関数を使うと、シミュレーションで使用されるパラメータの値を簡単に変更できます。用意されている関数は以下の 3 つです。

  1. setVariable:ワークスペースに変数として定義されているパラメータを変更
  2. setBlockParameter:ブロックのパラメータダイアログに設定されているパラメータを変更
  3. setModelParameter:シミュレーション時間やソルバーなど、モデル側のパラメータを変更

モデルのパラメータの変更というと、以前の記事でも紹介した set_param 関数が有名かと思いますが、set_param 関数と上述した関数は動作が大きく異なります。

まず、set_param 関数は、ブロックやモデルのパラメータを指定することで、モデルに直接変更を加えます。そのため、「MATLAB からモデルを編集したい!」という場合は非常に便利な機能です。

set_param-1024x538.png

それに対し、simulation オブジェクトの setVariable/setBlockParameter/setModelParameter 関数は、モデルには直接変更を加えず simulation オブジェクト内に変更したパラメータの値を保存しておき、シミュレーション実行時にその値を使用します。

setBlockParameter-1024x538.png

以前のバージョンで同じことをしたければ、Simulink.SimulationInput というオブジェクトを自分で定義し、それを sim 関数に渡してシミュレーションを行う必要がありましたが、今回それが simulation オブジェクト 1 つでまとめて行えるようになったというのは嬉しいポイントかと思います。

※ちなみに、3 つの関数で変更したパラメータの値は、それぞれVariables/BlockParameters/ModelParameters のプロパティに保存されます。

BlockParameters-300x135.png

2.3 シミュレーション中のパラメータの変更

Simulink のブロックパラメータの中には、シミュレーション中でもインタラクティブに値を変更できるものがあります(例えば Gain ブロックのゲインの値など)。今までシミュレーション中にパラメータを変更したい場合、sim 関数はシミュレーション中の変更をサポートしていないため、 set_param 関数 で SimulationCommand を start に指定してシミュレーションを開始し、その後再度 set_param 関数で直接モデルのパラメータの値を変更する必要がありました。

>> set_param("myModel","SimulationCommand","start");
>> set_param("myModel/Gain","Value","10");

それに対し、simlation オブジェクトの setBlockParameter 関数や setVariable 関数を使用すると、モデルに変更を加えることなくシミュレーション中にパラメータの値を変更することができます。

>> start(sm);
>> setBlockParameter(sm,"myModel/Gain","Value","10");

前述の通りsetBlockParameter 関数はモデル側のパラメータを変更しないので、気軽に色々なパラメータを試すことができますね。

ちなみに、simulation オブジェクトの TunableVariables プロパティと keys 関数を使うことで、モデル内に存在するシミュレーション中に変更可能なパラメータの一覧を確認できます。

>> keys(sm.TunableVariables)

各パラメータが変更可能かを確認するのはもちろん、シミュレーションアプリ側に変更可能なパラメータのみ表示&変更できるようにする、といった使い方もできるかも?

まとめると、今までのバージョンでは「シミュレーションをインタラクティブに制御する」ための機能が色々と散らばっていたのに対し、R2024a からは simulation オブジェクトを使うだけで簡単に制御できるようになった、という感じですね。

3 simulation オブジェクトのここに注意!

ここまで simulation オブジェクトの長所を書いてきましたが、使用する上での注意点もいくつか存在します。

3.1 並列シミュレーションはサポート外

「パラメータを変えてシミュレーション」と聞くと、色々なパラメータでのシミュレーションを並列計算で実施する、というのをイメージされた方もいらっしゃるかもしれませんが、残念ながら simulation オブジェクトは並列シミュレーションをサポートしていません。

parallel-1024x219.png

並列シミュレーションをする場合は parsim 関数(または batchsim 関数)と Simulink.SimulationInput オブジェクトを組み合わせて使う必要がありますので、注意しましょう。

3.2 実行中はモデルの操作不可

simulation オブジェクトでシミュレーションを開始すると、モデルの一時停止ボタンや停止ボタンなどのシミュレーションの実行を制御するボタンがロックされます(それ以外の機能は操作可能です)。

uncontrollable-1024x636.png

実行だけプログラムから行って停止は手動で、といったことはできないのでご注意ください。

3.3 シミュレーション結果の取得は停止、一時停止時のみ

前述の通り、simulation オブジェクトを使ったシミュレーションの結果は “SimulationOutput” プロパティの中に保存されます。しかし、このプロパティにはシミュレーションの実行中はアクセスできません。

outputError-1024x454.png

シミュレーション中に結果を実行中に逐次取得してアニメーションとしてリアルタイム描画、といったことはできないので注意しましょう。

4 試しに使ってみる

せっかくなので、simulation オブジェクトを使ってシミュレーションの制御を行う簡単なアプリを作ってみましょう(AppDesigner の操作方法などについては以前のシミュレーションアプリを作る記事も参考にしてみてください)。

今回シミュレーションするのはこちらのモデル。Sine Wave と Gain と Outport が繋がっているだけの簡単なモデルです。

mymodel-1024x636.png

ただし、後々アプリと連携しやすいように、シミュレーション時間を inf(無限)、”出力の形式” の設定を配列、”単一のシミュレーション出力” の設定を Off に設定しておきましょう。

config-1024x660.png

モデルの方の準備が整ったら、アプリのレイアウトを作ります。今回はシミュレーションの開始、一時停止、再開をするためのスタートボタン、停止をするためのストップボタン、可視化を行うための座標軸、ゲインの値を変更するためのスライダーを配置しました。

layout.png

次にコールバックの作成です。まずはアプリ起動時に simulation オブジェクトを作成するために、startup コールバックを定義します。

function startupFcn(app)
    app.sm = simulation("myModel");
end

あとはこの simulation オブジェクトを各種コールバックで使用するだけです。 simulation オブジェクトの “Status” プロパティにアクセスすることで現在のモデルの状態を確認できるので、こちらもうまく使って処理を書いていきます。

・スタートボタンのコールバック:

function StartButtonPushed(app, event)
    if strcmp(app.sm.Status,"inactive") %未実行の場合
        start(app.sm); %シミュレーション開始
        app.StartButton.Text = "Pause";
    elseif strcmp(app.sm.Status,"paused") %一時停止中の場合
        resume(app.sm); %シミュレーション再開
        app.StartButton.Text = "Pause";
    else %実行中の場合
        pause(app.sm); %シミュレーション一時停止
        app.StartButton.Text = "Resume";
        %プロット処理 %
        output = app.sm.SimulationOutput;
        t = output.tout;
        y = output.yout;
        plot(app.UIAxes,t,y);
        drawnow;
    end
end

・ストップボタンのコールバック:

function StopButtonPushed(app, event)
    stop(app.sm);
    app.StartButton.Text = "Start";
    output = app.sm.SimulationOutput;
    t = output.tout;
    y = output.yout;
    plot(app.UIAxes,t,y);
    drawnow;
end

・ゲインのスライダーのコールバック:

function GainSliderValueChanged(app, event)
    value = app.GainSlider.Value;
    setBlockParameter(app.sm,"myModel/Gain","Gain",num2str(value));
end

あとは実際に動かしてみると……

appResult.png

シミュレーションの制御とゲインの値の変更が可能なアプリの完成です!

simulation オブジェクトを 1 つ作るだけで色々な制御が行える分、アプリとの相性はよさそうですね。特に、Simulink Compiler を使って Simulink を持ってない人向けにシミュレーションアプリを作る、みたいな用途にはオススメかも?

5. まとめ

ということで、今回の記事は R2024a で新しく実装された simulation オブジェクトの紹介でした。実際に使ってみて、やはり 1 つのオブジェクトに機能が集約している分、コードが書きやすくなっているなと感じます。

「Simulink API、覚える関数がいっぱいあってちょっと苦手……」という方も、これを機にぜひ一度試してみてください!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK