首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

优达学城《无人驾驶入门》学习笔记——卡尔曼滤波器实现详解

  • 25-03-02 17:22
  • 4186
  • 6933
blog.csdn.net

优达学城《无人驾驶入门》的第二个项目是实现矩阵类,要求通过python编写一个用来计算矩阵的类Matrix.编写这个类并不难,涉及到的线性代数方面的知识也不多,比如矩阵的加法、减法、乘法,求逆矩阵,创建单位矩阵等。相比之下,理解编写矩阵类的目的反而显得更加重要。

编写矩阵类,是为实现了卡尔曼滤波器。卡尔曼滤波器涉及的知识很广,涵盖了《无人驾驶入门》课程第二部分“贝叶斯定理”和第三部分“使用矩阵”这两部分的内容,包括贝叶斯定义、高斯分布、运动模型、线性代数等内容。个人认为,如果把“实现卡尔曼滤波器”做为项目会更好。可能考虑到难度有些大,课程是通过workspace(“卡尔曼滤波器和你的矩阵类”)的形式演示了如何实现卡尔曼滤波器。workspace还调用了datagenerator用来生成输入的数据,它是非常好的学习资源,值得研究。

这篇文章的目的有2个:

第一个目的,介绍实现卡尔曼滤波器的3个步骤:

  1. 创建矩阵类。编写矩阵类是你需要完成的项目,我不会在这里公布答案,而是向你介绍一些扩展内容。项目要求使用列表来实现矩阵类,这样做的好处是,首先,需要的python知识比较基础,难度不大;其次,了解矩阵计算的原理。作为扩展内容,我会提供一个新思路,向你介绍如何通过numpy库来实现矩阵类。使用numpy库的ndarray和matrix来计算矩阵,会比列表方便得多。丰富的第三方库,正是python功能强大的原因之一。

  2. 创建汽车行驶的数据。我会对workspace“卡尔曼滤波器和你的矩阵类”中调用的datagenerator.py文件进行讲解,介绍函数generate_data和generate_lidar是如何生成汽车的行驶数据和测量数据的。这两个函数运用到了课程中学习过的运动模型和高斯分布等知识。

  3. 实现卡尔曼滤波器,并且可视化。把卡尔曼滤波器的公式编写成程序并不难,但是我希望你能了解公式中的参数分别代表哪些量,如何获得这些量。至于如何推导公式,如果有能力完成当然更好,推导不出来也没有关系。最后,通过matplotlib库将卡尔曼滤波器可视化。

 

第二个目的,推荐一些学习资料。主要包括numpy库,matplotlib库,卡尔曼滤波器的公式推导,以及一个神奇的公式可视化网站,你可以用来观察高斯分布等公式。

1 实现卡尔曼滤波器的步骤

1 创建矩阵类

numpy库的ndarry和matrix对象非常适合用来实现矩阵计算。两个列表相加,是这样实现的:

  1. a = [1,2,3]
  2. b = [4,5,6]
  3. print(a+b)
  4. ​
  5. [1, 2, 3, 4, 5, 6]

而两个长度相同的ndarray对象相加,结果完全不同:

  1. c = np.array([1,2,3])
  2. d = np.array([4,5,6])
  3. print(c+d)
  4. ​
  5. [5 7 9]

很显然,ndarray的加法就是矩阵的加法。ndarray还有很多矩阵计算的方法和属性,比如矩阵乘法:ndarray.dot();矩阵的迹:ndarray.trace();转置矩阵:ndarray.T.

matrix对象大部分功能和ndarray相同,但是它还提供了一个计算逆矩阵的方法:Matrix.I.

除此之外,numpy还提供了创建矩阵的函数,比如创建单位矩阵:numpy.eye().

下面是通过numpy类实现矩阵类的代码。如果你已经完成了这个项目,对比一下,你会发现,numpy库可以让代码简洁不少。

  1. import numbers
  2. import numpy as np
  3. import matplotlib.pyplot as plt  
  4. import math
  5. ​
  6. # 卡尔曼滤波器需要调用的矩阵类
  7. class Matrix(object):
  8.    # 构造矩阵
  9.    def __init__(self, grid):
  10.        self.g = np.array(grid)
  11.        self.h = len(grid)
  12.        self.w = len(grid[0])
  13. ​
  14.    # 单位矩阵
  15.    def identity(n):
  16.        return Matrix(np.eye(n))
  17. ​
  18.    # 矩阵的迹
  19.    def trace(self):
  20.        if not self.is_square():
  21.            raise(ValueError, "Cannot calculate the trace of a non-square matrix.")
  22.        else:
  23.            return self.g.trace()
  24.    # 逆矩阵
  25.    def inverse(self):
  26.        if not self.is_square():
  27.            raise(ValueError, "Non-square Matrix does not have an inverse.")
  28.        if self.h > 2:
  29.            raise(NotImplementedError, "inversion not implemented for matrices larger than 2x2.")
  30.        if self.h == 1:
  31.            m = Matrix([[1/self[0][0]]])
  32.            return m
  33.        if self.h == 2:
  34.            try:
  35.                m = Matrix(np.matrix(self.g).I)
  36.                return m
  37.            except np.linalg.linalg.LinAlgError as e:
  38.                print("Determinant shouldn't be zero.", e)
  39. ​
  40.    # 转置矩阵
  41.    def T(self):
  42.        T = self.g.T
  43.        return Matrix(T)
  44.                
  45.    # 判断矩阵是否为方阵
  46.    def is_square(self):
  47.        return self.h == self.w
  48. ​
  49.    # 通过[]访问
  50.    def __getitem__(self,idx):
  51.        return self.g[idx]
  52. ​
  53.    # 打印矩阵的元素
  54.    def __repr__(self):
  55.        s = ""
  56.        for row in self.g:
  57.            s += " ".join(["{} ".format(x) for x in row])
  58.            s += "\n"
  59.        return s
  60. ​
  61.    # 加法
  62.    def __add__(self,other):
  63.        if self.h != other.h or self.w != other.w:
  64.            raise(ValueError, "Matrices can only be added if the dimensions are the same")
  65.        else:
  66.            return Matrix(self.g + other.g)
  67. ​
  68.    # 相反数
  69.    def __neg__(self):
  70.        return Matrix(-self.g)
  71. ​
  72.    #减法
  73.    def __sub__(self, other):
  74.        if self.h != other.h or self.w != other.w:
  75.            raise(ValueError, "Matrices can only be subtracted
注:本文转载自blog.csdn.net的江浩-无人驾驶的文章"https://blog.csdn.net/dshgers/article/details/81190826"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top