电池不一致性:A correlation based fault detection method for short circuits in battery packs

严格地说,一个电池组中的电池单元并不完全相同。鉴于制造工艺、使用中的热条件、平衡状态等的变化,串联中相同类型的电池可能具有不同的OCV和内阻。
不同的OCV:会导致电池电压的偏移(体现在加法上)
内阻的不同:会导致不同幅度的电压波动(体现在乘法上);(不同老化程度的电池表现出不同的内部电阻)

思路

鉴于相关系数衡量的是两条曲线的趋势是否匹配,趋势的相似性。这里引入相关系数的思想,用相
关系数提取电压下降的非趋势性信息来检测短路的初始阶段,并将变化反映在相关系数的下降上。
应用移动平均窗口来保持电池的最新电压趋势,保持对短路故障的检测灵敏度。
理想情况下,两个串联电池电压的相关系数在正常运行时应接近1,当发生短路时,异常的电压降
低会影响电池电压的同步波动,从而被相关系数降低所反映。

技巧

利用移动窗口滤波器来忘记过去的数据并保持对故障的检测灵敏度,即在每个时间瞬间,只计算历
史时间窗口中的数据的相关系数
移动窗口大小:太大,由短路导致的异常电压变化对相关系数的影响可以忽略不计,太小,噪
声将被视为异常波动。
图3(b):三种不同窗口大小的计算结果之间的比较表明,较小的窗口大小会导致对异常电压变
化的更高灵敏度

对两个电压增加了独立同分布的白噪声
图4(b):提供的相关系数比图3(b)中的相关系数表现得更加波动。

鉴于相关系数公式特性,对两个电压增加方波,以防止在休息期间噪音主导电压变化时出现错误检测
防止假阳性检测。图4(a):当电池处于静止状态时,相关系数下降,图4©显示了加入方波后
的相关系数,表明诱发的故障可以很容易被识别。

结果

电池不一致性:A correlation based fault detection method for short circuits in battery packs_第1张图片

疑问

太难调参数了,结果不稳定,方波是个啥我也不知道。

脚本

from scipy.stats import pearsonr
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# 正常显示中文和负号
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 原始数据展示
data = pd.read_csv('data/raw.csv')
data = data.rename(columns = {'u1': 'a1', 'u2': 'a2'})
data = data.dropna()
x_columns = [x for x in data.columns if x in ['a1', 'a2']]
data = data[x_columns]
time = range(0, len(data["a1"]))

plt.subplot(231)
plt.plot(time, data["a1"], '#20B2AA', label = 'u1')
plt.plot(time, data["a2"], '#F08080', label = 'u2')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('mv')
plt.title('两个电芯电压图示')

# 按照滑动窗口w计算原始数据的相关系数
w = 5
l_cor = []
for i in range(len(data['a1']) - w):
    l_V1fn = []
    l_V2n = []
    for j in range(i, i + w, 1):
        l_V1fn.append(data["a1"][j])
        l_V2n.append(data["a2"][j])
    cor12 = pearsonr(l_V1fn, l_V2n)[0]
    l_cor.append(cor12)

plt.subplot(232)
time = range(0, len(l_cor))
plt.plot(time, l_cor, '#20B2AA')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('相关系数')
plt.title('两个电芯电压的相关系数,计算相关系数的滑动窗口设为5')

# 加了白噪声后的图示
mean = 0
std = 0.1
samples1 = np.random.normal(mean, std, size = len(data['a1']))
data["a11"] = data["a1"] + samples1
samples2 = np.random.normal(mean, std, size = len(data['a1']))
data["a12"] = data["a2"] + samples2
time = range(0, len(data["a1"]))
plt.subplot(233)
plt.plot(time, data["a11"], '#20B2AA', label = '电芯1的电压+白噪声')
plt.plot(time, data["a12"], '#F08080', label = '电芯2的电压+白噪声')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('mv')
plt.title('加了白噪声后两个电芯电压图示')

# 白噪声后相关系数
w = 5
l_cor = []
for i in range(len(data['a11']) - w):
    l_V1fn = []
    l_V2n = []
    for j in range(i, i + w, 1):
        l_V1fn.append(data["a11"][j])
        l_V2n.append(data["a12"][j])
    cor12 = pearsonr(l_V1fn, l_V2n)[0]
    l_cor.append(cor12)
plt.subplot(234)
time = range(0, len(l_cor))
plt.plot(time, l_cor, '#20B2AA')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('相关系数')
plt.title('加了白噪声后两个电芯电压的相关系数,计算相关系数的滑动窗口设为5')

# 构造异常
data["a12"][2] = data["a12"][2] - 30
time = range(0, len(data["a11"]))
plt.subplot(235)
plt.plot(time, data["a11"], '#20B2AA', label = 'u1+白噪声')
plt.plot(time, data["a12"], '#F08080', label = 'u2+白噪声+异常')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('mv')
plt.title('加了白噪声后电芯电压和加了白噪声加了异常后电芯电压图示')

