欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

拓展卡尔曼滤波学习(python源码)

程序员文章站 2022-07-14 22:24:56
...

拓展卡尔曼滤波的逐步理解与实现

这个文章讲的非常不错。配套代码实现文章。

【机器人位置估计】卡尔曼滤波的原理与实现

本文主要是针对两篇文章的基础上做笔记和记录学习过程。

一、基本模型

1.1 机器人小M

拓展卡尔曼滤波学习(python源码)

现在小M只具有一个物理量-位移x,也就是一维卡尔曼/

1.2 位移状态预测值

拓展卡尔曼滤波学习(python源码) 估计值自身会由于运动模型预测不准确而导致预测误差,由误差值得到的状态值也是存在误差的,如果以存在误差的状态值继续预测下一个状态值,误差会存在累计的问题。需要引入测量量进行修正。

1.3 传感器测量值

拓展卡尔曼滤波学习(python源码)

同样,我们使用的传感器也是存在测量精度的问题,无法完全的等于实际物理量的大小。

所以也就提出了卡尔曼老人解决这个问题的思路。既然测量值和估计值都存在一定的误差值,那么将两组数据进行融合,谁更准便将其权重提高。

1.4 卡尔曼核心思想

拓展卡尔曼滤波学习(python源码)

确定那个数据的置信度更高,这就牵扯到了预测误差的准确值Pt,所以需要通过一定的方式对Pt进行计算,随着整个过程进行一定的调整和变化。

1.5 计算 预测误差准确值

拓展卡尔曼滤波学习(python源码)

没有绝对准确的运动模型,也没有绝对准确的传感器

1.6 卡尔曼滤波公式

拓展卡尔曼滤波学习(python源码)

预测就是利用上一步的状态准确值和预测误差准确值,结合运动模型得到下一步的状态估计值和预测误差估计值

更新就是融入传感器信息,计算增益系数,将估计值再次转换为准确值。

2.拓展卡尔曼滤波

2.1 加入控制量

拓展卡尔曼滤波学习(python源码)

机器人的移动、转动都是人为引入的一种控制量。

2.2 观测系数

拓展卡尔曼滤波学习(python源码)

这里给的例子很明确的表现观测系数c的作用。引入观测洗漱势必会对预测误差产生一定比例的影响,发生一定变化。 拓展卡尔曼滤波学习(python源码)

2.3 拓展卡尔曼滤波公式

拓展卡尔曼滤波学习(python源码)

多维卡尔曼滤波

拓展卡尔曼滤波学习(python源码)拓展卡尔曼滤波学习(python源码)拓展卡尔曼滤波学习(python源码)

3.使用实例

拓展卡尔曼滤波学习(python源码)

import numpy as np
import math
import matplotlib.pyplot as plt

if __name__=="__main__":
    ## 1.设计一个匀加速直线运动,以观测此运动
    X_real = np.mat(np.zeros((2, 100))) # 空矩阵,用于存放真实状态向量
    X_real[:, 0] = np.mat([[0.0], # 初始状态向量
                           [1.0]])
    a_real = 0.1# 真实加速度
    F = np.mat([[1.0, 1.0], # 状态转移矩阵
                [0.0, 1.0]])
    Q = np.mat([[0.0001, 0.0], # 状态转移协方差矩阵,我们假设外部干扰很小
                [0.0, 0.0001]])
    B = np.mat([[0.5], # 控制矩阵
                [1.0]])
    for i in range(99):
        X_real[:, i + 1] = F * X_real[:, i] + B * a_real # 计算真实状态向量
    X_real = np.array(X_real)
    fig = plt.figure(1)
    plt.grid()
    plt.title('real displacement')
    plt.xlabel('k (s)')
    plt.ylabel('x (m)')
    plt.plot(X_real[0, :])
    plt.show()
    fig = plt.figure(2)
    plt.grid()
    plt.title('real velocity')
    plt.xlabel('k (s)')
    plt.ylabel('v (m/s)')
    plt.plot(X_real[1, :])
    plt.show()
    X_real = np.mat(X_real)

