Kalman Filter in SLAM (5) ——IMU Intergration and State Space Representation (IMU积分和状态空间表示)
对于旋转状态有两种表示方式,分别是四元数 qqq 和旋转矩阵 RRR。可以使用这两种中的任意一种表示姿态,比如 VINS-Mono 中用的是四元数,而 FAST-LIO 中用的是旋转矩阵。它们的导数和积分如下计算:q˙=q⊗[012ω]q=q⊗[112ωδt]\dot{q} = q\otimes\begin{bmatrix}0\\\frac{1}{2}\omega\end{bmatrix}\qqu
文章目录
1. IMU运动学方程和状态表示
1.1. 旋转状态的表达方式
对于旋转状态有两种表示方式,分别是四元数 q q q 和旋转矩阵 R R R。可以使用这两种中的任意一种表示姿态,比如 VINS-Mono 中用的是四元数,而 FAST-LIO 中用的是旋转矩阵。它们的导数和积分如下计算:
q ˙ = q ⊗ [ 0 1 2 ω ] q = q ⊗ [ 1 1 2 ω δ t ] \begin{align} \dot{q} = q\otimes\begin{bmatrix} 0\\ \frac{1}{2}\omega \end{bmatrix} \qquad q = q\otimes\begin{bmatrix} 1\\ \frac{1}{2}\omega\delta t \end{bmatrix} \end{align} q˙=q⊗[021ω]q=q⊗[121ωδt]
R ˙ = R ⋅ ω × R = R ⋅ e x p ( ω × δ t ) \begin{align} \dot{R} = R \cdot \omega _{\times } \qquad R = R \cdot exp(\omega _{\times}\delta t ) \end{align} R˙=R⋅ω×R=R⋅exp(ω×δt)
1.2. IMU运动学方程
{ p k + 1 w = p k w + v k w Δ t k + ∬ t i ∈ [ t k , t k + 1 ] ( R b i w ( a m − b a − n a ) − g w ) d t 2 v k + 1 w = v k w + ∫ t i ∈ [ t k , t k + 1 ] ( R b i w ( a m − b a − n a ) − g w ) d t q b k + 1 w = ∫ t i ∈ [ t k , t k + 1 ] q b k w ⊗ [ 0 1 2 ( ω m − b ω − n ω ) ] d t b ˙ a = n b a b ˙ ω = n b ω \begin{align} \left\{\begin{array}{l} \boldsymbol{p}_{k+1}^{w}=\boldsymbol{p}_{k}^{w}+\boldsymbol{v}_{k}^{w} \Delta t_{k}+\iint_{t_{i} \in\left[t_{k}, t_{k+1}\right]}\left(\boldsymbol{R}_{b_{i}}^{w}\left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right)-\boldsymbol{g}^{w}\right) d t^{2} \\ \boldsymbol{v}_{k+1}^{w}=\boldsymbol{v}_{k}^{w}+\int_{t_{i} \in\left[t_{k}, t_{k+1}\right]}\left(\boldsymbol{R}_{b_{i}}^{w}\left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right)-\boldsymbol{g}^{w}\right) d t \\ \boldsymbol{q}_{b_{k+1}}^{w}=\int_{t_{i} \in\left[t_{k}, t_{k+1}\right]} \boldsymbol{q}_{b_{k}}^{w} \otimes \begin{bmatrix} 0\\ \frac{1}{2}\left(\boldsymbol{\omega}_{m}-\boldsymbol{b}_{\omega }-\boldsymbol{n}_{\omega}\right)\end{bmatrix} d t \\ \boldsymbol{\dot{b}_{a}} = \boldsymbol{n}_{b_{a}} \\ \boldsymbol{\dot{b}_{\omega}} = \boldsymbol{n}_{b_{\omega}} \end{array}\right. \end{align} ⎩
⎨
⎧pk+1w=pkw+vkwΔtk+∬ti∈[tk,tk+1](Rbiw(am−ba−na)−gw)dt2vk+1w=vkw+∫ti∈[tk,tk+1](Rbiw(am−ba−na)−gw)dtqbk+1w=∫ti∈[tk,tk+1]qbkw⊗[021(ωm−bω−nω)]dtb˙a=nbab˙ω=nbω
其中,各个变量定义如下:
- a m \boldsymbol{a}_{m} am 和 ω m \boldsymbol{\omega}_{m} ωm——IMU传感器的加速度和角速度测量值读数;
- b a \boldsymbol{b}_{a} ba 和 b ω \boldsymbol{b}_{\omega } bω——加速度和角速度的零偏,随机游走过程,导数服从高斯分布,即 n b a ∼ N ( 0 , σ b a 2 ) , n b ω ∼ N ( 0 , σ b ω 2 ) \boldsymbol{n}_{\boldsymbol{b}_{a}} \sim \mathcal{N}\left(\mathbf{0}, \boldsymbol{\sigma}_{b_{a}}^{2}\right), \boldsymbol{n}_{\boldsymbol{b}_{\omega}} \sim \mathcal{N}\left(\mathbf{0}, \boldsymbol{\sigma}_{b_{\omega}}^{2}\right) nba∼N(0,σba2),nbω∼N(0,σbω2)
- n a \boldsymbol{n}_{a} na 和 n ω \boldsymbol{n}_{\omega} nω——加速度和角速度的测量高斯白噪声,即 n a ∼ N ( 0 , σ a 2 ) \boldsymbol{n}_{a} \sim \mathcal{N}\left(\mathbf{0}, \boldsymbol{\sigma}_{a}^{2}\right) na∼N(0,σa2) 和 n ω ∼ ( 0 , σ ω 2 ) \boldsymbol{n}_{\omega} \sim \left(0, \sigma_{\omega}^{2}\right) nω∼(0,σω2)
- R b i w \boldsymbol{R}_{b_{i}}^{w} Rbiw —— t i t_i ti 时刻IMU的姿态,是从IMU坐标系到世界坐标系的旋转;
- p k w \boldsymbol{p}_{k}^{w} pkw 和 v k w \boldsymbol{v}_{k}^{w} vkw—— k k k 时刻的位置和速度,在世界坐标系下表示的向量;
- g w \boldsymbol{g}^{w} gw ——世界坐标系下表示的重力加速度矢量;
- Ω ( ω ) \boldsymbol{\Omega} (\boldsymbol{\omega}) Ω(ω)——表示把 ω \boldsymbol{\omega} ω转成四元数的右乘矩阵。
值得注意的是,虽然下标 k k k 表示第 k k k 个时刻的状态, k + 1 k+1 k+1 是第 k + 1 k+1 k+1 时刻的状态,但这仍然是 连续 的运动学方程。因为后面我们是用积分算的,也就是用 k k k 到 k + 1 k+1 k+1 这个时间段内的每个时刻的IMU值,而不是单纯使用 k k k 或 k + 1 k+1 k+1 时刻的IMU值。
1.3. 名义状态、名义IMU值 和 真实状态、真实IMU值
1.3.1. 名义状态 x ^ \hat{\boldsymbol{x}} x^ 和 名义IMU值 a ^ \hat{\boldsymbol{a}} a^ / ω ^ \hat{\boldsymbol{\omega}} ω^
名义状态:我们知道的值,我们估计的值,我们能够算出来的值。它可以是先验(IMU运动学方程上一次的积分结果),也可以是后验(Kalman Filter的上一次矫正后的结果),总之它是你能够 真正算出来的东西。
名义加速度 和 名义角速度:由于我们后面建立状态空间方程的时候选择的状态变量中包括加速度和角速度的零偏 b a \boldsymbol{b}_{a} ba 和 b ω \boldsymbol{b}_{\omega } bω,也就是说零偏的真值我们是不知道的,我们用于计算的只是我们估计出来的 零偏的估计值,所以计算时候用的是 b a ^ \hat{\boldsymbol{b}_{a}} ba^ 和 b ω ^ \hat{\boldsymbol{b}_{\omega } } bω^。同理由于实际上每次测量的加速度和陀螺仪的噪声我们都是没有办法知道的,我们只知道噪声服从均值为0的高斯分布,所以这里就只能 把噪声简化为0。这样我们 实际知道、计算使用的名义加速度和名义角速度为:
a ^ = a m − b a ^ ω ^ = ω m − b ω ^ \begin{align} \hat{\boldsymbol{a}} = \boldsymbol{a}_{m} - \hat{\boldsymbol{b}_{a}} \\ \hat{\boldsymbol{\omega}} = \boldsymbol{\omega}_{m} - \hat{\boldsymbol{b}_{\omega}} \end{align} a^=am−ba^ω^=ωm−bω^
然后把 a ^ \hat{\boldsymbol{a}} a^ 和 ω ^ \hat{\boldsymbol{\omega}} ω^ 分别 替换运动学方程中的 ( a m − b a − n a ) \left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right) (am−ba−na)和 ( ω m − b ω − n ω ) \left(\boldsymbol{\omega}_{m}-\boldsymbol{b}_{\omega }-\boldsymbol{n}_{\omega}\right) (ωm−bω−nω),这样在运动学方程中 计算得到 的状态值就是我们的名义状态值 x ^ \hat{\boldsymbol{x}} x^,比如 p ^ k w \hat{\boldsymbol{p}}_{k}^{w} p^kw、 v ^ k w \hat{\boldsymbol{v}}_{k}^{w} v^kw。
1.3.2. 真实状态 x \boldsymbol{x} x 和 真实IMU值 a \boldsymbol{a} a / ω \boldsymbol{\omega} ω
真实状态:这个是我们永远都无法知道的值。但是我们可以对它进行建模。比如上面零偏不准确,噪声不知道是多少,但是我可以对零偏误差和噪声建模,这样带入系统运动学方程中我就能 表达出来 真实状态和我的零偏误差、噪声的关系,这样可以用来 评估 我们计算出来的名义状态有多不准确。
真实加速度 和 真实角速度:真实状态就是把所有东西都考虑进去,用于对系统的真实状态进行建模。由于我们估计的IMU的零偏不准确,所以在真值状态中就把估计的误差 δ b a \delta{\boldsymbol{b}_{a}} δba 和 δ b ω \delta{\boldsymbol{b}_{\omega } } δbω 也加进来。然后名义状态由于不知道噪声值所以简化为了 0,这里把噪声值也建模到真实值中,所以把IMU的测量噪声 n a \boldsymbol{n}_{a} na 和 n ω \boldsymbol{n}_{\omega} nω 也考虑进来。这样就得到了 表达真实状态 使用的真实加速度和真实角速度为:
a = a m − ( b a ^ + δ b a ) − n a = a ^ − δ b a − n a ω = ω m − ( b ω ^ + δ b ω ) − n ω = ω ^ − δ b ω − n ω \begin{align} \boldsymbol{a} = \boldsymbol{a}_{m} - (\hat{\boldsymbol{b}_{a}} + \delta{\boldsymbol{b_{a}}})- \boldsymbol{n}_{a} = \hat{\boldsymbol{a}} - \delta{\boldsymbol{b_{a}}} - \boldsymbol{n}_{a} \\ \boldsymbol{\omega} = \boldsymbol{\omega}_{m} - (\hat{\boldsymbol{b}_{\omega}} + \delta{\boldsymbol{b_{\omega}}})- \boldsymbol{n}_{\omega} = \hat{\boldsymbol{\omega}} - \delta{\boldsymbol{b_{\omega}}} - \boldsymbol{n}_{\omega} \end{align} a=am−(ba^+δba)−na=a^−δba−naω=ωm−(bω^+δbω)−nω=ω^−δbω−nω
然后把 a \boldsymbol{a} a 和 ω \boldsymbol{\omega} ω 分别 替换 运动学方程中的 ( a m − b a − n a ) \left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right) (am−ba−na) 和 ( ω m − b ω − n ω ) \left(\boldsymbol{\omega}_{m}-\boldsymbol{b}_{\omega }-\boldsymbol{n}_{\omega}\right) (ωm−bω−nω),这样带入运动学方程中得到的 状态值的表达式 就是我们的真实状态值 x \boldsymbol{x} x,比如 p k w \boldsymbol{p}_{k}^{w} pkw、 v k w \boldsymbol{v}_{k}^{w} vkw。
1.4. 离散时间下的运动学方程
连续时间的运动学方程为:
{ p k + 1 w = p k w + v k w Δ t k + ∬ t i ∈ [ t k , t k + 1 ] ( R b i w ( a m − b a − n a ) − g w ) d t 2 v k + 1 w = v k w + ∫ t i ∈ [ t k , t k + 1 ] ( R b i w ( a m − b a − n a ) − g w ) d t q b k + 1 w = ∫ t i ∈ [ t k , t k + 1 ] q b k w ⊗ [ 0 1 2 ( ω m − b ω − n ω ) ] d t b ˙ a = n b a b ˙ ω = n b ω \begin{align} \left\{\begin{array}{l} \boldsymbol{p}_{k+1}^{w}=\boldsymbol{p}_{k}^{w}+\boldsymbol{v}_{k}^{w} \Delta t_{k}+\iint_{t_{i} \in\left[t_{k}, t_{k+1}\right]}\left(\boldsymbol{R}_{b_{i}}^{w}\left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right)-\boldsymbol{g}^{w}\right) d t^{2} \\ \boldsymbol{v}_{k+1}^{w}=\boldsymbol{v}_{k}^{w}+\int_{t_{i} \in\left[t_{k}, t_{k+1}\right]}\left(\boldsymbol{R}_{b_{i}}^{w}\left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right)-\boldsymbol{g}^{w}\right) d t \\ \boldsymbol{q}_{b_{k+1}}^{w}=\int_{t_{i} \in\left[t_{k}, t_{k+1}\right]} \boldsymbol{q}_{b_{k}}^{w} \otimes \begin{bmatrix} 0\\ \frac{1}{2}\left(\boldsymbol{\omega}_{m}-\boldsymbol{b}_{\omega }-\boldsymbol{n}_{\omega}\right)\end{bmatrix} d t \\ \boldsymbol{\dot{b}_{a}} = \boldsymbol{n}_{b_{a}} \\ \boldsymbol{\dot{b}_{\omega}} = \boldsymbol{n}_{b_{\omega}} \end{array}\right. \end{align} ⎩ ⎨ ⎧pk+1w=pkw+vkwΔtk+∬ti∈[tk,tk+1](Rbiw(am−ba−na)−gw)dt2vk+1w=vkw+∫ti∈[tk,tk+1](Rbiw(am−ba−na)−gw)dtqbk+1w=∫ti∈[tk,tk+1]qbkw⊗[021(ωm−bω−nω)]dtb˙a=nbab˙ω=nbω
1.4.1. 欧拉积分
欧拉积分就是在 [ t k , t k + 1 ] [t_{k}, t_{k+1}] [tk,tk+1] 这段时间内的IMU测量值用 t k t_k tk 时刻的测量值来代替,由于加速度值要乘以姿态,所以旋转矩阵也用 t k t_k tk 时刻的旋转矩阵。此外IMU测量值的噪声也用 t k t_k tk 时刻的噪声代替。从而得到欧拉积分的离散运动学方程如下:
{ p k + 1 w = p k w + v k w Δ t k + 1 2 a Δ t k 2 v k + 1 w = v k w + a Δ t k q b k + 1 w = q b k w ⊗ [ 1 1 2 ω Δ t k ] b a k + 1 = b a k + n b a k Δ t k b ω k + 1 = b ω k + n b ω k Δ t k \begin{align} \left\{\begin{array}{l} \boldsymbol{p}_{k+1}^{w}=\boldsymbol{p}_{k}^{w}+\boldsymbol{v}_{k}^{w} \Delta t_{k} + \frac{1}{2} \boldsymbol{a} \Delta t_{k}^2 \\ \boldsymbol{v}_{k+1}^{w}=\boldsymbol{v}_{k}^{w}+ \boldsymbol{a} \Delta t_{k} \\ \boldsymbol{q}_{b_{k+1}}^{w}=\boldsymbol{q}_{b_{k}}^{w} \otimes \begin{bmatrix} 1\\ \frac{1}{2}\boldsymbol{\omega}\Delta t_k\end{bmatrix} \\ \boldsymbol{b}_{a_{k+1}} = \boldsymbol{b}_{a_{k}} + \boldsymbol{n}_{b_{ak}} \Delta t_{k} \\ \boldsymbol{b}_{{\omega}_{k+1}} = \boldsymbol{b}_{{\omega}_{k}} + \boldsymbol{n}_{b_{{\omega}k}} \Delta t_{k} \end{array}\right. \end{align} ⎩ ⎨ ⎧pk+1w=pkw+vkwΔtk+21aΔtk2vk+1w=vkw+aΔtkqbk+1w=qbkw⊗[121ωΔtk]bak+1=bak+nbakΔtkbωk+1=bωk+nbωkΔtk
其中使用的加速度和角速度值分别为:
a = R b k w ( a m k − b a k − n a k ) − g w ω = ω m k − b ω k − n ω k \begin{align} \boldsymbol{a} = \boldsymbol{R}_{b_{k}}^{w}\left(\boldsymbol{a}_{m_{k}}-\boldsymbol{b}_{a_{k}}-\boldsymbol{n}_{a_{k}}\right)-\boldsymbol{g}^{w} \\ \boldsymbol{\omega} = \boldsymbol{\omega}_{m_{k}}-\boldsymbol{b}_{{\omega}_k }-\boldsymbol{n}_{{\omega}_k} \end{align} a=Rbkw(amk−bak−nak)−gwω=ωmk−bωk−nωk
1.4.2. 中值积分
中值积分就是在 [ t k , t k + 1 ] [t_{k}, t_{k+1}] [tk,tk+1] 这段时间内的IMU测量值用 t k t_k tk 时刻和 t k + 1 t_{k+1} tk+1 时刻的测量值平均值来代替,但是由于加速度值要乘以姿态,所以两个加速度需要分别乘以各自时刻下的旋转矩阵。此外IMU测量值的噪声也用 t k t_k tk 时刻和 t k + 1 t_{k+1} tk+1 时刻的平均值代替。从而得到中值积分的离散运动学方程如下:
{ p k + 1 w = p k w + v k w Δ t k + 1 2 a Δ t k 2 v k + 1 w = v k w + a Δ t k q b k + 1 w = q b k w ⊗ [ 1 1 2 ω Δ t k ] b a k + 1 = b a k + 1 2 ( n b a k + n b a k + 1 ) Δ t k b ω k + 1 = b ω k + 1 2 ( n b ω k + n b ω k + 1 ) Δ t k \begin{align} \left\{\begin{array}{l} \boldsymbol{p}_{k+1}^{w}=\boldsymbol{p}_{k}^{w}+\boldsymbol{v}_{k}^{w} \Delta t_{k} + \frac{1}{2} \boldsymbol{a} \Delta t_{k}^2 \\ \boldsymbol{v}_{k+1}^{w}=\boldsymbol{v}_{k}^{w}+ \boldsymbol{a} \Delta t_{k} \\ \boldsymbol{q}_{b_{k+1}}^{w}=\boldsymbol{q}_{b_{k}}^{w} \otimes \begin{bmatrix} 1\\ \frac{1}{2}\boldsymbol{\omega}\Delta t_k\end{bmatrix} \\ \boldsymbol{b}_{a_{k+1}} = \boldsymbol{b}_{a_{k}} + \frac{1}{2}(\boldsymbol{n}_{b_{ak}} + \boldsymbol{n}_{b_{ak+1}}) \Delta t_{k} \\ \boldsymbol{b}_{{\omega}_{k+1}} = \boldsymbol{b}_{{\omega}_{k}} + \frac{1}{2}(\boldsymbol{n}_{b_{{\omega}k}} + \boldsymbol{n}_{b_{{\omega}k+1}}) \Delta t_{k} \end{array}\right. \end{align} ⎩ ⎨ ⎧pk+1w=pkw+vkwΔtk+21aΔtk2vk+1w=vkw+aΔtkqbk+1w=qbkw⊗[121ωΔtk]bak+1=bak+21(nbak+nbak+1)Δtkbωk+1=bωk+21(nbωk+nbωk+1)Δtk
其中使用的加速度和角速度值分别为:
a = 1 2 ( R b k w ( a m k − b a k − n a k ) + R b k + 1 w ( a m k + 1 − b a k + 1 − n a k + 1 ) ) g w ω = 1 2 ( ( ω m k − b ω k − n ω k ) + ( ω m k + 1 − b ω k + 1 − n ω k + 1 ) ) \begin{align} \boldsymbol{a} = \frac{1}{2}\left(\boldsymbol{R}_{b_{k}}^{w}\left(\boldsymbol{a}_{m_{k}}-\boldsymbol{b}_{a_{k}}-\boldsymbol{n}_{a_{k}}\right) + \boldsymbol{R}_{b_{k+1}}^{w}\left(\boldsymbol{a}_{m_{k+1}}-\boldsymbol{b}_{a_{k+1}}-\boldsymbol{n}_{a_{k+1}}\right)\right) \boldsymbol{g}^{w} \\ \boldsymbol{\omega} = \frac{1}{2}\left(\left(\boldsymbol{\omega}_{m_{k}}-\boldsymbol{b}_{{\omega}_k }-\boldsymbol{n}_{{\omega}_k} \right) + \left(\boldsymbol{\omega}_{m_{k+1}}-\boldsymbol{b}_{{\omega}_{k+1} }-\boldsymbol{n}_{{\omega}_{k+1}} \right)\right) \end{align} a=21(Rbkw(amk−bak−nak)+Rbk+1w(amk+1−bak+1−nak+1))gwω=21((ωmk−bωk−nωk)+(ωmk+1−bωk+1−nωk+1))
1.4.3. 注意
不论是欧拉积分还是中值积分,由于IMU的零偏是随机游走,在IMU的相邻两次测量时间内不会改变,所以无论欧拉积分还是中值积分都是使用 t k t_k tk时刻的IMU零偏。而相邻两次的测量噪声一般是不同的,所以中值积分中我们要使用两个时刻各自的噪声。
因此,后面建立离散的状态空间方程的时候,有两种状态变量的选择方式:
-
使用 欧拉积分 的离散运动学方程建立状态空间方程,状态变量和噪声变量分别是 :
x k = [ P k V k Q k b a k b ω k ] w k = [ n a k n ω k n b a k n b ω k ] \begin{align} \boldsymbol{x_k} = \begin{bmatrix} \boldsymbol{P_k} \\ \boldsymbol{V_k} \\ \boldsymbol{Q_k} \\ \boldsymbol{b_{a_k}} \\ \boldsymbol{b_{{\omega}_k}} \end{bmatrix} \qquad \boldsymbol{w_k} = \begin{bmatrix} \boldsymbol{n_{a_k}} \\ \boldsymbol{n_{\omega_{k}}} \\ \boldsymbol{n_{b_{ak}}} \\ \boldsymbol{n_{b_{\omega_{k}}}} \end{bmatrix} \end{align} xk= PkVkQkbakbωk wk= naknωknbaknbωk -
使用 中值积分 的离散运动学方程建立状态空间方程,状态变量和噪声分别是:
x k = [ P k V k Q k b a k b ω k ] w k = [ n a k n ω k n a k + 1 n ω k + 1 n b a k n b ω k ] \begin{align} \boldsymbol{x_k} = \begin{bmatrix} \boldsymbol{P_k} \\ \boldsymbol{V_k} \\ \boldsymbol{Q_k} \\ \boldsymbol{b_{a_k}} \\ \boldsymbol{b_{{\omega}_k}} \end{bmatrix} \qquad \boldsymbol{w_k} = \begin{bmatrix} \boldsymbol{n_{a_k}} \\ \boldsymbol{n_{\omega_{k}}} \\ \boldsymbol{n_{a_{k+1}}} \\ \boldsymbol{n_{\omega_{k+1}}} \\ \boldsymbol{n_{b_{ak}}} \\ \boldsymbol{n_{b_{\omega_{k}}}} \end{bmatrix} \end{align} xk= PkVkQkbakbωk wk= naknωknak+1nωk+1nbaknbωk
2. 非线性连续系统的线性化 推导 状态空间矩阵方程
2.1. 为什么要推导状态空间方程?
为什么要推导状态空间方程呢?根据运动学方程,每当有新的IMU测量值输入,我们不就可以计算出新的状态变量值了吗?原因有两个:
(1) 最重要的原因:我们后面想进行数据融合,无论是Kalman Filter还是非线性优化,我们都需要提供一个 由IMU的运动学方程得到的状态协方差矩阵(即置信度)。而协方差矩阵的传播必须是基于状态空间矩阵方程的,所以必须推导状态空间方程。如果不用计算协方差矩阵而只需要计算状态话,完全没有必要推导状态空间方程。
(2) 如果我们选择的状态变量不是运动学方程中的状态值(比如ErKF中选的是状态的误差),那么虽然此时用运动学方程也能通过 真实状态 − - −名义状态 计算状态的误差,但是并不如直接使用状态空间方程进行矩阵计算来的方便了。
2.2. 状态向量中的旋转如何表示?
要想表示旋转,可以用欧拉角、角轴(旋转向量)、四元数、旋转矩阵。前面两个都有周期性,并且欧拉角还存在万向节死锁的严重问题。后面两个没有周期性,但是又存在过参数化的问题。这里对比后选择 角轴(旋转向量) 作为状态向量,原因有两个:
(1) 我们建立状态空间方程最重要的原因就是想推导状态变量的协方差矩阵,如果选择后面两个作为状态变量的话,他们一个4个参数、一个9个参数,结果协方差矩阵分别是4x4和9x9,很奇怪(实际上工业界使用过四元数作为状态向量,用卡尔曼滤波精度还可以接受)。但是选择角轴是3x3的矩阵,符合旋转3DOF的情况。所以使用角轴能够避免误差协方差矩阵 过参数化 的情况。
(2) 注意我们使用状态空间方程推导协方差矩阵,要求状态向量必须是 向量,而从数学上来说四元数和旋转矩阵都不是向量,只有角轴是向量,所以它更符合状态空间方程的要求。
2.3. 连续时间运动学方程求导建立 连续时间 状态空间方程
首先选择状态变量,状态变量就是我们想要知道的状态量,我们感兴趣的值。对IMU运动学方程来说,状态变量的选择一般都是五个: P P P, V V V, Q Q Q, b a b_a ba, b ω b_\omega bω。
状态空间方程就是描述 状态变量的导数和状态变量之间的关系。因此我们要根据1中的运动学方程,将我们选择的状态变量对 时间 求导,从而得到状态的导数和状态之间的关系。并且由于我们建立状态空间方程的目的是对协方差矩阵进行传播,所以要求状态空间方程一定要是 线性 的,即它要写成 x ˙ = A x + B u \dot{x}=Ax+Bu x˙=Ax+Bu 的形式。如果最后有状态变量分离不出来,即写不成 A x Ax Ax 这种形式,那么我们就必须进行线性化。
2.3.1. 先来看一个倒立摆的例子
一阶倒立摆的运动学方程如下:
[ M + m m l cos θ m l cos θ I + m l 2 ] [ x ¨ θ ¨ ] + [ 0 − m l sin θ θ ˙ 0 0 ] [ x ˙ θ ˙ ] = [ u m g l sin θ ] \begin{align} \left[\begin{array}{cc} M+m & m l \cos \theta \\ m l \cos \theta & I+m l^{2} \end{array}\right]\left[\begin{array}{c} \ddot{x} \\ \ddot{\theta} \end{array}\right]+\left[\begin{array}{cc} 0 & -m l \sin \theta \dot{\theta} \\ 0 & 0 \end{array}\right]\left[\begin{array}{c} \dot{x} \\ \dot{\theta} \end{array}\right]=\left[\begin{array}{c} u \\ m g l \sin \theta \end{array}\right] \end{align} [M+mmlcosθmlcosθI+ml2][x¨θ¨]+[00−mlsinθθ˙0][x˙θ˙]=[umglsinθ]
可以看到最右边有一个 s i n ( θ ) sin(\theta) sin(θ) 项,这部分是没办法写成 a ∗ θ a*\theta a∗θ 的这种线性的形式的,因此我们就要把它在某个点附近线性化,比如在 θ 0 \theta_0 θ0 的地方线性化,那么就可以写成 s i n ( θ 0 ) + c o s ( θ 0 ) ∗ ( θ − θ 0 ) sin(\theta_0) + cos(\theta_0)*(\theta-\theta_0) sin(θ0)+cos(θ0)∗(θ−θ0),其中 c o s ( θ 0 ) cos(\theta_0) cos(θ0) 是这个点的导数值,这样我们就把它化成线性的了,就能写出状态空间方程了,如下:
[ x ˙ x ¨ θ ˙ θ ¨ ] = [ 0 1 0 0 0 0 − m 2 g l 2 I ( M + m ) + M m l 2 0 0 0 0 1 0 0 m g l ( M + m ) I ( M + m ) + M m l 2 0 ] [ x x ˙ θ θ ˙ ] + [ 0 I + m l 2 I ( M + m ) + M m l 2 0 − m l I ( M + m ) + M m l 2 ] u y = x = [ 1 0 0 0 ] [ x x ˙ θ θ ˙ ] \begin{align} \begin{array}{c} {\left[\begin{array}{c} \dot{x} \\ \ddot{x} \\ \dot{\theta} \\ \ddot{\theta} \end{array}\right]=\left[\begin{array}{cccc} 0 & 1 & 0 & 0 \\ 0 & 0 & \dfrac{-m^{2} g l^{2}}{I(M+m)+M m l^{2}} & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & \dfrac{m g l(M+m)}{I(M+m)+M m l^{2}} & 0 \end{array}\right]\left[\begin{array}{c} x \\ \dot{x} \\ \theta \\ \dot{\theta} \end{array}\right]+\left[\begin{array}{c} 0 \\ \dfrac{I+m l^{2}}{I(M+m)+M m l^{2}} \\ 0 \\ \dfrac{-m l}{I(M+m)+M m l^{2}} \end{array}\right] u} \\ y=x=\left[\begin{array}{llll} 1 & 0 & 0 & 0 \end{array}\right]\left[\begin{array}{c} x \\ \dot{x} \\ \theta \\ \dot{\theta} \end{array}\right] \end{array} \end{align}
x˙x¨θ˙θ¨
=
000010000I(M+m)+Mml2−m2gl20I(M+m)+Mml2mgl(M+m)0010
xx˙θθ˙
+
0I(M+m)+Mml2I+ml20I(M+m)+Mml2−ml
uy=x=[1000]
xx˙θθ˙
2.3.2. 连续时间力学方程求导建立 连续时间 状态空间方程
连续时间的运动学方程如下,状态变量是 P P P, V V V, Q Q Q, b a b_a ba, b ω b_\omega bω。
{ p k + 1 w = p k w + v k w Δ t k + ∬ t i ∈ [ t k , t k + 1 ] ( R b i w ( a m − b a − n a ) − g w ) d t 2 v k + 1 w = v k w + ∫ t i ∈ [ t k , t k + 1 ] ( R b i w ( a m − b a − n a ) − g w ) d t q b k + 1 w = ∫ t i ∈ [ t k , t k + 1 ] q b k w ⊗ [ 0 1 2 ( ω m − b ω − n ω ) ] d t b ˙ a = n b a b ˙ ω = n b ω \begin{align} \left\{\begin{array}{l} \boldsymbol{p}_{k+1}^{w}=\boldsymbol{p}_{k}^{w}+\boldsymbol{v}_{k}^{w} \Delta t_{k}+\iint_{t_{i} \in\left[t_{k}, t_{k+1}\right]}\left(\boldsymbol{R}_{b_{i}}^{w}\left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right)-\boldsymbol{g}^{w}\right) d t^{2} \\ \boldsymbol{v}_{k+1}^{w}=\boldsymbol{v}_{k}^{w}+\int_{t_{i} \in\left[t_{k}, t_{k+1}\right]}\left(\boldsymbol{R}_{b_{i}}^{w}\left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right)-\boldsymbol{g}^{w}\right) d t \\ \boldsymbol{q}_{b_{k+1}}^{w}=\int_{t_{i} \in\left[t_{k}, t_{k+1}\right]} \boldsymbol{q}_{b_{k}}^{w} \otimes \begin{bmatrix} 0\\ \frac{1}{2}\left(\boldsymbol{\omega}_{m}-\boldsymbol{b}_{\omega }-\boldsymbol{n}_{\omega}\right)\end{bmatrix} d t \\ \boldsymbol{\dot{b}_{a}} = \boldsymbol{n}_{b_{a}} \\ \boldsymbol{\dot{b}_{\omega}} = \boldsymbol{n}_{b_{\omega}} \end{array}\right. \end{align} ⎩ ⎨ ⎧pk+1w=pkw+vkwΔtk+∬ti∈[tk,tk+1](Rbiw(am−ba−na)−gw)dt2vk+1w=vkw+∫ti∈[tk,tk+1](Rbiw(am−ba−na)−gw)dtqbk+1w=∫ti∈[tk,tk+1]qbkw⊗[021(ωm−bω−nω)]dtb˙a=nbab˙ω=nbω
注意:求导是对 时间 t t t 求导。方程中 k k k时刻是一个确定的时刻,所以它的状态值都是常量,而 k + 1 k+1 k+1 时刻的状态量是待求的变量。所以对时间求导的时候,右边 p k p_k pk v k v_k vk 都是常量,对时间的导数是0。
(1) 先看 p k + 1 \boldsymbol{p_{k+1}} pk+1 对时间求导:
d p k + 1 d t = v k w + ∫ t i ∈ [ t k , t k + 1 ] ( R b i w ( a m − b a − n a ) − g w ) d t = v k + 1 w \begin{align} \frac{\mathrm{d} \boldsymbol{p_{k+1}}}{\mathrm{d} t} =\boldsymbol{v}_{k}^{w}+\int_{t_{i} \in\left[t_{k}, t_{k+1}\right]}\left(\boldsymbol{R}_{b_{i}}^{w}\left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right)-\boldsymbol{g}^{w}\right) d t = \boldsymbol{v}_{k+1}^{w} \end{align} dtdpk+1=vkw+∫ti∈[tk,tk+1](Rbiw(am−ba−na)−gw)dt=vk+1w
再次说明,这里 k + 1 k+1 k+1 并不代表某个确定的时刻,而是一个变量,所以这里省略下标写成 p \boldsymbol{p} p 更好,代表它是一个 状态变量,它的导数就是 v \boldsymbol{v} v。后面同理。所以我们得到了第一个状态变量和其他五个状态变量之间的关系是 p ˙ = v \dot{\boldsymbol{p}} = \boldsymbol{v} p˙=v。
(2) 再看 v k + 1 \boldsymbol{v_{k+1}} vk+1 对时间求导:
d v k + 1 d t = R b i w ( a m − b a − n a ) − g w = R b i w a m − R b i w b a − R b i w n a − g w \begin{align} \frac{\mathrm{d} \boldsymbol{v_{k+1}}}{\mathrm{d} t} =\boldsymbol{R}_{b_{i}}^{w}\left(\boldsymbol{a}_{m}-\boldsymbol{b}_{a}-\boldsymbol{n}_{a}\right)-\boldsymbol{g}^{w} = \boldsymbol{R}_{b_{i}}^{w}\boldsymbol{a}_{m} - \boldsymbol{R}_{b_{i}}^{w} \boldsymbol{b}_{a} - \boldsymbol{R}_{b_{i}}^{w}\boldsymbol{n}_{a} - \boldsymbol{g}^{w} \end{align} dtdvk+1=Rbiw(am−ba−na)−gw=Rbiwam−Rbiwba−Rbiwna−gw
可见其中 R b i w b a 和 R b i w n a \boldsymbol{R}_{b_{i}}^{w} \boldsymbol{b}_{a} 和 \boldsymbol{R}_{b_{i}}^{w}\boldsymbol{n}_{a} Rbiwba和Rbiwna 都写成了关于状态变量 b a \boldsymbol{b_a} ba 和 n a \boldsymbol{n_a} na 的线性项, g w \boldsymbol{g}^{w} gw 是常数项没影响。但是其中一项变量 R b i w a m \boldsymbol{R}_{b_{i}}^{w}\boldsymbol{a}_{m} Rbiwam 却没有办法写成关于状态量 P P P, V V V, Q Q Q, b a b_a ba, b ω b_\omega bω 的形式,注意这里面的 a m \boldsymbol{a_m} am 是IMU的测量值,我们每次都是知道的,所以这就是个系数向量。
而 R b i w \boldsymbol{R}_{b_{i}}^{w} Rbiw 就是 Q Q Q,就是系统的状态变量。但是前面我们已经讨论了,旋转部分的状态向量我们用 角轴(旋转向量) 来表示。而旋转矩阵和角轴直接的对应关系是罗德里格斯公式:
R = cos θ I + ( 1 − cos θ ) n n T + sin θ n ∧ \begin{align} \boldsymbol{R}=\cos \theta \boldsymbol{I}+(1-\cos \theta) \boldsymbol{n} \boldsymbol{n}^{T}+\sin \theta \boldsymbol{n}^{\wedge} \end{align} R=cosθI+(1−cosθ)nnT+sinθn∧
可见他们之间不是单纯的 R = K ∗ θ \boldsymbol{R} = \boldsymbol{K}*\theta R=K∗θ 的关系(其中 K \boldsymbol{K} K 是一个矩阵),而是包含了 c o s ( θ ) cos(\theta) cos(θ) 项,所以 旋转这里具有高度的非线性。因此旋转部分无法表示为 角轴 的线性函数,就好比现在我们得到的是 s i n ( θ ) sin(\theta) sin(θ),我没办法把他表示成 k ∗ θ k*\theta k∗θ 这种线性的形式,自然也就没办法写出来状态空间方程了(状态变量 θ \theta θ分离不出来)。
所以由于旋转的非线性必须对其在 某个姿态下(即某个旋转向量下) 进行线性化,从而得到状态转移矩阵。参考深蓝学院VIO中的PPT求导公式(对旋转施加右扰动):
∂ ( R p ) ∂ φ = lim φ → 0 R exp ( φ ∧ ) p − R p φ = lim φ → 0 R ( I + φ ∧ ) p − R p φ = lim φ → 0 R φ ∧ p φ = lim φ → 0 − R p ∧ φ φ = − R p ∧ . \begin{align} \begin{aligned} \frac{\partial(\mathbf{R} \mathbf{p})}{\partial \varphi} &=\lim _{\varphi \rightarrow \mathbf{0}} \frac{\mathbf{R} \exp \left(\boldsymbol{\varphi}^{\wedge}\right) \mathbf{p}-\mathbf{R} \mathbf{p}}{\varphi} \\ &=\lim _{\varphi \rightarrow \mathbf{0}} \frac{\mathbf{R}\left(\mathbf{I}+\varphi^{\wedge}\right) \mathbf{p}-\mathbf{R} \mathbf{p}}{\varphi} \\ &=\lim _{\varphi \rightarrow 0} \frac{\mathbf{R} \varphi^{\wedge} \mathbf{p}}{\varphi}=\lim _{\varphi \rightarrow 0} \frac{-\mathbf{R} \mathbf{p}^{\wedge} \boldsymbol{\varphi}}{\varphi}=-\mathbf{R} \mathbf{p}^{\wedge} . \end{aligned} \end{align} ∂φ∂(Rp)=φ→0limφRexp(φ∧)p−Rp=φ→0limφR(I+φ∧)p−Rp=φ→0limφRφ∧p=φ→0limφ−Rp∧φ=−Rp∧.
假设线性展开点的角轴是 θ 0 \boldsymbol{\theta}_0 θ0,则可求得这个点的状态变量 R b i w a m \boldsymbol{R}_{b_{i}}^{w}\boldsymbol{a}_{m} Rbiwam 对 θ \boldsymbol{\theta} θ 的导数为 − R 0 a m ∧ -\boldsymbol{R_0} \boldsymbol{a}^{\wedge}_m −R0am∧,其中 R 0 \boldsymbol{R_0} R0 是旋转向量 θ 0 \boldsymbol {\theta}_0 θ0 对应的旋转矩阵。所以线性展开结果就是 R b i w a m = R 0 w a m − R 0 w a m ∧ ( θ − θ 0 ) \boldsymbol{R}_{b_{i}}^{w} \boldsymbol{a}_{m} = \boldsymbol{R}_0^{w} \boldsymbol{a}_{m} - \boldsymbol{R}_0^{w} \boldsymbol{a}_{m}^{\wedge}(\boldsymbol \theta - \boldsymbol {\theta}_0) Rbiwam=R0wam−R0wam∧(θ−θ0),从而表示成了关于我们的旋转状态变量 θ \boldsymbol{\theta} θ 的线性形式。
(3) 旋转状态变量的求导更加麻烦,这里不赘述,理解上面线性化的思想即可。
(4) 关于两个零偏,运动学方程建模的时候就已经有了它们关于时间的导数。并且它们俩由于是IMU内部本身的变化,和IMU的运动状态无关,因此是 相对独立的。
2.3.3. 状态空间方程为什么写成 x ˙ = F x + W w \dot{x}=Fx+Ww x˙=Fx+Ww 的形式?
给出VINS中关于 预积分 的连续时间状态空间方程如下,注意VINS中是关于状态变量是预积分,而不是我们上面说的PVQ。
[ δ α ˙ t b k δ β ˙ t b k δ θ ˙ t b k δ b ˙ a t δ b w t ] = [ 0 I 0 0 0 0 0 − R t b k ⌊ a ^ t − b a t ⌋ × − R t b k 0 0 0 − [ ω ^ t − b w t ⌋ × 0 − I 0 0 0 0 0 0 0 0 0 0 ] [ δ α t b k δ β t b k δ θ t b k δ b a t δ b w t ] + [ 0 0 0 0 − R t b k 0 0 0 0 − I 0 0 0 0 I 0 0 0 0 I ] [ n a n w n b a n b w ] \begin{align} \begin{aligned} {\left[\begin{array}{c} \delta \dot{\boldsymbol{\alpha}}_{t}^{b_{k}} \\ \delta \dot{\boldsymbol{\beta}}_{t}^{b_{k}} \\ \delta \dot{\boldsymbol{\theta}}_{t}^{b_{k}} \\ \delta \dot{\mathbf{b}}_{a_{t}} \\ \delta \mathbf{\mathbf { b }}_{w_{t}} \end{array}\right] } =& {\left[\begin{array}{ccccc} 0 & \mathbf{I} & 0 & 0 & 0 \\ 0 & 0 & -\mathbf{R}_{t}^{b_{k}}\left\lfloor\hat{\mathbf{a}}_{t}-\mathbf{b}_{a_{t}}\right\rfloor_{\times} & -\mathbf{R}_{t}^{b_{k}} & 0 \\ 0 & 0 & -\left[\hat{\boldsymbol{\omega}}_{t}-\mathbf{b}_{w_{t}}\right\rfloor \times & 0 & -\mathbf{I} \\ 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 \end{array}\right]\left[\begin{array}{c} \delta \boldsymbol{\alpha}_{t}^{b_{k}} \\ \delta \boldsymbol{\beta}_{t}^{b_{k}} \\ \delta \boldsymbol{\theta}_{t}^{b_{k}} \\ \delta \mathbf{b}_{a_{t}} \\ \delta \mathbf{b}_{w_{t}} \end{array}\right] } \\ &+ {\left[\begin{array}{cccc} 0 & 0 & 0 & 0 \\ -\mathbf{R}_{t}^{b_{k}} & 0 & 0 & 0 \\ 0 & -\mathbf{I} & 0 & 0 \\ 0 & 0 & \mathbf{I} & 0 \\ 0 & 0 & 0 & \mathbf{I} \end{array}\right]\left[\begin{array}{c} \mathbf{n}_{a} \\ \mathbf{n}_{w} \\ \mathbf{n}_{b_{a}} \\ \mathbf{n}_{b_{w}} \end{array}\right] } \end{aligned} \end{align} δα˙tbkδβ˙tbkδθ˙tbkδb˙atδbwt = 00000I00000−Rtbk⌊a^t−bat⌋×−[ω^t−bwt⌋×000−Rtbk00000−I00 δαtbkδβtbkδθtbkδbatδbwt + 0−Rtbk00000−I00000I00000I nanwnbanbw
(1) 状态空间方程为什么写成了这种形式,即 x ˙ = F x + W w \dot{x}=Fx+Ww x˙=Fx+Ww这种形式?IMU的$a,\omega $ 不应该作为系统输入 u u u 吗?为什么不写成 x ˙ = F x + B u + W w \dot{x}=Fx+Bu+Ww x˙=Fx+Bu+Ww 的形式?
这里是和系统有关的,因为系统运动学方程推导状态空间方程的结果就是IMU的输入 u u u 包含在了 F F F 矩阵中,而不存在对关于 u u u 的线性相加项。
(2) 另外为什么要把和噪声有关的 W w Ww Ww 这一项单独摘出来作为一个状态变量矩阵相乘的项,而不是把它放到 F x Fx Fx 中扩充成一个维度更大的 F x Fx Fx 矩阵呢?原因是里面的 w w w 项,也就是noise的实际值我们始终都不知道, W w Ww Ww 这一项只是我们考虑到运动学方程中存在过程噪声而加入的,而实际我们计算状态变量的值的时候只能用 F x Fx Fx 来计算,而 把噪声项 W w Ww Ww 简化为0。也就是我们只能计算一个名义值,如果我们知道了噪音那么就能计算真实值了,那也就用不上卡尔曼滤波或者非线性优化了。所以后面的 W w Ww Ww 这一项是为了计算我状态空间方程计算结果的协方差矩阵而存在的。
(3) 这里也可以发现,明明在IMU中的测量噪声只是 w w w,但是到这里却不是 + w +w +w,而变成了 + W w +Ww +Ww。其实这就是因为我们的运动学方程是 x ˙ = f ( x , w ) \dot{x} = f(x,w) x˙=f(x,w)的形式,而不是 x ˙ = f ( x ) + w \dot{x} = f(x)+w x˙=f(x)+w 的形式。也就是噪声 w w w被传入我们的非线性的运动学模型中之后,它被放大了。而由于 f f f 是非线性的,放大出来的噪声不再服从高斯分布了,这样就没办法再利用状态空间方程计算状态量的协方差矩阵了,所以我们才对状态空间方程进行了线性化,而得到的矩阵 W W W 恰恰就是我们线性化的模型对噪声的放大倍数。(所以这里也解释了B站DR_CAN讲的 EKF 中为什么把 w w w 放在了 f f f 里面而不是外面,因为过程噪声不知道是在哪里被加入的,所以必须放在 f f f 里面,这样才具有一般性)
2.3.4. 连续时间运动学方程求导建立 连续时间 误差状态空间方程
上面我们推导的是直接基于 状态 的 状态空间方程,但是在IMU的状态空间方程中,更常用的是一种基于 误差状态 (Error-State) 的误差状态空间方程。
(1) 先看多元微分学中的 全增量 的概念:多元函数 z = f ( x , y ) z=f(x,y) z=f(x,y) 在点 P ( x , y ) P(x,y) P(x,y) 的某邻域内有定义, P ′ ( x + Δ x , y + Δ y ) P'(x+\Delta x, y+\Delta y) P′(x+Δx,y+Δy) 是该邻域内任意一点,则称 Δ z = f ( x + Δ x , y + Δ y ) − f ( x , y ) \Delta z = f(x+\Delta x, y+\Delta y) - f(x, y) Δz=f(x+Δx,y+Δy)−f(x,y) 为函数在点 P ( x , y ) P(x,y) P(x,y) 处的 全增量,并且满足
Δ z = f ( x + Δ x , y + Δ y ) − f ( x , y ) = ∂ z ∂ x Δ x + ∂ z ∂ y Δ y + o ( ρ ) \begin{align} \Delta z = f(x+\Delta x, y+\Delta y) - f(x, y) = \frac{\partial z}{\partial x} \Delta x + \frac{\partial z}{\partial y} \Delta y + o (\rho) \end{align} Δz=f(x+Δx,y+Δy)−f(x,y)=∂x∂zΔx+∂y∂zΔy+o(ρ)
其实全增量进一步扩展,即当自变量的增量足够小的时候,就变成了 全微分,即
d z = ∂ z ∂ x d x + ∂ z ∂ y d y \begin{align} dz = \frac{\partial z}{\partial x} dx + \frac{\partial z}{\partial y} dy \end{align} dz=∂x∂zdx+∂y∂zdy
观察上面的全增量公式,可以发现:把每个自变量都给一个微小的增量,然后求出由于所有自变量都变化导致的函数的全增量。而全增量中每一项前面的系数,恰恰就是 原来的函数对这个变量的偏导。所以当我们想求多个变量的每一个偏导的时候,可以使用全增量公式来求。
(2) 现在把上面我们对连续时间求导得到的连续时间的 状态关于状态的变化方程(旋转矩阵可以用罗德里格斯公式写成关于旋转向量的非线性函数)写成一个抽象的非线性函数 f f f,其中 x \boldsymbol{x} x 是状态变量, w \boldsymbol{w} w 是过程噪声,也就是IMU传感器的测量噪声。
x ˙ = f ( x , w ) \begin{align} \dot{\boldsymbol{x}} = f(\boldsymbol{x}, \boldsymbol{w}) \end{align} x˙=f(x,w)
由于这个函数是一个非线性的函数,根据上面的讨论,我们想把它展开成关于状态变量 x \boldsymbol{x} x 的线性函数。假设我们把 f f f 在 x \boldsymbol{x} x 处展开,如下所示:
x ˙ + δ x ˙ = f ( x + δ x , w + δ ω ) ≈ f ( x , w ) + ∂ f ∂ x δ x + ∂ f ∂ w δ w \begin{align} \dot{\boldsymbol{x}} + \dot{\boldsymbol{\delta x}} = f(\boldsymbol{x} + \delta \boldsymbol{x}, \boldsymbol{w} + \delta \boldsymbol{\omega}) \approx f(\boldsymbol{x}, \boldsymbol{w}) + \frac{\partial f}{\partial \boldsymbol{x}} \boldsymbol{\delta x} + \frac{\partial f}{\partial \boldsymbol{w}} \boldsymbol{\delta w} \end{align} x˙+δx˙=f(x+δx,w+δω)≈f(x,w)+∂x∂fδx+∂w∂fδw
其中,由于我们的等号左侧实际上是 x ˙ \dot{\boldsymbol{x}} x˙,所以当自变量 x \boldsymbol{x} x 变成是 x + δ x \boldsymbol{x} + \delta \boldsymbol{x} x+δx 之后,左边的函数值自然也就变成了
d ( x + δ x ) d t = x ˙ + δ x ˙ \begin{align} \frac{\mathrm{d}(\boldsymbol{x}+\boldsymbol{\delta x})}{\mathrm{d} t} = \dot{\boldsymbol{x}} + \dot{\boldsymbol{\delta x}} \end{align} dtd(x+δx)=x˙+δx˙
而 ≈ \approx ≈ 右边的是泰勒展开。由于 x ˙ = f ( x , w ) \dot{\boldsymbol{x}} = f(\boldsymbol{x}, \boldsymbol{w}) x˙=f(x,w),所以上面的公式化为:
δ x ˙ = ∂ f ∂ x δ x + ∂ f ∂ w δ w \begin{align} \dot{\boldsymbol{\delta x}} = \frac{\partial f}{\partial \boldsymbol{x}} \boldsymbol{\delta x} + \frac{\partial f}{\partial \boldsymbol{w}} \boldsymbol{\delta w} \end{align} δx˙=∂x∂fδx+∂w∂fδw
可见这就是上面说的 全增量公式,只不过由于我们的函数左侧是 x ˙ \dot{\boldsymbol{x}} x˙ 的形式看起来有点别扭,其实实际上是一样的。
(3) 回到误差状态空间方程的推导上
现在我们想推导误差状态空间方程,先看几种状态的定义和关系:
- 名义状态 : x ^ \hat{\boldsymbol{x}} x^
- 真实状态 : x \boldsymbol{x} x
- 误差状态 : δ x \delta{\boldsymbol{x}} δx
关系 : x = x ^ + δ x \boldsymbol{x} = \hat{\boldsymbol{x}} + \delta{\boldsymbol{x}} x=x^+δx, 即 真实状态 = = = 名义状态 + + + 误差状态。
在线性化上面的非线性状态方程的时候,我们只能在名义状态的地方进行线性化,因为名义状态是我们 唯一可以真实计算得到的状态,是我们可以真正操作的状态。而真实状态我们永远不知道,它只能对误差和噪声建模,然后带入公式中来表示我们的真实状态应该是多少,从而评估我们计算的名义状态误差有多大。所以利用上面的公式(28),在 名义状态 的地方展开,可以得到:
x ^ ˙ + δ x ˙ = f ( x ^ + δ x , w + δ ω ) ≈ f ( x ^ , ω ) + ∂ f ∂ x ∣ x = x ^ δ x + ∂ f ∂ w δ w \dot{\hat{\boldsymbol{x}} }+ \dot{\boldsymbol{\delta x}} = f(\boldsymbol{\hat{x}} + \delta \boldsymbol{x}, \boldsymbol{w} + \delta \boldsymbol{\omega}) \approx f(\boldsymbol{\hat{x}}, \boldsymbol{\omega}) + \left.\frac{\partial f}{\partial \boldsymbol{x}} \right|_{\boldsymbol{x} = \hat{\boldsymbol{x}}}\boldsymbol{\delta x} + \frac{\partial f}{\partial \boldsymbol{w}} \boldsymbol{\delta w} x^˙+δx˙=f(x^+δx,w+δω)≈f(x^,ω)+∂x∂f x=x^δx+∂w∂fδw
然后再由公式(30)就可以得到:
δ x ˙ = ∂ f ∂ x ∣ x = x ^ δ x + ∂ f ∂ w δ w \begin{align} \dot{\boldsymbol{\delta x}} = \left.\frac{\partial f}{\partial \boldsymbol{x}} \right|_{\boldsymbol{x} = \hat{\boldsymbol{x}}}\boldsymbol{\delta x} + \frac{\partial f}{\partial \boldsymbol{w}} \boldsymbol{\delta w} \end{align} δx˙=∂x∂f x=x^δx+∂w∂fδw
其实如果是推导基于状态变量的状态空间方程的话,我们直接按照 (2) 中在某个我们知道的状态点处展开就行了,而用不到上面的全增量公式。但是有一个需要注意的点是我们在计算名义状态值 f ( x ^ , ω ) f(\boldsymbol{\hat{x}}, \boldsymbol{\omega}) f(x^,ω) 的时候噪声 ω \boldsymbol{\omega} ω 是 0,因为名义状态下并不知道噪声,我们只能简化为0。
注意:我们这里是对函数 f f f (这个函数 f f f 是 运动学方程对时间求导得到的函数) 求它关于 各个状态变量 的偏导,而不是对 系统的运动学方程 求它关于各个状态变量的偏导。但是一个看深蓝学院VIO的推导里,他们都是直接就在对 离散运动学方程 上求了偏导,这是为什么呢?其实这里是两个求导的自变量不一样的原因,因为 运动学方程是对时间求全导,公式(31)是对 状态变量求偏导,两个求导并不影响。因此可见当我使用公式(31)对状态变量求偏导的时候,函数 f f f如果再对时间进行一次积分或二次积分,就相当于我 在运动学方程上直接对状态变量求偏导,实际上最后的结果就相当于差了一个和时间 t t t 有关的倍数。而这个和时间有关的倍数就是因为运动学方程是随着时间变化的,我们求得的 x ˙ \dot{\boldsymbol x} x˙ 表示了状态随时间变化的关系,所以下一个时刻的状态肯定是和经过的时间有关的,这就是为什么在运动学方程上直接对状态变量求导多了一个和时间 t t t 有关的倍数。实际上直接在运动学方程上对状态变量求导的结果相当于省去了 状态根据状态空间方程随时间变化 的这个过程,直接得到了 随时间变化的状态 关于 状态变量 的偏导。
2.3.5. 状态空间方程和误差状态空间方程的协方差矩阵一致吗?
在 VINS 中,IMU使用的是误差状态空间方程,然后在非线性优化中直接利用误差的协方差矩阵作为IMU预积分值(状态变量)的协方差矩阵。为什么可以用 误差状态的协方差矩阵 代替 状态的协方差矩阵 呢?
TODO: 公式标号有问题:
实际上还是可以从公式(24)和(25)中看出来。协方差矩阵是否一样关键就是他们的状态空间方程的系数矩阵是否一样,对比公式(24)和(25)可以看到,无论是状态空间方程还是误差状态空间方程,他们的系数矩阵 F F F 和 W W W 都是 函数 f f f对状态变量求偏导,在名义状态处取值 的结果。也就是状态空间方程和误差状态空间方程的 系数矩阵是完全一致的,因此协方差矩阵也是一致的。
2.4. 连续状态空间矩阵方程的离散化
上面我们做的是对连续的运动学方程进行线性化得到连续的状态空间方程,但是实际上我们的系统是离散的,不论IMU测量值还是我们进行计算的值都是离散的。所以还需要对上面的连续时间的状态空间方程进行离散化,这里根据系统运动学离散积分时选择方法的不同,连续状态空间方程进行离散化的方法也不同。
2.4.1. 欧拉积分的离散化(对应欧拉积分的运动学方程)
这里我们都是用误差状态空间方程来分析,因为IMU中用的基本都是误差状态空间方程。
假设前面我们推导得到的连续的误差状态空间方程为:
δ x ˙ = A δ x + B n k − 1 \begin{align} \dot{\delta x}=\mathbf{A} \delta \mathbf{x}+\mathbf{B} \mathbf{n}_{k-1} \end{align} δx˙=Aδx+Bnk−1
则离散的误差状态空间方程为:
δ x k = δ x k − 1 + δ x k − 1 Δ t → δ x k = ( I + A Δ t ) δ x k − 1 + B Δ t n k − 1 \begin{align} \begin{aligned} \delta \mathbf{x}_{k} &=\delta \mathbf{x}_{k-1}+\delta \mathbf{x}_{k-1} \Delta t \\ \rightarrow \delta \mathbf{x}_{k} &=(\mathbf{I}+\mathbf{A} \Delta t) \delta \mathbf{x}_{k-1}+\mathbf{B} \Delta t \mathbf{n}_{k-1} \end{aligned} \end{align} δxk→δxk=δxk−1+δxk−1Δt=(I+AΔt)δxk−1+BΔtnk−1
因为我们用的是欧拉积分,所以 δ x \delta \mathbf{x} δx 直接取上一个时刻的值即可,测量值和噪声也都是只取上一个时刻的。
2.4.2. 中值积分的离散化(对应中值积分的运动学方程):
这个要复杂一些,可以把误差状态空间方程矩阵拆开来看,分解成五个方程来计算。因为实际推导就是把五个方程从矩阵里分离出来,然后对每个方程进行推导的。
(1) 以预积分方程中关于 θ \boldsymbol \theta θ 的连续时间方程来看:
δ θ ˙ t b k = − [ ω ^ t − b w t ⌋ × δ θ t b k − δ b w t − n w \begin{align} \delta \dot{\boldsymbol{\theta}}_{t}^{b_{k}} = - \left[\hat{\boldsymbol{\omega}}_{t}-\mathbf{b}_{w_{t}}\right\rfloor_{\times}\delta \boldsymbol{\theta}_{t}^{b_{k}} - \delta \mathbf{b}_{w_{t}} - \mathbf{n}_{w} \end{align} δθ˙tbk=−[ω^t−bwt⌋×δθtbk−δbwt−nw
对于中值积分对应的离散状态空间方程来说,所有的 状态量值和测量值 都需要用相邻 两个时刻 的值来表示。而IMU的零偏和噪声对状态量没有依赖关系,所以它们不用考虑对状态变量的以来关系。但是状态变量PVQ中依赖关系是 P→V→Q,所以在更新状态变量的时候的顺序是 Q→V→P。比如上面这个关于旋转的连续时间方程,其中的角速度值就要用前后两个时刻的,角速度噪声要用前后两个时刻的。这样很轻松就可以推得下一个时刻的旋转向量。
(2) 而速度的连续时间方程如下:
δ β ˙ = − R t ( a ^ t − b a t ) ∧ δ θ − R t δ b a t − R t n a \begin{align} \delta \dot{\beta}=-R_{t}\left(\hat{a}_{t}-b_{a_{t}}\right)^{\wedge} \delta \theta-R_{t} \delta b_{a_{t}}-R_{t} n_{a} \end{align} δβ˙=−Rt(a^t−bat)∧δθ−Rtδbat−Rtna
可以看出来里面和状态有关的是姿态,所以这个姿态就要使用我们上一次的姿态 R k R_k Rk 和这一次刚刚算出来的姿态 R k + 1 R_{k+1} Rk+1 来计算。但是这里还不是简单的平均关系,因为 R R R 是作用在加速度上的,所以实际上我们应该把不同时刻的姿态乘以不同时刻的加速度,然后求平均作为加速度的平均值。位置P的计算类推,不再赘述。
所以这里能看出来,推导这个离散形式的 F F F 和 G G G 矩阵的时候,如果我们想写出来公式,实际上是很麻烦的,因为要按照 Q→V→P 的顺序依次迭代公式,最后才能得到P和V完整的离散状态空间方程的系数矩阵。但是这个在编程实现中却不困难,因为我们可以定义一个变量存储Q的系数矩阵,在V中计算的时候直接带入这个矩阵,然后计算得到V的系数矩阵,再存储这个系数矩阵,在P中计算的时候带入Q和V的系数矩阵。
3. 非线性离散系统的线性化 推导 状态空间矩阵方程
3.1. 离散状态空间方程的另一种推导方法(以R2Live为例)
上一章中的的方法是对连续的运动学方程先求导,得到连续的状态空间方程,然后再把连续的状态空间方程进行离散化。这样其中多了一个步骤,就是求连续的状态空间方程这里。从公式推导的角度来看,这样很麻烦,因为多了一个求连续状态空间方程的过程,而且离散化的时候如果用中值积分离散的话,存在Q→V→P顺序的系数矩阵的带入,最后推导公式结果会非常麻烦。但是这个方法的好处是在编程实现的时候非常容易,甚至编程实现的时候只需要推导得到连续的状态空间方程即可,离散的状态空间用系数矩阵带入即可。
现在用一种 方便公式推导 的方法:先把运动学方程离散化,然后直接对离散的运动学方程推导离散的状态空间方程。这个方法在公式推导的时候很好用,在 R2Live 的论文中优势表现非常明显,因为整个推导过程思路很清晰。这里的推导方便用的两个技巧是:
(1) 使用 全增量 的方式,一次把某一个状态对所有状态的偏导都求出来。将离散运动学方程在名义值处的 计算公式 值作为名义状态值,在真实状态处的 计算公式 值作为真实状态值,二者相减等号左侧就是误差状态值,等号右边就是 带入公式 得到的误差状态值的具体 表达式。如下所示:
δ x ^ i + 1 = x i + 1 ⊟ x ^ i + 1 = ( x i ⊞ ( Δ t ⋅ f ( x i , u i , w i ) ) ) ⊟ ( x ^ i ⊞ ( Δ t ⋅ f ( x ^ i , u i , 0 ) ) ) ≈ F δ x ^ δ x ^ + F w w i ∼ N ( 0 21 × 1 , Σ δ x ^ i + 1 ) \begin{align} \begin{aligned} \delta \hat{\mathbf{x}}_{i+1}&=\mathbf{x}_{i+1} \boxminus \hat{\mathbf{x}}_{i+1} \\ &=\left(\mathbf{x}_{i} \boxplus\left(\Delta t \cdot \mathbf{f}\left(\mathbf{x}_{i}, \mathbf{u}_{i}, \mathbf{w}_{i}\right)\right)\right) \boxminus\left(\hat{\mathbf{x}}_{i} \boxplus\left(\Delta t \cdot \mathbf{f}\left(\hat{\mathbf{x}}_{i}, \mathbf{u}_{i}, \mathbf{0}\right)\right)\right) \\ &\approx \mathbf{F}_{\delta \hat{\mathbf{x}}} \delta \hat{\mathbf{x}}+\mathbf{F}_{\mathbf{w}} \mathbf{w}_{i} \\ &\sim \mathcal{N}\left(\mathbf{0}_{21 \times 1}, \mathbf{\Sigma}_{\delta \hat{\mathbf{x}}_{i+1}}\right) \end{aligned} \end{align} δx^i+1=xi+1⊟x^i+1=(xi⊞(Δt⋅f(xi,ui,wi)))⊟(x^i⊞(Δt⋅f(x^i,ui,0)))≈Fδx^δx^+Fwwi∼N(021×1,Σδx^i+1)
其中:
x i + 1 \mathbf{x}_{i+1} xi+1 是下一刻真实状态,它的计算方法是带入上一刻的 真实状态 x i = x ^ i ⊞ δ x ^ \mathbf{x}_{i} = \hat{\mathbf{x}}_{i}\boxplus \delta \hat{\mathbf{x}} xi=x^i⊞δx^、加速度测量的真实值 a i = a ^ i − δ b ^ a i − n a i \mathbf{a}_{i}=\hat{\mathbf{a}}_{i}-\delta \hat{\mathbf{b}}_{\mathbf{a}_{i}}-\mathbf{n}_{\mathbf{a}_{i}} ai=a^i−δb^ai−nai 和 角速度测量的真实值 ω i = ω ^ i − δ b ^ g i − n g i \boldsymbol{\omega}_{i}=\hat{\boldsymbol{\omega}}_{i}-\delta \hat{\mathbf{b}}_{\mathbf{g}_{i}}-\mathbf{n}_{\mathbf{g}_{i}} ωi=ω^i−δb^gi−ngi 进行计算。
x i + 1 ^ \hat{\mathbf{x}_{i+1}} xi+1^ 是下一刻名义状态,它的计算方法是带入 上一刻的名义状态 x ^ i \hat{\mathbf{x}}_{i} x^i、加速度测量的名义值 a ^ i = a m i − b ^ a i \hat{\mathbf{a}}_{i} =\mathbf{a}_{m_{i}}-\hat{\mathbf{b}}_{\mathbf{a}_{i}} a^i=ami−b^ai 和 角速度测量的名义值 ω ^ i = ω m i − b ^ g i \hat{\boldsymbol{\omega}}_{i} = \boldsymbol{\omega}_{m_{i}}-\hat{\mathbf{b}}_{\mathbf{g}_{i}} ω^i=ωmi−b^gi 进行计算。
比如其中最复杂的 旋转状态误差 的推导如下:
(2) 姿态采用旋转矩阵表示,然后旋转矩阵求导使用李群和李代数,相比四元数更加方便。求真实姿态和名义姿态之间的误差的时候,就是名义姿态矩阵乘以真实姿态矩阵的逆,然后结果再取对数在李代数上应该接近零向量,也就是旋转向量的误差,非常方便。但是这其中用到了几个李群李代数的公式,比如右雅克比、BCH近似、旋转矩阵的伴随性质等等,这些公式在视觉SLAM14讲中都有,所以仔细看并不难。
3.2. R2Live论文公式的疑惑解答
如下公式,最后写的是 F δ x F_{\delta x} Fδx 和 F w F_w Fw 都是误差的导数在误差为0时候的值,这个看着不太好明白。
δ x ^ i + 1 = x i + 1 □ x ^ i + 1 = ( x i ⊞ ( Δ t ⋅ f ( x i , u i , w i ) ) ) □ ( x ^ i ⊟ ( Δ t ⋅ f ( x ^ i , u i , 0 ) ) ) ≈ F δ x ^ δ x ^ + F w w i ∼ N ( 0 21 × 1 , Σ δ x ^ i + 1 ) where: Σ δ x ^ i + 1 = F δ x ^ Σ δ x ^ i F δ x ^ T + F w Q F w T F δ x ^ = ∂ ( δ x ^ i + 1 ) ∂ δ x ^ i ∣ δ x ^ i = 0 , w i = 0 , F w = ∂ ( δ x ^ i + 1 ) ∂ w i ∣ δ x ^ i = 0 , w i = 0 \begin{align} \begin{aligned} &\delta \hat{\mathbf{x}}_{i+1}=\mathbf{x}_{i+1} \square \hat{\mathbf{x}}_{i+1} \\ &=\left(\mathbf{x}_{i} \boxplus\left(\Delta t \cdot \mathbf{f}\left(\mathbf{x}_{i}, \mathbf{u}_{i}, \mathbf{w}_{i}\right)\right)\right) \square\left(\hat{\mathbf{x}}_{i} \boxminus\left(\Delta t \cdot \mathbf{f}\left(\hat{\mathbf{x}}_{i}, \mathbf{u}_{i}, \mathbf{0}\right)\right)\right) \\ &\approx \mathbf{F}_{\delta \hat{\mathbf{x}}} \delta \hat{\mathbf{x}}+\mathbf{F}_{\mathbf{w}} \mathbf{w}_{i} \\ &\sim \mathcal{N}\left(\mathbf{0}_{21 \times 1}, \boldsymbol{\Sigma}_{\delta \hat{\mathbf{x}}_{i+1}}\right) \\ &\text { where: } \\ &\boldsymbol{\Sigma}_{\delta \hat{\mathbf{x}}_{i+1}}=\mathbf{F}_{\delta \hat{\mathbf{x}}} \boldsymbol{\Sigma}_{\delta \hat{\mathbf{x}}_{i}} \mathbf{F}_{\delta \hat{\mathbf{x}}}^{T}+\mathbf{F}_{\mathbf{w}} \mathbf{Q} \mathbf{F}_{\mathbf{w}}^{T} \\ &\mathbf{F}_{\delta \hat{\mathbf{x}}}=\left.\frac{\partial\left(\delta \hat{\mathbf{x}}_{i+1}\right)}{\partial \delta \hat{\mathbf{x}}_{i}}\right|_{\delta \hat{\mathbf{x}}_{i}=\mathbf{0}, \mathbf{w}_{i}=\mathbf{0}}, \quad \mathbf{F}_{\mathbf{w}}=\left.\frac{\partial\left(\delta \hat{\mathbf{x}}_{i+1}\right)}{\partial \mathbf{w}_{i}}\right|_{\delta \hat{\mathbf{x}}_{i}=\mathbf{0}, \mathbf{w}_{i}=\mathbf{0}} \end{aligned} \end{align} δx^i+1=xi+1□x^i+1=(xi⊞(Δt⋅f(xi,ui,wi)))□(x^i⊟(Δt⋅f(x^i,ui,0)))≈Fδx^δx^+Fwwi∼N(021×1,Σδx^i+1) where: Σδx^i+1=Fδx^Σδx^iFδx^T+FwQFwTFδx^=∂δx^i∂(δx^i+1) δx^i=0,wi=0,Fw=∂wi∂(δx^i+1) δx^i=0,wi=0
其实看之前我们推导的公式:
δ x ˙ = ∂ f ∂ x ∣ x = x ^ δ x + ∂ f ∂ w δ w \begin{align} \dot{\boldsymbol{\delta x}} = \left.\frac{\partial f}{\partial \boldsymbol{x}} \right|_{\boldsymbol{x} = \hat{\boldsymbol{x}}}\boldsymbol{\delta x} + \frac{\partial f}{\partial \boldsymbol{w}} \boldsymbol{\delta w} \end{align} δx˙=∂x∂f x=x^δx+∂w∂fδw
实际上这个误差方程关于 δ x \delta x δx 是线性的,所以 ∂ ( δ x ^ i + 1 ) ∂ δ x ^ i \frac{\partial\left(\delta \hat{\mathbf{x}}_{i+1}\right)}{\partial \delta \hat{\mathbf{x}}_{i}} ∂δx^i∂(δx^i+1) 的值与 δ x \delta x δx 没有关系,它一直都是原来的状态空间方程在名义值处的导数。只不过写成这里的形式是说我们只有名义值,而且每次我们给出的名义值都是我们能够给出的最精确的值,所以是无偏的,也就是每次的 δ x \delta x δx 都是 0。
4. IMU 积分的误差状态空间方程推导
参见我的另一篇博客:IMU 积分的误差状态空间方程推导
更多推荐
所有评论(0)