# Psins代码解析之全局变量&轨迹仿真（test_SINS_trj.m）&惯性解算（test_SINS.m）

9 篇文章 402 订阅

以上内容来自：《捷联惯导算法及车载组合导航系统研究（硕士论文）》严恭敏

#### 一、全局变量

global glv
if ~exist('Re', 'var'),  Re = [];  end
if ~exist('f', 'var'),   f = [];  end
if ~exist('wie', 'var'), wie = [];  end
if isempty(Re),  Re = 6378137;  end
if isempty(f),   f = 1/298.257;  end
if isempty(wie), wie = 7.2921151467e-5;  end
glv.Re = Re;                    % the Earth's semi-major axis
glv.f = f;                      % flattening
glv.Rp = (1-glv.f)*glv.Re;      % semi-minor axis
glv.e = sqrt(2*glv.f-glv.f^2); glv.e2 = glv.e^2; % 1st eccentricity
glv.ep = sqrt(glv.Re^2-glv.Rp^2)/glv.Rp; glv.ep2 = glv.ep^2; % 2nd eccentricity
glv.wie = wie;                  % the Earth's angular rate
glv.meru = glv.wie/1000;        % milli earth rate unit
glv.g0 = 9.7803267714;          % gravitational force
glv.mg = 1.0e-3*glv.g0;         % milli g
glv.ug = 1.0e-6*glv.g0;         % micro g 为 微g
glv.mGal = 1.0e-3*0.01;         % milli Gal = 1cm/s^2 ~= 1.0E-6*g0
glv.ugpg2 = glv.ug/glv.g0^2;    % ug/g^2
glv.ws = 1/sqrt(glv.Re/glv.g0); % Schuler frequency
glv.ppm = 1.0e-6;               % parts per million百万分之一
glv.deg = pi/180;               % arcdeg 弧度单位 rad
glv.min = glv.deg/60;           % arcmin
glv.sec = glv.min/60;           % arcsec
glv.hur = 3600;                 % time hour (1hur=3600second)
glv.dps = pi/180/1;             % arcdeg / second
glv.dph = glv.deg/glv.hur;      % arcdeg / hour ;最终单位为 rad/s;
glv.dpss = glv.deg/sqrt(1);     % arcdeg / sqrt(second) 为 rad/sqrt(s)
glv.dpsh = glv.deg/sqrt(glv.hur);  % arcdeg / sqrt(hour) 为 rad/sqrt(hour);最终单位为：rad/sqrt(s)
glv.dphpsh = glv.dph/sqrt(glv.hur); % (arcdeg/hour) / sqrt(hour) 为 rad/hour/sqrt(hour)
glv.Hz = 1/1;                   % Hertz
glv.dphpsHz = glv.dph/glv.Hz;   % (arcdeg/hour) / sqrt(Hz) 为 rad/hour/sqrt(Hz)
glv.ugpsHz = glv.ug/sqrt(glv.Hz);  % ug / sqrt(Hz)
glv.ugpsh = glv.ug/sqrt(glv.hur); % ug / sqrt(hour)
glv.mpsh = 1/sqrt(glv.hur);     % m / sqrt(hour)
glv.mpspsh = 1/1/sqrt(glv.hur); % (m/s) / sqrt(hour), 1*mpspsh~=1700*ugpsHz
glv.ppmpsh = glv.ppm/sqrt(glv.hur); % ppm / sqrt(hour)
glv.mil = 2*pi/6000;            % mil
glv.nm = 1853;                  % nautical mile 海里
glv.kn = glv.nm/glv.hur;        % knot 节
%%
glv.wm_1 = [0,0,0]; glv.vm_1 = [0,0,0];   % the init of previous gyro & acc sample
glv.cs = [                      % coning & sculling compensation coefficients
[2,    0,    0,    0,    0    ]/3
[9,    27,   0,    0,    0    ]/20
[54,   92,   214,  0,    0    ]/105
[250,  525,  650,  1375, 0    ]/504
[2315, 4558, 7296, 7834, 15797]/4620 ];
glv.csmax = size(glv.cs,1)+1;  % max subsample number
glv.v0 = [0;0;0];    % 3x1 zero-vector
glv.qI = [1;0;0;0];  % identity quaternion 初始四元数
glv.I33 = eye(3); glv.o33 = zeros(3);  % identity & zero 3x3 matrices
glv.pos0 = [34.246048*glv.deg; 108.909664*glv.deg; 380]; % position of INS Lab@NWPU
glv.eth = []; glv.eth = earth(glv.pos0);
%%
[glv.rootpath, glv.datapath, glv.mytestflag] = psinsenvi;
glv1 = glv;

#### 二、生成仿真轨迹 test_SINS_trj.m

%‘2’为航向角速率(转弯)，2deg/s，转弯时间为45秒;
%协调转弯时间为4秒，即飞机横滚时间，很滚角速率 根据前向速度和航向角速率计算出
seg = trjsegment(seg, 'coturnleft',   45, 2, xxx, 4);