拓展卡尔曼滤波学习(python源码)注意到这里预测值是非常准的,在置信度比例方面会提高的

拓展卡尔曼滤波学习(python源码)

    ## 2.建立传感器观测值
    z_t = np.mat(np.zeros((2, 100))) # 空矩阵,用于存放传感器观测值
    H = np.mat(np.zeros((2, 2)))
    H[0, 0], H[1, 1] = -1.0, -1.0
    noise = np.mat(np.random.randn(2,100)) # 加入位移方差为1,速度方差为1的传感器噪声
    R = np.mat([[1.0, 0.0], # 观测噪声的协方差矩阵
                [0.0, 1.0]])
    for i in range(100):
        z_t[:, i] = H * X_real[:, i] + noise[:, i]
    z_t = np.array(z_t)
    fig = plt.figure(3)
    plt.grid()
    plt.title('sensor displacement')
    plt.xlabel('k (s)')
    plt.ylabel('x (m)')
    plt.plot(z_t[0, :])
    plt.show()
    fig = plt.figure(4)
    plt.grid()
    plt.title('sensor velocity')
    plt.xlabel('k (s)')
    plt.ylabel('v (m/s)')
    plt.plot(z_t[1, :])
    plt.show()
    z_t = np.mat(z_t)

拓展卡尔曼滤波学习(python源码)

卡尔曼滤波实现

    ## 3.执行线性卡尔曼滤波
    Q = np.mat([[1.0, 0.0], # 状态转移协方差矩阵,我们假设外部干扰很小,
                [0.0, 1.0]])# 转移矩阵可信度很高
    # 建立一系列空序列用于储存结果
    X_update = np.mat(np.zeros((2, 100)))
    P_update = np.zeros((100, 2, 2))
    X_predict = np.mat(np.zeros((2, 100)))
    P_predict = np.zeros((100, 2, 2))
    P_update[0, :, :] = np.mat([[1.0, 0.0], # 状态向量协方差矩阵初值
                                [0.0, 1.0]])
    P_predict[0, :, :] = np.mat([[1.0, 0.0], # 状态向量协方差矩阵初值
                                 [0.0, 1.0]])
    for i in range(99):
        # 预测
        X_predict[:, i + 1] = F * X_update[:, i] + B * a_real
        P_p = F * np.mat(P_update[i, :, :]) * F.T + Q
        P_predict[i + 1, :, :] = P_p
        # 更新
        K = P_p * H.T * np.linalg.inv(H * P_p * H.T + R) # 卡尔曼增益
        P_u = P_p - K * H * P_p
        P_update[i + 1, :, :] = P_u
        X_update[:, i + 1] = X_predict[:, i + 1] + K * (z_t[:, i + 1] - H * X_predict[:, i + 1])
    X_update = np.array(X_update)   
    X_real = np.array(X_real) 
    fig = plt.figure(5)
    plt.grid()
    plt.title('Kalman predict displacement')
    plt.xlabel('k (s)')
    plt.ylabel('x (m)')
    plt.plot(X_real[0, :], label='real', color='b')
    plt.plot(X_update[0, :], label='predict', color='r')
    plt.legend()
    plt.show()
    fig = plt.figure(6)
    plt.grid()
    plt.title('Kalman predict velocity')
    plt.xlabel('k (s)')
    plt.ylabel('v (m/s)')
    plt.plot(X_real[1, :], label='real', color='b')
    plt.plot(X_update[1, :], label='predict', color='r')
    plt.legend()
    plt.show()
    X_update = np.mat(X_update)
    X_real = np.mat(X_real)

拓展卡尔曼滤波学习(python源码) 这里kt取到了很低,非常不信任传感器测量到的值。

卡尔曼滤波将存在误差的传感器信号和状态向量很好的融合,较好地预测出了真实地机器人运动状态。