マニピュレータの双方向遠隔制御システムを作成し、マスターおよびスレーブに関してlevel2 s-functionでカルマンフィルタを構築したのですが、連続時間で正常に作動するところ、Dworkベクトルを用いて離散時間で作動させると、入出力の要素が一致しないエラーが出るため、その解決方法をご教示いただけないでしょうか?
18 views (last 30 days)
Show older comments
function KF_Master(block)
setup(block);
function setup(block)
block.NumDialogPrms = 3; %ダイアログボックスに入力されたパラメータを取得(ダイアログパラメータ数)
% Settings for Input Port
block.NumInputPorts = 2; %ブロックの入力ポート番号
block.InputPort(1).Dimensions = 1; % Input(ブロックの入力ポート(1)は1次元)
block.InputPort(2).Dimensions = 2; % Observation data(ブロックの入力ポート(2)は2次元)
block.InputPort(1).DirectFeedthrough = false;
block.InputPort(2).DirectFeedthrough = false;
block.InputPort(1).SamplingMode ='Sample';
block.InputPort(2).SamplingMode ='Sample';
% Settings for Output Port
block.NumOutputPorts = 1; %ブロックの出力ポート番号
block.OutputPort(1).Dimensions = 10; %ブロックの出力ポート(1)は10次元
block.OutputPort(1).SamplingMode ='Sample';
% Setup functional port properties to dynamically
% inherited
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
% Settings for Sampling Time
block.SampleTimes = [0.001 0]; %ブロックが出力を生成するサンプリング時間とオフセット時間の設定(サンプルは連続でオフセットなし)
% Resistration of Callback Functions %コールバック関数の登録(ブロックコールバックメソッドを登録)
block.RegBlockMethod('PostPropagationSetup',@DoPostPropSetup);
block.RegBlockMethod('InitializeConditions', @InitializeConditions); %状態変数の初期化
block.RegBlockMethod('Outputs', @Outputs); %出力計算ルーチンの登録
block.RegBlockMethod('Derivatives', @Derivatives); %連続微係数の計算ルーチンの登録
function DoPostPropSetup(block)
%%Setup Dwork
block.NumDworks = 10;
% 推定値[3 1]と共分散行列[3 3]を連立する
% Estimation(推定値)
block.Dwork(1).Name = 'x';
block.Dwork(1).Dimensions = 1;
block.Dwork(1).DatatypeID = 0;
block.Dwork(1).Complexity = 'Real';
block.Dwork(1).UseAsDiscState = true;
block.Dwork(2).Name = 'dotx';
block.Dwork(2).Dimensions = 1;
block.Dwork(2).DatatypeID = 0;
block.Dwork(2).Complexity = 'Real';
block.Dwork(2).UseAsDiscState = true;
% Covariance(共分散)
block.Dwork(3).Name = 'p1';
block.Dwork(3).Dimensions = 1;
block.Dwork(3).DatatypeID = 0;
block.Dwork(3).Complexity = 'Real';
block.Dwork(3).UseAsDiscState = true;
block.Dwork(4).Name = 'p2';
block.Dwork(4).Dimensions = 1;
block.Dwork(4).DatatypeID = 0;
block.Dwork(4).Complexity = 'Real';
block.Dwork(4).UseAsDiscState = true;
block.Dwork(5).Name = 'p3';
block.Dwork(5).Dimensions = 1;
block.Dwork(5).DatatypeID = 0;
block.Dwork(5).Complexity = 'Real';
block.Dwork(5).UseAsDiscState = true;
%block.Dwork(6).Data(6) = 0.0; % p4
block.Dwork(6).Name = 'p4';
block.Dwork(6).Dimensions = 1;
block.Dwork(6).DatatypeID = 0;
block.Dwork(6).Complexity = 'Real';
block.Dwork(6).UseAsDiscState = true;
% Autocovariance(自己共分散)
block.Dwork(7).Name = 'pi1';
block.Dwork(7).Dimensions = 1;
block.Dwork(7).DatatypeID = 0;
block.Dwork(7).Complexity = 'Real';
block.Dwork(7).UseAsDiscState = true;
block.Dwork(8).Name = 'pi2';
block.Dwork(8).Dimensions = 1;
block.Dwork(8).DatatypeID = 0;
block.Dwork(8).Complexity = 'Real';
block.Dwork(8).UseAsDiscState = true;
block.Dwork(9).Name = 'pi3';
block.Dwork(9).Dimensions = 1;
block.Dwork(9).DatatypeID = 0;
block.Dwork(9).Complexity = 'Real';
block.Dwork(9).UseAsDiscState = true;
block.Dwork(10).Name = 'pi4';
block.Dwork(10).Dimensions = 1;
block.Dwork(10).DatatypeID = 0;
block.Dwork(10).Complexity = 'Real';
block.Dwork(10).UseAsDiscState = true;
function InitializeConditions(block) %状態変数の初期値設定(状態量ベクトルの初期化)
block.Dwork.Data(1) = 0.0;
block.Dwork.Data(2) = 0.0;
block.Dwork.Data(3) = 0.0;
block.Dwork.Data(4) = 0.0;
block.Dwork.Data(5) = 0.0;
block.Dwork.Data(6) = 0.0;
block.Dwork.Data(7) = 0.1;
block.Dwork.Data(8) = 0.0;
block.Dwork.Data(9) = 0.0;
block.Dwork.Data(10) = 0.1;
function Outputs(block) %ブロックの出力を計算
block.OutputPort(1).Data = block.Dworks.Data;
function Derivatives(block) %ブロックの連続状態の微分係数を取得
% Time Update
% State Estimate
% \hat{x}_m{k|k-1} = A_m*\hat{x_m{k-1|k-1}} + B_m*u_m{k-1}
% Covariance
% P_m{k|k-1} = A_m*P_m{k-1|k-1}*A_m' + G_m*Q_m{k-1}*G_m
%
% Observation Update
% State Estimate
% \hat{x}_m{k|k} = \hat{x}_m{k|k-1} + K_m*{y_m{k} - H_m*\hat{x}_m{k|k-1}}
% Kalman Gain
% K_m = P_m{k|k-1}*H_m'[H_mP_m{k|k-1}H_m' + R_m]^{-1}
% Covariance
% P_m{k|k} = {I - K_m*H_m}*P_m{k|k-1}
%
% Dialog Parameters %ダイアログボックスに入力されたパラメータを取得
Sys = block.DialogPrm(1).Data; %系
Obs = block.DialogPrm(2).Data; %観測値
Cov = block.DialogPrm(3).Data; %共分散
% Input Data %ブロックの入力ポートを取得
u = block.InputPort(1).Data;
dy = block.InputPort(2).Data;
% Estimation values
xhat = [block.Dwork(1).Data;block.Dwork(2).Data]; %推定値
% Autocovariance(自己共分散)
Pi = [block.Dwork(7).Data block.Dwork(8).Data;
block.Dwork(9).Data block.Dwork(10).Data];
% Covariance(共分散)
P = [block.Dwork(3).Data block.Dwork(4).Data;
block.Dwork(5).Data block.Dwork(6).Data];
% To Guarantee the symmetry(対称性保証)
P = (P + P.') ./ 2;
% Kalman Gain
Km_part = Pi*Obs.Cm.'*(Obs.Cm*Pi*Obs.Cm.' + Cov.Rm);
% Estimation(推定)
dxhat = Sys.Am*xhat + Sys.Bm*u + Pi*Obs.Cm.'*inv(Km_part)*(dy-Obs.Cm*xhat);
% Covariance(共分散)
dP = (eye(size((Km_part)*Obs.Cm),'like',(Km_part)*Obs.Cm)-(Km_part)*Obs.Cm)*P;
% Autocovariance
if (dy == 0)
dPi = Sys.Am*Pi*Sys.Am.' +Sys.Bm*(Kmp-1)*(u*u.')*(Kmp-1).'*Sys.Bm.'+ Sys.Gm*Cov.Qsm*Sys.Gm.';
else
dPi = Sys.Am*Pi*Sys.Am.' + Sys.Gm*Cov.Qsm*Sys.Gm.';
end
% Estimation
block.Derivatives.Data = [dxhat;reshape(dP,4,1);reshape(dPi,4,1)];
0 Comments
Answers (0)
See Also
Categories
Find more on データ分布プロット in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!