严恭敏老师PSINS工具箱学习笔记-3

惯性传感器测量误差模型

参考教材: 捷联惯导算法与组合导航原理-严恭敏、翁浚

insupdate函数里关于补偿的部分:

[phim, dvbm] = cnscl(imu,0);    % coning & sculling compensation
phim = ins.Kg*phim-ins.eb*nts; dvbm = ins.Ka*dvbm-ins.db*nts;  % calibration

ins.wib = phim/nts; ins.fb = dvbm/nts;  % same as trjsimu

coning & sculling compensation为旋转运动和划桨运动误差补偿,现仅了解。
得到的phimdvbm为角速度和速度增量,所以eb(gyro漂移)和db(acc零偏)这里乘了时间,在后面代码中角速度和比力又除了时间。
calibration为对准误差补偿,关于惯性器件的误差。
主要来自于四个部分:

  1. 失准角误差μ,因为惯性器件的坐标轴为非直角坐标系{bg},要使角速度和加速度在同一坐标系需要求坐标变换矩阵,详见教材附录D。其中中转的另一个坐标系{B}与载体坐标系{b}的等效旋转矢量即为失准角。
  2. 不正交误差φ,非直角坐标系到中转的直角坐标系的偏差角,可以反映{bg}坐标系的不正交程度,越小正交性越好。
  3. 刻度系数误差k,相当于直尺膨胀、紧缩带来的误差。与前三项包含在标定刻度误差矩阵KgKa中。下图为陀螺仪误差模型。
  4. 常值漂移(零漂)ε,上下标代表在某个坐标系中的投影。
    P89
    整理得到,加速度计同理:
    P89

kf相关函数的学习

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);

kfinit初始化

模型建立:

function kf = kfinit(ins, varargin)
global glv psinsdef
[Re,deg,dph,ug,mg] = ... % just for short
    setvals(glv.Re,glv.deg,glv.dph,glv.ug,glv.mg); 
o33 = zeros(3); I33 = eye(3); 
kf = [];
if isstruct(ins),    nts = ins.nts;
else                 nts = ins;
end

定义全局变量glvpsinsdef,后者包含卡尔曼滤波的状态、测量维数类型。

switch(psinsdef.kfinit)
    case psinsdef.kfinit153,
        psinsdef.kffk = 15;  psinsdef.kfhk = 153;  psinsdef.kfplot = 15;
        [davp, imuerr, rk] = setvals(varargin);
        kf.Qt = diag([imuerr.web; imuerr.wdb; zeros(9,1)])^2;
        kf.Rk = diag(rk)^2;
        kf.Pxk = diag([davp; imuerr.eb; imuerr.db]*1.0)^2;
        kf.Hk = kfhk(0);

SINS_GPS_153.m中psinstypedef(153);定义了psinsdef.kfinit的值为153,此时switch语句根据该值执行相应的语句。根据输入变量定义对应大小的davp,immerr,rk。

  1. 过程噪声矩阵Qt与gyro和acc的随机游走白噪声webwdb相关,且对准的是状态的前六项(失准角偏差和速度偏差)。
  2. 测量噪声矩阵Rk与输入的gps位置误差rk有关。
  3. 协方差矩阵Pxk是【avp的误差】,【gyro和acc的漂移】的平方。
  4. 最后定义Hk使用函数kfhk。
function Hk = kfhk(ins, varargin)
global psinsdef
    switch(psinsdef.kfhk)
        case 153,
            Hk = [zeros(3,6), eye(3), zeros(3,6)];

至此kf结构体如下:
KF

kf = kfinit0(kf, nts);

定义好上面四个矩阵后,最后还有一个非常重要的kfinit0函数。

function kf = kfinit0(kf, nts)
% Always called by kfinit and initialize the remaining fields of kf.
% See also kfinit, kfupdate, kffeedback, psinstypedef.
    kf.nts = nts;
    [kf.m, kf.n] = size(kf.Hk);
    kf.I = eye(kf.n);
    kf.Kk = zeros(kf.n, kf.m);
    kf.measmask = [];            % measurement mask for no update  20/11/2022
    kf.measstop = zeros(kf.m,1); % measurement stop time
    kf.measlost = zeros(kf.m,1); % measurement lost time
    kf.measlog = 0;              % measurement log flag

上面代码段记录了Hk矩阵的大小,定义增益矩阵Kk以及一系列的测量相关的空矩阵和变量。下面代码段定义了kf一系列cell,现在用上的是xkQk以及pconstrain

