NaveGo 开源组合导航代码框架介绍!

首先附一个介绍:NaveGo: an open-source MATLAB/GNU Octave toolbox for processing integrated navigation systems and performing inertial sensors analysis.

源码下载地址: NaveGo

编程语言:matlab


这个短小精悍的代码,主要包括以下几个部分:

(1)根据参考数据集和GPS datasheet,生成含有误差的GPS数据:

GPS 误差数据

% Garmin 5-18 Hz GPS error profile

GPS data structure:
        t: Mx1 time vector (seconds).
      lat: Mx1 latitude (radians).
      lon: Mx1 longitude (radians).
        h: Mx1 altitude (m).
      vel: Mx3 NED velocities (m/s).
      std: 1x3 position standard deviations (rad, rad, m).
     stdm: 1x3 position standard deviations (m, m, m).
     stdv: 1x3 velocity standard deviations (m/s).
     larm: 3x1 lever arm (x-right, y-fwd, z-down) (m).  杆臂效应 右-前-下
     freq: 1x1 sampling frequency (Hz).

主要是:以米为单位的latitude、longitude、高度误差设置;东北天三个速度误差设置、杆臂长度、频率等信息。

 GPS仿真数据(真实数据+误差数据)

参考数据频率为100HZ,在此处主要是通过round函数进行降采样,完成!

% Downsampling GPS estimates from 1/dt Hz to freq Hz.
dt   = mean(diff(ref.t));
freq = 1/dt;
dspl = round(freq / gps.freq); %四舍五入

dow = floor(m/dspl);  %数据点 ;向负无穷取整

gps_r.t     = ref.t    (1:dspl:end, :);
gps_r.lat   = ref.lat  (1:dspl:end, :);
gps_r.lon   = ref.lon  (1:dspl:end, :);
gps_r.h     = ref.h    (1:dspl:end, :);
gps_r.vel   = ref.vel  (1:dspl:end, :);

gps_r.kn = dow;
gps_r.freq = round(1/mean(diff(gps_r.t)));

(2)根据参考数据集和IMU datasheet,生成含有误差的IMU数据:

Reference.mat含有如下数据:

ref.mat contains the reference data structure from which inertial 
sensors and GPS wil be simulated. It must contain the following fields:

        t: Nx1 time vector (seconds).
      lat: Nx1 latitude (radians).
      lon: Nx1 longitude (radians).
        h: Nx1 altitude (m).
      vel: Nx3 NED velocities (m/s).
     roll: Nx1 roll angles (radians).
    pitch: Nx1 pitch angles (radians).
      yaw: Nx1 yaw angle vector (radians).
       kn: 1x1 number of elements of time vector.
    DCMnb: Nx9 Direct Cosine Matrix nav-to-body. Each row contains
           the elements of one matrix ordered by columns as 
           [a11 a21 a31 a12 a22 a32 a13 a23 a33].每行包含按照‘列’顺序排序的元素
     freq: sampling frequency (Hz).

IMU Error Profile

扫描二维码关注公众号,回复: 10375351 查看本文章
% ADIS16405 IMU error profile
IMU data structure:
        t: Ix1 time vector (seconds).
       fb: Ix3 accelerations vector in body frame XYZ (m/s^2).
       wb: Ix3 turn rates vector in body frame XYZ (radians/s).
      arw: 1x3 angle random walks (rad/s/root-Hz).
      vrw: 1x3 velocity random walks (m/s^2/root-Hz).
     gstd: 1x3 gyros standard deviations (radians/s).
     astd: 1x3 accrs standard deviations (m/s^2).
   gb_fix: 1x3 gyros static biases or turn-on biases (radians/s).常值零偏
   ab_fix: 1x3 accrs static biases or turn-on biases (m/s^2).
 gb_drift: 1x3 gyros dynamic biases or bias instabilities
 (radians/s).零偏稳定性/零漂
 ab_drift: 1x3 accrs dynamic biases or bias instabilities (m/s^2).
  gb_corr: 1x3 gyros correlation times (seconds).
  ab_corr: 1x3 accrs correlation times (seconds).
    gpsd : 1x3 gyros dynamic biases PSD (rad/s/root-Hz).
    apsd : 1x3 accrs dynamic biases PSD (m/s^2/root-Hz);
     freq: 1x1 sampling frequency (Hz).
ini_align: 1x3 initial attitude at t(1).
ini_align_err: 1x3 initial attitude errors at t(1).

ref dataset will be used to simulate IMU sensors.

解析一下,源码中是怎么根据Datasheet 生成IMU误差的:

只考虑了三种误差:常值零偏、零偏稳定性(零漂/In-Run Bias Stability)、随机游走(RW)

