MATLAB/Simulinkでルートレベルの入力ポートへMATLABのスクリプトから入力を与える話
はじめに
若干マニアックな話ですが、MATLABスクリプトでSimulinkモデルの入力信号を生成して、シミュレーション結果を得たい場合があります。あまり良くある使い方ではないのかあまりわかりやすい例がなく、苦労したので書いてみます。この例はMATLAB R2020bで動作確認しています。
Simulinkモデルの読み込み
まず始めに、シミュレーションに使うSimulinkモデルを読み込みます。今回はARCH-COMPのベンチマークの中の、オートマチックトランスミッションコントローラーのモデル (以下 ATモデル) を使います。
mdl = 'Autotrans_shift';
load_system(mdl);
入力信号の定義
次にATモデルへ与える入力信号を定義します。ATモデルの入力はスロットルとブレーキの二次元信号です。
今回作る信号は制御点が3つで、サンプル間の時間は10.0秒で等間隔の信号とします。
numberOfSamples = 3;
signalStep = 10.0;
timeVector = (0:(numberOfSamples-1)) * signalStep;
入力値は以下の様に、最初はブレーキが最大で次にスロットルが最大の信号とします。
throttleValues = [0, 100, 100];
brakeValues = [325, 0, 0];
これらの値を元にtimeseries
オブジェクトを定義します。
throttleInput = timeseries(throttleValues, timeVector);
brakeInput = timeseries(brakeValues, timeVector);
上記のtimeseriesを組み合わせてSimulink.SimulationData.DataSet
を作ります。
ds = Simulink.SimulationData.Dataset;
ds = ds.addElement(throttleInput, 'throttle');
ds = ds.addElement(brakeInput, 'brake');
Simulinkに定義した信号をExternalInputとして与えます。
set_param(mdl, 'LoadExternalInput', 'on');
set_param(mdl, 'ExternalInput', 'ds');
シミュレーションの実行
信号を定義したので、シミュレーションを実行します。
実行時間を30秒と設定します。
in = Simulink.SimulationInput(mdl);
in = in.setModelParameter('StopTime', '30.0');
実行結果の保存方法について設定を行い、シミュレーションを実行します。
in = in.setModelParameter('SaveOutput', 'on');
in = in.setModelParameter('OutputSaveName', 'yout');
in = in.setModelParameter('SaveTime', 'on');
simOut = sim(in);
実行結果のプロットは以下の様に行います。
plot(simOut.tout, simOut.yout(:, 1));
結果
シミュレーションの結果をプロットすると以下の様になります。
入力信号をちょっと変えて、最初からアクセルをかける様にすると次の様になります。出力信号が変化したのがわかると思います。
例の全体像
最後に今回の例の全体像は以下の様になります。
%% AT modelを読み込む
mdl = 'Autotrans_shift';
load_system(mdl);
%% 入力信号を定義する
numberOfSamples = 3;
signalStep = 10.0;
timeVector = (0:(numberOfSamples-1)) * signalStep;
throttleValues = [0, 100, 100];
brakeValues = [325, 0, 0];
throttleInput = timeseries(throttleValues, timeVector);
brakeInput = timeseries(brakeValues, timeVector);
ds = Simulink.SimulationData.Dataset;
ds = ds.addElement(throttleInput, 'throttle');
ds = ds.addElement(brakeInput, 'brake');
set_param(mdl, 'LoadExternalInput', 'on');
set_param(mdl, 'ExternalInput', 'ds');
%% シミュレーションを実行する
in = Simulink.SimulationInput(mdl);
in = in.setModelParameter('StopTime', '30.0');
in = in.setModelParameter('SaveOutput', 'on');
in = in.setModelParameter('OutputSaveName', 'yout');
in = in.setModelParameter('SaveTime', 'on');
simOut = sim(in);
plot(simOut.tout, simOut.yout(:, 1));