⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kalmanfilter.m

📁 本压缩文件包含GPS量测数据仿真和惯性导航解算以及卡尔曼滤波在导航解算中的应用
💻 M
字号:
%%%%%%%%%%%%%%%%%卡尔曼滤波程序%%%%%%%%%%%%%
clear all
close all
clc
deg_rad=pi/180;   %由度转化成弧度
rad_deg=180/pi;   %由弧度转化成度
%-----------------------常值定义区----------------------
Omega_ie=0.00007272205216643040;   %地球自转角速度 单位:弧度每妙
g0=9.78;
Wiee = [0 0 Omega_ie]';  %地球速率在地球系中的投影
Re=6378245.0; %地球长轴 《惯性导航系统》  P28
e=1/298.3;

fid_IMUout=fopen('IMUout.txt','r');    %读取惯性器件的输出 无误差
[AllDataIMUout NumofAllDataIMUout]=fscanf(fid_IMUout,'%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g',[17 inf]);
AllDataIMUout=AllDataIMUout';
NumofEachDataIMUout=fix(NumofAllDataIMUout/17);

TimeIMUout=AllDataIMUout(:,1);
pitch=AllDataIMUout(:,11);  %俯仰角(向上为正)
roll=AllDataIMUout(:,12);   %滚转角(向右为正)
head=-AllDataIMUout(:,13);   %偏航角(偏西为正)
%-------------------从文件中读取数据----------------------
fread_SINS=fopen('Navigation.txt','r');  %读取惯导输出
[AllData NumofAllData]=fscanf(fread_SINS,'%f %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ',[16 inf]);
AllData=AllData';
NumofEachData=fix(NumofAllData/16);

TimeSINS=AllData(:,1);
longitude=AllData(:,2);     %经度   单位:弧度
latitude=AllData(:,3);      %纬度   单位:弧度
High=AllData(:,4);      %高度 单位:米

Vn_err=AllData(:,5);
Vu_err=AllData(:,6);
Ve_err=AllData(:,7);  

