第3章 卡尔曼滤波入门:从贝叶斯滤波到卡尔曼滤波,线性系统的最优估计
3.1 为什么我们需要“最优估计”?
做电池状态估计,说白了就是跟不确定性打交道。
你想想看,电池的SOC(荷电状态)能直接测量吗?不能。你只能测电压、电流、温度。这些测量值还带着噪声——传感器精度有限,ADC量化有误差,甚至温度变化都会影响读数。
所以我们需要一个“滤波器”,从这些带噪声的测量中,把真实的状态“猜”出来。
卡尔曼滤波,就是目前最经典、最实用的线性系统最优估计算法。没有之一。
我个人习惯把卡尔曼滤波理解为“带权重的预测+修正”。你有一个模型,可以预测下一时刻的状态;你也有测量值,可以修正预测的偏差。卡尔曼滤波的核心,就是找到那个最优的权重——卡尔曼增益。
3.2 从贝叶斯滤波说起
要理解卡尔曼滤波,得先知道它的“爸爸”——贝叶斯滤波。
贝叶斯滤波的思想其实很简单:
- 先验:根据上一时刻的状态和系统模型,预测当前时刻的状态分布
- 似然:当前测量值告诉我们,状态可能是多少
- 后验:把先验和似然乘起来,归一化后就是当前状态的最优估计
用公式表达就是:
P(x_k | z_{1:k}) ∝ P(z_k | x_k) · P(x_k | z_{1:k-1})
其中:
- P(x_k | z_{1:k-1}) 是预测(先验)
- P(z_k | x_k) 是测量似然
- P(x_k | z_{1:k}) 是更新后的后验
嗯,这里要注意:贝叶斯滤波是一个通用的框架,但实际计算时,如果状态空间是连续的,积分会非常复杂。所以我们需要一些假设来简化。
3.3 卡尔曼滤波的三个关键假设
卡尔曼滤波之所以能成为“最优估计”,是因为它做了三个假设:
- 系统是线性的:状态转移和测量方程都是线性的
- 噪声是高斯白噪声:过程噪声和测量噪声都服从零均值高斯分布
- 初始状态也是高斯分布
在这三个假设下,贝叶斯滤波的积分问题就变成了高斯分布的解析计算问题——说白了,就是算均值和协方差矩阵。
核心结论:高斯分布经过线性变换后仍然是高斯分布。这就是卡尔曼滤波能解析求解的根本原因。
3.4 卡尔曼滤波的五个核心公式
卡尔曼滤波分为两步:预测(Time Update)和更新(Measurement Update)。
先定义系统模型:
x_k = A · x_{k-1} + B · u_k + w_k
z_k = H · x_k + v_k
其中:
- A:状态转移矩阵
- B:控制输入矩阵
- H:测量矩阵
- w_k ~ N(0, Q):过程噪声
- v_k ~ N(0, R):测量噪声
预测步骤(两步)
- 状态预测:x̂_k|k-1 = A · x̂_{k-1|k-1} + B · u_k
- 协方差预测:P_k|k-1 = A · P_{k-1|k-1} · A^T + Q
更新步骤(三步)
- 卡尔曼增益:K_k = P_k|k-1 · H^T · (H · P_k|k-1 · H^T + R)^{-1}
- 状态更新:x̂_k|k = x̂_k|k-1 + K_k · (z_k - H · x̂_k|k-1)
- 协方差更新:P_k|k = (I - K_k · H) · P_k|k-1
我的经验:刚开始学的时候,别死记公式。先理解物理意义——预测是“根据模型猜”,更新是“用测量纠偏”。卡尔曼增益K就是“你更相信模型还是测量”的权重。
3.5 卡尔曼增益的直观理解
卡尔曼增益K的表达式:
K = P_{pred} · H^T · (H · P_{pred} · H^T + R)^{-1}
你看这个公式:
- 如果测量噪声R很大,分母很大,K就很小 → 更相信模型预测
- 如果预测协方差P很大,分子很大,K就很大 → 更相信测量值
说白了,卡尔曼滤波就是在“模型预测”和“测量值”之间做最优权衡。
我曾经在项目中遇到过一个问题:电池的电流传感器噪声特别大,R设小了,滤波结果跟着测量值剧烈抖动;R设大了,又跟不上SOC的快速变化。后来我用了自适应卡尔曼滤波,在线调整R,才解决了这个问题。
3.6 一个简单的Python实现
下面是一个一维卡尔曼滤波的Python代码,用于估计一个恒定的电压值:
import numpy as np
import matplotlib.pyplot as plt
# 系统参数
dt = 0.1 # 采样时间
A = 1.0 # 状态转移矩阵(恒定值)
H = 1.0 # 测量矩阵
Q = 1e-5 # 过程噪声协方差
R = 0.01 # 测量噪声协方差
# 初始状态
x_hat = 0.0 # 初始估计
P = 1.0 # 初始协方差
# 模拟真实值和测量值
true_value = 3.3 # 真实电压
measurements = true_value + np.random.normal(0, np.sqrt(R), 100)
# 卡尔曼滤波
estimates = []
for z in measurements:
# 预测
x_pred = A * x_hat
P_pred = A * P * A + Q
# 更新
K = P_pred * H / (H * P_pred * H + R)
x_hat = x_pred + K * (z - H * x_pred)
P = (1 - K * H) * P_pred
estimates.append(x_hat)
# 绘图
plt.figure(figsize=(10, 4))
plt.plot(measurements, 'r.', alpha=0.5, label='测量值')
plt.plot(estimates, 'b-', linewidth=2, label='卡尔曼估计')
plt.axhline(true_value, color='g', linestyle='--', label='真实值')
plt.legend()
plt.xlabel('采样点')
plt.ylabel('电压 (V)')
plt.title('一维卡尔曼滤波示例')
plt.grid(True)
plt.show()
避坑指南:我曾经在调试时发现滤波结果发散,检查了半天才发现是Q和R的量级设置不合理。Q/R的比值决定了滤波器的“带宽”——比值越大,滤波器响应越快但噪声也越大;比值越小,滤波越平滑但响应越慢。这个平衡需要根据实际系统调参。
3.7 卡尔曼滤波在电池状态估计中的应用
在电池管理中,卡尔曼滤波最常见的应用就是SOC估计。系统模型通常是:
SOC_k = SOC_{k-1} - (η · I_k · Δt) / Q_nom + w_k
V_k = OCV(SOC_k) - I_k · R_0 - V_rc + v_k
其中:
- η:库仑效率
- I_k:电流(放电为正)
- Q_nom:电池标称容量
- OCV(SOC):开路电压与SOC的关系曲线
- R_0:欧姆内阻
- V_rc:RC网络的极化电压
这里有个关键点:OCV与SOC的关系是非线性的。所以严格来说,电池SOC估计需要用到扩展卡尔曼滤波(EKF)。但基础卡尔曼滤波的思想完全适用——先预测SOC,再用电压测量值修正。
3.8 本章小结
卡尔曼滤波的核心思想,我总结为三句话:
- 预测:用模型猜下一时刻的状态
- 更新:用测量值修正猜测
- 最优权重:卡尔曼增益告诉你该信谁
它之所以成为电池状态估计的基石,是因为它能在噪声环境下给出统计意义下的最优估计。而且计算量小,适合嵌入式实时实现。
下一章我们会把卡尔曼滤波扩展到非线性系统——扩展卡尔曼滤波(EKF),那才是电池SOC估计的真正主力。