# 加了白噪声后u1和加了白噪声加了异常u2图示相关系数
w = 5
l_cor = []
for i in range(len(data['a11']) - w):
    l_V1fn = []
    l_V2n = []
    for j in range(i, i + w, 1):
        l_V1fn.append(data["a11"][j])
        l_V2n.append(data["a12"][j])
    cor12 = pearsonr(l_V1fn, l_V2n)[0]
    l_cor.append(cor12)
plt.subplot(236)
time = range(0, len(l_cor))
plt.plot(time, l_cor, '#20B2AA')
plt.legend(loc = 1)
plt.xlabel('time')
plt.ylabel('相关系数')
plt.title('加了白噪声后的u1和加了白噪声加了异常后u2的相关系数')

plt.show()

调试脚本

"""
调试过程
"""
import numpy as np
import pandas as pd
from scipy.stats import pearsonr
import matplotlib.pyplot as plt

# 正常显示中文和负号
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用黑体显示中文
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号


def graph(u1, u2, type):
    if type == 1:
        time = range(0, len(u1))
        plt.plot(time, u1, '#20B2AA', label = 'u1')
        plt.plot(time, u2, '#F08080', label = 'u2')
        plt.legend(loc = 1)
        plt.xlabel('time')
        plt.ylabel('mv')
        plt.title('u1和u2图示')

    elif type == 2:
        time = range(0, len(u2))
        plt.plot(time, u2, '#20B2AA')
        plt.legend(loc = 1)
        plt.xlabel('time')
        plt.ylabel('相关系数')
        plt.title('u1和u2的相关系数')
    elif type == 3:
        time = range(0, len(u1))
        plt.plot(time, u1, '#20B2AA', label = 'u1+白噪声')
        plt.plot(time, u2, '#F08080', label = 'u2+白噪声')
        plt.legend(loc = 1)
        plt.xlabel('time')
        plt.ylabel('mv')
        plt.title('加了白噪声后u1和u2图示')
    elif type == 4:
        time = range(0, len(u1))
        plt.plot(time, u1, '#20B2AA', label = 'u1+白噪声')
        plt.plot(time, u2, '#F08080', label = 'u2+白噪声+异常')
        plt.legend(loc = 1)
        plt.xlabel('time')
        plt.ylabel('mv')
        plt.title('加了白噪声后u1和加了白噪声加了异常u2图示')
    elif type == 5:
        time = range(0, len(u2))
        plt.plot(time, u2, '#20B2AA')
        plt.legend(loc = 1)
        plt.xlabel('time')
        plt.ylabel('相关系数')
        plt.title('加了白噪声后的u1和加了白噪声加了异常后u2的相关系数')
    plt.show()


def corre(u1, u2, type):
    w = 5
    l_cor = []
    for i in range(len(u1) - w):
        l_V1fn = []
        l_V2n = []
        for j in range(i, i + w, 1):
            l_V1fn.append(u1[j])
            l_V2n.append(u2[j])
        cor12 = pearsonr(l_V1fn, l_V2n)[0]
        l_cor.append(cor12)
    if type == 1:
        graph(1, l_cor, 2)
    else:
        graph(1, l_cor, 5)


# corre ()

def raw_data():
    """ 原始数据图及原始数据相关系数
    :return:
    """
    data = pd.read_csv('data/raw.csv')
    data = data.rename(columns = {'u1': 'a1', 'u2': 'a2'})
    data = data.dropna()
    x_columns = [x for x in data.columns if x in ['a1', 'a2']]
    data = data[x_columns]
    graph(data["a1"], data["a2"], 1)
    corre(data["a1"], data["a2"], 1)
    data.to_csv("data/raw1.csv")


# raw_data()

def white_Noises():
    """对内短路电压数据,3列正常电压数据添加0均值1方差的白噪声
    :return:
    """
    data = pd.read_csv("data/raw1.csv")
    mean = 0
    std = 0.1
    num_samples = len(data['a1'])
    samples1 = np.random.normal(mean, std, size = num_samples)
    data["a11"] = data["a1"] + samples1
    samples2 = np.random.normal(mean, std, size = num_samples)
    data["a12"] = data["a2"] + samples2
    # data.to_csv ("data/White.csv")
    graph(data["a11"], data["a12"], 3)


# white_Noises ()


def buildData_InternalShortcircuit():
    """构造内短路数据v1f
    :return:
    """
    data = pd.read_csv("data/White.csv")
    data["a12"][2] = data["a12"][2] - 30
    graph(data["a11"], data["a12"], 4)
    data.to_csv("data/dataISC.csv")
    corre(data["a11"], data["a12"], 2)
# buildData_InternalShortcircuit()

你可能感兴趣的:(电池文献阅读,能源,电池一致性)