pitch_err=AllData(:,8);  %俯仰角(向上为正)
roll_err=AllData(:,9);   %滚转角(向右为正)
head_err=AllData(:,10);   %偏航角(偏西为正

omigax=AllData(:,11);   %陀螺输出
omigay=AllData(:,12);
omigaz=AllData(:,13);

fb_x=AllData(:,14);      %比力
fb_y=AllData(:,15);      %
fb_z=AllData(:,16);     %

fread_GPS=fopen('GPSout.txt','r');      %读取速度和位置信息 带有GPS误差
[GPSData NumofData]=fscanf(fread_GPS,'%g %g %g %g %g %g %g',[7 inf]);
GPSData=GPSData';
NumofGPSData=fix(NumofData/7);
TimeGPS=GPSData(:,1);
GPS_lon=GPSData(:,2);
GPS_lat=GPSData(:,3);
GPS_High=GPSData(:,4);
GPS_Vn=GPSData(:,5);
GPS_Vu=GPSData(:,6);
GPS_Ve=GPSData(:,7);



T_SINS=TimeSINS(2)-TimeSINS(1);   %惯导程序的解算周期
TimeAll=(NumofEachData-1)*T_SINS; 
T_GPS=TimeGPS(2)-TimeGPS(1);      %GPS的输出频率
numb_KF=TimeAll/T_GPS;
NUM=fix((NumofEachData)/(NumofGPSData));
%观测矩阵的初始化
H=zeros(3,12);                                                   
H(1,1)=1;
H(2,2)=1;
H(3,3)=1;
%初始状态向量  初始状态都设为0
X=zeros(12,1);  %12个状态分别为 速度误差 姿态角误差 惯性器件误差
X(4,1)=0*pi/180;
X(5,1)=0*pi/180;
X(6,1)=0*pi/180;
%初始方差阵的设置
P=zeros(12,12);
P(1,1)=1^2;
P(2,2)=1^2;
P(3,3)=1^2;
P(4,4)=(1*pi/180)^2;
P(5,5)=(1*pi/180)^2;
P(6,6)=(1*pi/180)^2;

P(7,7)=(1e-4*g0)^2;
P(8,8)=(1e-4*g0)^2;
P(9,9)=(1e-4*g0)^2;
P(10,10)=(0.2*pi/3600/180)^2;
P(11,11)=(0.2*pi/3600/180)^2;
P(12,12)=(0.2*pi/3600/180)^2;

%P=P;
%初始系统噪声误差阵
Q=zeros(12,12);                                                 
Q(1,1)=(5e-5*g0)^2;           %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Q(2,2)=(5e-5*g0)^2;
Q(3,3)=(5e-5*g0)^2; %系统噪声方差阵    和惯性器件的误差有关         
Q(4,4)=(0.2*pi/3600/180)^2;
Q(5,5)=(0.2*pi/3600/180)^2;
Q(6,6)=(0.2*pi/3600/180)^2;

%Q=Q;
%初始观测噪声误差阵
R=zeros(3,3);
R(1,1)=5^2;       %测量噪声方差阵    和GPS的测量精度有关
R(2,2)=5^2;
R(3,3)=5^2;

%R=5*R;

for ii=1:numb_KF
    KFii=1+(ii-1)*NUM; 
    A=zeros(12,12);

    M_roll=[1               0                   0;
            0       cos(roll_err(KFii))     sin(roll_err(KFii));
            0      -sin(roll_err(KFii))     cos(roll_err(KFii))];
    M_pitch=[cos(pitch_err(KFii))  sin(pitch_err(KFii))  0;
            -sin(pitch_err(KFii))  cos(pitch_err(KFii))  0;
             0                     0                     1];
    M_head=[cos(head_err(KFii))    0      -sin(head_err(KFii));
              0                    1              0;
            sin(head_err(KFii))    0       cos(head_err(KFii))];
    
    KF_Tbn_err=M_roll*M_pitch*M_head;   %地理系:北天东方向  弹体系:前上右  转序:head-pitch-roll
    KF_Tnb_err=KF_Tbn_err';

    KF_fb(1,1)=fb_x(KFii);
    KF_fb(2,1)=fb_y(KFii);
    KF_fb(3,1)=fb_z(KFii); 

    L=GPS_lat(ii);

    RM0=Re*(1.0-2.0*e+3.0*e*sin(L)^2)+GPS_High(ii);    %
    RN0=Re*(1.0+e*sin(L)^2)+GPS_High(ii);
    Re_ideal=Re+GPS_High(ii);       
    
    KF_Vn=GPS_Vn(ii);
    KF_Vu=GPS_Vu(ii);
    KF_Ve=GPS_Ve(ii);
    KF_lat=GPS_lat(ii);
    KF_lon=GPS_lon(ii);
    KF_High=GPS_High(ii);    
  
    KF_fn=KF_Tnb_err*KF_fb;

    A(1,1)=-KF_Vu/RM0;
    A(1,2)=-KF_Vn/RM0;
   %  A(1,3)=-(2*Omega_ie*sin(L)+KF_Ve*tan(L)/Re_ideal);          %%%%%%%%%%%%%%%%%%%%
   A(1,3)=-2*(Omega_ie*sin(L)+KF_Ve*tan(L)/RN0);
    A(1,5)=-KF_fn(3,1);
    A(1,6)=KF_fn(2,1);
    
    A(2,1)=2*KF_Vn/RM0;
  %  A(2,3)=2*Omega_ie*cos(L)+KF_Ve/Re_ideal;
    A(2,3)=2*(Omega_ie*cos(L)+KF_Ve/RN0);
    A(2,4)=KF_fn(3,1);
    A(2,6)=-KF_fn(1,1);
    
    A(3,1)=2*Omega_ie*sin(L)+KF_Ve/RN0*tan(L);
    A(3,2)=-(2*Omega_ie*cos(L)+KF_Ve/RN0);
    A(3,3)=(KF_Vn*tan(L))/RN0-KF_Vu/RN0;
    A(3,4)=-KF_fn(2,1);
    A(3,5)=KF_fn(1,1);
   
   

    A(4,3)=1.0/RN0;
    A(4,5)=-KF_Vn/RM0;
    A(4,6)=-(Omega_ie*sin(L)+(KF_Ve*tan(L))/RN0);
   
    A(5,3)=tan(L)/RN0;
    A(5,4)=KF_Vn/RM0;
    A(5,6)=Omega_ie*cos(L)+KF_Ve/RN0;
    
    A(6,1)=-1.0/RM0;
    A(6,4)=Omega_ie*sin(L)+KF_Ve*tan(L)/RN0;
    A(6,5)=-(Omega_ie*cos(L)+KF_Ve/RN0);

    A(1,7)=KF_Tnb_err(1,1);
    A(1,8)=KF_Tnb_err(1,2);        %12个状态分别为 速度误差 姿态角误差 惯性器件误差
    A(1,9)=KF_Tnb_err(1,3);
    A(2,7)=KF_Tnb_err(2,1);
    A(2,8)=KF_Tnb_err(2,2);
    A(2,9)=KF_Tnb_err(2,3);
    A(3,7)=KF_Tnb_err(3,1);
    A(3,8)=KF_Tnb_err(3,2);
    A(3,9)=KF_Tnb_err(3,3);
    
    A(4,10)=KF_Tnb_err(1,1);
    A(4,11)=KF_Tnb_err(1,2);
    A(4,12)=KF_Tnb_err(1,3);
    A(5,10)=KF_Tnb_err(2,1);
    A(5,11)=KF_Tnb_err(2,2);
    A(5,12)=KF_Tnb_err(2,3);
    A(6,10)=KF_Tnb_err(3,1);
    A(6,11)=KF_Tnb_err(3,2);
    A(6,12)=KF_Tnb_err(3,3);
    
%==================状态矩阵和系统噪声阵的离散化====================% 
    T_discre=T_GPS;                  %离散化时间
    FI=eye(12);
    Qdct=zeros(12);
        temp2=1;
        M{1}=Q;
        for j=1:10
            temp2=temp2*j;
            FI=FI+T_discre^j*(A)^j/temp2;
            if(j~=1)
                M{j}=A*M{j-1}+(A*M{j-1})';
            end
            Qdct =Qdct+T_discre^j*M{j}/temp2;
        end
% 读取观测数据进行卡尔曼滤波
    Z(1,1)=Vn_err(KFii)-GPS_Vn(ii);
    Z(2,1)=Vu_err(KFii)-GPS_Vu(ii);
    Z(3,1)=Ve_err(KFii)-GPS_Ve(ii);
%进行一次递推
     P=FI*P*FI'+Qdct;
     K=P*H'*inv(H*P*H'+R);
     ZZ(ii,:)=(Z-H*FI*X)';
     KK(:,:,ii)=K;
     X=FI*X+K*(Z-H*FI*X);
     P=(eye(12)-K*H)*P*(eye(12)-K*H)'+K*R*K';
     
     KF_dVn(ii)=X(1,1);
     KF_dVu(ii)=X(2,1);
     KF_dVe(ii)=X(3,1);
     
     KF_fien(ii)=X(4,1);
     KF_fieu(ii)=X(5,1);
     KF_fiee(ii)=X(6,1);
     
    