trjsegment子函数中对应部分：

case 'coturnleft', % coordinate turn left
rolllasting = var1; rollw = atan(cf/9.8)/dps/rolllasting; %rollw为横滚角速率（deg/s）
seg = trjsegment(seg, 'rollleft',  rolllasting, rollw);
seg = trjsegment(seg, 'turnleft',  lasting, w);
seg = trjsegment(seg, 'rollright', rolllasting, rollw);

case 'turnleft',
seg.wat = [seg.wat; [lasting, seg.vel, 0, 0, w*dps,-cf, 0, 0]];
case 'turnright',
seg.wat = [seg.wat; [lasting, seg.vel, 0, 0,-w*dps, cf, 0, 0]];
case 'rollleft',
seg.wat = [seg.wat; [lasting, seg.vel, 0,-w*dps, 0, 0, 0, 0]];
case 'rollright',
seg.wat = [seg.wat; [lasting, seg.vel, 0, w*dps, 0, 0, 0, 0]];

• 初始化
• 静止100秒
• 向北加速飞行10秒（a=1m/s^2）
• 匀速保持100秒
• 左转弯90°(最终方向为正西，包括飞机先滚转、再转弯、最后反向滚转，恢复滚转角为0)
• 匀速保持100秒
• 右转弯450°（最终方向为正北，包括飞机先滚转、再转弯、最后反向滚转，恢复滚转角为0）
• 匀速保持100秒
• climb 抬头(2°/s *10s=20°)-匀速保持-低头(-2°/s *10s=-20°)
• 匀速保持100秒
• descent 低头(-2°/s *10s=-20°) -保持 -抬头(2°/s *10s=20°)
• 匀速保持100秒
• 减速 5秒（a=-2m/s^2），至速度为0
• 静止100秒

#### 三、纯惯性导航仿真 test_SINS.m

（1）imuerrset.m

%% constant bias & random walk
imuerr.eb(1:3) = eb*glv.dph;   imuerr.web(1:3) = web*glv.dpsh;
imuerr.db(1:3) = db*glv.ug;    imuerr.wdb(1:3) = wdb*glv.ugpsHz;

imuerr.db单位为：m/s^2 ;  imuerr.wdb单位为：m/s^2/sqrt(s)

drift = [ ts*imuerr.eb(1) + sts*imuerr.web(1)*randn(m,1), ...
ts*imuerr.eb(2) + sts*imuerr.web(2)*randn(m,1), ...
ts*imuerr.eb(3) + sts*imuerr.web(3)*randn(m,1), ...
ts*imuerr.db(1) + sts*imuerr.wdb(1)*randn(m,1), ...
ts*imuerr.db(2) + sts*imuerr.wdb(2)*randn(m,1), ...
ts*imuerr.db(3) + sts*imuerr.wdb(3)*randn(m,1) ];
imu(:,1:6) = imu(:,1:6) + drift;

2、初始姿态、速度、位置误差

avpseterr.m

function davp = avpseterr(phi, dvn, dpos)
% avp errors setting.
% Inputs: phi - platform misalignment angles. NOTE: leveling errors
%               phi(1:2) in arcsec, azimuthe error phi(3) in arcmin
%         dvn - velocity errors in m/s
%         dpos - position errors dpos=[dlat;dlon;dhgt], all in m
% Output: davp = [phi; dvn; dpos]

3、利用一阶马尔可夫生成气压高度计仿真信息

bhsimu.m

t = (trj.avp(1,10):ts:trj.avp(end,10))';
bh = interp1(trj.avp(:,10), trj.avp(:,9), t, 'linear');
bh = bh + bias + markov1(var, tau, ts, length(bh),1);

ins.vn(3) = href(k1,2);  ins.pos(3) = href(k1,1);

4、纯惯导解算：

（1）首先对地球、载体相关参数进行外推以双子样为例，nts=2*ts，外推ts;

%% earth & angular rate updating
vn01 = ins.vn+ins.an*nts2; pos01 = ins.pos+ins.Mpv*vn01*nts2;  % extrapolation at t1/2
ins.eth = ethupdate(ins.eth, pos01, vn01);
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/2时刻，所以除以2

• 前一时刻速度、加速度、前一时刻位置；外推得到nts时刻的速度、位置
• 利用外推得到的速度、位置去更新地球相关参数，主要为：子午圈、卯酉圈半径；东北天下wnie分量（与纬度有关）、wnen分量（与速度、位置有关）、重力加速度（与纬度、高度有关）、等信息

（2）速度更新：以双子样为例，nts=2*ts

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

%% (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;
vn1 = ins.vn + ins.an*nts;

（3）位置更新：以双子样为例，nts=2*ts

%% (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;

（4）姿态更新：以双子样为例，nts=2*ts

%% (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];

5、误差图：

• 25
点赞
• 118
收藏
觉得还不错? 一键收藏
• 3
评论
04-05 6431

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

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

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