第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 卡尔曼滤波的三个关键假设

卡尔曼滤波之所以能成为“最优估计”,是因为它做了三个假设:

  1. 系统是线性的:状态转移和测量方程都是线性的
  2. 噪声是高斯白噪声:过程噪声和测量噪声都服从零均值高斯分布
  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):测量噪声

预测步骤(两步)

  1. 状态预测:x̂_k|k-1 = A · x̂_{k-1|k-1} + B · u_k
  2. 协方差预测:P_k|k-1 = A · P_{k-1|k-1} · A^T + Q

更新步骤(三步)

  1. 卡尔曼增益:K_k = P_k|k-1 · H^T · (H · P_k|k-1 · H^T + R)^{-1}
  2. 状态更新:x̂_k|k = x̂_k|k-1 + K_k · (z_k - H · x̂_k|k-1)
  3. 协方差更新: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 本章小结

卡尔曼滤波的核心思想,我总结为三句话:

  1. 预测:用模型猜下一时刻的状态
  2. 更新:用测量值修正猜测
  3. 最优权重:卡尔曼增益告诉你该信谁

它之所以成为电池状态估计的基石,是因为它能在噪声环境下给出统计意义下的最优估计。而且计算量小,适合嵌入式实时实现。

下一章我们会把卡尔曼滤波扩展到非线性系统——扩展卡尔曼滤波(EKF),那才是电池SOC估计的真正主力。