IMU比较详细的内容(主要是针对卡尔曼滤波器)(摘自于ipythonnotebook)

IMU比较详细的内容(主要是针对卡尔曼滤波器)(摘自于ipythonnotebook)

C++代码,编的比较好,可以仿照。下面是对他的资料的整理。

  • 代码均是基于面向对象设计的,调用函数后发现参数输入太少了吧
    • 运行后发现结果不对
    • 对于GPS的模块的调用显得很复杂,最后给位置算积分也不太对
      实际上是仿照这个代码 Kalman-master ,内容主要包含下面两张图:
      IMU比较详细的内容(主要是针对卡尔曼滤波器)(摘自于ipythonnotebook)_第1张图片IMU比较详细的内容(主要是针对卡尔曼滤波器)(摘自于ipythonnotebook)_第2张图片
      The coordinate system is as in DIN70000:
      IMU比较详细的内容(主要是针对卡尔曼滤波器)(摘自于ipythonnotebook)_第3张图片
      非常重要:横滚(roll)(fai)和俯仰(pitch)(seta)摇头(yaw)(psi)
      单位如下:
	The units are:
			Lat/Lon in decimal degree (from GPS)
			speed in km/h (from GPS)
			course in degree (from GPS)
			roll/pitch/yaw in degree (from IMU)
			roll-/pitch-/yawrate in degrees/second (from IMU)
			acclerations in m/(from IMU)

该开源项目主要是针对“汽车”而言,所以很多情况下是一个二维的系统,只有xy两个方向。为此,首先的简化如下:

  1. 恒定速度行驶,汽车过隧道
    这里阐述了相应矩阵的确定:
		P: 初始化不确定性
		R: 观测误差协方差
		Q: 过程噪声协方差(类似于风的印象,加速度的干扰)

P 0 = [ σ x 2 0 0 0 0 σ y 2 0 0 0 0 σ x 2 0 0 0 0 σ y 2 ] P_{0}=\left[\begin{array}{cccc}{\sigma_{x}^{2}} & {0} & {0} & {0} \\ {0} & {\sigma_{y}^{2}} & {0} & {0} \\ {0} & {0} & {\sigma_{x}^{2}} & {0} \\ {0} & {0} & {0} & {\sigma_{y}^{2}}\end{array}\right] P0=σx20000σy20000σx20000σy2

R = [ σ x ˙ 2 0 0 σ y ˙ 2 ] R=\left[\begin{array}{cc}{\sigma_{\dot{x}}^{2}} & {0} \\ {0} & {\sigma_{\dot{y}}^{2}}\end{array}\right] R=[σx˙200σy˙2]
过程噪声协方差比较复杂:
Q = [ σ x 2 σ x y σ x x σ x y σ y x σ y 2 σ y x ˙ σ y y ˙ σ x x σ x y σ x 2 σ x y ˙ σ y x σ y y σ y x σ y 2 ] Q=\left[\begin{array}{cccc}{\sigma_{x}^{2}} & {\sigma_{x y}} & {\sigma_{x x}} & {\sigma_{x y}} \\ {\sigma_{y x}} & {\sigma_{y}^{2}} & {\sigma_{y \dot{x}}} & {\sigma_{y \dot{y}}} \\ {\sigma_{x x}} & {\sigma_{x y}} & {\sigma_{x}^{2}} & {\sigma_{x \dot{y}}} \\ {\sigma_{y x}} & {\sigma_{y y}} & {\sigma_{y x}} & {\sigma_{y}^{2}}\end{array}\right] Q=σx2σyxσxxσyxσxyσy2σxyσyyσxxσyx˙σx2σyxσxyσyy˙σxy˙σy2
有如下:
Q = G ⋅ G T ⋅ σ v 2 Q=G \cdot G^{T} \cdot \sigma_{v}^{2} Q=GGTσv2
其中,
G = [ 0.5 d t 2 0.5 d t 2 d t d t ] T G=\left[\begin{array}{llll}{0.5 d t^{2}} & {0.5 d t^{2}} & {d t} & {d t}\end{array}\right]^{T} G=[0.5dt20.5dt2dtdt]T
代码如下:

