捷联惯导更新算法
首先通过AVP
参数使用insinit
函数初始化获得导航结构体ins;再调用insupdate
函数进行惯导更新。
insinit
函数初始化
ins
结构体初始化的成员较多,在insinit
中显示如下:
function ins = insinit(avp0, ts, var1, var2)
% SINS structure array initialization.
%
% Prototype: ins = insinit(avp0, ts, var1, var2)
% Initialization usages(maybe one of the following methods):
% ins = insinit(avp0, ts);
% ins = insinit(avp0, ts, avperr);
% ins = insinit(qnb0, vn0, pos0, ts);
% Inputs: avp0 - initial avp0 = [att0; vn0; pos0]
% ts - SIMU sampling interval
% avperr - avp error setting
% Output: ins - SINS structure array
%
% See also insupdate, avpset, kfinit.
% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 22/03/2008, 12/01/2013, 18/03/2014
global glv
avp0 = avp0(:);
if length(avp0)==1, avp0=zeros(9,1); end % ins = insinit(0, ts);
if length(avp0)==4, avp0=[0;0;avp0(1); 0;0;0; avp0(2:4)]; end % ins = insinit([yaw;pos], ts);
if length(avp0)==6, avp0=[avp0(1:3); 0;0;0; avp0(4:6)]; end % ins = insinit([att;pos], ts);
if nargin==2 % ins = insinit(avp0, ts);
[qnb0, vn0, pos0] = setvals(a2qua(avp0(1:3)), avp0(4:6), avp0(7:9));
elseif nargin==3 % ins = insinit(avp0, ts, avperr);
avperr = var1;
avp0 = avpadderr(avp0, avperr);
[qnb0, vn0, pos0] = setvals(a2qua(avp0(1:3)), avp0(4:6), avp0(7:9));
elseif nargin==4 % ins = insinit(qnb0, vn0, pos0, ts);
[qnb0, vn0, pos0, ts] = setvals(avp0, ts, var1, var2);
end
ins = [];
ins.ts = ts; ins.nts = 2*ts;
[ins.qnb, ins.vn, ins.pos] = setvals(qnb0, vn0, pos0); ins.vn0 = vn0; ins.pos0 = pos0;
[ins.qnb, ins.att, ins.Cnb] = attsyn(ins.qnb); ins.Cnb0 = ins.Cnb;
ins.avp = [ins.att; ins.vn; ins.pos];
ins.eth = ethinit(ins.pos, ins.vn);
% 'wib,web,fn,an,Mpv,MpvCnb,Mpvvn,CW' may be very useful outside SINS,
% so we calucate and save them.
ins.wib = ins.Cnb'*ins.eth.wnin;
ins.fn = -ins.eth.gn; ins.fb = ins.Cnb'*ins.fn;
[ins.wnb, ins.web, ins.an] = setvals(zeros(3,1));
ins.Mpv = [0, 1/ins.eth.RMh, 0; 1/ins.eth.clRNh, 0, 0; 0, 0, 1];
ins.MpvCnb = ins.Mpv*ins.Cnb; ins.Mpvvn = ins.Mpv*ins.vn;
[ins.Kg, ins.Ka] = setvals(eye(3)); % calibration parameters
[ins.eb, ins.db] = setvals(zeros(3,1));
[ins.tauG, ins.tauA] = setvals(inf(3,1)); % gyro & acc correlation time
ins.lever = zeros(3,1); ins = inslever(ins); % lever arm
ins.tDelay = 0; % time delay
ins.openloop = 0;
glv.wm_1 = zeros(3,1)'; glv.vm_1 = zeros(3,1)'; % for 'single sample+previous sample' coning algorithm
ins.an0 = zeros(3,1); ins.anbar = ins.an0;
insupdate
函数进行惯导更新
insupdate
函数先进行不可交换误差补偿->再进行传感器标定->再计算地球相关参数;不可交换误差在前面博客已讲过(圆锥和划桨误差);传感器的标定主要就是,不正交安装误差,如果在卡尔曼滤波中,若能估计出来陀螺和加速度计零偏,能估计出来,就扣减一下,进行标定。
function ins = insupdate(ins, imu)
% SINS Updating Alogrithm including attitude, velocity and position
% updating.
%
% Prototype: ins = insupdate(ins, imu)
% Inputs: ins - SINS structure array created by function 'insinit'
% imu - gyro & acc incremental sample(s)
% Output: ins - SINS structure array after updating
%
% See also insinit, cnscl, earth, trjsimu, imuadderr, avpadderr, q2att,
% inslever, alignvn, aligni0, etm, kffk, kfupdate, insplot.
% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 22/03/2008, 12/01/2013, 18/03/2014, 09/09/2014
nn = size(imu,1);
nts = nn*ins.ts; nts2 = nts/2; ins.nts = nts;
[phim, dvbm] = cnscl(imu,0); % coning & sculling compensation
% [phim, dvbm] = cnscl0(imu); % coning & sculling compensation
phim = ins.Kg*phim-ins.eb*nts; dvbm = ins.Ka*dvbm-ins.db*nts; % calibration
%% earth & angular rate updating
vn01 = ins.vn+ins.an*nts2; pos01 = ins.pos+ins.Mpv*vn01*nts2; % extrapolation at t1/2
if ins.openloop==0, ins.eth = ethupdate(ins.eth, pos01, vn01);
elseif ins.openloop==1, ins.eth = ethupdate(ins.eth, ins.pos0, ins.vn0); end
ins.wib = phim/nts; ins.fb = dvbm/nts; % same as trjsimu
ins.web = ins.wib - ins.Cnb'*ins.eth.wnie;
% ins.wnb = ins.wib - ins.Cnb'*ins.eth.wnin;
ins.wnb = ins.wib - (ins.Cnb*rv2m(phim/2))'*ins.eth.wnin; % 2014-11-30
%% (1)velocity updating
ins.fn = qmulv(ins.qnb, ins.fb);
% ins.an = qmulv(rv2q(-ins.eth.wnin*nts2),ins.fn) + ins.eth.gcc;
ins.an = rotv(-ins.eth.wnin*nts2, ins.fn) + ins.eth.gcc; ins.anbar = 0.9*ins.anbar + 0.1*ins.an;
vn1 = ins.vn + ins.an*nts;
%% (2)position updating
% ins.Mpv = [0, 1/ins.eth.RMh, 0; 1/ins.eth.clRNh, 0, 0; 0, 0, 1];
ins.Mpv(4)=1/ins.eth.RMh; ins.Mpv(2)=1/ins.eth.clRNh;
% ins.Mpvvn = ins.Mpv*((ins.vn+vn1)/2+(ins.an-ins.an0)*nts^2/3); % 2014-11-30
ins.Mpvvn = ins.Mpv*(ins.vn+vn1)/2;
ins.pos = ins.pos + ins.Mpvvn*nts;
ins.vn = vn1;
ins.an0 = ins.an;
%% (3)attitude updating
ins.Cnb0 = ins.Cnb;
% ins.qnb = qupdt(ins.qnb, ins.wnb*nts); % lower accuracy than next line
ins.qnb = qupdt2(ins.qnb, phim, ins.eth.wnin*nts);
[ins.qnb, ins.att, ins.Cnb] = attsyn(ins.qnb);
ins.avp = [ins.att; ins.vn; ins.pos];
计算地球相关参数调用ethupdate
函数,主要是根据位置pos
和速度vn
信息计算比力方程中的有害加速度相关项。
function eth = ethupdate(eth, pos, vn)
% Update the Earth related parameters, much faster than 'earth'.
%
% Prototype: eth = ethupdate(eth, pos, vn)
% Inputs: eth - input earth structure array
% pos - geographic position [lat;lon;hgt]
% vn - velocity
% Outputs: eth - parameter structure array
%
% See also ethinit, earth.
% Copyright(c) 2009-2014, by Gongmin Yan, All rights reserved.
% Northwestern Polytechnical University, Xi An, P.R.China
% 23/05/2014
if nargin==2, vn = [0; 0; 0]; end
eth.pos = pos; eth.vn = vn;
eth.sl = sin(pos(1)); eth.cl = cos(pos(1)); eth.tl = eth.sl/eth.cl;
eth.sl2 = eth.sl*eth.sl; sl4 = eth.sl2*eth.sl2;
sq = 1-eth.e2*eth.sl2; RN = eth.Re/sqrt(sq);
eth.RNh = RN+pos(3); eth.clRNh = eth.cl*eth.RNh;
eth.RMh = RN*(1-eth.e2)/sq+pos(3);
% eth.wnie = [0; eth.wie*eth.cl; eth.wie*eth.sl];
eth.wnie(2) = eth.wie*eth.cl; eth.wnie(3) = eth.wie*eth.sl;
% eth.wnen = [-vn(2)/eth.RMh; vn(1)/eth.RNh; vn(1)/eth.RNh*eth.tl];
eth.wnen(1) = -vn(2)/eth.RMh; eth.wnen(2) = vn(1)/eth.RNh; eth.wnen(3) = eth.wnen(2)*eth.tl;
% eth.wnin = eth.wnie + eth.wnen;
eth.wnin(1) = eth.wnie(1) + eth.wnen(1); eth.wnin(2) = eth.wnie(2) + eth.wnen(2); eth.wnin(3) = eth.wnie(3) + eth.wnen(3);
% eth.wnien = eth.wnie + eth.wnin;
eth.wnien(1) = eth.wnie(1) + eth.wnin(1); eth.wnien(2) = eth.wnie(2) + eth.wnin(2); eth.wnien(3) = eth.wnie(3) + eth.wnin(3);
% eth.gn = [0;0;-eth.g];
eth.g = eth.g0*(1+5.27094e-3*eth.sl2+2.32718e-5*sl4)-3.086e-6*pos(3); % grs80
eth.gn(3) = -eth.g;
% eth.gcc = eth.gn - cros(eth.wnien,vn); % Gravitational/Coriolis/Centripetal acceleration
% eth.gcc = [ eth.wnien(3)*vn(2)-eth.wnien(2)*vn(3); % faster than previous line
% eth.wnien(1)*vn(3)-eth.wnien(3)*vn(1);
% eth.wnien(2)*vn(1)-eth.wnien(1)*vn(2)+eth.gn(3) ];
eth.gcc(1) = eth.wnien(3)*vn(2)-eth.wnien(2)*vn(3);
eth.gcc(2) = eth.wnien(1)*vn(3)-eth.wnien(3)*vn(1);
eth.gcc(3) = eth.wnien(2)*vn(1)-eth.wnien(1)*vn(2)+eth.gn(3);
最后,insupdate
先后依次完成速度更新、位置更新和姿态更新。