我的编程空间,编程开发者的网络收藏夹
学习永远不晚

锂离子电池健康状态估计简介(一):基于Python的数据处理计算SOH,RUL,CCCT,CVCT

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

锂离子电池健康状态估计简介(一):基于Python的数据处理计算SOH,RUL,CCCT,CVCT

锂离子电池无论是在军用还是民用领域都得到了广泛的应用,在锂离子电池健康评估中主要关注的参数有SOH和RUL。准确对其进行健康状态(Stateof Health, SOH)评估及剩余使用寿命(Remaning Useful Life, RUL)预测对于提高电池安全性与使用寿命具有重要意义
后续源码仓库:https://github.com/Wuito/Estimation-of-residual-life-of-particle-filter-lithium-ion-battery

电池SOH

锂离子电池健康状态基本定义为:选择适当的放电条件下,对其进行充电,直到锂电池充满结束。然后再选择一定倍率对其进行放电,直到满足放电截止电压结束,此时电池的容量与其标称容量的比值。即为锂离子电池的健康状态,通常运用SOH表示电池的健康状态。锂离子电池的存储能力与快速充放电能力均会随着老化而不断下降,而SOH正是用于评价锂电池老化程度的量化指标,锂离子电池健康状态是表征锂电池存储电能的能力,和电池老化评价指标。锂电池的健康状态定义方式有多种,分别为基于容量定义的SOH、基于内阻定义的SOH、基于功率定义的SOH、基于自放电定义的SOH。

电池RUL

锂离子电池寿命是个广义的概念,它还可以具体分为很多种,如储存寿命,使用寿命和剩余循环寿命。锂离子电池的存储寿命表示锂离子电池在静态或非运行条件下退化到一定程度所需的时间。锂离子电池的RUL是指在某种充放电条件下,锂离子电池的当前可用容量衰减退化到某一规定的失效阈值所需要经历的循环周期数量。RUL预测是一个基于锂离子电池历史数据运用一定的数学手段对其残值寿命进行预测计算的过程。随着锂离子电池在各领域上的广泛应用,锂离子电池RUL预测技术得到了广泛的关注和研究。

常用锂离子电池寿命经验模型的数学表达式

在这里插入图片描述

锂离子电池结构

锂离子电池主要由以下几个部分组成:
(1)正极活性材料
正极活性材料是锂离子电池的核心组成部分,其决定了锂电池工作时锂离子的空间和扩散路径,由此决定了锂离子电池的基本性能。目前业内常见的正极材料有磷酸铁锂、锰酸锂、钴酸锂、以及由多种材料构成的三元锂,如镍钴锰、镍钴铝。
(2)负极活性材料
负极活性材料是以薄层状附着在铜基上的糊状物质,通常由碳材料、黏合材料以及有机溶剂混合制成。
(3)隔膜
隔膜是一种经过特殊工艺处理的高分子薄膜,通常使用聚丙烯或聚乙烯材料的微多孔膜制成,用于在正极和负极之间作为锂离子的移动通道,同时能够防止电子通过。
(4)电解液
电解液主要负责在充放电过程中锂离子的传送,通常为混有有机溶剂和添加剂的锂盐电解液。电解液需要能够在电池工作过程时的氧化还原反应中保持化学性能稳定。

基本性能参数

(1)电池电压
电动势:电池正极与负极之间的电位差。
工作电压(端电压):在电池两端接上负载后,在放电过程中显示的电压。开路电压:指电池处于开路状态,即电池不放电时电池正负极的电位差。
额定电压:指电池厂家规定的电池电压,是电池出厂的重要性能参数,电池正常工作时,电池工作电压应该长时间在电池额定电压附近变化。
终止电压:电池在一定标准所规定的充放电条件下对电池进行充放电,当电池不宜再继续充放电时,此时的工作电压称为终止电压。当电池的电压下降到终止电压后,再继续使用,因受到化学“活性物质”性能的限制,“活性物质”会遭到破坏。
(2)电池容量
理论容量:是假设活性物质全部参加电池的反应所给出的电量。它是根据活性物质的量按照法拉第定律计算求得的。实际电池放出的容量只是理论容量的一部分。
实际容量:是指在一定条件下,电池实际放出的电量,等于放电电流与放电时间的乘积。
剩余容量:指电池经过一段时间的放电之后电池还剩余多少电量,数值上等于电池在当前状态下以标准环境温度和标准放电电流放电至最小截止电压时释放的电量。
额定容量:是指设计和制造电池时,规定或保证电池在一定的放电条件下应该放出的最低限度的电量。
(3)电池自放电率
电池自放电率衡量了电池在静置状态时,对其自身电量的保持能力。通常电池自放电率越小越好,其大小与环境温度、电池材料和加工方式密切相关。一般而言,在电池适宜的温度范围内,环境温度越低,自放电率也越低,同时也应注意,温度过低或过高均有可能造成电池损坏而无法正常投入使用。
(4)放电深度:
放电深度是放电程度的一种度量,常用 DOD(depth of discharge)表示,它体现参与反应的活性材料所占的比例。
(5)电池内阻:
该指标是指电流通过电池内部时受到的阻力,包括欧姆内阻和极化内阻两部分。由于电池的内阻作用,使得电池在放电时端电压低于电动势和开路电压,在充电时端电高于电动势和开路电压。

