2. 安时积分法累积误差的量化分析与补偿策略设计

为什么安时积分会漂移:误差来源拆解

安时积分法的核心递推式为:

SOC(k) = SOC(k-1) − (η · I(k) · Δt) / (3600 · C_N)

其中 I 以放电为正、充电为负(本节统一采用该符号约定),C_N 为额定容量(Ah),η 为库仑效率。误差并非只来自"积分",而是由三类源头叠加:

  • 电流零漂 b:传感器在 I=0 时输出非零偏置,积分后变成随时间线性增长的 SOC 偏移,是最主要的长期漂移源。
  • 采样周期 Δt 的离散化误差:用矩形法近似积分,Δt 越大,电流快速变化段(如靠离泊、加减速)的截断误差越大。
  • 容量与效率偏差:C_N 随老化衰减、η 随温度变化,属于慢变参数误差。

本节聚焦前两项:先用同一组船舶工况电流数据量化不同 Δt 下的漂移量,再设计零漂估计补偿,最后验证收敛效果。

安时积分误差链与零漂补偿信号流 真实电流 I_true 船舶航行工况序列 电流传感器 I_meas = I_true + b + n 采样保持 周期 Δt 离散化 安时积分累加 Σ I·Δt / (3600·C_N) SOC_est 含漂移 零漂 b(准恒定) 积分后 → 线性 SOC 偏移 矩形法截断误差 Δt↑ → 快变段误差↑ 零漂估计器 静置段 I≈0 时取均值 b̂ ← (1−α)b̂ + α·I_meas 补偿后电流 I_corr = I_meas − b̂ 回灌积分器 反馈补偿 验证指标 |SOC_est − SOC_ref| 收敛 漂移斜率 → 0

构造可复现的船舶工况电流数据

为了让漂移量可量化,先构造一段 2 小时、含典型船舶工况的电流序列(放电为正):

  • 0–20 min:锚泊待机,真实电流 0 A(这是零漂估计的"黄金窗口")。
  • 20–50 min:低速巡航,约 120 A。
  • 50–70 min:靠泊操纵,电流在 60–260 A 间快速波动(考验 Δt 离散化)。
  • 70–120 min:正常航行,约 180 A。

传感器模型:I_meas = I_true + b + n,取零漂 b = 2.5 A(典型霍尔传感器温漂量级),噪声 n 为 ±0.3 A 均匀分布。电池参数:C_N = 500 Ah,η = 0.98,初始 SOC = 80%。

量化不同采样周期下的漂移

import numpy as np

rng = np.random.default_rng(42)
C_N, ETA, SOC0 = 500.0, 0.98, 0.80
B_TRUE = 2.5          # 真实零漂 (A)
T_END = 7200          # 2 h

def true_current(t):
    if t < 1200:   return 0.0
    if t < 3000:   return 120.0
    if t < 4200:   return 160.0 + 100.0*np.sin(2*np.pi*(t-3000)/300.0)
    return 180.0

def measure(t):
    return true_current(t) + B_TRUE + rng.uniform(-0.3, 0.3)

def ah_integrate(dt, b_hat=0.0):
    soc, t = SOC0, 0.0
    while t < T_END:
        i_corr = measure(t) - b_hat
        soc -= ETA * i_corr * dt / (3600.0 * C_N)
        t += dt
    return soc

soc_ref = ah_integrate(0.1, b_hat=B_TRUE)   # 理想参考:零漂已扣除
for dt in (1.0, 5.0, 10.0, 30.0, 60.0):
    s = ah_integrate(dt)
    print(f"dt={dt:5.1f}s  SOC={s:.4f}  漂移={100*(s-soc_ref):+.3f}%")

预期现象(示例数据下的典型结果):Δt 从 1 s 增大到 60 s,漂移量从约 −0.9% 增至约 −1.1%,其中零漂贡献约 −0.98%(2.5 A × 2 h / 500 Ah ≈ 1%),离散化误差在靠泊快变段额外贡献 0.1–0.2%。结论:零漂是主导项,Δt 是次要项——这决定了补偿策略应优先针对零漂。

零漂估计器设计

利用船舶"锚泊待机/停泊充电前静置"这类 I_true≈0 的窗口,对测量电流做指数滑动平均,得到 b̂:

class ZeroDriftEstimator:
    def __init__(self, alpha=0.05, i_idle=5.0):
        self.alpha, self.i_idle = alpha, i_idle
        self.b_hat, self.ready = 0.0, False

    def update(self, i_meas):
        # 仅当电流接近零(判定为静置)时才更新,避免把负荷电流误当零漂
        if abs(i_meas) < self.i_idle:
            self.b_hat = (1 - self.alpha) * self.b_hat + self.alpha * i_meas
            self.ready = True
        return self.b_hat

关键约束:i_idle 阈值必须大于零漂量级(本例 2.5 A)又小于最小真实负荷(本例 60 A),取 5 A 合理;alpha 越小估计越稳但收敛越慢,0.05 对应约 20 个静置采样点收敛。

补偿前后收敛验证

est = ZeroDriftEstimator(alpha=0.05, i_idle=5.0)
# 前 20 min 静置段喂入测量值
for t in np.arange(0, 1200, 1.0):
    est.update(measure(t))
print(f"b_hat={est.b_hat:.3f} A  (真值 {B_TRUE} A)")

soc_raw  = ah_integrate(1.0, b_hat=0.0)
soc_comp = ah_integrate(1.0, b_hat=est.b_hat)
print(f"补偿前漂移={100*(soc_raw -soc_ref):+.3f}%")
print(f"补偿后漂移={100*(soc_comp-soc_ref):+.3f}%")

示例结果判读:b̂ 收敛到约 2.4–2.6 A;补偿前 SOC 漂移约 −0.98%,补偿后降至约 −0.05% 以内,漂移斜率基本归零。若补偿后仍残留明显线性漂移,说明静置窗口不足或阈值设置不当,需检查 i_idle 与 alpha。

工程要点:零漂估计器应做成"常驻后台"模块,每次船舶停泊/静置自动刷新 b̂;航行中冻结估计值,避免负荷电流污染。若长期无静置窗口,可退化为"充电末期电流恒定时"的准静置窗口。
常见误区:把 Δt 调小当作万能解。本例中 Δt 从 60 s 降到 1 s 仅改善约 0.2%,而零漂补偿改善约 0.9%。先做零漂补偿,再优化采样周期,才是正确的优先级。