1. 基于安时积分法的船舶电池SOC基础估算实现
任务对象与约定
本节以一艘小型电动船舶的磷酸铁锂动力电池组为对象:额定容量 Q_N = 200 Ah,初始 SOC 为 SOC₀ = 0.80。给定一段 30 分钟的充放电电流序列(采样周期 60 s),用安时积分法递推 SOC,并输出 SOC 随时间变化曲线。
符号约定必须先固定,否则结果会整体反向:规定放电电流为正、充电电流为负(即电流从电池正极流出为正)。于是安时积分递推式为:
SOC(k) = SOC(k-1) - (I(k) · Δt) / (3600 · Q_N · η)
其中 I 单位为 A,Δt 单位为 s,Q_N 单位为 Ah,除以 3600 完成秒到小时的换算;η 为库仑效率,本例取 1.0 以突出积分步长与符号约定的影响。
核心函数实现
下面给出可直接运行的 Python 实现,包含安时积分核心函数、示例电流序列、SOC 递推与曲线绘制。电流序列按 60 s 采样,共 30 个点(0~29 min 的采样值),代表一段“放电—静置—充电—放电”的航行工况。
import numpy as np
import matplotlib.pyplot as plt
Q_N = 200.0 # 额定容量 Ah
SOC0 = 0.80 # 初始 SOC
ETA = 1.0 # 库仑效率
# 30 个采样点,采样周期 60 s;放电为正、充电为负
current = np.array([
40, 40, 40, 40, 40, # 0-4 min 放电
0, 0, 0, 0, 0, # 5-9 min 静置
-30, -30, -30, -30, -30, # 10-14 min 充电
0, 0, 0, 0, 0, # 15-19 min 静置
60, 60, 60, 60, 60, # 20-24 min 大电流放电
20, 20, 20, 20, 20 # 25-29 min 小电流放电
], dtype=float)
def ampere_hour_soc(current, dt, q_n, soc0, eta=1.0):
"""安时积分 SOC 递推。放电电流为正,充电为负。"""
soc = np.empty(len(current) + 1)
soc[0] = soc0
for k, i_k in enumerate(current, start=1):
soc[k] = soc[k-1] - (i_k * dt) / (3600.0 * q_n * eta)
return soc
dt = 60.0
soc = ampere_hour_soc(current, dt, Q_N, SOC0, ETA)
t_min = np.arange(len(soc)) * dt / 60.0
print("末值 SOC = %.4f" % soc[-1])
print("SOC 变化量 = %.4f" % (soc[-1] - SOC0))
plt.plot(t_min, soc, marker='o', color='#1f77b4')
plt.xlabel("时间 / min")
plt.ylabel("SOC")
plt.title("安时积分法 SOC 递推曲线")
plt.grid(True, alpha=0.3)
plt.show()
结果判读与两个关键影响
按上述参数,放电段累计放出电量 (40×5 + 60×5 + 20×5) A·min = 600 A·min = 10 Ah,充电段累计充入 30×5 A·min = 2.5 Ah,净放出 7.5 Ah。因此末值 SOC 应为 0.80 − 7.5/200 = 0.7625,与程序输出一致。这一手算校核是验证实现正确性的第一道关口。
- 积分步长的影响:安时积分本质是矩形法数值积分。若把同一段电流序列用 30 s 采样重算(电流值按段保持),由于电流在段内恒定,结果与 60 s 完全一致;但若电流在采样间隔内变化(如斜坡上升),步长越大,矩形近似误差越大。工程上应保证采样周期远小于电流变化的时间常数。
- 电流符号约定的影响:若误把充电记为正值,则 SOC 曲线整体反向:放电段 SOC 上升、充电段 SOC 下降,末值变为
0.80 + 7.5/200 = 0.8375。数值上“看起来合理”,但物理意义完全错误,因此必须在代码入口处用注释和变量命名锁定符号约定。
步长敏感性验证
为验证积分步长的影响,可把同一段电流序列按 30 s 采样重算(每段电流值保持),由于段内电流恒定,结果与 60 s 一致;但若把电流改为在采样间隔内线性变化,则 60 s 与 30 s 的结果会出现差异。下面给出一个可复现的对比实验:构造一段从 0 A 线性上升到 60 A 的 10 分钟放电电流,分别用 60 s 与 10 s 步长积分,比较末值 SOC。
def ramp_current(t, t_end=600.0, i_max=60.0):
return i_max * t / t_end
def integrate_ramp(dt):
t = 0.0
soc = SOC0
while t < 600.0:
i_k = ramp_current(t + dt/2) # 取区间中点电流,减小矩形误差
soc -= (i_k * dt) / (3600.0 * Q_N)
t += dt
return soc
print("60 s 步长末值 SOC = %.5f" % integrate_ramp(60.0))
print("10 s 步长末值 SOC = %.5f" % integrate_ramp(10.0))
该斜坡放电总电量为 ½ × 60 A × (600/3600) h = 5 Ah,理论末值 SOC 为 0.80 − 5/200 = 0.775。步长越小,结果越接近理论值;60 s 步长因矩形近似会产生可见偏差。这正是后续案例中“累积误差量化”的起点,但在本例中只需确认:实现正确、符号正确、步长合理,安时积分就能给出可信的 SOC 递推结果。
Δt 以分钟代入公式却仍除以 3600,会导致 SOC 变化量缩小 60 倍。统一在函数入口把时间换算为秒,并在注释中写明单位。