if ~isfield(kf, 'xk'),  kf.xk = zeros(kf.n, 1);  end
    if ~isfield(kf, 'Qk'),  kf.Qk = kf.Qt*kf.nts;  end
    if ~isfield(kf, 'Gammak'),  kf.Gammak = 1; kf.l = kf.n;  else, kf.l=size(kf.Gammak,2);  end
    if ~isfield(kf, 'fading'),  kf.fading = 1;  end
    if ~isfield(kf, 'adaptive'),  kf.adaptive = 0;  end
%     if kf.adaptive==1
        if ~isfield(kf, 'b'),  kf.b = 0.5;  end
        if ~isfield(kf, 'beta'),  kf.beta = 1;  end
        if ~isfield(kf, 'Rmin'),  kf.Rmin = 0.01*kf.Rk;  end
        if ~isfield(kf, 'Rmax'),  kf.Rmax = 100*kf.Rk;  end
        if ~isfield(kf, 'Qmin'),  kf.Qmin = 0.01*kf.Qk;  end
        if ~isfield(kf, 'Qmax'),  kf.Qmax = 100*kf.Qk;  end
%     end
    if ~isfield(kf, 'xtau'),  kf.xtau = ones(size(kf.xk))*eps;   end
    if ~isfield(kf, 'T_fb'),  kf.T_fb = 1;   end
    if ~isfield(kf, 'fbstr'),  kf.fbstr = 'avped';  end
    if ~isfield(kf, 'xconstrain'),  kf.xconstrain = 0;  end
    if ~isfield(kf, 'pconstrain'),  kf.pconstrain = 0;  end
    kf.Pmax = (diag(kf.Pxk)+1)*1.0e10;
    kf.Pmin = kf.Pmax*0;
%     kf.Pykk_1 = kf.Hk*kf.Pxk*kf.Hk'+kf.Rk;
    kf.Pykk_1 = kf.Hk*kf.Pxk*kf.Hk'+0;
    kf.xfb = zeros(kf.n, 1);
%     kf.coef_fb = (1.0-exp(-kf.T_fb./kf.xtau));
%     kf.coef_fb = ar1coefs(kf.T_fb, kf.xtau);
    xtau = kf.xtau;
    xtau(kf.xtau<kf.T_fb) = kf.T_fb;  kf.coef_fb = kf.T_fb./xtau;  %2015-2-22
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);

上面定义kf最小协方差矩阵,并将pconstrain设置为1,可以达到限制协方差矩阵发散的效果吗?
prealloc函数为滤波后的数据提前分配好空间。

kfupdate更新

进入滤波,先将ins的数据更新,得到更新后的ins。kffk函数创造转移矩阵。

转移矩阵
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);

下面为kffk函数,当kffk全局变量为15时,使用etm函数创造误差转移矩阵,可在严老师的教材和博士毕业论文学习。
得到Ft后再离散化,采样间隔大时指数运算离散化,采样间隔小时泰勒展开到一阶。

function [Fk, Ft] = kffk(ins, varargin)
%Create Kalman filter system transition matrix.
global psinsdef
    %% get Ft
    if isstruct(ins),    nts = ins.nts;
    else                 nts = ins;
    end
    switch(psinsdef.kffk)
        case 15,
            Ft = etm(ins);

 %% discretization
	Fk = Ft*nts;
    if nts>0.1  % for large time interval, this may be more accurate.
        Fk = expm(Fk);
    else   % Fk = I + Ft*nts + 1/2*(Ft*nts)^2  , 2nd order expension
        Fk = eye(size(Ft)) + Fk;% + Fk*Fk*0.5; 
    end

这里涉及到avp更新方程和误差方程的推导

