1. 电池模型参数辨识
任务说明
本案例基于一组电池HPPC(混合脉冲功率特性)实验数据,使用带遗忘因子的递推最小二乘法(FF-RLS)在线辨识一阶RC等效电路模型参数。目标是通过给定输入电流与端电压数据,辨识出欧姆内阻R₀、极化电阻R₁、极化电容C₁以及开路电压OCV,从而建立可用的电池等效电路模型。
一阶RC等效电路模型
电池端电压方程如下:
UL(k) = OCV − R₀·I(k) − R₁·Ip(k)
其中Ip为极化电流,经离散化后可转化为如下线性回归形式:
y(k) = φT(k)·θ
式中:y(k) = UL(k) − UL(k−1),φ(k) = [UL(k−1), I(k), I(k−1)]T,θ = [a₁, b₀, b₁]T。辨识得到θ后,模型参数由以下关系反解:
R₀ = b₀,R₁ = (a₁·b₀ − b₁) / (1 + a₁),τ = −Ts / ln(−a₁),C₁ = τ / R₁
其中Ts为采样周期。OCV通过脉冲静置段端电压均值估计。
代码实现
import numpy as np
import matplotlib.pyplot as plt
# ========== 1. 生成模拟HPPC实验数据(真实参数已知,用于验证算法) ==========
np.random.seed(42)
Ts = 1.0 # 采样周期 1s
t = np.arange(0, 600, Ts) # 600s数据
N = len(t)
# 真实模型参数
R0_true = 0.02 # 欧姆内阻 Ω
R1_true = 0.015 # 极化电阻 Ω
C1_true = 1200.0 # 极化电容 F
tau_true = R1_true * C1_true # 时间常数
OCV_true = 3.7 # 开路电压 V
# 输入电流:脉冲序列(放电为正)
I = np.zeros(N)
for start in range(50, N, 100):
I[start:start+10] = 5.0 # 10s 5A放电脉冲
I[start+40:start+50] = -5.0 # 10s 5A充电脉冲
# 仿真端电压(一阶RC模型)
U = np.zeros(N)
Up = np.zeros(N) # 极化电压
U[0] = OCV_true
for k in range(1, N):
Up[k] = Up[k-1] * np.exp(-Ts/tau_true) + R1_true * (1 - np.exp(-Ts/tau_true)) * I[k-1]
U[k] = OCV_true - R0_true * I[k] - Up[k]
# 添加测量噪声
U_meas = U + np.random.normal(0, 0.002, N) # 2mV噪声
# ========== 2. FF-RLS参数辨识 ==========
lam = 0.98 # 遗忘因子
theta_hat = np.array([0.0, 0.0, 0.0]) # [a1, b0, b1]
P = np.eye(3) * 1000.0 # 协方差矩阵初始化
a1_hist, b0_hist, b1_hist = [], [], []
U_pred = np.zeros(N)
for k in range(1, N):
# 构造回归向量 φ(k) = [U(k-1), I(k), I(k-1)]
phi = np.array([U_meas[k-1], I[k], I[k-1]])
y = U_meas[k] - U_meas[k-1]
# 增益与协方差更新
K = P @ phi / (lam + phi @ P @ phi)
P = (P - np.outer(K, phi) @ P) / lam
P = (P + P.T) / 2 # 保持对称
# 参数更新
error = y - phi @ theta_hat
theta_hat = theta_hat + K * error
a1_hist.append(theta_hat[0])
b0_hist.append(theta_hat[1])
b1_hist.append(theta_hat[2])
# 预测端电压(用于验证)
U_pred[k] = U_meas[k-1] + phi @ theta_hat
# ========== 3. 参数反解 ==========
a1_final = theta_hat[0]
b0_final = theta_hat[1]
b1_final = theta_hat[2]
R0_est = b0_final
R1_est = (a1_final * b0_final - b1_final) / (1 + a1_final)
tau_est = -Ts / np.log(-a1_final)
C1_est = tau_est / R1_est
# OCV估计:取静置段(无电流段)电压均值
idle_idx = np.where(np.abs(I) < 0.01)[0]
OCV_est = np.mean(U_meas[idle_idx[-100:]]) # 取最后静置段
# ========== 4. 输出结果 ==========
print("=== 辨识结果 ===")
print(f"R0: 真实={R0_true:.4f}Ω, 辨识={R0_est:.4f}Ω")
print(f"R1: 真实={R1_true:.4f}Ω, 辨识={R1_est:.4f}Ω")
print(f"C1: 真实={C1_true:.1f}F, 辨识={C1_est:.1f}F")
print(f"OCV: 真实={OCV_true:.3f}V, 辨识={OCV_est:.3f}V")
# 计算预测误差
rmse = np.sqrt(np.mean((U_meas[1:] - U_pred[1:])**2))
print(f"端电压预测RMSE: {rmse*1000:.2f}mV")
# ========== 5. 绘图 ==========
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6))
ax1.plot(t, U_meas, 'b-', label='测量电压', linewidth=0.8)
ax1.plot(t, U_pred, 'r--', label='模型预测', linewidth=0.8)
ax1.set_ylabel('电压 (V)')
ax1.legend()
ax1.grid(True)
ax2.plot(t[1:], a1_hist, label='a₁')
ax2.plot(t[1:], b0_hist, label='b₀')
ax2.plot(t[1:], b1_hist, label='b₁')
ax2.set_xlabel('时间 (s)')
ax2.set_ylabel('参数值')
ax2.legend()
ax2.grid(True)
plt.tight_layout()
plt.savefig('battery_identification_result.png', dpi=150)
plt.show()
运行与验证
依赖环境:Python 3.8+,numpy,matplotlib。
运行方式:将代码保存为battery_id.py,在终端执行python battery_id.py。
验证方法:
- 观察终端输出的辨识参数与真实参数(代码中已设定)的误差:R₀、R₁误差应在±10%以内,C₁误差应在±20%以内,OCV误差应在±5mV以内;
- 查看生成的
battery_identification_result.png:上图红色预测曲线应与蓝色测量曲线基本重合;下图三条参数曲线应在约100s后收敛至稳定值; - 端电压预测RMSE应小于5mV。
判定标准:满足上述三项条件即视为辨识成功,模型可用于后续SOC估算等BMS算法。