第四节:状态空间模型——将电池模型转化为离散状态空间方程

好,咱们接着往下聊。前面几节我们把电池的等效电路模型搭好了,参数也辨识出来了。但有个问题——这些模型都是连续时间的,而我们的BMS芯片是离散采样运行的。怎么办?

答案就是:把连续模型转成离散状态空间方程。

说白了,就是写出下面这个形式:

x(k+1) = A·x(k) + B·u(k)
y(k)   = C·x(k) + D·u(k)

这玩意儿看着简单,但里面的门道不少。我当年第一次做SOC估算时,就在这一步栽过跟头——状态变量选错了,结果卡尔曼滤波怎么调都不收敛。嗯,咱们今天就把这个坑填上。

4.1 状态变量的选择——这是第一步,也是最关键的一步

我个人习惯把状态变量分成两类:

  • 直接可测的:比如端电压、电流(这些通常作为输入或输出)
  • 需要估计的:比如SOC、极化电压(这些才是状态变量)

对于一阶RC模型,我通常选:

x(k) = [SOC(k),  U₁(k)]ᵀ

其中:

  • SOC(k) —— 第k时刻的荷电状态
  • U₁(k) —— 第k时刻的极化电压(RC并联支路两端电压)

为什么选这两个?你想想看:

  • SOC是我们最终要估算的目标,必须放在状态里
  • 极化电压U₁反映了电池的动态特性,卡尔曼滤波需要它来修正预测
⚠️ 我曾经犯过的错: 有次我把开路电压Uoc也当成了状态变量,结果状态维度变成3维,计算量上去了,精度却没提升。后来才明白——Uoc是SOC的函数,不是独立变量。

4.2 连续模型回顾——先写清楚再离散化

咱们的一阶RC模型,连续时间下的微分方程是这样的:

SOĊ(t) = -η·I(t) / Qₙ
U₁̇(t) = -U₁(t) / (R₁·C₁) + I(t) / C₁

其中:

  • η —— 库仑效率(通常取0.98~1.0)
  • Qₙ —— 电池额定容量(Ah)
  • R₁、C₁ —— 极化电阻和极化电容

端电压输出方程:

U(t) = Uoc(SOC) - U₁(t) - I(t)·R₀

这里Uoc(SOC)是个非线性函数,我一般用多项式拟合或者查表。这个后面会细讲。

4.3 离散化方法——这一步决定了精度

把连续模型转成离散,最常用的方法是前向欧拉法。为什么?简单、计算量小,适合嵌入式实时系统。

前向欧拉法的核心思想:

ẋ(t) ≈ [x(k+1) - x(k)] / Ts

其中Ts是采样周期(我一般取0.1s~1s,看BMS主频和精度要求)。

代入SOC的微分方程:

[SOC(k+1) - SOC(k)] / Ts = -η·I(k) / Qₙ
→ SOC(k+1) = SOC(k) - (η·Ts / Qₙ)·I(k)

代入U₁的微分方程:

[U₁(k+1) - U₁(k)] / Ts = -U₁(k) / (R₁·C₁) + I(k) / C₁
→ U₁(k+1) = [1 - Ts/(R₁·C₁)]·U₁(k) + (Ts/C₁)·I(k)

🔑 关键点: 写成矩阵形式就是:

x(k+1) = A·x(k) + B·u(k)

其中:
A = [1,          0     ]
    [0,  1 - Ts/(R₁·C₁)]

B = [-η·Ts/Qₙ ]
    [  Ts/C₁   ]

u(k) = I(k)   (输入电流)

4.4 输出方程的离散化——别忘了非线性部分

输出方程相对简单,因为它是代数方程,没有微分项:

y(k) = U(k) = Uoc(SOC(k)) - U₁(k) - I(k)·R₀

写成矩阵形式:

y(k) = C·x(k) + D·u(k)

其中:
C = [∂Uoc/∂SOC,  -1]   (注意!这里线性化了)
D = [-R₀]

u(k) = I(k)

💡 我的经验: 这里的C矩阵其实是个雅可比矩阵。因为Uoc(SOC)是非线性的,卡尔曼滤波需要在线性化点处求导。我一般用差分法近似:

∂Uoc/∂SOC ≈ [Uoc(SOC+δ) - Uoc(SOC-δ)] / (2·δ)

δ取0.01左右,效果不错。

4.5 完整的离散状态空间模型——拿来就能用

好了,把上面所有东西拼起来,咱们得到:

符号 表达式 说明
A [1, 0; 0, 1-Ts/(R₁·C₁)] 状态转移矩阵
B [-η·Ts/Qₙ; Ts/C₁] 输入矩阵
C [∂Uoc/∂SOC, -1] 输出矩阵(线性化后)
D [-R₀] 前馈矩阵

状态方程:

[SOC(k+1)]   [1,          0     ] [SOC(k)]   [-η·Ts/Qₙ]
[U₁(k+1)] = [0,  1 - Ts/(R₁·C₁)] [U₁(k)] + [  Ts/C₁  ] · I(k)

输出方程:

U(k) = [∂Uoc/∂SOC, -1] · [SOC(k)]  +  [-R₀] · I(k)
                         [U₁(k)]

4.6 避坑指南——我踩过的三个坑

  1. 采样周期Ts选太大:有次我为了省计算资源,把Ts设成2s,结果卡尔曼滤波发散得一塌糊涂。后来发现Ts必须小于RC时间常数的1/10。比如R₁·C₁=10s,Ts最好≤1s。
  2. 忘记处理Uoc的非线性:直接用固定值代替∂Uoc/∂SOC,结果SOC估算误差超过10%。后来改用查表+线性插值,误差降到2%以内。
  3. 状态变量初始化不当:SOC初始值偏差太大,卡尔曼滤波需要很长时间才能收敛。我现在的做法是:上电时先静置几分钟,用开路电压法粗估SOC,再作为初始值。

📌 总结一下:

  • 状态变量选SOC和U₁,别多选也别少选
  • 离散化用前向欧拉法,简单够用
  • 输出方程要线性化,别忘了求导
  • 采样周期Ts要匹配RC时间常数

下一节咱们就用这个模型,开始写卡尔曼滤波的预测步骤代码。到时候你会发现——模型建得好,滤波跑得顺。