其中生成噪声的代码段如下:

% Set static bias randomly from interval
a = -imu.gb_fix(1);
b = imu.gb_fix(1);
gb_fix = (b-a).*rand(3,1) + a;

% Random vectors
r1=randn(ref.kn,1);
r2=randn(ref.kn,1);
r3=randn(ref.kn,1);
r4=randn(ref.kn,1);
r5=randn(ref.kn,1);
r6=randn(ref.kn,1);
o=ones(ref.kn,1);

if (isinf(imu.gb_corr))
    sigmc = imu.gb_drift;
    gb_corr = [sigmc(1).*r4 sigmc(2).*r5 sigmc(3).*r6];
else
    % Gyro correlation noise
    gb_corr = zeros(ref.kn,3);
    dt=mean(diff(ref.t));
    alpha = exp(-dt./imu.gb_corr);
    sigmc = imu.gb_drift .* sqrt(1 - alpha.^2);
    gb_corr(1,:) = gb_fix' + [sigmc(1).*r4(1) sigmc(2).*r5(1) sigmc(3).*r6(1)];

    for i=2:ref.kn    
        gb_corr (i,:) = alpha .* gb_corr (i-1,:) + [sigmc(1).*r4(i) sigmc(2).*r5(i) sigmc(3).*r6(i)]; 
    end
end

wb = gyro_b + gyro_err_b + ...
     [imu.gstd(1).*r1    imu.gstd(2).*r2    imu.gstd(3).*r3 ] + ...
     [gb_fix(1).*o   gb_fix(2).*o   gb_fix(3).*o] + ...
     gb_corr; 

代码解析:以陀螺仪为例;

ARW为角度随机游走,其表达成为高斯白噪声序列:

imu_nav.gstd   = imu_nav.arw ./ sqrt(dt); % rad/s/root-Hz  ->  rad/s
r1=randn(ref.kn,1);
imu.gstd(1).*r1 

 gb_fix为常值零偏,其每次开机都不同,但是开机之后为固定值;因此代码中将常值零偏设定为【-常值零偏 +常值零偏】之间的任意一个数;

In_Run Bias Stability为零偏稳定性,将其设为一阶马尔可夫过程,计算公式如下:

加速度噪声也假定为:速度随机游走、常值零偏、零偏稳定性;其代码配置方式和陀螺仪一样!

Gyroscope仿真数据生成(理想数据+误差数据):

生成陀螺仪理想数据的数学公式如下:

% True gyro
if (isfield(ref, 'wb'))    
    
    gyro_b = ref.wb;

% Obtain gyros from DCM    
else
    gyro_raw = gyro_gen_delta(ref.DCMnb, diff(ref.t)); % 速率
    gyro_raw = [gyro_raw; 0 0 0;];
    gyro_b  = sgolayfilt(gyro_raw, 10, 45);
end

% omega_en_n and omega_ie_n
gyro_err_b = zeros(ref.kn, 3); 
for i = 1:ref.kn,
    
    dcmnb = reshape(ref.DCMnb(i,:), 3, 3); 
    omega_ie_n = earthrate(ref.lat(i));
    omega_en_n = transportrate(ref.lat(i), ref.vel(i,1), ref.vel(i,2), ref.h(i));
    omega_in_b = dcmnb * (omega_en_n + omega_ie_n ); 
    gyro_err_b(i,:) = ( omega_in_b )';   
end

加速度误差数据生成(理想数据+误差数据):要简单的多,在此,不做表述!

(3)组合导航代码实现:

首先是进行时间“对齐”:

找到大于第一个gps数据时间点的 IMU数据时间;

IMU最后一个数据左边的最后一个GPS时间;

采用21误差状态,反馈的方式进行组合导航;

【Roll Pitch Yaw Vn Ve Vd Latitude Longitude Height Bias_gyro Bias_acc Dirft_gyro Drift_acc】

载体坐标系为:前右下;

导航坐标系为:北东地;

(4)plot;线性插值进行时间对齐

%Interpolate reference dataset 

ref_1 = navego_interpolation (imu1_e, ref);
ref_2 = navego_interpolation (imu2_e, ref);
ref_g = navego_interpolation (gps, ref);

采用 method = 'linear';方法进行插值;进行误差对比;

参考轨迹图:红圈处为开始点;

姿态误差图:

总结:在“飞机”起飞后,先做提升运动,然后向北飞行,100秒左右,拐弯大约90°,向东飞行;此时可以看到kalman滤波器能够迅速收敛,将误差估计到一个比较好的状态!

发布了103 篇原创文章 · 获赞 38 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/wuwuku123/article/details/104923816