IMU传感器
旋转运动学
旋转的线速度为:
r˙=(−aθ˙sinθ,aθ˙cosθ,0)⊤=⎣⎡0θ˙0−θ˙00000⎦⎤⎣⎡acosθasinθh⎦⎤=ω×r(1)
取模得到角速度和线速度之间的关系:
∣r˙∣=∣ω∣∣r∣sinϕ=a∣θ˙∣(2)
从Body系和Inertial系分别看旋转运动得到的速度关系为:
r˙I=RIBr˙B+R˙IBrB=RIBr˙B+[RIBωb]×r=RIBvb+ω×r(3)
vI≡RIBvb+ω×r⇔RIBvb≡vI−ω×r(4)
对公式(3)中速度求导得到加速度:
r¨I=RIBv˙B+R˙IBvB+ω×r˙+[R˙IBωb+RIBω˙b]×r=RIBaB+2ω×v+ω×(ω×r)+ω˙×r(5)
对公式(5)进行变形得到:
a=aI−科氏力2ω×v−欧拉力ω˙×r−离心力ω×(ω×r)(6)
其中:v=RIBvb,a=RIBab,它们表示body下的速度或加速度在Inertial系下的表示。要区别这几种表示,习惯了找一个真实值,只不过是不同系下的不同表示罢了
测量模型与运动模型
MEMS加速度计
使用电容或者电阻桥来进行测量,注意有可能测出来的加速度计值方向是与实际力相反的,因为是使用弹簧测出的惯性力。
陀螺仪
- 振动陀螺仪使用的是科氏力作用来测得旋转,一个主运动轴+一个敏感轴,与运动方向垂直方向(敏感轴方向)受一个科氏力。
- 一般使用两个运动方向相反的质量块来侧科氏力,这样可以抵消加速度的影响。若质量不一致会导致有差别。
IMU误差模型
分为:确定性误差,随机误差。前者可以提前标定,后者建模成高斯分布。
确定性误差
- 偏差bias
- 尺度因子Scale
- 轴偏差(非正交误差)
- Run-to-Run Bias/Scale Factor 即每次上电启动的值都不一样
- In Run (Stability) Bias/Scale Factor 即在运行过程中也会发生变化
- Temperature-Dependent Bias/Scale Factor 即受温度影响的变化值
尺度因子和非对称误差为:
⎣⎡laxlaylaz⎦⎤=⎣⎡sxxmyxmzxmxysyymzymxzmyzszz⎦⎤⎣⎡axayaz⎦⎤(7)
确定性误差标定方法——六面法
对于加速度计;
三轴分别朝上朝下放置一段时间,如果考虑为都是正交的,相加相减就可以得到:
bS=2lfup+lfdown=2⋅glfup−lfdown(8)
考虑轴间误差时,实际值与测量值之间的关系为
⎣⎡laxlaylaz⎦⎤=⎣⎡sxxmyxmzxmxysyymzymxzmyzszz⎦⎤⎣⎡axayaz⎦⎤+⎣⎡baxbaybaz⎦⎤(9)
变为齐次坐标得到:
⎣⎡laxlaylaz⎦⎤=⎣⎡sxxmyxmzxmxysyymzymxzmyzszzbaxbaybaz⎦⎤⎣⎢⎢⎡axayaz1⎦⎥⎥⎤(10)
然后再进行转置,标准的加速度值已知,利用最小二乘求解12个参数即可。
对于陀螺仪;
也可以使用六面法,需要高精度转台提供真实值,六个值分别为绕各个轴的顺时针和逆时针的角速度。
温度相关
进行温度补偿,获得不同温度时的bias和scale值,绘制成曲线。
- soak 方法:控制不同的恒温值,测得传感器数据。
- ramp 方法:记录一段时间内线性升温和降温时传感器数据。
随机误差
高斯白噪声建模成均值为0,方差σ的各时刻独立的高斯过程,一般是由AD转换器引起的外部噪声。
E[n(t)]≡0E[n(t1)n(t2)]=σ2δ(t1−t2)(11)
其中δ()表示狄拉克函数。
离散的数据噪声,与连续的高斯白噪声方差之间的转换关系为:
nd[k]≜n(t0+Δt)≃Δt1∫t0t0+Δtn(τ)dtE(nd[k]2)=E(Δt21∫t0t0+Δt∫t0t0+Δtn(τ)n(t)dτdt)=E(Δt2σ2∫t0t0+Δt∫t0t0+Δtδ(t−τ)dτdt)=E(Δtσ2)(12)
所以离散的高斯白噪声为:
nd[k]=σdw[k](13)
其中:w[k]∼N(0,1),σd=σΔt1
随机游走可以把它看做是一种布朗运动,或者将其称之为维纳过程。该模型可以看做是高斯白噪声的积分。该噪声参数一般是由传感器的内部构造、温度等变化量综合影响下的结果。建模成导数为高斯分布的噪声。
b˙(t)=n(t)=σbw(t)(14)
同样离散的和连续的之间转换为:
bd[k]≜E((bd[k]−bd[k−1]2)b(t0)+∫t0t0+Δtn(t)dt=E(∫t0t0+Δt∫t0t0+Δtn(t)n(τ)dτdt)=E(σb2∫t0t0+Δt∫t0t0+Δtδ(t−τ)dτdt)=E(σb2Δt)(15)
即:
bd[k]=bd[k−1]+σbdw[k](16)
其中:w[k]∼N(0,1),σbd=σbΔt
随机误差的标定方法——Allan方差法
具体流程如下:
- 将陀螺仪静止放置时间T ,单个采样周期为 τ0 ,共有N组采样值。
- 计算单次采样输出角度θ 和 平均因子m,m要尽量取得均匀。
θ(n)m=∫τ0Ω(n)dt=Rand(1,2N−1)(17)
- 计算Allan方差,当m取不同的值的时候会有不同的Allan方差值。
θ2(τ)=2τ2(N−2m)1k=1∑N−2m(θK+2m−2θK+m+θK)2(18)
其中:τ=mτ0
- 一般在绘制Allan方差曲线的时候使用的是Allan方差的平方根,将公式(18)开根号。
使用最小二乘对计算出来的Allan方差曲线进行拟合,得到如下的示意图。
按照上表中的值进行对应求得相应的噪声值,因为画出的曲线图是log-log对数图,因此斜率分别就是τ的次幂。
认为这些噪声源是相互独立的,则Allan方差是各类型误差的平方和:
σ total 2(τ)=σQ2(τ)+σN2(τ)+σB2(τ)+σK2(τ)+σR2(τ)=τ23Q2+τN2+π2B2ln2+3K2τ+2R2τ2(19)
把公式(19)整理下:
σtotal2(τ)=i=−2∑2Ciτi(20)
其中:i=(−2,−1,0,1,2)
使用最小二乘方法对公式(20)与公式(18)计算出来的值进行拟合,得到Ci值,然后得到相应的误差系数:
⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧Q=36003C−2(∘)N=60C−1(∘)/hB=0.664C0(∘)/hK=603C1[(∘)⋅h−1]/hR=36002C2[(∘)⋅h−1]/h(21)
其中陀螺仪的数据数据转为 deg/h,τ还是sec单位,加速度计还是m/s2 。
imu_utils
其中就是使用ceres求解最小二乘得到相应的系数,公式(18)到公式(21)的过程,注意其中的单位转换。
有一点不明白的是这几个误差系数是单独作用在每一段么?代码中测试发现就是令τ就是求得值。画出来的就是总的Allan方差曲线,为什么拟合出来可以单独代表其中一部分的噪声?公式(19)怎么获得单独的噪声?
找到一种解释:1s 量级的平均时间范围内加速度计的误差主要是速度随机游走, 在 100s 以上的范围内主要是零偏不稳定性. 对于更长的平均时间而言, 限于采集数据的长度, 用于 Allan 方差分析的独立子集个数有限, 因此其置信程度很低。
也就是说它确实是分段的,因此可以直接拟合得到。试了下为什么可以直接赋值1计算,是因为其他的太小了,忽略不计。因为次幂的不同,因此取不同时间时,噪声的大小差别很大,因此就直接忽略了,因此可以看做分段的。
数学模型
加速度计
amB=SaTaRBG(aG−gG)+na+ba(22)
陀螺仪
ωmB=SgTgωB+sgaaB+ng+bg(23)
S是尺度因子,T是非对称误差,n是高斯白噪声,b是零偏随机游走,sga是加速度计对陀螺仪的影响。
VIO中模型
VIO中忽略尺度因子和轴偏差,只考虑白噪声和bias随机游走。
ω~ba~b=ωb+bg+ng=qbw(aw+gw)+ba+na(24)
这里的**g加号减号**注意就行了,和g定义的正负,加速度计输出的加速度正负都有关系。
运动模型
参考预积分或者VINS的笔记就好了。
离散积分方法
pwbk+1vk+1wqwbk+1=pwbk+vkwΔt+21aΔt2=vkw+aΔt=qwbk⊗[121ωδt](25)
对于非线性函数有以下的方法。
欧拉法
Xn+1=Xn+KΔtK=f′(tn, Xn)(26)
其中公式(24)中
aω=qwbk(abk−bka)−gw=ωbk−bkg
中值法(mid-point)
Xn+1K2K1=Xn+K2Δt=f′(tn+21Δt, Xn+K12Δt)=f′(tn, Xn)(27)
其中公式(24)中的
aω=21[qwbk(abk−bka)−gw+qwbk+1(abk+1−bka)−gw]=21[(ωbk−bkg)+(ωbk+1−bkg)]
四阶龙格库塔(RK4)
龙格库塔法的微分方程中必须有原来的量,即y˙=f(t,y)形式才适用。
Xn+1K1K2K3K4=Xn+6Δt(K1+2K2+2K3+K4)=f′(tn, Xn)=f′(tn+2Δt, Xn+2ΔtK1)=f′(tn+2Δt, Xn+2ΔtK2)=f′(tn+Δt, Xn+ΔtK3)(28)
其中公式(24)中的
a=21[qwbk(abk−bka)−gw+qwbk+1(abk+1−bka)−gw]
template <typename _T>
inline void imu_tk::quatIntegrationStepRK4(
const Eigen::Matrix< _T, 4, 1> &quat,
const Eigen::Matrix< _T, 3, 1> &omega0,
const Eigen::Matrix< _T, 3, 1> &omega1,
const _T &dt, Eigen::Matrix< _T, 4, 1> &quat_res )
{
Eigen::Matrix< _T, 3, 1> omega01 = _T(0.5)*( omega0 + omega1 );
Eigen::Matrix< _T, 4, 1> k1, k2, k3, k4, tmp_q;
Eigen::Matrix< _T, 4, 4> omega_skew;
// First Runge-Kutta coefficient
computeOmegaSkew( omega0, omega_skew );
k1 = _T(0.5)*omega_skew*quat;
// Second Runge-Kutta coefficient
tmp_q = quat + _T(0.5)*dt*k1;
computeOmegaSkew( omega01, omega_skew );
k2 = _T(0.5)*omega_skew*tmp_q;
// Third Runge-Kutta coefficient (same omega skew as second coeff.)
tmp_q = quat + _T(0.5)*dt*k2;
k3 = _T(0.5)*omega_skew*tmp_q;
// Forth Runge-Kutta coefficient
tmp_q = quat + dt*k3;
computeOmegaSkew( omega1, omega_skew );
k4 = _T(0.5)*omega_skew*tmp_q;
_T mult1 = _T(1.0)/_T(6.0), mult2 = _T(1.0)/_T(3.0);
quat_res = quat + dt*(mult1*k1 + mult2*k2 + mult2*k3 + mult1*k4);
normalizeQuaternion(quat_res);
}
总的标定流程
以IMU_tk为例,直接用本科毕设论文里的吧,有些符号可能不一样,比如考虑陀螺仪轴和加速度计轴不垂直、不重合的轴向误差。