卡尔曼滤波器¶
理论¶
卡尔曼滤波基于线性、高斯系统的假设,能够利用前一时刻的状态(和可能的测量值)来得到当前时刻下的状态的最优估计。算法由预测、更新(校正)两步骤组成,既能够基于状态空间模型进行状态预测,本质上又是一个数据融合算法。
概述¶
以状态空间的形式描述一个线性高斯系统,下标表示时刻:
其中
为区分状态的多种表示,定义以下符号:
现实中我们并不知道噪声的实际值,但我们可以通过迭代优化,逼近最优的状态估计。由
由
由于噪声的存在,
其中系数
此处
卡尔曼增益¶
我们希望最优估计与实际值误差最小,即后验估计误差
卡尔曼增益最优问题可转化为求
由
经计算得到:
则卡尔曼增益为:
观察上式可知,观测噪声协方差
卡尔曼滤波¶
先验估计误差
由
需要上一时刻的后验协方差
此时
其中,预测部分将后验状态估计和后验协方差从
观测数据融合¶
由于卡尔曼滤波的本质是数据融合,在没有状态空间模型的情况下,若有两个观测器对同一个状态进行观测,产生两组数据,则它们也可以通过卡尔曼滤波的思想进行融合。此时,
参数调整¶
实际实现时,观测噪声协方差
调整后验估计误差协方差初值
此外,可以在运行时根据模型的实际情况改变
快速开始¶
组件源码仓库地址:https://github.com/ZJU-HelloWorld/HW-Components
要在项目中使用该组件,需添加仓库内的以下文件:
使用前准备¶
本组件涉及 CMSIS-DSP 矩阵运算等操作。
使用本组件前需要做以下准备:
- 添加源文件, 包含头文件路径;注意 DSP 版本须在 1.10.0 及以上
- 添加预处理宏以开启浮点运算单元(FPU)
- 在使用 STM32CubeMX 生成项目时,请在 Code Generator 界面 Enable Full Assert,来帮助断言设备驱动中的错误;在
main.c
中修改assert_failed
函数以指示断言结果,如添加while(1);
- 在
system.h
中system options: user config
处进行系统设置
示例¶
在项目中引用头文件:
C | |
---|---|
实例化一个卡尔曼滤波器:
指定状态维度、滤波器类型和各矩阵初值,初始化卡尔曼滤波器。
注意以下几点:
- 若有状态空间模型,需要
七组矩阵数据;若为 2 传感器数据融合,需要 四组矩阵数据。 - 注意矩阵维度,注意协方差矩阵均为对角阵
- 矩阵数据的排列顺序:从左至右,从上到下。
对于 KF_MODEL_BASED 模式,调用控制量设定方法以及预测方法,获得状态量预测值;对于 KF_SENSOR_FUSION 模式,传入第一个传感器观测状态量的数组指针,得到初步状态估计值。如:
传入(另一个)传感器观测状态量数组指针,调用更新方法,可获得状态量后验估计,如:
组件说明¶
Kf
类¶
线性卡尔曼滤波器。
属性
名称 | 类型 | 示例值 | 描述 |
---|---|---|---|
type |
KfType_t |
KF_MODEL_BASED KF_SENSOR_FUSION |
滤波器类型 |
x_dim |
uint8_t |
2 |
状态维度 |
x_x1d, P_xxd, Q_xxd, R_zzd, A_xxd, B_xxd, u_x1d, H_zxd |
arm_matrix_instance_f32 |
/ | 各种参数矩阵 |
方法
名称 |
参数说明 | 描述 |
---|---|---|
KfInit |
按声明要求传入状态维度、滤波器类型和各矩阵初值等参数 | 按指定的类型和给定的数据,初始化一个卡尔曼滤波器 |
predict |
(仅 KF_SENSOR_FUSION 类型)传入另一组 float* 观测量数组地址 |
运行卡尔曼滤波预测部分 |
update |
传入 float* 观测量数组地址 |
根据传入的观测量,运行卡尔曼滤波更新部分 |
getX |
传入 float* 数组地址,用于存储状态量 |
返回当前状态量 |
setU |
(仅 KF_MODEL_BASED 类型)传入 float* u 控制量数组地址 |
设置控制量 |
setQ |
传入 float* Q 矩阵数组地址 |
设置过程噪声协方差 Q 矩阵 |
setR |
传入 float* R 矩阵数组地址 |
设置观测噪声协方差 R 矩阵 |
附录¶
版本说明¶
版本号 | 发布日期 | 说明 | 贡献者 |
---|---|---|---|
2023.4.11 | 完成卡尔曼滤波说明文档 | 薛东来 |
参考资料¶
[1] 卡尔曼滤波器介绍