在控制领域,获取控制对象精确的当前状态至关重要。但是在传感器测量过程中由于自身误差和外部干扰导致采样值不准确,卡尔曼滤波的作用就是为了纠正(correct)这些不准确,从而得到较准确的“状态值”(采样数据);
卡尔曼滤波的适用场景、原理以及使用中的关键概念
- 原理:
a. 卡尔曼滤波假设各种采样数据的噪音(测量值和实际值的差)符合高斯分布,并且这些采样数据之间存在某些关系;
b. 例如,有两种采样数据分别是小车的速度(v)和离障碍物的距离(d)(关系: d 2 = d 1 − Δ t ∗ v d2=d1- \Delta t*v d2=d1−Δt∗v , d 1 d 2 d1 \space d2 d1 d2 分别是相隔一段时间的距离采样值,采样相隔时间为 Δ t \Delta t Δt);
c. 如下图所示,采样数据 v 和 d 的噪音分别对应高斯分布 ( μ 0 , σ 0 ) (\mu_0,\sigma_0) (μ0,σ0), ( μ 1 , σ 1 ) (\mu_1,\sigma_1) (μ1,σ1), μ 0 \mu_0 μ0和 μ 1 \mu_1 μ1 分别代表出现概率最高的噪音值;
d. 卡尔曼滤波,参照高斯分布的乘积仍然符合高斯分布原理,根据速度(v)和离障碍物的距离(d)采样值、变化值以及关系公式,计算出一组权重公式(卡尔曼增益矩阵),对采样结果进行补偿,从而降低噪音,如上图,两个高斯分布的乘积形成的新的高斯分布,噪音的最大振幅降低了。
e. 卡尔曼滤波是一种迭代滤波器,使用不断迭代“训练”出的“规律”,对当前采样值的进行优化。 - 想使用卡尔曼滤波,需要具备下列条件:
a. 多种 “状态值”(不只一个),并且它们之间存在可以用公式描述的关系;
b. 这些数据都是独立传感器的采样结果;
c. 可以获得每次采样的间隔时间; - 使用卡尔曼滤波中相关的概念:
a. 状态协方差矩阵 P k P_k Pk :描述多“状态值”之间互相影响程度的矩阵,初始值随意,几次迭代后会逼近状态值之间的真实关系;
b. 预测矩阵 F k F_k Fk :描述各种“状态值”伴随时间的变化规律,包含了各种“状态值” S k − 1 S_{k-1} Sk−1 计算下一个“状态值” S k S_k Sk 的计算公式,示意图如下。
c. 控制矩阵 Bk 和控制向量 μ →:描述控制指令引发“状态值”变化规律的矩阵和参数。比如,无人车内部有操控指令(加速、减速、左转、右转等),操控指令对无人车状态带来的变化时可以推断的,例如控制无人车加速,则该矩阵代表此加速度对速度的影响,为可选项。
d. 外部噪音协方矩阵 Q k Q_k Qk :代表可能存在的外部噪音,比如风速、地势等,为可选项。
e. 单位变换矩阵 H k H_k Hk : 预测值和传感器读值的单位和比例可能有区别,这个矩阵用于两个矩阵进行计算前必须的单位和比例的转换,是个常量。
f. 传感器噪音协方矩阵 R k R_k Rk:代表传感器本身的误差噪音, R k R_k Rk的中心值$ \overrightarrow{z} $等于传感器本次的测量值, R k R_k Rk由传感器厂家提供。
g. 卡尔曼增益矩阵 K K K: 卡尔曼滤波的核心,示意图如下,本质上是一个融合预测值和测量值的一个权重矩阵,融合的过程就是用“预测值”去纠正“测量值”的过程。
h. 迭代更新的计算流程图
实践场景
- 霍尔传感器测速
a. 硬件配置:玩具车轮上安装 3 个磁铁,搭配一个霍尔传感器
b. 基本原理:使用 STM32 定时器获得进出磁场的时间戳
c. 定时器累加频率,20KHz - 超声波传感器测距
测距实验数据:接近障碍物时采样值偏大,会引起避障不及时
实际距离 cm | 测量距离 cm |
---|---|
12 | 21 |
20 | 28 |
41.5 | 49 |
60 | 65 |
121.5 | 127 |
161.5 | 149-152 |
201.5 | 186-188 |
281.5 | 232-234 |
361.5 | 310-327 |
- 为什么需要卡尔曼滤波:超声波传感器受环境影响太大,尤其是接近障碍物时采样值偏大,希望通过滤波纠正。
套用卡尔曼滤波公式
1、小车状态描述:
x
=
[
v
d
]
x = \begin{bmatrix} v \\ d \end{bmatrix}
x=[vd]
x : 为小车当前状态
v : 当前方向上的行驶速度,单位为 cm/s
d : 当前行进方向上离障碍物的距离,单位为 cm
2、 预测矩阵 F ,使用恒定速度模型:
d
k
+
1
=
d
k
−
Δ
t
×
v
d_{k+1} = d_k - \Delta t \times v
dk+1=dk−Δt×v
x
k
+
1
=
F
∗
x
k
x_{k+1} = F * x_k
xk+1=F∗xk
F
=
[
1
0
−
Δ
t
/
1000
1
]
F = \begin{bmatrix} 1 & 0 \\ -\Delta t/1000 & 1 \end{bmatrix}
F=[1−Δt/100001]
Δ
t
\Delta t
Δt 为每次迭代计算的间隔时间,单位为 ms
3、测量矩阵 H ,传感器测量出的既是速度和距离
H = [ 1 0 0 1 ] \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} [1001]
4、运动噪音协方差矩阵 Q,也就是可能随机存在的小车加/减速的过程(随机的加速度 a a a造成的),定义为正态分布 N ( 0 , Q ) N(0,Q) N(0,Q)
速度噪音: Δ v = a × Δ t \Delta v = a \times \Delta t Δv=a×Δt,符合平均值为 0 的正态分布
距离噪音: Δ d = − 1 2 × a × Δ t 2 \Delta d = -\frac{1}{2} \times a \times \Delta t^2 Δd=−21×a×Δt2,符合平均值为 0 的正态分布
注意:
Δ
v
Δ
d
\Delta v \space \Delta d
Δv Δd 线是性相关的(
ρ
Δ
v
Δ
d
=
1
\rho_{\Delta v \Delta d} = 1
ρΔvΔd=1,即相关系数为 1)
σ
Δ
v
2
=
c
o
r
(
Δ
v
)
=
c
o
r
(
a
×
Δ
t
)
=
D
e
l
t
a
t
2
×
σ
a
2
\sigma_{\Delta v}^2 = cor(\Delta v) = cor(a \times \Delta t) = Delta t^2 \times \sigma_a^2
σΔv2=cor(Δv)=cor(a×Δt)=Deltat2×σa2
σ
Δ
d
2
=
c
o
r
(
Δ
d
)
=
c
o
r
(
1
2
×
a
×
Δ
t
2
)
=
1
4
×
Δ
t
4
×
σ
a
2
\sigma_{\Delta d}^2 = cor(\Delta d) = cor(\frac{1}{2} \times a \times \Delta t^2) = \frac{1}{4} \times \Delta t^4 \times \sigma_a^2
σΔd2=cor(Δd)=cor(21×a×Δt2)=41×Δt4×σa2
σ
Δ
v
Δ
d
=
c
o
r
(
Δ
v
,
Δ
d
)
=
ρ
Δ
v
Δ
d
×
σ
Δ
v
2
×
σ
Δ
d
2
=
1
2
×
Δ
t
3
×
σ
a
2
\sigma_{\Delta v \Delta d} = cor(\Delta v,\Delta d) = \rho_{\Delta v \Delta d} \times \sqrt{\sigma_{\Delta v}^2} \times \sqrt{\sigma_{\Delta d}^2} = \frac{1}{2} \times \Delta t^3 \times \sigma_a^2
σΔvΔd=cor(Δv,Δd)=ρΔvΔd×σΔv2×σΔd2=21×Δt3×σa2
Q = [ σ Δ v 2 σ Δ v Δ d σ Δ d Δ v σ Δ d 2 ] = [ ( Δ t / 1000 ) 2 1 2 ( Δ t / 1000 ) 3 1 2 ( Δ t / 1000 ) 3 1 4 ( Δ t / 1000 ) 4 ] ∗ σ a 2 Q = \begin{bmatrix} \sigma_{\Delta v}^2 & \sigma_{\Delta v \Delta d} \\ \sigma_{\Delta d \Delta v} & \sigma_{\Delta d}^2 \end{bmatrix}\ = \begin{bmatrix} (\Delta t/1000)^2 & \frac{1}{2}(\Delta t/1000)^3 \\ \frac{1}{2}(\Delta t/1000)^3 &\frac{1}{4}(\Delta t/1000)^4 \end{bmatrix} * \sigma_a^2 Q=[σΔv2σΔdΔvσΔvΔdσΔd2] =[(Δt/1000)221(Δt/1000)321(Δt/1000)341(Δt/1000)4]∗σa2
其中 a = 50cm/s2 , σ a 2 \sigma_a^2 σa2 设定为 625 ( c m / s 2 ) 2 (cm/s^2)^2 (cm/s2)2 ,即 2 σ a = 50 2\sigma_a=50 2σa=50!,加速度在 50 c m / s 2 cm/s^2 cm/s2以内的概率在 60% 以上。
5、控制矩阵 B B B 和控制向量 μ → \overrightarrow{\mu} μ
a) 小车的加减速控制方式很简陋并且非常灵活
b) 涉及到很多随机因素(电池电量、是否在转弯、速度变化的梯度大小)
c) 定义为控制矩阵的话会非常复杂
d) 因此把控制导致的速度变化定义为了“随机”噪音,由运动噪音矩阵 Q Q Q 表示。
6、测量噪音 R R R,也就是传感器的精度,定义为正态分布 N($ \overrightarrow{z}$, R R R)
z → \overrightarrow{z} z: 为每次传感器的测量值
测速误差 : 最大误差为 5% , 2 σ v e = 0.05 v 2\sigma_{ve}=0.05v 2σve=0.05v
测距误差 : 最大误差为 10% , 2 σ v d = 0.1 d 2\sigma_{vd}=0.1d 2σvd=0.1d
注意:因为速度和距离的测量是完全独立的两个传感器,相关系数为 0,因此两者误差的协方差为 0
σ v e 2 = 0.000625 × v 2 \sigma_{ve}^2=0.000625 \times v^2 σve2=0.000625×v2
σ d e 2 = 0.0025 × d 2 \sigma_{de}^2=0.0025 \times d^2 σde2=0.0025×d2
c o r ( v e , d e ) = 0 cor(ve,de) = 0 cor(ve,de)=0
E = [ 0.000625 0 0 0.0025 ] E = \begin{bmatrix} 0.000625 & 0 \\ 0 & 0.0025 \end{bmatrix} E=[0.000625000.0025]
R = [ 0.000625 × v 2 0 0 0.0025 × d 2 ] = d i a g ( d i a g ( E ∗ z → ) ∗ z → ) R = \begin{bmatrix} 0.000625 \times v^2 & 0 \\ 0 & 0.0025 \times d^2 \end{bmatrix} = diag(diag(E* \overrightarrow{z} )* \overrightarrow{z} ) R=[0.000625×v2000.0025×d2]=diag(diag(E∗z)∗z)
7、协方矩阵 P P P 初始化, P P P 是一个迭代更新的量,每一轮预测和更新后, P P P 都会更新一个新的值,因此初始化时可以根据估计协定,因为随着几轮迭代会越来越趋近真实值。
P = [ 1 0 0 1 ] P = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} P=[1001]
8、套用公式后结果为:
x ^ k = F k x ^ k − 1 \hat{x}_k = F_k\hat{x}_{k-1} x^k=Fkx^k−1
P k = F k P k − 1 F k T + Q k P_k = F_kP_{k-1}F_k^T + Q_k Pk=FkPk−1FkT+Qk
x ^ k ′ = x ^ k + K ′ ( z k → − x ^ k ) \hat{x}_k' = \hat{x}_k + K'(\overrightarrow{z_k} - \hat{x}_k) x^k′=x^k+K′(zk−x^k)
P k ′ = P k − K ′ P k P_k' = P_k - K'P_k Pk′=Pk−K′Pk
K ′ = P k P k + R k K' = \frac{P_k}{P_k + R_k} K′=Pk+RkPk
利用 matlab 把二维矩阵运算转换为符号运算
由于 STM32 单片机中存储空间有限,计算能力有限,调用矩阵计算函数库不现实,所以可以利用 matlab 的符号定义功能,把矩阵运算转换为符号运算。定义迭代更新中使用的变量:p11 p12 p21 p22 ve de vk dk delt_t cor_a cor_ve cor_de ,它们的含义如下:
运动噪音的加速度方差 σ a 2 = c o r _ a \sigma_a^2= cor\_a σa2=cor_a
传感器误差矩阵 E = [ c o r _ v 0 0 c o r _ d e ] E = \begin{bmatrix} cor\_v &0 \\ 0 & cor\_de \end{bmatrix} E=[cor_v00cor_de]
本次迭代初始协方矩阵 P k − 1 = [ p 11 p 12 p 21 p 22 ] P_{k-1} = \begin{bmatrix} p11 & p12 \\ p21 & p22 \end{bmatrix} Pk−1=[p11p21p12p22]
本次迭代初始状态 x ^ k − 1 = [ v e d e ] \hat{x}_{k-1}=\begin{bmatrix} ve \\ de \end{bmatrix} x^k−1=[vede]
本次测量值 z k → = [ v k d k ] \overrightarrow{z_k} = \begin{bmatrix} vk \\ dk \end{bmatrix} zk=[vkdk]
本次测量时间间隔 Δ t k = d e l t a _ t \Delta t_k = delta\_t Δtk=delta_t
% 把二维的卡尔曼滤波的矩阵运算转换为普通运算
clear; close all; clc
% 符号定义
syms p11 p12 p21 p22 vk dk ve de delt_t;
% 初始状态
P_km1 = [p11, p12; p21, p22];
x_km1 = [ve; de];
% 预测矩阵
F = [1, 0; -delt_t/1000, 1];
Ft = [1, -delt_t/1000; 0, 1];
% 运动噪音协方差矩阵
cor_a = 10000;
Q = [(delt_t/1000)^2, 1/2*(delt_t/1000)^3; 1/2*(delt_t/1000)^3, 1/4*;(delt_t/1000)^4]*cor_a;
% 预测状态
x_exp_k = F*x_km1;
P_k = F*P_km1*Ft + Q;
% 测量状态
z_k = [vk; dk];
% 测量噪音
cor_ve = 0.000625;
cor_de = 0.0025;
R_k = [cor_ve*vk^2, 0; 0, (150/dk)^2];
%卡尔曼增益
K = P_k/(P_k + R_k);
%更新状态
P_k_target = P_k - K*P_k;
x_exp_k_target = x_exp_k + K*(z_k - x_exp_k);
实验结果
加入卡尔曼滤波后,已经起到了一定的效果(如图所示),调试的过程中遇到的问题和思考如下:
- 遇到问题:障碍物变动或者运动方向变化会使预测失效,导致结果误差偏大;解决思路:加入控制信息,发生运动变化时,重新计算。
- 采样误差过大:传感器超过 2m 后的测试结果极不稳定,不信任 2m 以上的结果,2m 作为超声波传感器的极限距离,所有大于 2m 的测量值一律返回2m。
- 调试和优化的思路是:信任速度采样结果,而怀疑距离采样结果,最终结果如下(红线为纠正后的结果,蓝线为采样数据):
参考文档
http://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures
https://blog.youkuaiyun.com/AdamShan/article/details/78248421
https://blog.youkuaiyun.com/u011362822/article/details/95905113