設計ケーススタディ | ![]() ![]() |
定常状態の設計
関数kalman
を用いて、上記の定常状態Kalmanフィルタを設計することができます。まず、つぎのプロセスノイズをもつプラントモデルを設定します。
% 注意:サンプル時間を-1に設定することにより、モデルが離散系であることを示す。 Plant = ss(A,[B B],C,0,-1,'inputname',{'u' 'w'},... 'outputname','y');
と仮定すると、以下の方法で離散Kalmanフィルタを設計することができます。
Q = 1; R = 1; [kalmf,L,P,M] = kalman(Plant,Q,R);
これは、フィルタの状態空間モデルkalmf
とイノベーションゲインM
を出力します。
M M = 3.7980e-01 8.1732e-02 -2.5704e-01
kalmf
の入力は、および
で、その出力は、プラント出力、および、つぎの状態推定値です(
と
)。
ここで、関心があるのは出力推定値なので、つぎの
kalmf
の第1出力のみを抜き出します。
kalmf = kalmf(1,:);MATLABは、つぎの出力を行います。
kalmf a = x1_e x2_e x3_e x1_e 0.76830 -0.49400 0.11290 x2_e 0.62020 0 0 x3_e -0.08173 1.00000 0 b = u y x1_e -0.38320 0.35860 x2_e 0.59190 0.37980 x3_e 0.51910 0.08173 c = x1_e x2_e x3_e y_e 0.62020 0 0 d = u y y_e 0 0.37980 Sampling time: unspecified Discrete-time system.
フィルタが、どのように機能するかを見るためには、何らかの入力データとランダムノイズを生成し、フィルタを適用した応答と真の応答
を比較します。それぞれの応答は、別々に生成することも、同時に生成することもできます。それぞれの応答を別々にシミュレーションするには、まずプラントだけで
lsim
を使用し、ついでプラントとフィルタを一緒にして、lsimを使用します。両者を同時にシミュレーションする、もう1つの方法については、つぎに説明します。
下のブロックダイアグラムは、真の出力とフィルタを適用した出力を生成する方法を示したものです。
このブロックダイアグラムの状態空間モデルは、関数parallel
とfeedback
を用いて設計することができます。まず、を入力とし、
と
(測定値)を出力とする完全なプラントモデルを作成します。
a = A; b = [B B 0*B]; c = [C;C]; d = [0 0 0;0 0 1]; P = ss(a,b,c,d,-1,'inputname',{'u' 'w' 'v'},... 'outputname',{'y' 'yv'});
つぎに、parallel
を用いて、つぎの並列結合を作成します。
sys = parallel(P,kalmf,1,1,[],[])
最後に、プラント出力を正のフィードバックで、フィルタ入力
に結合することによってセンサループを閉じます。
% 入力#4と出力#2に関してループを閉じる SimModel = feedback(sys,1,4,2,1) % I/Oリストからyvを削除する SimModel = SimModel([1 3],[1 2 3])
結果として得られるシミュレーションモデルは、を入力とし、
を出力とします。
SimModel.input ans = 'w' 'v' 'u' SimModel.output ans = 'y' 'y_e'
これで、フィルタの挙動をシミュレーションする準備ができました。正弦波入力、プロセスノイズベクトル
、測定ノイズベクトル
を生成します。
t = [0:100]'; u = sin(t/5); n = length(t) randn('seed',0) w = sqrt(Q)*randn(n,1); v = sqrt(R)*randn(n,1);
[out,x] = lsim(SimModel,[w,v,u]); y = out(:,1); % 真の応答 ye = out(:,2); % フィルタを適用した応答 yv = y + v; % 観測した応答
また、真の応答とフィルタを適用した応答をグラフ上で比較します。
subplot(211), plot(t,y,'--',t,ye,'-'), xlabel('No. of samples'), ylabel('Output') subplot(212), plot(t,y-yv,'-.',t,y-ye,'-'), xlabel('No. of samples'), ylabel('Error')
![]()
最初のプロットは、真の応答(破線)とフィルタを適用した出力
(実線)を示しています。第2のプロットは、測定誤差(鎖線と点)と推定誤差(実線)を比較しています。このプロットは、ノイズレベルが著しく減少したことを示しています。これは、つぎの誤差共分散の計算で確認されます。
MeasErr = y-yv; MeasErrCov = sum(MeasErr.*MeasErr)/length(MeasErr); EstErr = y-ye; EstErrCov = sum(EstErr.*EstErr)/length(EstErr);
フィルタ処理を行う前の誤差共分散(測定誤差)は、つぎのとおりです。
MeasErrCov MeasErrCov = 1.1138
一方、フィルタ処理を行った後の誤差共分散(推定誤差)は、つぎのとおりです。
EstErrCov EstErrCov = 0.2722
![]() | 離散Kalmanフィルタ | 時変Kalmanフィルタ | ![]() |