Simulink7.3 (R2009a)以降のバージョンでは、分割シミュレーションに利用できるSimState 機能が搭載されています。
SimState にはStateflow のチャートブロックの状態やTransport Delay ブロックの遅延情報も保存されているので、R2008b以前のバージョンよりも簡単に分割シミュレーションができます。
以下の二つの方法を紹介します。
1. コンフィギュレーションパラメータによる方法
2. コマンドによる方法
1. コンフィギュレーションパラメータによる方法
mymodel_r2009b.mdlを用いて、シミュレーション時間を0~5秒、5~10秒の2回に分けて継続シミュレーションします。
mymodel_r2009b.mdl は、下部のリンクよりダウンロードできます。
1-1) 1回目のシミュレーション(0~5秒)
はじめに、各ブロックに設定された初期条件の下でシミュレーションします。ここで、時間、信号、および最終状態を出力するように設定しておきます。
[シミュレーション] -> [コンフィギュレーションパラメータ] を選択し、以下のように設定します(以下、Ts = 0.5 とします)。
・[ソルバ]
・[データのインポート/エクスポート]
SimStateを使用するには、上図のように、'最終状態のすべてのSimStateを保存'にチェックを入れます。
シミュレーションを実行すると、tout1、yout1に1回目のシミュレーション結果が出力されます。また、最終状態量が xFinal1 に出力されます。
1-2) 2回目のシミュレーション(5~10秒)
1 回目のシミュレーションで得られた最終状態を2 回目のシミュレーションの初期状態として用いることで、継続シミュレーションができます。
シミュレーションパラメータを次のように変更します。
・[ソルバ]
・[データのインポート/エクスポート]
シミュレーションを実行すると、tout2、yout2に2回目のシミュレーション結果が出力されます。
1-3) 結果の結合
1 回目のシミュレーションの最終要素(最終ステップの値)と 2 回目のシミュレーション結果の最初の要素(初期ステップの値)は等しいので、この重複部分を削除してからデータを結合します。結合データをプロットすると、シミュレーション時間を 0~10 秒に設定したときと同じ結果が得られていることを確認できます。
tout1(end) = []; yout1(end) = [];
t_total = [tout1;tout2]; y_total = [yout1;yout2];
stairs(t_total,y_total), grid on
以上の方法で、総シミュレーション時間を分割した逐次シミュレーションが可能となります。
この方法は、シミュレーション時間が非常に長くかかるモデルに対して有効です。
2. コマンドによる方法
SIM 関数を利用すると、シミュレーション時間の分割・最終状態を効率的に継続できます。
以下に示す MATLAB プログラム suceeded_sim.m は、mymodel.mdl に対して総シミュレーション時間を 5 分割する例です。
分割シミュレーションの結果は、総シミュレーション時間をそのまま用いた一括シミュレーションと同じであることが確認できます。
suceeded_sim.m は、下部のリンクからダウンロードできます。
clear variables
clc
mdl = 'mymodel_r2009b';
open(mdl)
Ts = 0.5;
t_start = 0; t_stop = 10;
N = 5; t_div = (t_stop-t_start)/5;
tspan1 = [t_start t_stop];
[t1,x1,y1] = sim(mdl,tspan1);
t_total = []; y_total = [];
opts = simget(mdl);
opts = simset(opts,'OutputVariables','txy');
set_param(mdl, 'SaveFinalState', 'on', 'FinalStateName', [mdl '_SimState'],'SaveCompleteFinalSimState', 'on')
for n = 1:N
tspan2 = t_start + [(n-1)*t_div n*t_div];
[t2,x2,y2] = sim(mdl, tspan2(2),opts);
set_param(mdl, 'LoadInitialState', 'on', 'InitialState',[mdl '_SimState']);
if n ~= N
t2(end) = []; y2(end) = [];
end
t_total = [t_total;t2]; y_total = [y_total;y2];
end
hold on
stairs(t1,y1), stairs(t_total,y_total,'r')
hold off
legend('一括','分割'), grid on