マニピュレータの双方​向遠隔制御システムを​作成し、マスターおよ​びスレーブに関してl​evel2 s-function​でカルマンフィルタを​構築したのですが、連​続時間で正常に作動す​るところ、Dwork​ベクトルを用いて離散​時間で作動させると、​入出力の要素が一致し​ないエラーが出るため​、その解決方法をご教​示いただけないでしょ​うか?

18 ビュー (過去 30 日間)
Yuichi Sawada
Yuichi Sawada 2023 年 9 月 8 日
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 件)

カテゴリ

Help Center および File Exchangeデータ分布プロット についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!