sa = 0.1
G = np.matrix([[1/2.0*dt**2],
               [1/2.0*dt**2],
               [dt],
               [dt],
               [1.0],
               [1.0]])
Q = G*G.T*sa**2
print(Q, Q.shape)

但是有如下结果,是不是代表已经发散了?
IMU比较详细的内容(主要是针对卡尔曼滤波器)(摘自于ipythonnotebook)_第4张图片
事实证明已经发散了。因为这里观测的是加速度,但是位置的初始误差是很难估计出来的。
2. 球在三维中运动,观测球的位置
模拟球的运动:

Hz = 100.0 # Frequency of Vision System
dt = 1.0/Hz
T = 1.0 # s measuremnt time
m = int(T/dt) # number of measurements

px= 0.0 # x Position Start
py= 0.0 # y Position Start
pz= 1.0 # z Position Start

vx = 10.0 # m/s Velocity at the beginning
vy = 0.0 # m/s Velocity
vz = 0.0 # m/s Velocity

c = 0.1 # Drag Resistance Coefficient阻力阻力系数
d = 0.9 # Damping阻尼

Xr=[]
Yr=[]
Zr=[]
for i in range(int(m)):
    accx = -c*vx**2  # Drag Resistance
    
    vx += accx*dt
    px += vx*dt

    accz = -9.806 + c*vz**2 # Gravitation + Drag
    vz += accz*dt
    pz += vz*dt
    
    if pz<0.01:
        vz=-vz*d
        pz+=0.02
    if vx<0.1:
        accx=0.0
        accz=0.0
        
    Xr.append(px)
    Yr.append(py)
    Zr.append(pz)
# 模拟球的运动

估计位置距离球的位置0.25m。
卡尔曼滤波器仅用于线性动态系统。阻力系数在某种状态下是非线性的,但是滤波器可以处理该阻力,直到达到一定程度的阻力为止。但是这时,球撞到了地面,非线性度过高,滤波器提供了错误的解决方案。因此,必须在滤波器环路中对开关进行建模,这有助于滤波器获得它。
下面给出了离散的动力学模型:
x k + 1 = [ 1 0 0 Δ t 0 0 1 2 Δ t 2 0 0 0 1 0 0 Δ t 0 0 1 2 Δ t 2 0 0 0 1 0 0 Δ t 0 0 Δ t 2 0 0 0 1 0 0 Δ t 0 0 0 0 0 0 1 0 0 Δ t 0 0 0 0 0 0 1 0 0 Δ t 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 ] x k x_{k+1}=\left[\begin{array}{ccccccccc}{1} & {0} & {0} & {\Delta t} & {0} & {0} & {\frac{1}{2} \Delta t^{2}} & {0} & {0} \\ {0} & {1} & {0} & {0} & {\Delta t} & {0} & {0} & {\frac{1}{2} \Delta t^{2}} & {0} \\ {0} & {0} & {1} & {0} & {0} & {\Delta t} & {0} & {0} & {\Delta t^{2}} \\ {0} & {0} & {0} & {1} & {0} & {0} & {\Delta t} & {0} & {0} \\ {0} & {0} & {0} & {0} & {1} & {0} & {0} & {\Delta t} & {0} \\ {0} & {0} & {0} & {0} & {0} & {1} & {0} & {0} & {\Delta t} \\ {0} & {0} & {0} & {0} & {0} & {0} & {1} & {0} & {0} \\ {0} & {0} & {0} & {0} & {0} & {0} & {0} & {1} & {0} \\ {0} & {0} & {0} & {0} & {0} & {0} & {0} & {0} & {1}\end{array}\right]x_{k} xk+1=100000000010000000001000000Δt001000000Δt001000000Δt00100021Δt200Δt00100021Δt200Δt001000Δt200Δt001xk
这里同样结果很糟糕
3. 观测位置与加速度
结果不错。
4. 这里涉及到加速度计与陀螺仪之间的关系估算角度,观测是用加速度计和陀螺仪
转速传感器直接测量,加速度传感器直接测量重力,因此不直接测量倾斜角ф。倾斜角和由加速度传感器测量的垂直加速度a之间存在数学联系。它是余弦。如果自行车直立,则加速度a恰好为1g,如果ф= 90°,则加速度为0g。
a = g ⋅ cos ⁡ ( 9 0 ∘ − ϕ ) a=g \cdot \cos \left(90^{\circ}-\phi\right) a=gcos(90ϕ)
有如下关系:
![]IMU比较详细的内容(主要是针对卡尔曼滤波器)(摘自于ipythonnotebook)_第5张图片

page2 扩展卡尔曼滤波

概括如下:
P ~ k = F k − 1 P ^ k − 1 F k − 1 T + Q k ′ \tilde{P}_{k}=F_{k-1} \hat{P}_{k-1} F_{k-1}^{T}+Q_{k}^{\prime} P~k=Fk1P^k1Fk1T+Qk
x ~ k = f ( x ^ k − 1 , v k , 0 ) \tilde{x}_{k}=f\left(\hat{x}_{k-1}, v_{k}, 0\right) x~k=f(x^k1,vk,0)
K k = P ~ k G k T ( G k P ~ k G k T + R k ′ ) − 1 K_{k}=\tilde{P}_{k} G_{k}^{T}\left(G_{k} \tilde{P}_{k} G_{k}^{T}+R_{k}^{\prime}\right)^{-1} Kk=P~kGkT(GkP~kGkT+Rk)1
P ^ k = ( I − K k G k ) P ~ k \hat{P}_{k}=\left(I-K_{k} G_{k}\right) \tilde{P}_{k} P^k=(IKkGk)P~k ,
x ^ k = x ~ k + K k ( y k − g ( x ~ k , 0 ) ) \hat{x}_{k}=\tilde{x}_{k}+K_{k}\left(y_{k}-g\left(\tilde{x}_{k}, 0\right)\right) x^k=x~k+Kk(ykg(x~k,0))
其中,
F k − 1 = ∂ f ∂ x k − 1 ∣ x ^ k − 1 , G k = ∂ h ∂ x k ∣ x ~ k F_{k-1}=\left.\frac{\partial f}{\partial x_{k-1}}\right|_{\hat{x}_{k-1}}, G_{k}=\left.\frac{\partial h}{\partial x_{k}}\right|_{\tilde{x}_{k}} Fk1=xk1fx^k1,Gk=xkhx~k
故而,下面整理了kalman滤波的普遍做法:

Labbe

x ‾ = F x + B u P ‾ = F P F T + Q y = z − H x ‾ S = H P ‾ H T + R K = P ‾ H T S − 1 x = x ‾ + K y P = ( I − K H ) P ‾ \begin{aligned} \overline{\mathbf x} &= \mathbf{Fx} + \mathbf{Bu} \\ \overline{\mathbf P} &= \mathbf{FPF}^\mathsf{T} + \mathbf Q \\ \\ \mathbf y &= \mathbf z - \mathbf{H}\overline{\mathbf x} \\ \mathbf S &= \mathbf{H}\overline{\mathbf P}\mathbf{H}^\mathsf{T} + \mathbf R \\ \mathbf K &= \overline{\mathbf P}\mathbf{H}^\mathsf{T}\mathbf{S}^{-1} \\ \mathbf x &= \overline{\mathbf x} +\mathbf{Ky} \\ \mathbf P &= (\mathbf{I}-\mathbf{KH})\overline{\mathbf P} \end{aligned} xPySKxP=Fx+Bu=FPFT+Q=zHx=HPHT+R=PHTS1=x+Ky=(IKH)P

Wikipedia

x ^ k ∣ k − 1 = F k x ^ k − 1 ∣ k − 1 + B k u k P k ∣ k − 1 = F k P k − 1 ∣ k − 1 F k T + Q k y ~ k = z k − H k x ^ k ∣ k − 1 S k = H k P k ∣ k − 1 H k T + R k K k = P k ∣ k − 1 H k T S k − 1 x ^ k ∣ k = x ^ k ∣ k − 1 + K k y ~ k P k ∣ k = ( I − K k H k ) P k ∣ k − 1 \begin{aligned} \hat{\mathbf x}_{k\mid k-1} &= \mathbf{F}_{k}\hat{\mathbf x}_{k-1\mid k-1} + \mathbf{B}_{k} \mathbf{u}_{k} \\ \mathbf P_{k\mid k-1} &= \mathbf{F}_{k} \mathbf P_{k-1\mid k-1} \mathbf{F}_{k}^{\textsf{T}} + \mathbf Q_{k}\\ \tilde{\mathbf{y}}_k &= \mathbf{z}_k - \mathbf{H}_k\hat{\mathbf x}_{k\mid k-1} \\ \mathbf{S}_k &= \mathbf{H}_k \mathbf P_{k\mid k-1} \mathbf{H}_k^\textsf{T} + \mathbf{R}_k \\ \mathbf{K}_k &= \mathbf P_{k\mid k-1}\mathbf{H}_k^\textsf{T}\mathbf{S}_k^{-1} \\ \hat{\mathbf x}_{k\mid k} &= \hat{\mathbf x}_{k\mid k-1} + \mathbf{K}_k\tilde{\mathbf{y}}_k \\ \mathbf P_{k|k} &= (I - \mathbf{K}_k \mathbf{H}_k) \mathbf P_{k|k-1} \end{aligned} x^kk1Pkk1y~kSkKkx^kkPkk=Fkx^k1k1+Bkuk=FkPk1k1FkT+Qk=zkHkx^kk1=HkPkk1HkT+Rk=Pkk1HkTSk1=x^kk1+Kky~k=(IKkHk)Pkk1

Brookner

X n + 1 , n ∗ = Φ X n , n ∗ X n , n ∗ = X n , n − 1 ∗ + H n ( Y n − M X n , n − 1 ∗ ) H n = S n , n − 1 ∗ M T [ R n + M S n , n − 1 ∗ M T ] − 1 S n , n − 1 ∗ = Φ S n − 1 , n − 1 ∗ Φ T + Q n S n − 1 , n − 1 ∗ = ( I − H n − 1 M ) S n − 1 , n − 2 ∗ \begin{aligned} X^*_{n+1,n} &= \Phi X^*_{n,n} \\ X^*_{n,n} &= X^*_{n,n-1} +H_n(Y_n - MX^*_{n,n-1}) \\ H_n &= S^*_{n,n-1}M^\mathsf{T}[R_n + MS^*_{n,n-1}M^\mathsf{T}]^{-1} \\ S^*_{n,n-1} &= \Phi S^*_{n-1,n-1}\Phi^\mathsf{T} + Q_n \\ S^*_{n-1,n-1} &= (I-H_{n-1}M)S^*_{n-1,n-2} \end{aligned} Xn+1,nXn,nHnSn,n1Sn1,n1=ΦXn,n=Xn,n1+Hn(YnMXn,n1)=Sn,n1MT[Rn+MSn,n1MT]1=ΦSn1,n1ΦT+Qn=(IHn1M)Sn1,n2

Gelb

x ^ ‾ k ( − ) = Φ k − 1 x ^ ‾ k − 1 ( + ) x ^ ‾ k ( + ) = x ^ ‾ k ( − ) + K k [ Z k − H k x ^ ‾ k ( − ) ] K k = P k ( − ) H k T [ H k P k ( − ) H k T + R k ] − 1 P k ( + ) = Φ k − 1 P k − 1 ( + ) Φ k − 1 T + Q k − 1 P k ( − ) = ( I − K k H k ) P k ( − ) \begin{aligned} \underline{\hat{x}}_k(-) &= \Phi_{k-1} \underline{\hat{x}}_{k-1}(+) \\ \underline{\hat{x}}_k(+) &= \underline{\hat{x}}_k(-) +K_k[Z_k - H_k\underline{\hat{x}}_k(-)] \\ K_k &= P_k(-)H_k^\mathsf{T}[H_kP_k(-)H_k^\mathsf{T} + R_k]^{-1} \\ P_k(+) &= \Phi_{k-1} P_{k-1}(+)\Phi_{k-1}^\mathsf{T} + Q_{k-1} \\ P_k(-) &= (I-K_kH_k)P_k(-) \end{aligned} x^k()x^k(+)KkPk(+)Pk()=Φk1x^k1(+)=x^k()+Kk[ZkHkx^k()]=Pk()HkT[HkPk()HkT+Rk]1=Φk1Pk1(+)Φk1T+Qk1=(IKkHk)Pk()

Brown

x ^ k + 1 − = ϕ k x ^ k x ^ k = x ^ k − + K k [ z k − H k x ^ k − ] K k = P k − H k T [ H k P k − H k T + R k ] − 1 P k + 1 − = ϕ k P k ϕ k T + Q k P k = ( I − K k H k ) P k − \begin{aligned} \hat{\mathbf x}^-_{k+1} &= \mathbf{\phi}_{k}\hat{\mathbf x}_{k} \\ \hat{\mathbf x}_k &= \hat{\mathbf x}^-_k +\mathbf{K}_k[\mathbf{z}_k - \mathbf{H}_k\hat{\mathbf{}x}^-_k] \\ \mathbf{K}_k &= \mathbf P^-_k\mathbf{H}_k^\mathsf{T}[\mathbf{H}_k\mathbf P^-_k\mathbf{H}_k^T + \mathbf{R}_k]^{-1}\\ \mathbf P^-_{k+1} &= \mathbf{\phi}_k \mathbf P_k\mathbf{\phi}_k^\mathsf{T} + \mathbf Q_{k} \\ \mathbf P_k &= (\mathbf{I}-\mathbf{K}_k\mathbf{H}_k)\mathbf P^-_k \end{aligned} x^k+1x^kKkPk+1Pk=ϕkx^k=x^k+Kk[zkHkx^k]=PkHkT[HkPkHkT+Rk]1=ϕkPkϕkT+Qk=(IKkHk)Pk

Zarcha

x ^ k = Φ k x ^ k − 1 + G k u k − 1 + K k [ z k − H Φ k x ^ k − 1 − H G k u k − 1 ] M k = Φ k P k − 1 ϕ k T + Q k K k = M k H T [ H M k H T + R k ] − 1 P k = ( I − K k H ) M k \begin{aligned} \hat{x}_{k} &= \Phi_{k}\hat{x}_{k-1} + G_ku_{k-1} + K_k[z_k - H\Phi_{k}\hat{x}_{k-1} - HG_ku_{k-1} ] \\ M_{k} &= \Phi_k P_{k-1}\phi_k^\mathsf{T} + Q_{k} \\ K_k &= M_kH^\mathsf{T}[HM_kH^\mathsf{T} + R_k]^{-1}\\ P_k &= (I-K_kH)M_k \end{aligned} x^kMkKkPk=Φkx^k1+Gkuk1+Kk[zkHΦkx^k1HGkuk1]=ΦkPk1ϕkT+Qk=MkHT[HMkHT+Rk]1=(IKkH)Mk
或者也可以表示如下:
![]IMU比较详细的内容(主要是针对卡尔曼滤波器)(摘自于ipythonnotebook)_第6张图片

你可能感兴趣的:(IMU比较详细的内容(主要是针对卡尔曼滤波器)(摘自于ipythonnotebook))