function Ft = etm(ins)
%SINS Error Transition Matrix (see my PhD dissertation p39

%%     fi     dvn    dpos    eb       db
Ft = [ Maa    Mav    Map    -ins.Cnb  O33 
       Mva    Mvv    Mvp     O33      ins.Cnb 
       O33    Mpv    Mpp     O33      O33
       zeros(6,9)  diag(-1./[ins.tauG;ins.tauA]) ];

%[ins.tauG, ins.tauA] = setvals(inf(3,1)); % gyro & acc correlation time
更新函数

注释部分介绍很详细。

TimeMeasBoth - described as follows,
            TimeMeasBoth='T' (or nargin==1) for time updating only, 
            TimeMeasBoth='M' for measurement updating only, 
            TimeMeasBoth='B' (or nargin==2) for both time and measurement updating.
  • (1) If kf.adaptive=1, then use Sage-Husa adaptive method (but only
    for measurement noise ‘Rk’), where minimum constrain ‘Rmin’
    and maximum constrain ‘Rmax’ are considered to avoid divergence.
  • (2) If kf.fading>1, then use fading memory filtering method.
  • (3) Using Pmax&Pmin to constrain Pxk, such that Pmin<=diag(Pxk)<=Pmax.

根据输入变量数目调整TimeMeasBoth的值。

if nargin==1;
    TimeMeasBoth = 'T';
elseif nargin==2
    TimeMeasBoth = 'B';
end

见代码部分,如果仅更新时间(也就是状态向前传播,协方差也向前传播),此处的Gammk设置为1,作用还未知;并记录下测量停止的时间,测量丢失的时间(还未知,后面可能在丢失测量值时能用上或者两者频率不一样时能用上),其初始值都是zeros(3,1),到此函数结束,步出kfupdate。

if TimeMeasBoth=='T'            % Time Updating
    kf.xk = kf.Phikk_1*kf.xk;
    kf.Pxk = kf.Phikk_1*kf.Pxk*kf.Phikk_1' + kf.Gammak*kf.Qk*kf.Gammak';
    kf.measstop = kf.measstop - kf.nts;  kf.measlost = kf.measlost + kf.nts;
else

仅测量更新和两者都更新是并列的,TimeMeasBoth=='M' 就是将上一个时刻传播的状态和协方差矩阵更新; TimeMeasBoth=='B'就是状态向前传播,协方差也向前传播,并记录下测量停止的时间,测量丢失的时间。
然后将测量值yk用于更新状态和协方差。并且可以实现自适应卡尔曼滤波器、衰减记忆滤波器;限制xk,Pk的功能防止其发散以达到好的滤波效果。

if TimeMeasBoth=='M'        % Meas Updating
    kf.xkk_1 = kf.xk;
    kf.Pxkk_1 = kf.Pxk;
elseif TimeMeasBoth=='B'    % Time & Meas Updating
    kf.xkk_1 = kf.Phikk_1*kf.xk;
    kf.Pxkk_1 = kf.Phikk_1*kf.Pxk*kf.Phikk_1' + kf.Gammak*kf.Qk*kf.Gammak';
    kf.measstop = kf.measstop - kf.nts;  kf.measlost = kf.measlost + kf.nts;
else
    error('TimeMeasBoth input error!');
end
kf.Pxykk_1 = kf.Pxkk_1*kf.Hk';
kf.Py0 = kf.Hk*kf.Pxykk_1;
kf.ykk_1 = kf.Hk*kf.xkk_1;
kf.rk = yk-kf.ykk_1;
idxbad = [];  % bad measurement index
if kf.adaptive==1  % for adaptive KF, make sure Rk is diag 24/04/2015
    for k=1:kf.m
        if yk(k)>1e10, idxbad=[idxbad;k]; continue; end  % 16/12/2019
        ry = kf.rk(k)^2-kf.Py0(k,k);
        if ry<kf.Rmin(k,k), ry = kf.Rmin(k,k); end
        if ry>kf.Rmax(k,k),     kf.Rk(k,k) = kf.Rmax(k,k);
        else                	kf.Rk(k,k) = (1-kf.beta)*kf.Rk(k,k) + kf.beta*ry;
        end
    end
    kf.beta = kf.beta/(kf.beta+kf.b);
end

应用例子:

function kf = kfupdate(kf, yk, TimeMeasBoth)

kf = kfupdate(kf);相当于TimeMeasBoth='T',仅向前传播xk、Pk,在没有接收到测量值yk之前一直传播。
kf = kfupdate(kf, ins.pos-posGPS, 'M');将GPS与ins的位置误差输入,同时将前面传播过来的xk、Pk赋值,后加入yk进行卡尔曼增益矩阵的计算以及xk、Pk的估计更新。
kf = kfupdate(kf, ins.pos-posGPS, 'B');将两个步骤合并,传播和更新合并在一起,在本例程中测量值和状态的频率不一致所以分开进行两个步骤。

kffeedback反馈

应用:

[kf, ins] = kffeedback(kf, ins, 1, 'avp');

function [kf, ins, xfb] = kffeedback(kf, ins, T_fb, fbstr)

T_fb为反馈时间间隔,fbstr为反馈字符串(反馈变量类型),输出反馈状态xfb
下面部分代码kf中的反馈时间间隔与输入的不一致时,如何调整的反馈相关系数。

    if nargin<4, fbstr=kf.fbstr; end
    if nargin<3, T_fb=1; end
    if kf.T_fb~=T_fb
        kf.T_fb = T_fb;
%         kf.coef_fb = (1.0-exp(-kf.T_fb./kf.xtau));
%         kf.coef_fb = ar1coefs(kf.T_fb, kf.xtau);
%         xtau = kf.xtau;
%     	xtau(kf.xtau<kf.T_fb) = kf.T_fb;  kf.coef_fb = kf.T_fb./xtau;  %2015-2-22
%         kf.coef_fb(kf.xtau>kf.T_fb) = 1;
        idx = kf.T_fb>kf.xtau;  % scale<vector
        kf.coef_fb(idx) = 1;  kf.coef_fb(~idx) = kf.T_fb./kf.xtau(~idx);   %2022-6-25
        kf.coef_fb(kf.xtau<0.001 & kf.T_fb~=inf) = 1;
    end

下面xfb_tmp为相关系数处理后的反馈缓存值,并创造等大小的零矩阵xfb
根据不同的fbstr,使用卡尔曼滤波和相关系数处理后的xk对ins中的相应变量进行修正并进行反馈记录。

xfb_tmp = kf.coef_fb.*kf.xk;  xfb = xfb_tmp*0;
for k=1:length(fbstr)
    switch fbstr(k)
        case 'a',
            idx = 1:3; ins.qnb = qdelphi(ins.qnb, xfb_tmp(idx));
        case 'v',
            idx = 4:6; ins.vn = ins.vn - xfb_tmp(idx);
        case 'p',
            idx = 7:9; ins.pos = ins.pos - xfb_tmp(idx);
        case 'e',
            idx = 10:12; ins.eb = ins.eb + xfb_tmp(idx);
        case 'd',
            idx = 13:15; ins.db = ins.db + xfb_tmp(idx);
        case 'A',
            idx = 1:2; ins.qnb = qdelphi(ins.qnb, [xfb_tmp(idx);0]);
        case 'V',
            idx = 6; ins.vn(3) = ins.vn(3) - xfb_tmp(idx);
        case 'P',
            idx = 9; ins.pos(3) = ins.pos(3) - xfb_tmp(idx);
        case 'E',
            idx = 10:11; ins.eb(1:2) = ins.eb(1:2) + xfb_tmp(idx);
        case 'D',
            idx = 15; ins.db(3) = ins.db(3) + xfb_tmp(idx);
        case 'L',
            idx = 16:18; ins.lever = ins.lever + xfb_tmp(idx);
        case 'T',
            idx = 19; ins.tDelay = ins.tDelay + xfb_tmp(idx);
        case 'G',
            idx = 20:28; dKg = xfb_tmp(idx);  dKg = [dKg(1:3),dKg(4:6),dKg(7:9)];
            ins.Kg = (eye(3)-dKg)*ins.Kg;
        case 'C',
            idx = 29:34; dKa = xfb_tmp(idx);  dKa = [dKa(1:3),[0;dKa(4:5)],[0;0;dKa(6)]];
            ins.Ka = (eye(3)-dKa)*ins.Ka;
        case 'H',
            idx = [6,9,15];                         ins.vn(3) = ins.vn(3) - xfb_tmp(6);
            ins.pos(3) = ins.pos(3) - xfb_tmp(9);	ins.db(3) = ins.db(3) + xfb_tmp(15);
        otherwise,
            error('feedback string mismatch in kf_feedback');
    end
        kf.xk(idx) = kf.xk(idx) - xfb_tmp(idx);    
        kf.xfb(idx) = kf.xfb(idx) + xfb_tmp(idx);  % record total feedback
        xfb(idx) = xfb_tmp(idx);

a、v、p、e、d分别使用估计出来的误差对ins中四元数姿态、速度、位置、陀螺漂移、加表零偏进行补偿。
A、V、P分别对姿态的pitch、roll角、z方向的速度、z方向的位置进行补偿。
E、D分别对陀螺漂移的x、y方向角速度、加表零偏的z方向比力
L、T、G、C使用更多维数的状态估计补偿。
H为进行高度(z方向)上的avp补偿。

误差方程的推导

以下均参考严老师教材第四章。

姿态

attitude
误差产生原因:
P90
误差方程推导(在大多数情况下,比如在惯导系统标定比较准确的时候或者运载体机动不大时,可以忽略标度系数矩阵误差δKG、δKA的影响,过程噪声矩阵Q(t)对角线前三个元素为web陀螺角度随机游走/角速率白噪声:
误差方程推导
列状态转移矩阵:
在这里插入图片描述

速度

误差方程来自于更新方程,原因和姿态误差处类似。
velocity
列状态转移矩阵,过程噪声矩阵Q(t)对角线第4-6个元素为wdb加计速度随机游走/比力白噪声:
err

位置

![pos](https://img-blog.csdnimg.cn/direct/9247a774524b41898a2055e693a9d272.jpeg

惯性器件模型误差:

在这里插入图片描述
状态转移矩阵Ft,在函数etm中,自己建模型时重新写一个函数即可:

%%     fi     dvn    dpos    eb       db
Ft = [ Maa    Mav    Map    -ins.Cnb  O33 
       Mva    Mvv    Mvp     O33      ins.Cnb 
       O33    Mpv    Mpp     O33      O33
       zeros(6,9)  diag(-1./[ins.tauG;ins.tauA]) ];

%[ins.tauG, ins.tauA] = setvals(inf(3,1)); % gyro & acc correlation time
  • 44
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 2/3维图像分割工具箱 2 PSORT粒子群优化工具箱 3 matlab计量工具箱Lesage 4 MatCont7p1 5 matlab模糊逻辑工具箱函数 6 医学图像处理工具箱 7 人工蜂群工具箱 8 MPT3安装包 9 drEEM toolbox 10 DOMFluor Toolbox v1.7 11 Matlab数学建模工具箱 12 马尔可夫决策过程(MDP)工具箱MDPtoolbox 13 国立SVM工具箱 14 模式识别与机器学习工具箱 15 ttsbox1.1语音合成工具箱 16 分数阶傅里叶变换的程序FRFT 17 魔方模拟器与规划求解 18 隐马尔可夫模型工具箱 HMM 19 图理论工具箱GrTheory 20 自由曲线拟合工具箱ezyfit 21 分形维数计算工具箱FracLab 2.2 22 For-Each 23 PlotPub 24 Sheffield大学最新遗传算法工具箱 25 Camera Calibration 像机标定工具箱 26 Qhull(二维三维三角分解、泰森图)凸包工具箱 2019版 27 jplv7 28 MatlabFns 29 张量工具箱Tensor Toolbox 30 海洋要素计算工具箱seawater 31 地图工具箱m_map 32 othercolor配色工具包 33 Matlab数学建模工具箱 34 元胞自动机 35 量子波函数演示工具箱 36 图像局域特征匹配工具箱 37 图像分割graphcut工具箱 38 NSGA-II工具箱 39 chinamap中国地图数据工具箱(大陆地区) 40 2D GaussFit高斯拟合工具箱 41 dijkstra最小成本路径算法 42 多维数据快速矩阵乘法 43 约束粒子群优化算法 44 脑MRI肿瘤的检测与分类 45 Matlab数值分析算法程序 46 matlab车牌识别完整程序 47 机器人工具箱robot-10.3.1 48 cvx凸优化处理工具箱 49 hctsa时间序列分析工具箱 50 神经科学工具箱Psychtoolbox-3-PTB 51 地震数据处理工具CREWES1990版 52 经济最优化工具箱CompEcon 53 基于约束的重构分析工具箱Cobratoolbox 54 Schwarz-Christoffel Toolbox 55 Gibbs-SeaWater (GSW)海洋学工具箱 56 光声仿真工具箱K-Wave-toolbox-1.2.1 57 语音处理工具箱Sap-Voicebox 58 贝叶斯网工具箱Bayes Net Toolbox(BNT) 59 计算机视觉工具箱VFfeat-0.9.21 60 全向相机校准工具箱OCamCalib_v3.0 61 心理物理学数据分析工具箱Palamedes1_10_3 62 生理学研究工具箱EEGLAB 63 磁共振成像处理工具箱CONN 18b 64 matlab 复杂网络工具箱 65 聚类分析工具箱FuzzyClusteringToolbox 66 遗传规划matlab工具箱 67 粒子群优化工具箱 68 数字图像处理工具箱DIPUM Toolbax V1.1.3 69 遗传算法工具箱 70 鱼群算法工具箱OptimizedAFSAr 71 蚁群算法工具箱 72 matlab优化工具箱 73 数据包络分析工具箱 74 图像分割质量评估工具包 75 相关向量机工具箱 76 音频处理工具箱 77 nurbs工具箱 78 Nurbs-surface工具箱 79 grabit数据提取工具箱 80 量子信息工具箱QLib 81 DYNAMO工具箱 82 NEDC循环的整车油耗量 83 PlotHub工具箱 84 MvCAT_Ver02.01 85 Regularization Tools Version 4.1 86 MatrixVB 4.5(含注册) 87 空间几何工具箱 matGeom-1.2.2 88 大数计算工具箱 VariablePrecisionIntegers 89 晶体织构分析工具包 mtex-5.7.0 90 Minimal Paths 2工具箱 91 Matlab数学建模工具箱

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值