牛伯城 2016-08-05 09:13 采纳率: 0%
浏览 2593

卡尔曼滤波在航迹推算中优化有问题

我在做一个水下航行器的航迹推算仿真,应用卡尔曼滤波进行优化,发现优化后的曲线存在问题。
水下航行器运动模型 V(导航系下速度)=C(姿态转移矩阵)*v(载体系下的速度)

导航系固定在航行器上,方向指向北东地,其方向不随航行器自身状态改变而改变,载体系随航行器转动,存在三个欧拉角。

卡尔曼滤波中,X(k)=A*X(k-1)+Q
Z=H*X+R
采用常速度模型,
所求状态X包含导航系下的位置和速度两个量,分别在XYZ三个方向,因此X是6 *1的矩阵,X=[X; Y; Z; VX; VY; VZ] 建立X导数和X关系,离散化后得到矩阵A;
观测值Z取载体系下的速度,Z=[vx; vy; vz];利用载体系下的速度与导航系下的速度之前的关系,观测矩阵为H=[0,inv(C)],inv(C)是从导航系到载体系下的姿态转移矩阵;观测矩阵为3*6的矩阵,Z=H*X中,H主要使X中导航系下的位置和速度与H矩阵相乘得到载体系下的速度,即观测值v
matlab代码如下,

 clear all;
close all;
clc;

%------------------------------仿真数据生成----------------------------------%

%第一阶段
A=[0:0.01:2;   zeros(1,201);   zeros(1,201)];
o1=[zeros(1,201);   zeros(1,201);   zeros(1,201)];      %该阶段沿x轴直线运动
%第二阶段 
B=[2.01:0.01:4;zeros(1,200);zeros(1,200)];
o2=[zeros(1,200);
    -pi/400:(-pi/400):(-pi/4),(-pi/4):(pi/400):-pi/400;
    zeros(1,200)];    %该阶段做下潜运动
%第三阶段 
C=[4*ones(1,100);   zeros(1,100);   zeros(1,100)];
o3=[zeros(1,100);zeros(1,100);2*pi/100:2*pi/100:2*pi];   %该阶段在xoy平面内圆周运动
%第四阶段  
D=[4:(-0.01):2.01;   zeros(1,200);   zeros(1,200)];
o4=[zeros(1,200);
    -pi/400:(-pi/400):(-pi/4),(-pi/4):(pi/400):-pi/400;
    -pi/400:(-pi/400):(-pi/4),(-pi/4):(pi/400):-pi/400;];   %该阶段继续下潜
%第五阶段 
E=[ 2.01:0.01:4;   zeros(1,200);    (-0.01):(-0.01):(-2)];
o5=[zeros(1,200);  pi/800:pi/800:pi/4;   zeros(1,200)];   %该阶段上浮

v1=[A,B,C,D,E];   %整合传感器速度数据
ou1=[o1,o2,o3,o4,o5];    %整合传感器欧拉角数据


%----------------------------传感器噪声值生成------------------------------%

ZS1=0.3*randn(3,size(v1,2));      %速度噪声
ZS2=pi/40*randn(3,size(ou1,2));   %欧拉角噪声

v2=v1+ZS1;                       %加噪声后的速度
ou2=ou1+ZS2;                      %加噪声后的欧拉角


%----------------------------仿真航迹推算----------------------------------%

V1=[0,0,0]';         %初始化参数
xyz1=[0,0,0]';
XYZ1=[0,0,0]';
for i=1:size(ou1,2);
    t=0.01;    %时间间隔

    v=v1(:,i); %取对应时刻载体系下的x、y、z方向的速度列向量

    a=ou1(1,i);  %取对应时刻三个欧拉角
    b=ou1(2,i);
    c=ou1(3,i);

    C=[cos(c)*cos(b), cos(c)*sin(b)*sin(a)-cos(a)*sin(c), cos(c)*sin(b)*cos(a)+sin(c)*sin(a);
       cos(b)*sin(c), sin(c)*sin(b)*sin(a)-cos(a)*cos(c), sin(c)*sin(b)*cos(a)-cos(c)*sin(a);
       -sin(b),             cos(b)*sin(a),                        cos(a)*cos(b)];   %姿态转移矩阵 

    tempV=C*v;           %计算得到对应时刻导航系下的三个方向3*1的速度列向量
    tempXYZ=tempV*t;     %计算得到对应时间间隔内导航系下的三个方向3*1的位移列向量
    xyz1=xyz1+tempXYZ;   %累加近似得到该时刻3*1的位移列向量
    V1=[V1,tempV];       %串联速度列向量,得到速度矩阵
    XYZ1=[XYZ1,xyz1];    %串联位移列向量,得到位移矩阵
end
V1=V1(:,2:size(V1,2));
XYZ1=XYZ1(:,2:size(XYZ1,2)); %去掉第一行初始值
X1=XYZ1(1,:);      %取X方向的位移行向量
Y1=XYZ1(2,:);      %取Y方向的位移行向量
Z1=XYZ1(3,:);      %取Z方向的位移行向量


%---------------------------加噪声的航迹推算-------------------------------%