锂离子电池的充电特征

电池经过长时间的放电后,需要对电池再次充电才能投入使用。电池过充电对电池性能影响很大,过度充电会对电池造成损坏,缩短使用寿命,因此,选择安全高效的电池充电方式对保护电池至关重要。目前,常用的电池充电方式有恒流充电法、恒压充电法、恒流恒压充电法(Constant Current-Constant Voltage ,CC-CV)以及脉冲式充电法。
恒流充电法是指在整个充电过程中,保持电池充电回路中电流保持不变的充电方法。通常可以利用调整电源输出电压或改变充电回路阻值的方式使得充电电流不变。该方法较为容易实施,充电时间短,但电池到了充电后期,对电流的接受能力逐渐下降,会造成了能量的浪费。
恒压充电法是在整个充电过程中,让电源输出电压保持不变的充电方法。使用该方法对电池进行充电时,充电回路中的电流会逐渐减小,从而减少能量浪费及防止电池过充电,但在充电初期,充电回路中的电流太大,会减少电池工作时间,电流过大时还有可能导致电池报废。
恒流恒压充电法是指电池先以恒流方式充电,使得电池电压逐步升高,当电池电压达到充电截止电压时,再将恒流充电方式转换为恒压充电方式。恒流恒压充电模式是普通锂离子电池最常用的充电方式,该方法能够快速充电,有效防止电池过充电,合理利用能量,延长电池的使用寿命。
在这里插入图片描述上面图里的数据是从马里兰大学公开电池数据集得到的CS2电池组数据。马里兰大学寿命实验室

锂离子SOH定义

1)基于容量定义的健康状态
采用当前锂电池的额定容量比上初始是锂电池的容量,再乘上100%,即为锂离子电池的容量健康度。
在这里插入图片描述
式中,〖SOH〗_c为电池容量健康度,C_t为电池在t时刻的额定容量,C_0为电池的初始额定容量。
2)基于内阻定义的健康状态
在这里插入图片描述
式中,〖SOH〗_R为电池内阻(通常指电池的欧姆内阻)健康度,R_end为电池寿命终止时刻的内阻,R(t)为电池在t时刻的内阻,R_0为电池的初始内阻。
3)基于功率定义的健康状态
在这里插入图片描述
式中,〖SOH〗_P为电池功率健康度,P(0)锂离子电池的最开始的功率或铭牌功率(W),P(t)第t次充电后可供给的方均根(有效)功率(W)。
4)基于自放电定义的健康状态
在这里插入图片描述
式中,〖SOH〗_Rd为电池自放电健康度,R_d (end)为电池寿命终止时刻的自放电电阻,R_d (t)为采样t时刻的电池自放电电阻,R_d (0)代表电池在初始时刻的自放电电阻。

数据预处理代码

首先要明白马里兰大学数据集的结构:
在这里插入图片描述
数据是以xlsx表格的格式存储的
在这里插入图片描述
包含的数据主要有这几个类别,其中有用得比较多的就是电流电压和时间这几项。
这里要特别注意:充电和放电的数据是连续记录在表里的,要注意区分。NASA的数据则是充电和放电分开的。

===================================

废话不多说,我们上干货,具体代码作用看注释,写的比较清楚了。编程细节参考浙大的大佬python的数据处理,感谢大佬,让我们减轻了很多工作量。代码里SOH是用上面SOH定义的第一种计算方法得到的。