%-----------------用滤波的结果对姿态矩阵进行校正------------------------
Tbn(1,1)=cos(pitch_err(KFii))*cos(head_err(KFii));     %地理坐标系 北天东
Tbn(1,2)=sin(pitch_err(KFii));                    %载体坐标系 前上右
Tbn(1,3)=-cos(pitch_err(KFii))*sin(head_err(KFii));    %旋转顺序  head-pitch-roll                                           
Tbn(2,1)=sin(roll_err(KFii))*sin(head_err(KFii))-sin(pitch_err(KFii))*cos(roll_err(KFii))*cos(head_err(KFii));   
Tbn(2,2)=cos(roll_err(KFii))*cos(pitch_err(KFii));                                                
Tbn(2,3)=cos(roll_err(KFii))*sin(head_err(KFii))*sin(pitch_err(KFii))+sin(roll_err(KFii))*cos(head_err(KFii));
Tbn(3,1)=cos(roll_err(KFii))*sin(head_err(KFii))+sin(roll_err(KFii))*sin(pitch_err(KFii))*cos(head_err(KFii));
Tbn(3,2)=-sin(roll_err(KFii))*cos(pitch_err(KFii));
Tbn(3,3)=-sin(roll_err(KFii))*sin(head_err(KFii))*sin(pitch_err(KFii))+cos(roll_err(KFii))*cos(head_err(KFii));
Tnb=Tbn';

     Tnn11=[1               -X(6,1)          X(5,1);
            X(6,1)            1             -X(4,1);
           -X(5,1)           X(4,1)            1];
     %用滤波的结果对有较大误差的姿态角进行校正
     Tnb_modify=Tnn11*Tnb;
     Tbn_modify=Tnb_modify';
     %解算姿态角
    flag_pitch=asin(Tnb_modify(2,1));
    flag_roll=atan(-Tnb_modify(2,3)/Tnb_modify(2,2));
    flag_head=atan(-Tnb_modify(3,1)/Tnb_modify(1,1));
    if(Tnb_modify(2,2)<0)
        if(flag_roll<0)
            flag_roll=flag_roll+pi;
        else
            flag_roll=flag_roll-pi;
        end
    end
    % 偏航角范围 -180度——180度  北偏西为正
    if(Tnb_modify(1,1)<0)
        if(flag_head<0)
            flag_head=flag_head+pi;
        else
            flag_head=flag_head-pi;
        end
    end
    pitch_modify(ii)=flag_pitch;
    head_modify(ii)=flag_head;
    roll_modify(ii)=flag_roll;
    dpitch_modify(ii)=(pitch_modify(ii)-pitch(KFii))*rad_deg*60;
    dhead_modify(ii)=(head_modify(ii)-head(KFii))*rad_deg*60;        %单位:角分
    droll_modify(ii)=(roll_modify(ii)-roll(KFii))*rad_deg*60;
     
end;
% -------------------------画图------------------------------
t=T_GPS:T_GPS:TimeAll;
figure(1)
plot(t,dpitch_modify,t,-18,'r',t,18,'r')
xlabel('时间(t)')
ylabel('俯仰角的修正误差(角分)')
legend('收敛曲线','最后收敛值±18角分')

figure(2)
plot(t,dhead_modify,t,-18,'r',t,18,'r')
xlabel('时间(t)')
ylabel('航向角的修正误差(角分)')
legend('收敛曲线','最后收敛值±18角分')

figure(3)
plot(t,droll_modify,t,-18,'r',t,18,'r')
xlabel('时间(t)')
ylabel('滚转角的修正误差(角分)')
legend('收敛曲线','最后收敛值±18角分')
fclose(fid_IMUout);
fclose(fread_SINS);
fclose(fread_GPS);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -