前言
通常,在实践工程中,对于机器人姿态解算的算法有很多,如Mahony互补滤波算法、卡尔曼滤波算法。并且,这些算法都是基于IMU惯性传感器的数据完成的。即根据IMU数据中的三轴加速度计和三轴角速度(基于机体坐标系
),根据坐标系转换关系来实现姿态解算。(默认读者均了解IMU的工作原理,减少相关赘述。
)
卡尔曼滤波器
卡尔曼滤波器作为最优预测的数据融合算法,能够将加速度计和陀螺仪数据更好的结合起来,得到理想姿态数据。
卡尔曼滤波器之前做过一篇推导的博客,链接卡尔曼滤波器
这里不做重复赘述,直接给出卡尔曼滤波器的结论:
对于线性状态系统
X
˙
=
A
X
+
B
U
Y
=
C
X
\dot{\bold{X}}=A\bold{X}+B\bold{U}\\ \bold{Y}=C\bold{X}
X˙=AX+BUY=CX
Step1:用上一次的后验误差协方差矩阵计算先验误差协方差矩阵
P
k
+
1
−
=
A
P
k
A
T
+
Q
{\color{red} P_{k+1}^{-}=A P_{k} A^{T}+Q}
Pk+1−=APkAT+Q
Step2:先验估计
x
^
k
+
1
−
=
A
x
^
k
+
B
u
k
{\color{red} \hat{x}_{k+1}^{-}=A\hat{x}_{k}+Bu_{k}}
x^k+1−=Ax^k+Buk
Step3:计算卡尔曼增益
K
k
+
1
=
P
k
+
1
−
H
T
H
P
k
+
1
−
H
T
+
R
{\color{red} K_{k+1}=\frac{P_{k+1}^{-}H^{T}}{HP_{k+1}^{-}H^{T}+R}}
Kk+1=HPk+1−HT+RPk+1−HT
Step4:后验估计
x
^
k
+
1
=
x
^
k
+
1
−
+
K
k
+
1
(
z
k
+
1
−
H
x
^
k
+
1
−
)
{\color{red} \hat{x}_{k+1}=\hat{x}_{k+1}^{-}+K_{k+1}(z_{k+1}-H\hat{x}_{k+1}^{-})}
x^k+1=x^k+1−+Kk+1(zk+1−Hx^k+1−)
Step5:计算后验误差协方差矩阵
P
k
+
1
=
(
I
−
K
k
+
1
H
)
P
k
+
1
−
{\color{red} P_{k+1}=(I-K_{k+1}H)P_{k+1}^{-}}
Pk+1=(I−Kk+1H)Pk+1−
基于卡尔曼滤波器的姿态解算
卡尔曼滤波器使用方法
对于卡尔曼滤波器的使用,无论是否对卡尔曼滤波器熟悉掌握,通常只需要明确以下两个点,再套公式就可以完成整个数据融合的过程。
- 状态转移关系(
先验估计
),明确状态转移方程相关矩阵 A , B A,B A,B以及系统噪声 Q Q Q - 状态测量值(
通过传感器观测得到
),明确观测值 z k \boldsymbol{z_{k}} zk和测量噪声 R R R
在给定初始的后验协方差矩阵 P 0 P_{0} P0后,经过一定时间的迭代,卡尔曼滤波器即可收敛到最优区间,实现数据融合和预测作用。
IMU数据解析
相关的公式在之前的博客中都做过推导,这里直接给结论
- 首先,定义惯性系和机体系的坐标变换矩阵,由惯性系到机体系的坐标系转换矩阵为
R
\boldsymbol{R}
R(
这里是重要的前提
)
R = R X ( ϕ ) R Y ( θ ) R Z ( ψ ) = [ C ψ C θ S ψ C θ − S θ C ψ S θ S ϕ − S ψ C ϕ S ψ S θ S ϕ + C ψ C ϕ C θ S ϕ C ψ S θ C ϕ + S ψ S ϕ S ψ S θ C ϕ − C ψ S ϕ C θ C ϕ ] \boldsymbol{R}=\boldsymbol{R_{X}(\phi)}\boldsymbol{R_{Y}(\theta)}\boldsymbol{R_{Z}(\psi)}=\left[\begin{array}{ccc} C_{\psi} C_{\theta} & S_{\psi} C_{\theta} &-S_{\theta} \\ C_{\psi} S_{\theta} S_{\phi}-S_{\psi} C_{\phi} & S_{\psi} S_{\theta} S_{\phi}+C_{\psi} C_{\phi} & C_{\theta} S_{\phi} \\ C_{\psi} S_{\theta} C_{\phi}+S_{\psi} S_{\phi} &S_{\psi} S_{\theta} C_{\phi}-C_{\psi} S_{\phi}& C_{\theta} C_{\phi} \end{array}\right] R=RX(ϕ)RY(θ)RZ(ψ)= CψCθCψSθSϕ−SψCϕCψSθCϕ+SψSϕSψCθSψSθSϕ+CψCϕSψSθCϕ−CψSϕ−SθCθSϕCθCϕ - 接着,对于机体系下角速度向量
[
p
q
r
]
\begin{bmatrix}p\\q\\r\end{bmatrix}
pqr
,对于惯性系下欧拉角向量
[
ϕ
θ
ψ
]
\begin{bmatrix}\boldsymbol{\phi}\\\boldsymbol{\theta}\\\boldsymbol{\psi}\end{bmatrix}
ϕθψ
,满足以下关系(
这里是通过陀螺仪所能得到的欧拉角变化趋势(欧拉角导数)
)
[ ϕ ˙ θ ˙ ψ ˙ ] = [ 1 S ϕ T θ C ϕ T θ 0 C ϕ − S ϕ 0 S ϕ / C θ C ϕ / C θ ] [ p q r ] \begin{array}{ll} {\left[\begin{array}{c} \dot{\boldsymbol{\phi}} \\ \dot{\boldsymbol{\theta}} \\ \dot{\boldsymbol{\psi}} \end{array}\right]=\left[\begin{array}{ccc} 1 & S_{\phi} T_{\theta} & C_{\phi} T_{\theta} \\ 0 & C_{\phi} & -S_{\phi} \\ 0 & S_{\phi} / C_{\theta} & C_{\phi} / C_{\theta} \end{array}\right]\left[\begin{array}{c} p \\ q \\ r \end{array}\right]} \end{array} ϕ˙θ˙ψ˙ = 100SϕTθCϕSϕ/CθCϕTθ−SϕCϕ/Cθ pqr - 最后,对于加速度数据而言,在静止状态或匀速运动状态下,加速度计采样得到的三轴数据为重力加速度在机体坐标系中的表示。
对于惯性系下重力加速度向量为 [ 0 0 − g ] \begin{bmatrix}0\\0\\-g\end{bmatrix} 00−g ,在机体系下为 [ a x a y a z ] \begin{bmatrix}a_{x}\\a_{y}\\a_{z}\end{bmatrix} axayaz 。
根据坐标系转换的几何关系,可以得到以下关系
ϕ = a t a n ( a y / a z ) θ = − a t a n ( a x / a y 2 + a z 2 ) \boldsymbol{\phi}=atan(a_{y}/a_{z})\\ \boldsymbol{\theta}=-atan(a_{x}/\sqrt{a_{y}^{2}+a_{z}^{2}}) ϕ=atan(ay/az)θ=−atan(ax/ay2+az2)
这里的几何关系结论是按照从Z->Y->X的顺序进行旋转变换得到的,可以自己动手绘制一下按照这个顺序进行旋转变换的坐标系,帮助了解。
卡尔曼滤波器模型
先假设初始的欧拉角为 [ ϕ θ ψ ] = [ 0 0 0 ] \begin{bmatrix}\boldsymbol{\phi}\\\boldsymbol{\theta}\\\boldsymbol{\psi}\end{bmatrix}=\begin{bmatrix}0\\0\\0\end{bmatrix} ϕθψ = 000 ,因为一开始的数据可能存在非常大的偏差,因此初始的后验协方差矩阵可以给的大一点,根据实际情况调整。
-
s
t
e
p
1
step1
step1:先验估计
先读取到陀螺仪的角速度数据 [ p q r ] \begin{bmatrix}p\\q\\r\end{bmatrix} pqr ,转换成单位 r a d / s rad/s rad/s,代入以下公式得到欧拉角的导数 [ ϕ ˙ θ ˙ ψ ˙ ] \begin{bmatrix}\dot{\boldsymbol{\phi}} \\ \dot{\boldsymbol{\theta}} \\ \dot{\boldsymbol{\psi}}\end{bmatrix} ϕ˙θ˙ψ˙ :
[ ϕ ˙ θ ˙ ψ ˙ ] = [ 1 S ϕ T θ C ϕ T θ 0 C ϕ − S ϕ 0 S ϕ / C θ C ϕ / C θ ] [ p q r ] (1) \begin{array}{ll} {\left[\begin{array}{c} \dot{\boldsymbol{\phi}} \\ \dot{\boldsymbol{\theta}} \\ \dot{\boldsymbol{\psi}} \end{array}\right]=\left[\begin{array}{ccc} 1 & S_{\phi} T_{\theta} & C_{\phi} T_{\theta} \\ 0 & C_{\phi} & -S_{\phi} \\ 0 & S_{\phi} / C_{\theta} & C_{\phi} / C_{\theta} \end{array}\right]\left[\begin{array}{c} p \\ q \\ r \end{array}\right]} \end{array} \tag{1} ϕ˙θ˙ψ˙ = 100SϕTθCϕSϕ/CθCϕTθ−SϕCϕ/Cθ pqr (1)
将欧拉角的导数 [ ϕ ˙ θ ˙ ψ ˙ ] \begin{bmatrix}\dot{\boldsymbol{\phi}} \\ \dot{\boldsymbol{\theta}} \\ \dot{\boldsymbol{\psi}}\end{bmatrix} ϕ˙θ˙ψ˙ 作为系统状态转移方程的输入向量 U \bold{U} U,即
U = [ ϕ ˙ θ ˙ ψ ˙ ] (2) \bold{U}=\begin{bmatrix}\dot{\boldsymbol{\phi}} \\ \dot{\boldsymbol{\theta}} \\ \dot{\boldsymbol{\psi}}\end{bmatrix} \tag{2} U= ϕ˙θ˙ψ˙ (2)
设离散周期为 T \boldsymbol{T} T,最终可以得到离散的系统状态转移方程(实际使用均是离散系统
):
X k + 1 = A X k + B U k \bold{X_{k+1}}=A\bold{X_{k}}+B\bold{U_{k}} Xk+1=AXk+BUk
展开后得到
[ ϕ k + 1 θ k + 1 ψ k + 1 ] = [ 1 0 0 0 1 0 0 0 1 ] [ ϕ k θ k ψ k ] + [ T 0 0 0 T 0 0 0 T ] [ ϕ k ˙ θ k ˙ ψ k ˙ ] (3) \begin{bmatrix}\boldsymbol{\phi_{k+1}} \\ \boldsymbol{\theta_{k+1}} \\ \boldsymbol{\psi_{k+1}}\end{bmatrix} \ =\begin{bmatrix}1 & 0&0 \\ 0&1&0 \\ 0&0&1\end{bmatrix}\ \begin{bmatrix}\boldsymbol{\phi_{k}} \\ \boldsymbol{\theta_{k}} \\ \boldsymbol{\psi_{k}}\end{bmatrix}\ +\begin{bmatrix}T & 0&0 \\ 0&T&0 \\ 0&0&T\end{bmatrix}\ \begin{bmatrix}\dot{\boldsymbol{\phi_{k}}} \\ \dot{\boldsymbol{\theta_{k}}} \\ \dot{\boldsymbol{\psi_{k}}}\end{bmatrix} \tag{3} ϕk+1θk+1ψk+1 = 100010001 ϕkθkψk + T000T000T ϕk˙θk˙ψk˙ (3)
其中,矩阵 A A A是三阶单位矩阵,矩阵 B B B是三阶单位矩阵乘以 T T T,即
A = [ 1 0 0 0 1 0 0 0 1 ] , B = [ T 0 0 0 T 0 0 0 T ] (4) A=\begin{bmatrix}1 & 0&0 \\ 0&1&0 \\ 0&0&1\end{bmatrix},B=\begin{bmatrix}T & 0&0 \\ 0&T&0 \\ 0&0&T\end{bmatrix} \tag{4} A= 100010001 ,B= T000T000T (4)
最终,得到了先验估计计算公式:
[ ϕ ^ k + 1 − θ ^ k + 1 − ψ ^ k + 1 − ] = [ 1 0 0 0 1 0 0 0 1 ] [ ϕ ^ k θ ^ k ψ ^ k ] + [ T 0 0 0 T 0 0 0 T ] [ ϕ k ˙ θ k ˙ ψ k ˙ ] (5) \begin{bmatrix}\boldsymbol{\hat{\phi}_{k+1}^{-}} \\ \boldsymbol{\hat{\theta}_{k+1}^{-}} \\ \boldsymbol{\hat{\psi}_{k+1}^{-}}\end{bmatrix} \ =\begin{bmatrix}1 & 0&0 \\ 0&1&0 \\ 0&0&1\end{bmatrix}\ \begin{bmatrix}\boldsymbol{\hat{\phi}_{k}} \\ \boldsymbol{\hat{\theta}_{k}} \\ \boldsymbol{\hat{\psi}_{k}}\end{bmatrix}\ +\begin{bmatrix}T & 0&0 \\ 0&T&0 \\ 0&0&T\end{bmatrix}\ \begin{bmatrix}\dot{\boldsymbol{\phi_{k}}} \\ \dot{\boldsymbol{\theta_{k}}} \\ \dot{\boldsymbol{\psi_{k}}}\end{bmatrix} \tag{5} ϕ^k+1−θ^k+1−ψ^k+1− = 100010001 ϕ^kθ^kψ^k + T000T000T ϕk˙θk˙ψk˙ (5)
再根据卡尔曼滤波器的公式结论计算先验估计协方差矩阵:
P k + 1 − = A P k A T + Q (6) P_{k+1}^{-}=A P_{k} A^{T}+Q \tag{6} Pk+1−=APkAT+Q(6) -
s
t
e
p
2
step2
step2:状态测量值
对于状态测量值与系统状态,满足以下关系:
z k = H X m k z_{k}=H\bold{X}_{mk} zk=HXmk
通过加速度计数据转换得到的姿态角向量 z k z_{k} zk为
z k = [ ϕ m k θ m k ψ m k ] z_{k}=\begin{bmatrix}\boldsymbol{\phi_{mk}} \\ \boldsymbol{\theta_{mk}} \\ \boldsymbol{\psi_{mk}}\end{bmatrix}\ zk= ϕmkθmkψmk
通过读取到的三轴加速度计数据 [ a x a y a z ] \begin{bmatrix}a_{x}\\a_{y}\\a_{z}\end{bmatrix} axayaz ,可以计算得到以下信息:
ϕ m k = a t a n ( a y / a z ) θ m k = − a t a n ( a x / a y 2 + a z 2 ) (7) \boldsymbol{\phi_{mk}}=atan(a_{y}/a_{z})\\ \boldsymbol{\theta_{mk}}=-atan(a_{x}/\sqrt{a_{y}^{2}+a_{z}^{2}}) \tag{7} ϕmk=atan(ay/az)θmk=−atan(ax/ay2+az2)(7)
重力加速度在加速度计的数据无法解算得到航向角!
最终得到测量转移矩阵 H H H为:
H = [ 1 0 0 0 1 0 0 0 0 ] H=\begin{bmatrix}1 & 0&0 \\ 0&1&0 \\ 0&0&0\end{bmatrix}\ H= 100010000 -
s
t
e
p
3
step3
step3:后验估计
根据前两步的推导,可以得到系统状态的先验估计(公式5
)和先验协方差矩阵(公式6
)。
接下来需要计算卡尔曼增益:
K k + 1 = P k + 1 − H T H P k + 1 − H T + R (8) K_{k+1}=\frac{P_{k+1}^{-}H^{T}}{HP_{k+1}^{-}H^{T}+R} \tag{8} Kk+1=HPk+1−HT+RPk+1−HT(8)
计算后验估计:
x ^ k + 1 = x ^ k + 1 − + K k + 1 ( z k + 1 − H x ^ k + 1 − ) (9) \hat{x}_{k+1}=\hat{x}_{k+1}^{-}+K_{k+1}(z_{k+1}-H\hat{x}_{k+1}^{-}) \tag{9} x^k+1=x^k+1−+Kk+1(zk+1−Hx^k+1−)(9)
以及计算后验估计协方差矩阵:
P k + 1 = ( I − K k + 1 H ) P k + 1 − (10) P_{k+1}=(I-K_{k+1}H)P_{k+1}^{-} \tag{10} Pk+1=(I−Kk+1H)Pk+1−(10)
总结
使用IMU进行基于卡尔曼滤波器的姿态解算,整个过程可以概括为:
- 读取IMU三轴角速度数据和三轴加速度数据;
- 通过公式1计算得到欧拉角导数;
- 通过公式5计算先验估计,并且通过公式6计算先验估计协方差;
- 通过公式7计算得到系统状态测量值,再通过公式8计算卡尔曼增益,将二者代入公式9计算后验估计,最终通过公式10计算出后验估计的协方差,完成整个卡尔曼滤波器的计算周期。
下一篇博客将使用实际IMU传感器完成基于卡尔曼滤波器的姿态解算,完成后将实现源码共享
感谢阅读!