之前一直在忙项目,今天趁着程序员日,浅浅谈一下自己这段时间对IMU标定的一些见解吧。
目录
九轴传感器标定
1.1 IMU误差
随机误差我们一般通过均值、方差、Allan方差来评价,但是由于随机误差不是这篇文章的侧重点,所以关于随机误差大家,可以打开matlab运行下面这段代码,浅浅看一下高斯白噪声和随机游走噪声具体长什么样子。
rng(0); % 随机数种子
n1 = randn(10000,1); % 高斯白噪声1
n2 = randn(10000,1); % 高斯白噪声2
n3 = randn(10000,1); % 高斯白噪声3
w1 = cumsum(n1); % 随机游走1
w2 = cumsum(n2); % 随机游走2
w3 = cumsum(n3); % 随机游走3
figure(1);plot([n1 n2 n3], '.');
title('高斯白噪声');
legend('$n_1$','$n_2$','$n_3$', 'interpreter', 'latex');
figure(2);plot([w1 w2 w3]);
title('随机游走');
legend('$w_1$', '$w_2$', '$w_3$', 'interpreter', 'latex');
运行结果也可以给大家贴出来做一下参考。
然后就是重点,我们来分析一下IMU的确定性误差,这里因为我目前接触到的大多数IMU基本很少出现XYZ轴不正交和加速度计与陀螺仪坐标轴不重合的问题,所以这两个问题我们就不谈了。
关于温飘,一般我们会用温度及温度变化率多项式拟合温度产生的误差,这个式子就是:
上面这几个都不是我们这次讨论的重点,现在我们来好好讨论一下怎么解决零偏和尺度误差。
1.2 IMU简单校准
1.2.1 加速度计校准零偏与尺度误差
最简单的校准步骤如下:
- 将六个面朝上,分别获取每个面的最值为:
- 计算各个面的零偏与尺度误差,以x轴为例:,
- 则校准后的值为:
1.2.2 校准陀螺仪零偏
最简单的校准步骤如下:
- 静止一段时间,采集N组数据,求其平均值,为初始零偏:
- 将采集的数据减去初始零偏为校准后的值:
上述校准过程我们可以发现,陀螺仪我们是可以做到这样校准的,但是加速度计的校准我们在实际生活中无法保证每次只有固定一个面朝上而其他面不受影响,所以针对加速度计和磁力计,我们一般采用椭球拟合去校准。
1.2.3 椭球拟合流程
- 椭球方程:
- 展开可得:
- 定义误差:
- 目标函数:
- 根据线性最小二乘理论,最优解:,其中,
1.2.4 椭球拟合加速度计校准步骤
- 获取N次静止时加速度计数据,第i次为:
- 根据计算与,其中为,为v,为
- 获取M与p
- 计算最优解,即a,b,c,d,e,f
- 计算,算得
- 则校准结果为:
下面大家可以打开matlab,根据这段代码有更深入的理解:
%% 数据读取
dat = [ 9.9604 -0.0975 0.0549;
-9.6576 0.0974 -0.0145;
0.0889 9.7972 -0.0812;
0.0340 -9.8285 0.0264;
0.0909 -0.0595 9.9975;
0.1680 0.0215 -9.7350];
x = dat(:,1);
y = dat(:,2);
z = dat(:,3);
%% 最小二乘法参数估计
N = length(dat);
M = zeros(N, 6);
p = zeros(N, 1);
for k = 1:N
M(k,:) = [y(k)^2 z(k)^2 x(k) y(k) z(k) 1]; % 矩阵M
p(k) = -x(k)^2; % 向量p
end
v = inv(M'*M) * M' * p; % 计算最优解
x0 = -v(3) / 2; % 拟合出的x0
y0 = -v(4) / (2*v(1)); % 拟合出的y0
z0 = -v(5) / (2*v(2)); % 拟合出的z0
A = sqrt(x0*x0 + v(1)*y0*y0 + v(2)*z0*z0 - v(6)); % 拟合出的x方向上的轴半径A
B = A/sqrt(v(1)); % 拟合出的y方向上的轴半径B
C = A/sqrt(v(2)); % 拟合出的z方向上的轴半径C
dat_cali = zeros(size(dat));
scale = 9.8 ./ [A, B, C]; % 尺度因子
offset = [x0, y0, z0]; % 偏移
for k = 1:N
dat_cali(k,:) = scale .* (dat(k,:) - offset); % 校准结果
end
1.2.5 椭球拟合磁力计校准步骤
与加速度计椭球拟合步骤大致一样
- 转动磁力计,获取N次数据,第i次为:
- 根据计算与,其中为,为v,为
- 获取M与p
- 计算最优解,即a,b,c,d,e,f
- 计算,算得
- 则校准结果为:
这里给大家提供一个matlab的函数,可以直接调用进行椭球拟合:
function [scale, offset, cali_data] = func_lms_calibrate(data)
x = data(:,1);
y = data(:,2);
z = data(:,3);
%% 最小二乘法参数估计
N = length(data);
M = zeros(N, 6);
p = zeros(N, 1);
for k = 1:N
M(k,:) = [y(k)^2 z(k)^2 x(k) y(k) z(k) 1]; % 矩阵M
p(k) = -x(k)^2; % 向量p
end
v = inv(M'*M) * M' * p; % 计算最优解
x0 = -v(3) / 2; % 拟合出的x0
y0 = -v(4) / (2*v(1)); % 拟合出的y0
z0 = -v(5) / (2*v(2)); % 拟合出的z0
A = sqrt(x0*x0 + v(1)*y0*y0 + v(2)*z0*z0 - v(6)); % 拟合出的x方向上的轴半径A
B = A/sqrt(v(1)); % 拟合出的y方向上的轴半径B
C = A/sqrt(v(2)); % 拟合出的z方向上的轴半径C
cali_data = zeros(size(data));
scale = [A, B, C]; % 尺度因子
offset = [x0, y0, z0]; % 偏移
for k = 1:N
cali_data(k,:) = 1 ./ scale .* (data(k,:) - offset); % 校准结果
end
end
下面展示一下用这个方法拟合出来的磁力计数据效果: