State Estimation and Localization for Self-Driving Cars 第二周作业 EKF练习

本文详细介绍了扩展卡尔曼滤波(EKF)在自动驾驶车辆定位中的应用,包括汽车运动模型、观测模型及滤波方程。通过python编程实现EKF,并分享了编程中常见错误及解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.运动和测量模型

1.1汽车运动模型

xk=xk−1+T[cos⁡θk−10sin⁡θk−1001]([vkωk]+wk),wk=N(0,Q)\mathbf{x}_{k}=\mathbf{x}_{k-1}+T\left[\begin{array}{cc} \cos \theta_{k-1} & 0 \\ \sin \theta_{k-1} & 0 \\ 0 & 1 \end{array}\right]\left(\left[\begin{array}{c} v_{k} \\ \omega_{k} \end{array}\right]+\mathbf{w}_{k}\right), \quad \mathbf{w}_{k}=\mathcal{N}(\mathbf{0}, \mathbf{Q})xk=xk1+Tcosθk1sinθk10001([vkωk]+wk),wk=N(0,Q)

其中,xk=[x,y,θ]T\mathbf{x}_{k}=[x , y, \theta]^{T}xk=[xyθ]T是目前汽车的2D位姿。vkv_{k}vkwkw_{k}wk是速度和角速度里程计的度数。

1.2 观测模型

  观测模型按照如下公式将LIDAR测量的距离和方位ykl=[r,ϕ]T\mathbf{y}_{k}^{l}=[r, \phi]^{T}ykl=[rϕ]T与汽车的位姿结合起来。
ykl=[(xl−xk−dcos⁡θk)2+(yl−yk−dsin⁡θk)2atan⁡2(yl−yk−dsin⁡θk,xl−xk−dcos⁡θk)−θk]+nkl,nkl=N(0,R)\mathbf{y}_{k}^{l}=\left[\begin{array}{c} \sqrt{\left(x_{l}-x_{k}-d \cos \theta_{k}\right)^{2}+\left(y_{l}-y_{k}-d \sin \theta_{k}\right)^{2}} \\ \operatorname{atan} 2\left(y_{l}-y_{k}-d \sin \theta_{k}, x_{l}-x_{k}-d \cos \theta_{k}\right)-\theta_{k} \end{array}\right]+\mathbf{n}_{k}^{l}, \quad \mathbf{n}_{k}^{l}=\mathcal{N}(\mathbf{0}, \mathbf{R})ykl=[(xlxkdcosθk)2+(ylykdsinθk)2atan2(ylykdsinθk,xlxkdcosθk)θk]+nkl,nkl=N(0,R)

其中,xlx_lxlyly_lyl是陆标lll的真实坐标。xkx_kxkyky_kykθk\theta_kθk是汽车的当前位姿。ddd是汽车中心和LIDAR的距离。(已知)

2. 滤波方程

2.1 一步预测

x˘k=f(x^k−1,uk−1,0)Pˇk=Fk−1P^k−1Fk−1T+Lk−1Qk−1Lk−1TFk−1=∂f∂xk−1∣x^k−1,uk,0,Lk−1=∂f∂wk∣x^k−1,uk,0\begin{aligned} \breve{\mathbf{x}}_{k} &=\mathbf{f}\left(\hat{\mathbf{x}}_{k-1}, \mathbf{u}_{k-1}, \mathbf{0}\right) \\ \check{\mathbf{P}}_{k} &=\mathbf{F}_{k-1} \hat{\mathbf{P}}_{k-1} \mathbf{F}_{k-1}^{T}+\mathbf{L}_{k-1} \mathbf{Q}_{k-1} \mathbf{L}_{k-1}^{T} \\ \mathbf{F}_{k-1}=&\left.\frac{\partial \mathbf{f}}{\partial \mathbf{x}_{k-1}}\right|_{\hat{\mathbf{x}}_{k-1}, \mathbf{u}_{k}, 0}, \quad \mathbf{L}_{k-1}=\left.\frac{\partial \mathbf{f}}{\partial \mathbf{w}_{k}}\right|_{\hat{\mathbf{x}}_{k-1}, \mathbf{u}_{k}, 0} \end{aligned}x˘kPˇkFk1==f(x^k1,uk1,0)=Fk1P^k1Fk1T+Lk1Qk1Lk1Txk1fx^k1,uk,0,Lk1=wkfx^k1,uk,0

2.2 状态更新

ykl=h(xk,nkl)Hk=∂h∂xk∣xˇk,0,Mk=∂h∂nk∣xˇk,0Kk=PˇkHkT(HkPˇkHkT+MkRkMkT)−1y˘kl=h(xˇk,0)x^k=x˘k+Kk(ykl−y˘kl)P^k=(I−KkHk)Pˇk\begin{aligned} &\mathbf{y}_{k}^{l}=\mathbf{h}\left(\mathbf{x}_{k}, \mathbf{n}_{k}^{l}\right)\\ &\mathbf{H}_{k}=\left.\frac{\partial \mathbf{h}}{\partial \mathbf{x}_{k}}\right|_{\check{\mathbf{x}}_{k}, 0}, \quad \mathbf{M}_{k}=\left.\frac{\partial \mathbf{h}}{\partial \mathbf{n}_{k}}\right|_{\check{\mathbf{x}}_{k}, 0}\\ &\mathbf{K}_{k}=\check{\mathbf{P}}_{k} \mathbf{H}_{k}^{T}\left(\mathbf{H}_{k} \check{\mathbf{P}}_{k} \mathbf{H}_{k}^{T}+\mathbf{M}_{k} \mathbf{R}_{k} \mathbf{M}_{k}^{T}\right)^{-1}\\ &\breve{\mathbf{y}}_{k}^{l}=\mathbf{h}\left(\check{\mathbf{x}}_{k}, \mathbf{0}\right)\\ &\hat{\mathbf{x}}_{k}=\breve{\mathbf{x}}_{k}+\mathbf{K}_{k}\left(\mathbf{y}_{k}^{l}-\breve{\mathbf{y}}_{k}^{l}\right)\\ &\hat{\mathbf{P}}_{k}=\left(\mathbf{I}-\mathbf{K}_{k} \mathbf{H}_{k}\right) \check{\mathbf{P}}_{k} \end{aligned}ykl=h(xk,nkl)Hk=xkhxˇk,0,Mk=nkhxˇk,0Kk=PˇkHkT(HkPˇkHkT+MkRkMkT)1y˘kl=h(xˇk,0)x^k=x˘k+Kk(ykly˘kl)P^k=(IKkHk)Pˇk

3.程序代码

  附上作业所要求提交的子程序,仅供参考

3.1 测量更新函数
def measurement_update(lk, rk, bk, P_check, x_check):
    bk = wraptopi(bk)
    x_check[:,2]= wraptopi(x_check[:,2])    
    A = lk[0] - x_check[:,0] - d * math.cos(x_check[:,2])
    B = lk[1] - x_check[:,1] - d * math.sin(x_check[:,2])
    # 1. Compute measurement Jacobian
    M = np.identity(2)
    H = np.array([[-A * (A ** 2 + B ** 2) ** (-0.5),-B * (A ** 2 + B ** 2) ** (-0.5),d * (A ** 2 + B ** 2) ** (-0.5) * (A * math.sin(x_check[:,2])- B *  math.cos(x_check[:,2]))],
                 [(1 + (B/A) ** 2) ** (-1) * B / A ** 2,-(1 + (B/A) ** 2) ** (-1) / A, (1 + (B/A) ** 2) ** (-1)/ A ** 2 * (-d*math.cos(x_check[:,2]) * A - B * d * math.sin(x_check[:,2]))-1]])
    H = H.reshape(2,3)
    # 2. Compute Kalman Gain
    K = P_check @ H.T @ np.linalg.inv(H @ P_check @ H.T + M @cov_y @ M.T )
    # 3. Correct predicted state (remember to wrap the angles to [-pi,pi])
    h = math.atan2(B,A) - x_check[:,2]
    h = wraptopi(h)
    ss = K @ np.array([rk-(A ** 2 + B ** 2) ** 0.5,bk-h])
    x_check = x_check + ss.reshape(1,3)
    x_check[:,2]= wraptopi(x_check[:,2])

    # 4. Correct covariance
    P_check = (np.identity(3)-K @ H) @ P_check 

    return x_check, P_check

3.2 滤波主程序
#### 5. Main Filter Loop #######################################################################
for k in range(1, len(t)):  # start at 1 because we've set the initial prediciton
    delta_t = t[k] - t[k - 1]  # time step (difference between timestamps)
    x_check[:,2]= wraptopi(x_check[:,2])
    theta = x_check[:,2]
    # 1. Update state with odometry readings (remember to wrap the angles to [-pi,pi])
    cc = delta_t * np.array([[math.cos(theta),0],[math.sin(theta),0],[0,1]]) @ np.array([[v[k]],[om[k]]])
    x_check = x_check + cc.T

    
    x_check[:,2] = wraptopi(x_check[:,2])

    # 2. Motion model jacobian with respect to last state
    F_km = np.array([[1,0,-delta_t * v[k] *math.sin(theta)],[0,1,delta_t * v[k]* math.cos(theta)],[0,0,1]])

    # 3. Motion model jacobian with respect to noise
    L_km = delta_t * np.array([[math.cos(theta),0],[math.sin(theta),0],[0,1]])

    # 4. Propagate uncertainty
    P_check =  F_km @ P_check @  F_km.T + L_km @ Q_km @L_km.T

    # 5. Update state estimate using available landmark measurements
    for i in range(len(r[k])):
        x_check, P_check = measurement_update(l[i], r[k, i], b[k, i], P_check, x_check)
    # Set final state predictions for timestep
    x_est[k, 0] = x_check[:,0]
    x_est[k, 1] = x_check[:,1]
    x_est[k, 2] = x_check[:,2]
    P_est[k, :, :] = P_check
3.3 仿真结果


图1 地面真值


图2 估计值

个人心得,评注

  这个EKF练习要求用python进行编程。我在编程的时候犯了两个错误,卡了很久。现在分享出来,希望读者在自己学习这门课的时候多加留意,避免这些坑。

  1. python做矩阵运算确实不如matlab方便,尤其是带向量的运算,一会儿是一维,一会儿是二维数组,傻傻分不清。要想要使能够按照矩阵来操作,必须把向量变成二维的。例如上面程序中有x=x.reshape(1,3)x = x.reshape(1,3)x=x.reshape(1,3)。这是把xxx变成一个行向量。(当然,也可以变成列向量)。
  2. 文中把姿态角限定在了−π到π-\pi到\piππ之间。编程中有个地方需要进行限定。滤波主程序中有2处,分别是在状态一步递推的前后。更新子函数中有3处,一处是最开始对一步预测的结果进行限定,另外两处是对真实测量值和一步预测对应的测量计算值进行限定。(文中已经标黄)
  3. len(v)可以计算数组v的行数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值