# 程序功能: 读取一种电池的数据解析计算#           SOH,CCCT,CVCT,resistance,capacity数据并存储为npy文件# From: SWUST IPC14 Daiimport numpy as npimport matplotlib.pyplot as pltimport pandas as pdimport globBattery_name = 'CS2_36' # 加载数据dir_path = 'dataset/'# 除去数据异常的较大值和较小值点def drop_outlier(array, count, bins):    index = []    range_ = np.arange(1, count, bins)  # 返回一个有终点和起点的固定步长的排列,起始为1,终值为count,步长为bins    for i in range_[:-1]:        array_lim = array[i:i+bins] # 从array中截取一个从i到i+bins的数组段        sigma = np.std(array_lim)   # 计算该数组段的全局标准差        mean = np.mean(array_lim)   # 计算数组段的平均值        th_max,th_min = mean + sigma*2, mean - sigma*2  # 以方差和平均值作为上下限取值        idx = np.where((array_lim < th_max) & (array_lim > th_min))        idx = idx[0] + i    # 将当前的idx值+i后赋值到实际数组的角标        index.extend(list(idx))     # 在列尾增加一个list    return np.array(index)Battery = {}print('Load the data directory structure ' + Battery_name + ' ...')path = glob.glob(dir_path + Battery_name + '/*.xlsx')dates = []for p in path:    df = pd.read_excel(p, sheet_name=1)    print('Load file sequence ' + str(p) + ' ...')    dates.append(df['Date_Time'][0])idx = np.argsort(dates)path_sorted = np.array(path)[idx]print("The file structure was read successfully. There are {} files in total".format(len(path_sorted)))count = 0discharge_capacities = []health_indicator = []internal_resistance = []CCCT = []CVCT = []for p in path_sorted:    df = pd.read_excel(p, sheet_name=1)    print('Load and Analytical data' + str(p) + ' ...')    cycles = list(set(df['Cycle_Index']))             # 按照每个循环次数读取    # 在单个表中按照Cycle_Index(实验次数)逐次取出每次的数据进行处理    for c in cycles:        df_lim = df[df['Cycle_Index'] == c]        # Charging        df_c = df_lim[(df_lim['Step_Index'] == 2) | (df_lim['Step_Index'] == 4)]    # 第2步和第4步充电        c_v = df_c['Voltage(V)']        # 电压        c_c = df_c['Current(A)']        # 实时电流值        c_t = df_c['Test_Time(s)']      # 记录的测试时间        # CC or CV        df_cc = df_lim[df_lim['Step_Index'] == 2]   # 第2步恒流充电        df_cv = df_lim[df_lim['Step_Index'] == 4]   # 第4步恒压充电        CCCT.append(np.max(df_cc['Test_Time(s)']) - np.min(df_cc['Test_Time(s)']))      # 恒定电流充电时间        CVCT.append(np.max(df_cv['Test_Time(s)']) - np.min(df_cv['Test_Time(s)']))      # 恒定电压充电时间        # Discharging        df_d = df_lim[df_lim['Step_Index'] == 7]    # 第7步时放电        d_v = df_d['Voltage(V)']        d_c = df_d['Current(A)']        d_t = df_d['Test_Time(s)']               # 步长时间        d_im = df_d['Internal_Resistance(Ohm)']  # 内阻        if len(list(d_c)) != 0:            time_diff = np.diff(list(d_t))  # 求时间差,np.diff:计算数组中n[a]-n[a-1]            d_c = np.array(list(d_c))[1:]   # 读出电流值            discharge_capacity = time_diff * d_c / 3600  # 计算安培时(Ah)Q = A*h            # print("discharge_capacity shape[0] is:{}".format(discharge_capacity.shape[0]))            # 将所有第7步中的电池放电容量求和并正定            # discharge_capacity_sum = np.sum(discharge_capacity)            # discharge_capacities.append(-1 * discharge_capacity_sum)            discharge_capacity = [np.sum(discharge_capacity[:n]) for n in range(discharge_capacity.shape[0])]            discharge_capacities.append(-1 * discharge_capacity[-1])            dec = np.abs(np.array(d_v) - 3.8)[1:]       # np.abs:求绝对值            # np.argmin:将数组展平返回最小值的下标            start = np.array(discharge_capacity)[np.argmin(dec)]    # 取出当电压最接近3.8V时电池的放电量            dec = np.abs(np.array(d_v) - 3.4)[1:]            end = np.array(discharge_capacity)[np.argmin(dec)]  # 取出电压最接近3.4V时的电池放电量            health_indicator.append((-1 * (end - start)))     # 这里定义的SOH是电池从3.8V放电到3.4V的电池容量            internal_resistance.append(np.mean(np.array(d_im)))     # 求放电阶段电池的的内阻平均值            count += 1health_indicator = health_indicator/np.max(health_indicator)    # 计算SOHdischarge_capacities = np.array(discharge_capacities)SOC = discharge_capacities/1.1                  # CS2电池的标准容量为1.1Ahhealth_indicator = np.array(health_indicator)internal_resistance = np.array(internal_resistance)CCCT = np.array(CCCT)CVCT = np.array(CVCT)idx = drop_outlier(discharge_capacities, count, 40)     # 以所有轮次中放电步骤的放电容量值为原始数据,以40为步长,对数据进行清洗处理df_result = pd.DataFrame({'cycle': np.linspace(1, idx.shape[0], idx.shape[0]),  # 步数                          'capacity': SOC[idx],            # 容量                          'SoH': health_indicator[idx],     # SOH                          'resistance': internal_resistance[idx],   # 电池内阻                          'CCCT': CCCT[idx],                          'CVCT': CVCT[idx]})Battery[Battery_name] = df_resultnp.save(dir_path + Battery_name, Battery)print("Data parsing succeeded. The .npy file was saved to {}".format(dir_path + Battery_name + '.npy'))

在这里插入图片描述

来源地址:https://blog.csdn.net/weixin_47407066/article/details/127405618

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

锂离子电池健康状态估计简介(一):基于Python的数据处理计算SOH,RUL,CCCT,CVCT

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录