V2=[0,0,0]';         %初始化参数
xyz2=[0,0,0]';
XYZ2=[0,0,0]';
for i=1:size(ou2,2);
    t=0.01;      %时间间隔

    v=v2(:,i);   %取对应时刻载体系下的x、y、z方向的速度列向量

    a=ou2(1,i);  %取对应时刻三个欧拉角
    b=ou2(2,i);
    c=ou2(3,i);

    C=[cos(c)*cos(b), cos(c)*sin(b)*sin(a)-cos(a)*sin(c), cos(c)*sin(b)*cos(a)+sin(c)*sin(a);
       cos(b)*sin(c), sin(c)*sin(b)*sin(a)-cos(a)*cos(c), sin(c)*sin(b)*cos(a)-cos(c)*sin(a);
       -sin(b),             cos(b)*sin(a),                        cos(a)*cos(b)];

    tempV=C*v;           %计算得到对应时刻导航系下的三个方向3*1的速度列向量
    tempXYZ=tempV*t;     %计算得到对应时间间隔内导航系下的三个方向3*1的位移列向量
    xyz2=xyz2+tempXYZ;   %累加近似得到该时刻3*1的位移列向量
    V2=[V2,tempV];       %串联速度列向量,得到速度矩阵
    XYZ2=[XYZ2,xyz2];    %串联位移列向量,得到位移矩阵
end
V2=V2(:,2:size(V2,2));
XYZ2=XYZ2(:,2:size(XYZ2,2));
X2=XYZ2(1,:);      %取X方向的位移行向量
Y2=XYZ2(2,:);      %取Y方向的位移行向量
Z2=XYZ2(3,:);      %取Z方向的位移行向量


%------------------------------卡尔曼滤波----------------------------------%

AA=[zeros(6,3),[eye(3);zeros(3,3)]];
A=expm(AA*0.01);

R=0.1*eye(3);
Q=0.09*eye(6);       

I=eye(6);          %定义一个单位阵方便计算
p=100*I;           %协方差矩阵初值为单位阵
X33=zeros(6,1);    %坐标初值


Xk=zeros(6,1);
Z=v2;
for k=2:size(Z,2);
    ZZ=Z(:,k);
    Xkk=A*Xk;
    p=A*p*A'+Q;

    a=ou1(1,k-1);  %取对应时刻三个欧拉角
    b=ou1(2,k-1);
    c=ou1(3,k-1);
    C=[cos(c)*cos(b), cos(c)*sin(b)*sin(a)-cos(a)*sin(c), cos(c)*sin(b)*cos(a)+sin(c)*sin(a);
       cos(b)*sin(c), sin(c)*sin(b)*sin(a)-cos(a)*cos(c), sin(c)*sin(b)*cos(a)-cos(c)*sin(a);
       -sin(b),             cos(b)*sin(a),                        cos(a)*cos(b)];   %姿态转移矩阵 

    NI=ni(C);

    H=[zeros(3,3),NI];       %观测矩阵
    K=p*H'*inv(H*p*H'+R);    %计算增益
    Xkk=Xkk+K*(ZZ-H*Xk); 
    p=(I-K*H)*p;              %协方差迭代更新

    X33=[X33,Xkk];
    Xk=Xkk;

end
X3=X33(1,:);
Y3=X33(2,:);
Z3=X33(3,:);

%---------------------------------绘图------------------------------------%

subplot(2,2,1);plot3(X1,Y1,Z1,'b',X2,Y2,Z2,'r',X3,Y3,Z3,'g'),grid on;
title('航迹曲线');
xlabel('X');ylabel('Y');zlabel('Z');
set(gca,'zdir','reverse');

subplot(2,2,2);plot(1:size(X1,2),X2-X1,'b',1:size(X1,2),X3-X1,'r'),grid on;
legend('加噪声-仿真','卡尔曼-仿真');
title('X方向差值');
ylabel('X');

subplot(2,2,3);plot(1:size(X1,2),Y2-Y1,'b',1:size(X1,2),Y3-Y1,'r'),grid on;
legend('加噪声-仿真','卡尔曼-仿真');
title('Y方向差值');
ylabel('Y');

subplot(2,2,4);plot(1:size(X1,2),Z2-Z1,'b',1:size(X1,2),Z3-Z1,'r'),grid on;
legend('加噪声-仿真','卡尔曼-仿真');
title('Z方向差值');
ylabel('Z');

图片说明

代码中的ni()是自己写的求逆矩阵函数
画图用的是卡尔曼滤波值和噪声值分别减去仿真值,得到的图像本应是卡尔曼滤波值在X轴和噪声值之间,实际上却并不是,已经被困扰了几天,求各位大神指导啊

  • 写回答

9条回答 默认 最新

  • 散步咏凉天 2016-08-05 12:40
    关注

    按我的理解,Z=H_*X+R,H是X和Z之间转换的矩阵,有什么样的X,就对应什么样的Z,它们之间要有线性相关的机制,才能滤波,而程序中给出的Z和X是不同时刻一次测量的值,它们没有相关关系(叠加的又是随机数,没有机制),如果叠加的不是随机数,或者是多次测量同一个量得到的值再列成矩阵,就有可能降噪。
    我想运行程序,但是NI=ni(C);中的ni()函数没有定义,不知道是不是我的Matlab版本低没有这个函数。_

    评论

报告相同问题?

悬赏问题

  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥30 python代码,帮调试,帮帮忙吧
  • ¥15 #MATLAB仿真#车辆换道路径规划