作者 | 司南牧(李韬) 编辑 | 汽车人
原文链接:https://zhuanlan.zhihu.com/p/77327349
点击下方卡片,关注“自动驾驶之心”公众号
ADAS巨卷干货,即可获取
本文只做学术分享,如有侵权,联系删文
“今日疯言疯语:
”
学完卡尔曼滤波可以说你就是地球上战斗力超强的人了!因为几乎任何带电的军事装备、航空航天装备都需要Kalman滤波算法!—— @司南牧(李韬)
直观理解
首先卡尔曼滤波要解决的问题是什么?我以我军发射一枚导弹攻击敌方某固定位置目标为例(搞科技的总要点情怀,老是讲啥小车运动,温度计这些就太low)。导弹需要每隔一秒开雷达测量下离目标的距离。然后由于雷达有误差,所以需要融合自己上个时刻的位置、速度等信息来更准确的确定当前时刻离目标的距离。这就是卡尔曼滤波需要解决的事
从直观理解卡尔曼滤波是怎么解决这个问题的呢?
首先导弹已知“当前这秒雷达测量的导弹离目标的距离(我们称它为观测值,比如雷达直接测量导弹离目标距离7m)”,“上个时刻导弹离目标距离”和“导弹自己当前时刻的速度”这三个数据。而根据“上个时刻导弹离目标距离”和“导弹自己当前时刻的速度”可以估算出当前导弹离目标的距离(我们称它为估计值)。比如:上一秒离目标10m,速度是4m/s,那么现在这秒估计就离目标距离是6m。这个速度数据可以从传感器里面读取也可以从发动机那获得。(根据速度估计导弹距离这个计算叫做移动模型建模,想了解移动模型与观测值和滤波算法之间的联系可以看这篇文章《机器人移动模型:根据控制命令预测机器人位置》)
那么问题来了,导弹离目标的距离现在既有个观测值7m,又有个估计值6m。到底相信哪个?单纯相信观测值万一雷达被敌方干扰了呢?单纯相信估计值那么万一上个时刻的距离估计值或者速度不准呢?所以,我们要根据观测值和估计值的准确度来得到最终导弹离目标的距离估计值。准确度

直观理解讲完了,以上。
卡尔曼滤波怎么做的?
我们先回顾总结下直观理解中是怎么做的。
根据上一秒导弹的位置 和 导弹的的速度估计出当前时刻导弹的位置粗略估计值。
将雷达测得导弹位置测量值和我们计算出的导弹位置粗略估计值根据这两种数据可信度来进行线性加权和得到准确的导弹位置估计值。
在前面我们也提到了导弹的位置和雷达测量值都是有误差的。所以卡尔曼想用概率来衡量数据的可信度。
比如:雷达测量的数据它就不只是一个数字了。而是说测量发现导弹有0.8的概率在7m那个位置,有0.1的概率在7.2m那个位置。有0.1的概率在6.9m那个位置。这些数据就叫做概率分布。概率分布的意思就是很多个值还有它们各自出现的概率多大所组成的数据就叫做概率分布。
卡尔曼认为导弹速度、导弹位置、雷达测距的测量值这些都服从正态分布(对就是高中学的那个正态分布)。这是啥意思呢?比如下面这个图是讲上个时刻导弹的位置的概率分布,从图中看出它在10m(横轴)那个位置的纵坐标最高所以概率最大。它在其他地方的概率相对小一点。

我们用 表示导弹在t-1时刻的位置的概率分布(它画出来就和上面那个图长的一样)。 表示导弹在t-1时刻的速度的概率分布。用 表示雷达测量到导弹离目标的距离概率分布。并且它们都是正态分布。
我们知道正态分布可以这么表示 N(均值,方差)。
现在我们是已知
导弹在t-1时刻的位置的概率分布,为=N(10,)。其实0.2就是上个时刻导弹位置的误差
导弹的速度的概率分布,为 =N(4,)。其实0.7就是获取速度的那个传感器噪声误差。你会问咋就有噪声误差了?不知道你有没有用过手机里面的指南针那个软件,明明你没动那个指南针还是会在某个范围内波动。还有称体重,明明你没动那个称数据就是不断的动。这就是噪声误差。
雷达在t时刻测量到导弹离目标的距离的概率分布,为=N(7,),这0.1就是雷达的噪声误差
在前面我们知道了卡尔曼滤波算法为了融合雷达测量值和上个时刻的导弹状态数据来减少误差,需要实施“两步走”战略。
根据上一秒导弹的位置 和 导弹的速度估计出当前时刻导弹的位置粗略估计值。
将雷达测得导弹位置测量值和我们计算出的导弹位置粗略估计值根据这两种数据可信度来进行线性加权和得到准确的导弹位置估计值。
我们来看看具体怎么做的。
计算粗略估计值(这个是做了一个硬假设:导弹是保持匀速运动),大家可以对比着看下直观理解是怎么做的:

