第四节:状态空间模型——将电池模型转化为离散状态空间方程
好,咱们接着往下聊。前面几节我们把电池的等效电路模型搭好了,参数也辨识出来了。但有个问题——这些模型都是连续时间的,而我们的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 避坑指南——我踩过的三个坑
- 采样周期Ts选太大:有次我为了省计算资源,把Ts设成2s,结果卡尔曼滤波发散得一塌糊涂。后来发现Ts必须小于RC时间常数的1/10。比如R₁·C₁=10s,Ts最好≤1s。
- 忘记处理Uoc的非线性:直接用固定值代替∂Uoc/∂SOC,结果SOC估算误差超过10%。后来改用查表+线性插值,误差降到2%以内。
- 状态变量初始化不当:SOC初始值偏差太大,卡尔曼滤波需要很长时间才能收敛。我现在的做法是:上电时先静置几分钟,用开路电压法粗估SOC,再作为初始值。
📌 总结一下:
- 状态变量选SOC和U₁,别多选也别少选
- 离散化用前向欧拉法,简单够用
- 输出方程要线性化,别忘了求导
- 采样周期Ts要匹配RC时间常数
下一节咱们就用这个模型,开始写卡尔曼滤波的预测步骤代码。到时候你会发现——模型建得好,滤波跑得顺。