UKF在GNSS/INS组合导航中的应用

UKF在组合导航中小试牛刀

% SINS/GPS intergrated navigation simulation unsing kalman filter.
% Please run 'test_SINS_trj.m' to generate 'trj10ms.mat' beforehand!!!
% See also  test_SINS_trj, test_SINS, test_SINS_GPS_186, test_SINS_GPS_193.
% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 17/06/2011
glvs
psinstypedef(153);
trj = trjfile('trj10ms.mat');
% initial settings
[nn, ts, nts] = nnts(2, trj.ts);
imuerr = imuerrset(0.03, 100, 0.001, 5);
imu = imuadderr(trj.imu, imuerr);
davp0 = avperrset([0.5;-0.5;20], 0.1, [1;1;3]);
ins = insinit(avpadderr(trj.avp0,davp0), ts);
% KF filter
rk = poserrset([1;1;3]);
kf = kfinit(ins, davp0, imuerr, rk);
kf.Pmin = [avperrset(0.01,1e-4,0.1); gabias(1e-3, [1,10])].^2;  kf.pconstrain=1;
len = length(imu); [avp, xkpk] = prealloc(fix(len/nn), 10, 2*kf.n+1);
%timebar(nn, len, '15-state SINS/GPS Simulation.'); 
ki = 1;
% for k=1:nn:len-nn+1
%     k1 = k+nn-1;  
%     wvm = imu(k:k1,1:6);  t = imu(k1,end);
%     ins = insupdate(ins, wvm);
%     kf.Phikk_1 = kffk(ins);
%     kf = kfupdate(kf);
%     if mod(t,1)==0
%         posGPS = trj.avp(k1,7:9)' + davp0(7:9).*randn(3,1);  % GPS pos simulation with some white noise
%         kf = kfupdate(kf, ins.pos-posGPS, 'M');
%         [kf, ins] = kffeedback(kf, ins, 1, 'p');
%         avp(ki,:) = [ins.avp', t];
%         xkpk(ki,:) = [kf.xk; diag(kf.Pxk); t]';  ki = ki+1;
%     end
%     timebar;
% end
% %% UKF 参数配置
L=15;     % L为状态维度
a=1;     % a控制采样点的分布状态
k=1;     % k为待选参数 没有界限,但是要保证(n+lamda)*P为半正定矩阵
b=2;     % b非负的权系数
lambda=a*a*(L+k)-L; % lambda为缩放比列参数,用于降低总的预测误差
%%%%%%%%%%%%%%%%%%%%%% sigma点的权值 %%%%%%%%%%%%%%%%%
Wm=zeros(1,2*L+1);
Wc=zeros(1,2*L+1);
Wm(1)=lambda/(L+lambda);
Wc(1)=lambda/(L+lambda)+1-a*a+b; % 第一个采样点的均值和协方差的权值
for j=2:2*L+1      % 剩下2n个sigma点的均值和协方差的权值
    Wm(j)= 1/(2*(L+lambda));  % 下标m为均值的权值
    Wc(j)= 1/(2*(L+lambda));  % 下标c为协方差的权值
end
%增加航向量测
headGPS=0.0;
kf.Hk(4,:)=zeros(1,15);kf.Hk(4,3)=1.0;
temp=zeros(4,4);temp(1:3,1:3)=kf.Rk;kf.Rk=temp;kf.Rk(4,4)=(pi*180)*(pi*180);
%% UKF 仿真
for k=1:nn:len-nn+1
    k1 = k+nn-1;  
    wvm = imu(k:k1,1:6);  t = imu(k1,end);
    ins = insupdate(ins, wvm);
    kf.Phikk_1 = kffk(ins);
    cho=(chol(kf.Pxk*(L+lambda)))';
    %cho=m_skysd(kf.Pxk*(L+lambda));
    for ks=1:L
        xgamaP1(:,ks)=kf.xk+cho(:,ks);
        xgamaP2(:,ks)=kf.xk-cho(:,ks);
    end
    Xsigma=[kf.xk xgamaP1 xgamaP2]; % 获得 2L+1 个Sigma点
    % 一步预测
    Xsigmapre=kf.Phikk_1*Xsigma;
    % 求预测后的均值
    Xpred=zeros(L,1);
    for ks=1:2*L+1
        Xpred=Xpred+Wm(ks)*Xsigmapre(:,ks);
    end
    Ppred=zeros(L,L); %协力差阵预测
    for ks=1:2*L+1
        Ppred=Ppred+Wc(ks)*(Xsigmapre(:,ks)-Xpred)*(Xsigmapre(:,ks)-Xpred)';
    end
    %Ppred=Ppred+G*Q*G';
    if mod(t,1)==0
        posGPS = trj.avp(k1,7:9)' + davp0(7:9).*randn(3,1);
        if trj.avp<-pi
            headGPS=trj.avp(k1,3)+2*pi+pi*180*randn(1);
        else
            headGPS=trj.avp(k1,3)+pi*180*randn(1);
        end
        headGPS=trj.avp(k1,3)+randn(1);
        resp=ins.pos-posGPS;
        resp(4)=ins.att(3)-headGPS;
        %根据Ut变换获得新的sigma点集
        chor=(chol((L+lambda)*Ppred))';
        for ks=1:L
            XaugsigmaP1(:,ks)=Xpred+chor(:,ks);
            XaugsigmaP2(:,ks)=Xpred-chor(:,ks);
        end
        Xaugsigma=[Xpred XaugsigmaP1 XaugsigmaP2];
        % 观测预测
        Zsigmapre=kf.Hk*Xaugsigma;
        % 计算观测预测的均值和协方差
        Zpred=zeros(4,1); %观测预测的均值
        for ks=1:2*L+1
            Zpred=Zpred+ Wm(ks)*Zsigmapre(:,ks);
        end
        Pzz=zeros(4,4);
        for ks=1:2*L+1
            Pzz=Pzz+Wc(ks)*(Zsigmapre(:,ks)-Zpred)*(Zsigmapre(:,ks)-Zpred)';
        end
        Pzz=Pzz+kf.Rk; %得到协方差Pzz
        Pxz= zeros(L,4);
        for ks=1:2*L+1
            Pxz=Pxz+Wc(ks)*(Xaugsigma(:,ks)-Xpred)*(Zsigmapre(:,ks)-Zpred)';
        end
        %计算卡尔曼增益
        K=Pxz/Pzz;
        %K=Pxz*inv(Pzz);  % Kalman
        % 状态更新和协方差更新
        kf.xk=Xpred+K*(resp-Zpred);% 状态更新
        kf.Pxk=Ppred-K*Pzz*K'; %方差更新
        % 反馈更新
        [kf, ins] = kffeedback(kf, ins, 1, 'avp');
    else
        kf.xk=Xpred;
        kf.Pxk=Ppred;
    end
    Xk(ki,:)=kf.xk';
    result_avp(ki,:) = [ins.avp', t];ki=ki+1;
end
%%
% avp(ki:end,:) = [];  xkpk(ki:end,:) = []; 
% % show results
% insplot(avp);
% avperr = avpcmpplot(trj.avp, avp);
% kfplot(xkpk, avperr, imuerr);


备注:
如有错误,勿喷,请多指点(刚刚入行的小菜鸟!)
参考文献:
感谢严恭敏老师的开源软件PSINS

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值