根据 粗略估计值的概率分布与雷达的测量值概率分布得到精确估计值的概率分布。现在我们是用概率分布来计算。所以和直观理解中的计算方式有不同。因为直观理解中的计算方式是相当于粗略估计值这个概率分布的均值与雷达测量值的概率分布的均值进行加权和得到精确估计值的概率分布的均值。由于正态分布是均值那个地方的概率最大,所以当前时刻导弹位置的精确估计值就是它概率分布的均值。但是现在我们还是没有回答怎么根据粗略估计值的概率分布与雷达的测量值概率分布得到精确估计值的概率分布。其实这个也很简单。直接把这两个概率分布相乘即可。关于为何是直接相乘请参考这个回答《如何通俗并尽可能详细解释卡尔曼滤波?》。这是由贝叶斯滤波所推导得到的。所以我们得到当前时刻导弹位置的精确估计是

以上!你的赞和关注是我愿意分享的最大动力!
卡尔曼滤波Python代码实践
“这个实践的已知量是导弹做水平运动,已知导弹每个时刻的速度dv,和速度测量仪器的标准差是v_std,还已知每个时刻用GPS测量出导弹位置position_noise以及GPS的方差是predict_var。(注意标准差的平方是方差,不用觉得奇怪)
”
我们需要用卡尔曼滤波根据这些信息获得融合两种传感器后的位置信息position_predict

# -*- coding: utf-8 -*-
"""
@司南牧
"""
import numpy as np
t = np.linspace(1,100,100) # 在1~100s内采样100次
a = 0.5 # 加速度值
position = (a * t**2)/2
position_noise = position+np.random.normal(0,120,size=(t.shape[0])) # 模拟生成GPS位置测量数据(带噪声)
import matplotlib.pyplot as plt
plt.plot(t,position,label='truth position')
plt.plot(t,position_noise,label='only use measured position')
#---------------卡尔曼滤波----------------
# 初始的估计导弹的位置就直接用GPS测量的位置
predicts = [position_noise[0]]
position_predict = predicts[0]
predict_var = 0
odo_var = 120**2 #这是我们自己设定的位置测量仪器的方差,越大则测量值占比越低
v_std = 50 # 测量仪器的方差(这个方差在现实生活中是需要我们进行传感器标定才能算出来的,可搜Allan方差标定)
for i in range(1,t.shape[0]):
dv = (position[i]-position[i-1]) + np.random.normal(0,50) # 模拟从IMU读取出的速度
position_predict = position_predict + dv # 利用上个时刻的位置和速度预测当前位置
predict_var += v_std**2 # 更新预测数据的方差
# 下面是Kalman滤波
position_predict = position_predict*odo_var/(predict_var + odo_var)+position_noise[i]*predict_var/(predict_var + odo_var)
predict_var = (predict_var * odo_var)/(predict_var + odo_var)
predicts.append(position_predict)
plt.plot(t,predicts,label='kalman filtered position')
plt.legend()
plt.show()
① 全网独家视频课程
BEV感知、毫米波雷达视觉融合、多传感器标定、多传感器融合、多模态3D目标检测、点云3D目标检测、目标跟踪、Occupancy、cuda与TensorRT模型部署、协同感知、语义分割、自动驾驶仿真、传感器部署、决策规划、轨迹预测等多个方向学习视频(扫码学习)

② 国内首个自动驾驶学习社区
近2000人的交流社区,涉及30+自动驾驶技术栈学习路线,想要了解更多自动驾驶感知(2D检测、分割、2D/3D车道线、BEV感知、3D目标检测、Occupancy、多传感器融合、多传感器标定、目标跟踪、光流估计)、自动驾驶定位建图(SLAM、高精地图、局部在线地图)、自动驾驶规划控制/轨迹预测等领域技术方案、AI模型部署落地实战、行业动态、岗位发布,欢迎扫描下方二维码,加入自动驾驶之心知识星球,这是一个真正有干货的地方,与领域大佬交流入门、学习、工作、跳槽上的各类难题,日常分享论文+代码+视频,期待交流!

③【自动驾驶之心】技术交流群
自动驾驶之心是首个自动驾驶开发者社区,聚焦目标检测、语义分割、全景分割、实例分割、关键点检测、车道线、目标跟踪、3D目标检测、BEV感知、多模态感知、Occupancy、多传感器融合、transformer、大模型、点云处理、端到端自动驾驶、SLAM、光流估计、深度估计、轨迹预测、高精地图、NeRF、规划控制、模型部署落地、自动驾驶仿真测试、产品经理、硬件配置、AI求职交流等方向。扫码添加汽车人助理微信邀请入群,备注:学校/公司+方向+昵称(快速入群方式)