一维角度跟踪的kalman算法(C语言+matlab)
1 matlab
% ---------机载卫通角度自跟踪研究
% 1、目标捕获。 目的:获得目标大致的俯仰角theta0
% 2、单脉冲测角。目的:获得目标精准的俯仰角thetas
% 3、卡尔曼滤波。目的:获得滤波后的角度thetas_est
close all;
clear all;
clc;
%----------------参数设置
% 主函数相关参数
T=1; % 滤波周期
M=100; % 仿真步数
% 目标捕获函数相关参数
c=3e8; % 光速
f=3e9; % 信号频率
fs=20*f; % 采样频率
N=8; % 阵元个数
bujing=1; % 扫描步进
count=6000; % 采样点数
SNR=-20; % 信噪比
% 单脉冲测角相关参数
bujing1=1; % 扫描步进
SNR1=-20; % 信噪比
count1=3000;
thetak=0.5*(100/N);% 子波束与跟踪轴的夹角
% 卡尔曼滤波函数相关参数
% TT=[T*T/2,0,0;T,0,0;0,T*T/2,0;0,T,0;0,0,T*T/2;0,0,T]; %状态噪声的输入矩阵(XYZ)
TT=[T*T/2,0;T,0;0,T*T/2;0,T]; % 状态噪声的输入矩阵(XY)
Q1=0.1*eye(2); % 两个方向的伪加速度
Q=TT*Q1*TT'; % 系统状态噪声的方差 因为目标的状态在变化,所以不可以精确建模,故有状态噪声
% Q=10*eye(4) ; % 系统状态噪声的方差 因为目标的状态在变化,所以不可以精确建模,故有状态噪声
Error_est =10; % 测量误差的方差;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 设定目标运动轨迹
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X=[]; % 目标水平方向的真实位置、速度;垂直方向的的真实位置
r=[]; % 目标与原点的距离
X0 = 2000;
Y0 = 5000;
Vx = 300;
Vy = 200;
Y(:,1)=[X0,Vx,Y0,Vy]; % 目标初始位置为(100,100)、初始速度为(200,100) x,vx,y,vy
F=[1,T,0,0;0,1,0,0;0,0,1,T;0,0,0,1];% 状态转移矩阵
w=sqrt(Q)*randn(4,M); % 在匀速运动轨迹上叠加噪声
for p=2:M
Y(:,p)=F*Y(:,p-1)+w(:,p); % 目标运动轨迹方程
% Y(:,p)=F*Y(:,p-1); % 目标运动轨迹方程
r(p)=sqrt(Y(1,p)^2+Y(3,p)^2);
theta_true(p)=acos(Y(3,p)/r(p))*180/pi;
end
% 循环从2开始,所以需要下面两行代码
r(1)=sqrt(Y(1,1)^2+Y(3,1)^2);
theta_true(1)=acos(Y(3,1)/r(1))*180/pi; % 将位置换成角度
% figure(1)
% plot(Y(1,:),Y(3,:)); grid on;
% xlabel('X坐标/m');ylabel('Y坐标/m');
% % title('目标的运动轨迹');
% figure(2)
% plot(theta_true); grid on;
% xlabel('迭代次数');ylabel('角度');
% % title('目标角度的运动轨迹');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 第零次迭代
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%------------初始化 初始值越接近于真值,则收敛越快
% X_pre=[sind(theta_true(1)),cosd(theta_true(1)),cosd(theta_true(1)),-sind(theta_true(1))]'; % 飞机初始位置和速度 相当于X(0,0)
% X_est=[sind(theta_true(1)),(sind(theta_true(2))-sind(theta_true(1)))/T,cosd(theta_true(1)),(cosd(theta_true(2))-cosd(theta_true(1)))/T]';
% P_pre=1e-2*eye(4); % 状态误差自相关矩阵的估计值的初始值 相当于P(0,0)
%------------预测
% X_pre=F*X_est; % 预测下一时刻飞机的位置和速度 相当于X(1,0)
% X_pre=X_est; % 预测下一时刻飞机的位置和速度 相当于X(1,0)
% P_pre=P_est; % 状态误差自相关矩阵预测方程。相当于P(1,0)
%%%%%%%%测量值%%%%%%%%%%%%%%%%%
% theta0 = theta_true + sqrt(Error_est)*randn(1,M); % 第一次的测量值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 函数功能:测量目标大致角度
% 调用函数: 目标捕获
% 输入参数: 目标运动轨迹角度theta_ture
% 输出参数: 粗捕获得到的目标大致角度theta0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
theta0=target_get(theta_true(1),c,f,fs,N,bujing,count,SNR);% 跟踪轴角度 每次搜索更新跟踪轴角度
for p=1:M
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 调用函数:单脉冲测角
% 输入参数:跟踪轴角度theta0,目标偏离跟踪轴的角度thetat
% 输出参数:单脉冲测角得到的目标真实角度thetas
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (p==1)
thetat(p)=theta_true(p)-theta0; % 用粗捕获的角度作为跟踪轴
thetas(p)=dmc_angle_esti(theta0,thetat(p),c,f,fs,N,bujing1,count1,SNR1,thetak);% 调用单脉冲测角函数
else
thetat(p)=theta_true(p)-thetas(p-1); % 用上一次的单脉冲测角角度作为跟踪轴
thetas(p)=dmc_angle_esti(thetas(p-1),thetat(p),c,f,fs,N,bujing1,count1,SNR1,thetak);% 调用单脉冲测角函数
end
end
% 5次
% thetas=[21.5076548036461,23.9035640695852,25.2549934363390,26.9359550143116,28.8976558818146];
% 100次
thetas=[21.5076548036461,23.9035640695852,25.2549934363390,26.9359550143116,28.8976558818146,31.0009336978619,30.8565778509341,32.3050100914770,34.1862053875184,34.6904798952295,35.6555170269539,36.8713678226845,37.1700434897918,37.8389043614815,37.8665872036294,39.7945125094379,39.6106898841655,40.4003792934401,41.4180428538889,41.4790716187582,41.9403468544136,42.9627346703708,42.8729673509037,43.4776654550822,43.7688342799448,43.1743927104658,44.2316718831226,44.4622411398221,44.4357070013545,45.3733188602618,45.5381975917392,46.5509298322948,45.6779847577037,47.1478396968443,46.2527226765848,46.3331447782597,47.4674626156377,45.8765540678496,47.1034394976255,46.8513567531198,48.6420380019551,48.8216730355858,48.0296108609148,48.3289066445719,49.1132668391982,48.0066000039878,48.7820375861355,48.6914931956388,48.6337594800962,48.6157152073843,49.4954097429769,49.9225918920769,49.2825002645643,49.5208738839231,50.2002660345929,49.5801729922124,50.9578089119918,48.6497288186680,50.2503630361635,49.4157770529638,50.6370793324727,50.9491032882535,51.2537774460507,51.3993217927973,49.6599949628813,50.1393171940319,51.0485148999235,51.2377563456300,51.3944425778218,50.3739007440455,51.3243416853895,51.1267954929477,51.0013308184272,50.8653367318906,52.7125778551996,51.3631307431436,51.5294521250658,52.0227598624784,51.5894953246860,51.7960221122716,50.7512572053516,51.4269769710341,52.1261355228410,51.3940536344455,51.3188234648857,52.3363148397478,52.3472901324124,51.3844978167153,51.6115223790734,52.5232396047085,53.1894031569837,53.3431758996074,54.2913611442235,52.8017240930785,51.7148643527885,51.6888832902782,52.5546540827346,52.7532214510904,53.6832072070126,53.7407670804744];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 第零次迭代
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%------------初始化 初始值越接近于真值,则收敛越快
X_pre=[sind(thetas(1)),cosd(thetas(1)),cosd(thetas(1)),-sind(thetas(1))]'; % 飞机初始位置和速度 相当于X(0,0)
P_pre=1e-2*eye(4); % 状态误差自相关矩阵的估计值的初始值 相当于P(0,0)
%------------预测
% X_pre=F*X_est; % 预测下一时刻飞机的位置和速度 相当于X(1,0)
% X_pre=X_est; % 预测下一时刻飞机的位置和速度 相当于X(1,0)
% P_pre=P_est; % 状态误差自相关矩阵预测方程。相当于P(1,0)
for p=1:M
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 函数功能:卡尔曼滤波 更新估计、预测
% 输入参数:状态预测值,估计误差预测值,目标捕获得到的角度,状态转移矩阵,状态噪声方差,测量噪声方差
% 输出参数:卡尔曼滤波的角度thetas_est,下一时刻的预测值,估计误差的预测值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[X_est(:,p),X_pre,P_pre] = KEM_tracking( X_pre,P_pre,thetas(p),F,Q,Error_est);
% theta_est(p) = atand(X_est(1,p)/X_est(3,p));
theta_est(p) = acos(X_est(3,p)/( sqrt( X_est(1,p)*X_est(1,p)+X_est(3,p)*X_est(3,p)) ))*180.0/pi;
% if (X_est(3,p)>1)% 如果角度的余弦值大于1,将估计角度固定为90度
% theta_est(p)=90;
% else
% theta_est(p) = acosd(X_est(3,p));
% end
end
for p=1:length(thetas) % 最后20次结果
fprintf('thetas[%g] is %g\n',p-1,thetas(p));
fprintf('theta_KEM[%g] is %g\n',p-1,theta_est(p));
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 滤波平均角度误差计算
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% error=0;
% for p=1:50 % 最后20次结果
% error=error+abs(theta_est(M-50+p)-theta_true(M-50+p));
% end
% fprintf('滤波平均角度误差为%g\n',error/50);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 绘图
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% figure(3)
% plot(theta_true,'-r');hold on; % 目标真实轨迹的真实角度
% plot(thetas,'-bo');hold on; % 单脉冲测角得到的角度
% plot(theta_est,'-k*');grid on; % 卡尔曼滤波得到的目标角度
% legend('目标真实角度','单脉冲测角得到的角度','卡尔曼估计的角度');
% xlabel('跟踪步数');ylabel('角度/度');
% figure(4)
% plot(thetas-theta_true,'-bo');hold on; % 单脉冲测角得到的目标角度误差
% plot(theta_est-theta_true,'-k*');grid on; % 卡尔曼估计的角度误差
% legend('单脉冲测角得到的角度误差','卡尔曼估计的角度误差');
% xlabel('跟踪步数');ylabel('角度/度');
function [X_est,X_pre,P_pre] = KEM_tracking(X_pre,P_pre,theta_m,F,Q,Error_est)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 函数功能:卡尔曼滤波 更新估计、预测
% 输入参数:状态预测值,估计误差预测值,目标捕获得到的角度,状态转移矩阵,状态噪声方差,测量噪声方差
% 输出参数:卡尔曼滤波的角度thetas_est,下一时刻的预测值,估计误差的预测值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 观测方程的系数矩阵
H=[1,0,0,0;0,0,1,0];
% 观测值
Z=[sind(theta_m) cosd(theta_m)]';
% fprintf('Z(1)=%g\n',Z(1));
% fprintf('Z(2)=%g\n',Z(2));
%测量误差
% T = [cosd(theta_true) -sind(theta_true)]';
% R = T*[Error_est]*T';
R =Error_est*eye(2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 开始迭代过程(第一次迭代等等)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for p=1:length(X_pre)
% fprintf('X_pre[%g] is %g\n',p,X_pre(p,1));
% end
% 更新
a=Z -H*X_pre; % 新息计算
% fprintf('a(1)=%g\n',a(1));
% fprintf('a(2)=%g\n',a(2));
A=H*P_pre*H'+R ; % 新息过程的自相关矩阵
% for p=1:2
% for q=1:2
% fprintf('A[%g][%g] is %g\n',p,q,A(p,q));
% end
% end
K=P_pre*H'*inv(A); % 计算卡尔曼增益
X_est=X_pre+K*a; % 状态估计
% 法一
% P_est=(eye(4)-K*H)*P_pre*(eye(4)-K*H)'+K*R*K'; % 估计误差自相关矩阵
% 法2
P_1=(eye(4)-K*H); %
P_1_est= P_1*P_pre; % P_1_est=(eye(4)-K*H)*P_pre = P_1*P_pre
P_2_L=K*R; %P_2_L=K*R
P_2 =P_2_L*K';% P_2=K*R*K'=P_2_L*K'
P_est=P_1_est*(P_1)'+P_2; % 估计误差自相关矩阵
% 预测
X_pre = F*X_est ; % 下一时刻状态的预测值 相当于X(n+1,n)
P_pre = F*P_est*F'+Q; % 预测状态误差自相关矩阵 相当于P(n+1,n)
end
2 C语言
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define PI 3.1415926
#define COUNT 100
int p;
int q;
int r;
int n;
double theta_m[COUNT]={21.5076548036461,23.9035640695852,25.2549934363390,26.9359550143116,28.8976558818146,31.0009336978619,30.8565778509341,32.3050100914770,34.1862053875184,34.6904798952295,35.6555170269539,36.8713678226845,37.1700434897918,37.8389043614815,37.8665872036294,39.7945125094379,39.6106898841655,40.4003792934401,41.4180428538889,41.4790716187582,41.9403468544136,42.9627346703708,42.8729673509037,43.4776654550822,43.7688342799448,43.1743927104658,44.2316718831226,44.4622411398221,44.4357070013545,45.3733188602618,45.5381975917392,46.5509298322948,45.6779847577037,47.1478396968443,46.2527226765848,46.3331447782597,47.4674626156377,45.8765540678496,47.1034394976255,46.8513567531198,48.6420380019551,48.8216730355858,48.0296108609148,48.3289066445719,49.1132668391982,48.0066000039878,48.7820375861355,48.6914931956388,48.6337594800962,48.6157152073843,49.4954097429769,49.9225918920769,49.2825002645643,49.5208738839231,50.2002660345929,49.5801729922124,50.9578089119918,48.6497288186680,50.2503630361635,49.4157770529638,50.6370793324727,50.9491032882535,51.2537774460507,51.3993217927973,49.6599949628813,50.1393171940319,51.0485148999235,51.2377563456300,51.3944425778218,50.3739007440455,51.3243416853895,51.1267954929477,51.0013308184272,50.8653367318906,52.7125778551996,51.3631307431436,51.5294521250658,52.0227598624784,51.5894953246860,51.7960221122716,50.7512572053516,51.4269769710341,52.1261355228410,51.3940536344455,51.3188234648857,52.3363148397478,52.3472901324124,51.3844978167153,51.6115223790734,52.5232396047085,53.1894031569837,53.3431758996074,54.2913611442235,52.8017240930785,51.7148643527885,51.6888832902782,52.5546540827346,52.7532214510904,53.6832072070126,53.7407670804744};
double thetas_KEM[COUNT]={0};
double X_pre[4][1]={{0},{0},{0},{0}};
double X_est[4][1]={{0},{0},{0},{0}};
double P_pre[4][4]={0};
double T=1;
double TT[4][2]={{T*T/2,0},{T,0},{0,T*T/2},{0,T}};
double TT_z[2][4]={ {T*T/2,T,0,0},{0,0,T*T/2,T} };
double Q1[2][2]={{0.1,0},{0,0.1}};
double Q_temp[4][2]={0};
double Q[4][4]={0};
double F[4][4]={{1,T,0,0},{0,1,0,0},{0,0,1,T},{0,0,0,1}};
double Error_est =10;
typedef struct
{
double X_est[4][1];
double X_pre[4][1];
double P_pre[4][4];
}KEM_struct;
KEM_struct KEM_back_parameter;
KEM_struct KEM_func(double X_pre[][1],double P_pre[][4],double thetam,double F[][4],double Q[][4],double Error_est);
int main()
{
printf("beign\r\n");
for (p=0;p<4;p++)
{
for (q=0;q<2;q++)
{
for (r=0;r<2;r++)
{
Q_temp[p][q]=Q_temp[p][q]+TT[p][r]*Q1[r][q] ;
}
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
for (r=0;r<2;r++)
{
Q[p][q]=Q[p][q]+Q_temp[p][r]*TT_z[r][q] ;
}
}
}
X_pre[0][0]=sin(theta_m[0]*PI/180);
X_pre[1][0]=cos(theta_m[0]*PI/180);
X_pre[2][0]=cos(theta_m[0]*PI/180);
X_pre[3][0]=-sin(theta_m[0]*PI/180);
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
if(p==q)
P_pre[p][q]=0.01;
else
P_pre[p][q]=0;
}
}
for (n=0;n<COUNT;n++)
{
KEM_back_parameter=KEM_func(X_pre,P_pre,theta_m[n],F,Q,Error_est);
for (p=0;p<4;p++)
{
X_est[p][0]=KEM_back_parameter.X_est[p][0] ;
X_pre[p][0]=KEM_back_parameter.X_pre[p][0] ;
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
P_pre[p][q]=KEM_back_parameter.P_pre[p][q] ;
}
}
thetas_KEM[n] = acos(X_est[2][0]/( sqrt( X_est[2][0]*X_est[2][0]+X_est[0][0]*X_est[0][0] ) ))*180.0/PI;
printf("thetas[%d] is %.4f\r\n",n,theta_m[n]);
printf("thetas_KEM[%d] is %.4f\r\n",n,thetas_KEM[n]);
}
return 0;
}
KEM_struct KEM_func(double X_pre[][1],double P_pre[][4],double thetam,double F[][4],double Q[][4],double Error_est)
{
double A1[2][4]={0};
double a[2][1]={0};
double A[2][2]={0};
double A_inv[2][2]={0};
double K[4][2]={0};
double K_z[2][4]={0};
double K1[4][2]={0};
double K_2L[4][2]={0};
double P_1[4][4]={0};
double P_1_est[4][4]={0};
double P_2_L[4][2]={0};
double P_2[4][4]={0};
double P_1_z[4][4]={0};
double P_est[4][4]={0};
double F_z[4][4]={0};
double F_P[4][4]={0};
for (p=0;p<2;p++)
{
for (q=0;q<2;q++)
{
A[p][q]=0;
A_inv[p][q]=0;
}
}
for (p=0;p<2;p++)
{
for (q=0;q<4;q++)
{
K_z[p][q]=0;
A1[p][q]=0;
}
}
for (p=0;p<4;p++)
{
for (q=0;q<2;q++)
{
K[p][q]=0;
K1[p][q]=0;
K_2L[p][q]=0;
P_2_L[p][q]=0;
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
P_1[p][q]=0;
P_1_est[p][q]=0;
P_2[p][q]=0;
P_1_z[p][q]=0;
P_est[p][q]=0;
F_z[p][q]=0;
F_P[p][q]=0;
}
}
double H[2][4]={ {1,0,0,0}, {0,0,1,0}};
double H_z[4][2]={ {1,0},{0,0},{0,1},{0,0} };
double Z[2][1]={{sin(thetam*PI/180.0)},{cos(thetam*PI/180.0)}};
double R[2][2] ={{Error_est,0},{0,Error_est}};
a[0][0]=Z[0][0] -H[0][0]*X_pre[0][0];
a[1][0]=Z[1][0] -H[1][2]*X_pre[2][0];
for (p=0;p<2;p++)
{
for (q=0;q<4;q++)
{
for(r=0;r<4;r++)
{
A1[p][q]=A1[p][q]+H[p][r]*P_pre[r][q];
}
}
}
for (p=0;p<2;p++)
{
for (q=0;q<2;q++)
{
for(r=0;r<4;r++)
{
A[p][q]=A[p][q]+A1[p][r]*H_z[r][q]+R[p][q]/4.0;
}
}
}
double A1_inv[2][2]={{A[1][1],-A[0][1]},{-A[1][0],A[0][0]}};
for (p=0;p<2;p++)
{
for (q=0;q<2;q++)
{
A_inv[p][q]=A1_inv[p][q]/(A[0][0]*A[1][1]-A[1][0]*A[0][1]);
}
}
for (p=0;p<4;p++)
{
for (q=0;q<2;q++)
{
for(r=0;r<4;r++)
{
K1[p][q]=K1[p][q]+P_pre[p][r]*H_z[r][q];
}
}
}
for (p=0;p<4;p++)
{
for (q=0;q<2;q++)
{
for(r=0;r<2;r++)
{
K[p][q]=K[p][q]+K1[p][r]*A_inv[r][q];
}
}
}
double X1_est[4][1]={0};
for (p=0;p<4;p++)
{
X1_est[p][0]=K[p][0]*a[0][0]+K[p][1]*a[1][0];
X_est[p][0]=X_pre[p][0]+X1_est[p][0];
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
if (p==q)
P_1[p][q]=1-(K[p][0]*H[0][q]+K[p][1]*H[1][q]);
else
P_1[p][q]=0-(K[p][0]*H[0][q]+K[p][1]*H[1][q]);
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
for (r=0;r<4;r++)
{
P_1_est[p][q]=P_1_est[p][q]+P_1[p][r]*P_pre[r][q];
}
}
}
for (p=0;p<4;p++)
{
for (q=0;q<2;q++)
{
for(r=0;r<2;r++)
{
P_2_L[p][q]=P_2_L[p][q]+K[p][r]*R[r][q];
}
}
}
for (p=0;p<2;p++)
{
for (q=0;q<4;q++)
{
K_z[p][q]=K[q][p];
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
P_2[p][q]=P_2_L[p][0]*K_z[0][q]+P_2_L[p][1]*K_z[1][q];
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
P_1_z[p][q]=P_1[q][p];
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
for (r=0;r<4;r++)
{
P_est[p][q]=P_est[p][q]+P_1_est[p][r]*P_1_z[r][q]+P_2[p][q]/4.0;
}
}
}
printf("\n\r");
for (p=0;p<4;p++)
{
X_pre[p][0]=0;
}
for (p=0;p<4;p++)
{
for (r=0;r<4;r++)
{
X_pre[p][0]=X_pre[p][0]+F[p][r]*X_est[r][0];
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
for (r=0;r<4;r++)
{
F_P[p][q]=F_P[p][q]+F[p][r]*P_est[r][q];
}
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
F_z[p][q]=F[q][p];
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
P_pre[p][q]=0;
}
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
for (r=0;r<4;r++)
{
P_pre[p][q]=P_pre[p][q]+F_P[p][r]*F_z[r][q]+Q[p][q]/4.0;
}
}
}
for (p=0;p<4;p++)
{
KEM_back_parameter.X_est[p][0] = X_est[p][0];
KEM_back_parameter.X_pre[p][0] = X_pre[p][0];
}
for (p=0;p<4;p++)
{
for (q=0;q<4;q++)
{
KEM_back_parameter.P_pre[p][q] = P_pre[p][q];
}
}
return KEM_back_parameter;
}
3 结果对比
4 完整工程链接
一维角度跟踪 二维角度跟踪
|