MATLAB,SIMULINKによる制御問題のシミュレーション
SIMULINK3になってからSIMULINKの出力形式が、構造体形式に変更になった。ここでは、構造体形式を例に
プログラミング言語であるMATLABと、制御用シミュレーションソフトウェアSIMULINKを比較し、実例を示しながら双方でのシ ミュレーションの仕方について解説していく。
伝達関数のシミュレーション
ここでは、のローパスフィルタを例に解説をしていく。
SIMUILNKでこのローパスフィルタのシミュレーションをするには、
のようなブロックを作成する。各種パラメータの設定は以下の通りである。
Signal Generatorの中は、
Transfer Fcnの中は、
なおDenominatorは、伝達関数の分母の係数を表し
conv([1 1],conv([1 1],conv([1 1],conv([1 1],conv([1 1],[1
1])))))
とする。この計算で(s+1)6の係数が計算できる。
Muxブロックは、
この設定でシミュレーションのスタートを選択、Scopeをダブルクリックでオープンすればよい。
MATLABへのデータの転送
SIMULINKのデータをMATLABのワークスペース上に持ってきてMATLAB変数として使えるとグラフを書いたり、データ処理したりできる。そのような場合には、
To Workspace ブロックを用いる。
To Workspaceの設定は上のようにする。この場合、simoutと言う変数名の構造体に時間データや応答データが保存される。ちなみにシミュレーションが終わった後でMATLABコマンドウィンドウで
》 simout
simout =
time: []
signals: [1x1 struct]
blockName: 'untitled/To Workspace'
》
と言うように出てくる。simout変数は、構造体で保存されておりこの場合には、simout.signalsの中にデータが格納されている。つまり
》
simout.signals
ans =
values: [53x2 double]
label: ''
要するに、simout.signals.values(:,1),simout.signals.values(:,2)に値が格納されている。この場合、simout.signals.values(:,1)には、伝達関数の応答出力,simout.signals.values(:,2)には、入力信号が出力される。
また、whosとするとわかるが、SIMULINKでシミュレーションをするとsimout以外に、tout変数も出力される。これは、シミュレーション時間を示している。
よってこれらを使いMATLAB上でシミュレーション結果をプロットするには、
》 plot(tout,simout.signals.values)
とすればよい。
MATLABから入力信号をSIMUINKに与えるには、From Workspaceを用いる。
この場合、サンプリング時間を0.01secとして
simin構造体にtime変数、signals.values変数を追加し値を代入する。
》 simin.time=(0:0.01:10)';
》 simin.signals.values=sin(simin.time*1);
この時、timeは、列ベクトルにする必要があるので注意すること。
としてシミュレーションをスタートする。
出来たらsimout変数にシミュレーション結果が格納されているので
plot(tout,simout.signals.values)
とすれば表示される。
わざわざSIMULINKのメニューからスタートを選択しなくてもMATLAB上からSIMULINKのmdlファイルを呼び出すことも可能である。
》 simin.time=(0:0.01:10)';
》 simin.signals.values=sin(simin.time*1);
》 sim('simlow',simin.time);
》 plot(tout,simout.signals.values)
とすればよい。
このシミュレーションでは、10秒間のシミュレーションであるが、1ステップごとのシミュレーションも可能である。この場合には、SIMULINKモデルを若干書き換える必要がある。基本的には、サンプリング時間、データ点数の個所である。
つまり
である。
UU=[ ];YY=[ ];TT=[ ];
T=0.01;
simoptions=simget('simlow');
simoptions.Solver='ode5';
simoptions.FixedStep=T;
simoptions.MaxRows=1;
for i=0:0.01:10
simin.time=i;UU=[UU i];
simin.signals.values=sin(i);
sim('simlow',simin.time);
YY=[YY; simout.signals.values];
end
plot(YY)
SIMULINKは、元来、制御系の
SIMULINK
[num den]=c2dm([-7.49 0.39],[0.0256 0.448 2.4+0.0256*wc^2 4+0.448*wc^2 0.02+2.4*wc^2 4*wc^2],0.01);
より離散伝達関数を求める。
求められた離散伝達関数は、
printsys(num,den);
num/den =
-1.1771e-007 z^4 - 1.1326e-006 z^3 + 4.3781e-008 z^2 + 1.1019e-006 z + 1.06e-007
--------------------------------------------------------------------
z^5 - 4.8305 z^4 + 9.3313 z^3 - 9.0104 z^2 + 4.3491 z - 0.83946
となった。
つまり
function y=smpfil(u)
persistent preu
persistent prey
if(isempty(preu)) preu=[0;0;0;0;0;u];end
if(isempty(prey)) prey=[0;0;0;0;0;0];end
[num den]=c2dm([-7.49 0.39],[0.0256 0.448 2.4+0.0256*wc^2 4+0.448*wc^2 0.02+2.4*wc^2 4*wc^2],0.01);
y = (num(1)*preu(5)+num(2)*preu(4)+num(3)*preu(3)+num(4)*preu(2)+num(5)*preu(1)+...
(-prey(5)*den(2)-prey(4)*den(3)-prey(3)*den(4)-prey(2)*den(5)-prey(1)*den(6))/den(1);
preu = [0 1 0 0 0;0 0 1 0 0;0 0 0 1 0;0 0 0 0 1;0 0 0 0 0]*preu;
prey = [0 1 0 0 0;0 0 1 0 0;0 0 0 1 0;0 0 0 0 1;0 0 0 0 0]*prey;
preu(5)=u;
prey(5)=y;
[num den]=c2dm(1,[1 1],0.01)
》 printsys(num,den,'z')
num/den =
0.0099502
-----------
z - 0.99005
function y=smpfil(u)
persistent preu
persistent prey
if(isempty(preu)) preu=u;end
if(isempty(prey)) prey=0;end
[num den]=c2dm([1],[1 1],0.01);
y = (-prey*den(2)+u*num(1)+preu*num(2))/den(1);
preu = u;
prey = y;
となる。