资讯动态

虚拟电厂多时间尺度调度中的储能衰减建模与Matlab复现

发布时间:2026/10/21 19:13:12 来源:尧图企业网站定制
当风电光伏装机占比一路走高之后电网调度里出现了一个此前没这么尖锐的矛盾系统要足够的灵活性来应对出力波动可灵活性资产里最顺手的储能每动作一次都在消耗寿命。之前我接到一篇 SCI 论文的复现任务标题正好把这两个问题放在一起高比例可再生能源并网如何平衡灵活性与储能成本用虚拟电厂做多时间尺度调度再给储能加一个衰减建模。这个题目第一眼看不算复杂真正把公式转成 Matlab 代码的时候才体会到最值得做的是储能衰减和调度模型的耦合。这篇帖子写给谁打算做论文复现、拿代码对比算法、或者想搞明白虚拟电厂调度怎么落地的人。我会把模型设计逻辑、衰减建模的常见做法和代码改进点、Matlab 求解路径、以及我在复现时踩过的坑都过一遍。代码片段给的是能直接跑通思路的示意版本参数则全部可调方便你对着自己的算例改。1. 为什么要把“灵活性与储能成本”绑在一起建模1.1 高比例可再生能源并网后的“灵活性”到底是什么先把“灵活性”这个词说透。电力系统运行本质上是实时平衡发用两侧每一秒钟都要相等。传统火电时代发电机组的出力曲线相对可控调度员按负荷预测安排开机和出力就行。新能源比例上来之后系统净负荷变成了“负荷减去风光出力”这条曲线比原负荷曲线陡得多、抖得多一片云飘过来光伏可能几分钟内掉一半傍晚风电爬坡和负荷晚高峰叠在一起净负荷可以在几个小时内跳变几十兆瓦。灵活性指的就是系统在不改变长期装机结构的前提下在给定时间尺度内调整出力的能力。工程上通常拆成四个指标上调爬坡、下调爬坡、上调备用、下调备用。举个例子未来15分钟如果光伏突然降低5MW那么系统里必须有某个资源能在15分钟内多发出5MW这就是上调灵活性反过来如果风电大发导致消纳困难系统要能在15分钟内少消纳或者多充电5MW这就是下调灵活性。储能之所以成为高比例可再生能源系统的核心灵活性资源是因为它正反向都能调响应速度以毫秒到分钟计不依赖一次能源供应。但它有一个致命短板容量有限寿命有限。每充放一个循环电池内部的化学活性物质就在缓慢减少SOH健康状态会从100%往下走。如果我们只把灵活性当作“能不能爬坡”来建模那储能怎么用都是最优的一旦把寿命损耗换算成钱储能就不是怎么用都划算了。灵活性越强、储能动作越猛电池成本越高这就是标题里说的“平衡”。1.2 储能衰减最容易被调度模型“做假账”的成本我自己在做复现时发现很多论文的储能模型非常简单SOC有上下限充放电功率有约束效率给定完事。这种模型忽略了两个关键事实第一储能充放电的深度和次数直接影响寿命第二电池可用容量会随着使用天数增加而逐年下降不是恒定参数。从电化学角度看电池老化主要来自负极SEI膜持续生长、锂离子损失、电解液分解这几个过程影响因素包括温度、充放电倍率、放电深度DOD和SOC工作窗口。工程上处理这些物理过程时不可能在优化模型里求解电化学偏微分方程所以一般用两类近似一类是等效循环寿命法另一类是经验老化模型。等效循环寿命法很直观。假设某个型号电池在100%放电深度下循环次数是3000次在50%放电深度下是6000次那么一次100%深度循环消耗的寿命资产就是1/3000一次50%深度循环消耗1/6000。调度模型知道每次充放电的深度就能把寿命损耗折算成成本。经验老化模型则更接近实验曲线常用形式是容量损失率与累积安时吞吐量的指数关系。实际复现中这种模型可以直接查数据表也可以拟合成分段线性函数嵌入优化求解器。难点在于参数标定不同厂家、不同材料体系的电池差异很大论文一般会给出一个实验范围内的拟合结果复现时需要把论文里的曲线重新读出来或者先用公开的典型参数跑通框架再替换成自己的实验数据。如果调度目标里没有衰减成本优化器一定会做出一种很“激进”的决策风光大发时拼命充电负荷高峰时拼命放电因为电费差的套利收益是正的而电池损耗是零成本。这种结果画出来曲线很好看弃电率很低但储能实际运行一两年就废了。说白了不看衰减成本等于给储能做假账把设备损耗转嫁给后续年份。1.3 多时间尺度调度把不同时间颗粒度的矛盾分层解决为什么单靠一个日前优化不够因为风光预测误差会随着预测时长的缩短而减小。提前24小时预测光伏误差可能到20%以上提前1小时预测误差可能只有5%左右。如果只做一个日前调度为了保证全天平衡模型不得不预留大量备用容量灵活性成本被高估如果只做实时调度没有前瞻性储能的充放电策略会变得短视无法为晚高峰提前腾出容量。多时间尺度调度就是把这层矛盾分层解决。典型结构是三层日前调度、日内滚动、实时控制。日前调度以1小时为间隔基于未来24小时的风光负荷预测确定机组启停、储能充放电计划、备用容量安排时间颗粒粗但能保证全天能量平衡和电量成本最优化。日内滚动调度通常每15分钟或5分钟执行一次预测时域缩短到未来2到4小时模型滚动刷新用来跟踪日前计划并修正预测偏差。实时控制则在秒级到分钟级响应处理实际功率与计划之间的偏差通常由自动发电控制或者储能本地控制器完成。储能衰减在三个尺度上都有体现。日前尺度关注全天循环次数和充放电深度日内尺度关注每一次滚动窗口内的动作强度实时尺度则涉及高频小幅充放是否要计入寿命损耗。我把衰减成本同时放进日前和日内目标函数之后模型会自动在“多用储能换灵活性”和“少充放保寿命”之间权衡而不是用一种拍脑袋的固定策略。2. 虚拟电厂如何把分散资源装进一个优化框架2.1 资源侧画像风光储荷缺一不可虚拟电厂和传统发电厂最大的区别是它不依赖一个物理集中式的电站而是把分布式光伏、风电、储能、柔性负荷、小型机组聚合起来对外像一个电厂一样参与调度和交易。复现代码时第一步就是把每类资源的数学模型定义清楚。不可控电源方面分布式光伏和风电是出力主体它们的预测出力曲线作为输入数据实际出力与预测的偏差在日内和实时阶段处理。可控电源方面可以布置一台5MW左右的小型燃气机组作为可靠备用特点是爬坡快、成本高适合在极端场景下兜底如果算例里没有也可以设置成外购电接口。储能方面容量、最大充放电功率、效率、SOC上下限、初始SOH这些参数都要单独配置。柔性负荷方面可削减负荷和可转移负荷一起建模比如空调、充电桩、一部分工业负荷它们可以通过补偿成本调用是灵活性资源的补充。聚合方式在Matlab代码里通常体现为把所有设备的参数导入同一个结构体比如params.ess.Ecap、params.pv.Pmax这样便于后续统一建模。模型内部不需要区分谁是业主只要保证节点功率平衡并在目标函数里给不同资源设置不同的边际成本。2.2 日前-日内-实时三层架构怎么搭我复现时的做法是把三层调度拆成三个独立函数数据流单向传递日前结果传给日内日内结果传给实时这样调试起来很清楚。| 阶段 | 时间间隔 | 预测时域 | 决策重点 | 执行频率 | | 日前 | 1h | 24h | 机组启停、储能全天计划、备用容量 | 每天一次 | | 日内 | 5-15min | 2-4h | 滚动修正、弃电调整、储能充放电 | 每15分钟 | | 实时 | 1-5min | 5-15min | 功率跟踪、调频响应 | 秒级-分钟级 |日前模型的核心是能量平衡和备用约束目标函数以运行成本为主。日内模型引入了滚动优化思想每15分钟根据最新的风光实测和超短期预测对日前计划做修正。这里有个容易被忽视的细节日前模型给出的是“计划值”日内模型不必照单全收而是以跟踪偏差惩罚为软约束让模型在成本和跟踪精度之间自行取舍。实时控制层则简单一些用比例积分或者模型预测控制把日内计划与实际功率的偏差降到最低。三层架构的价值在于误差在不同层级被逐级消化而不是全部压给一次优化。日前算错的部分日内还能救日内没救回来的部分实时再调。储能衰减成本在每一层都会被重复评估所以我在日内模型里也加了衰减成本项避免滚动窗口内的储能被频繁深度充放。2.3 灵活性平衡如何量化并进入目标函数灵活性不能只是一个概念进入模型必须变成可计算的量。我在代码里把它拆成两类一类是备用约束一类是灵活性收益或惩罚。备用约束的写法不复杂。假设需要上调备用那么任意时刻t可控机组剩余可增出力加上储能可放电功率之和必须大于等于风光预测误差的某个置信区间。下调备用同理要求可控机组剩余可减出力加上储能可充电功率之和足够应对风光超发。这个约束写成Matlab代码就是一组线性不等式Yalmip处理起来很轻松。但只满足备用约束还不够因为模型可能会选择“刚刚好”的备用容量而实际上更高比例的灵活性在未来能带来更大收益。所以我还建议在目标函数中加入灵活性效益项。简单做法是给上调备用和下调备用赋予一个价值系数让优化器权衡“多留一份灵活性”与“多花一份成本”孰轻孰重。更精细的做法是引入灵活性不足惩罚如果某个时段预测误差超过了可用备用系统需要被迫切负荷或者弃电对应一个比较高的惩罚成本。这样一来灵活性和成本就不再是并列的两个目标而是统一在同一个经济目标里。3. 储能衰减建模复现时最考验功夫的部分3.1 先搞清楚老化的物理来源和工程近似我在1.2里简单提过储能老化不是单一机制而是多种电化学副反应叠加的结果。负极端SEI膜会持续增厚消耗锂离子高温下电解液分解加快大倍率充电容易在负极表面析出锂金属深度放电会让正极结构不稳定。实际调度模型不可能追踪这么多机理所以工程上普遍把老化折算成寿命损耗。最常用也最好理解的是循环次数-放电深度曲线。厂商标定的数据一般写成表格100% DOD下N次循环80% DOD下N2次循环50% DOD下N3次循环。调度模型里我们把一次充放电循环的寿命损耗定义为1/N(DOD)。如果某天储能完成了若干次不同深度的循环总寿命损耗就是每个循环损耗的累加。更准确一点的做法是Ah吞吐量经验模型。它认为容量损失率与累积安时吞吐量呈幂函数关系同时受温度影响。这里不展开具体参数因为不同论文给出的拟合值差异很大复现时一定要以目标文献的曲线为准。如果文献给的是曲线图可以用数据提取工具把点读出来再拟合成分段线性函数这样就能无缝嵌入优化问题。3.2 把衰减成本写进优化目标线性化是关键在Matlab里用Yalmip和Gurobi求解时最怕引入非线性项因为这会让问题从MILP变成MINLP求解时间暴涨。衰减成本天然含绝对值储能净功率为正表示放电为负表示充电值的大小都造成寿命损耗。解决办法是把净功率拆成两个非负变量充电功率Pch和放电功率Pdis然后给它们加一个“不能同时为正”的约束通常用两个二进制变量实现。目标函数里的衰减项可以写成C_deg lambda_deg * sum(Pch Pdis) * dt;lambda_deg是边际老化成本系数单位是元/kWh含义是每吞吐一度电平均消耗多少电池寿命对应的经济损失。它的数值可以从循环寿命曲线反推电池系统每kWh容量成本除以总可吞吐电量再乘以效率修正系数。比如电池容量成本为1500元/kWh总可吞吐电量按5000次*1kWh计那么平均每吞吐1kWh的老化成本大约是0.3元。这个值只是示意不同参数差很多但要的就是这个量级。如果嫌弃单一常系数不够精细可以按SOC区间分段标定老化系数。低SOC区间和大DOD条件下的老化成本更高高SOC浅充浅放更低。将SOC分成若干段每一段对应一个线性老化项整体仍然是线性模型。我在复现中试过分层段数越多结果越接近半经验模型但增加段数会引入更多整数变量求解时间变长。一般三段就够了。3.3 SOH闭环不是算完一天就结束这是我复现中最想强调的一点。仅仅把衰减成本加进目标函数还只是一个“开环”的调度储能容量当成常数用算出来的SOH下降也只是事后统计不会反馈到后续调度里。实际物理过程是随着容量衰减储能的可用充放电功率和能量都下降如果第二年还按第一年的容量做调度计划必然失真。所以我在代码里加了一个SOH闭环循环。外层按天迭代每天的调度完成后根据当天储能实际充放电的深度和次数计算寿命损耗更新SOH再将新的容量和功率限值代入第二天的调度模型。for day 1:365 params.ess.Ecap params.ess.Ecap0 * soh(day); params.ess.Pmax params.ess.Pmax0 * soh(day); [plan, result] run_dispatch(params, forecast(:, :, day)); loss cal_degradation(result.ess_profile); soh(day 1) max(soh_min, soh(day) - loss); end这个闭环会让结果发生明显变化没有SOH反馈时储能容量下降带来的影响被忽略全年成本被低估后半段调度计划偏乐观加入闭环后模型会提前一些放慢储能吞吐节奏用适度的弃电换取更长的寿命。这也正是标题里“平衡”二字的真正含义。4. Matlab代码复现路径从工具箱配置到算例出图4.1 环境与求解器配置复现这套模型我建议的软件组合是Matlab Yalmip Gurobi。Yalmip是一个建模层负责把优化问题描述清楚然后调用底层的求解器。Gurobi是高性能商用求解器对MILP问题求解速度非常快学术许可申请也方便如果暂时没有许可也可以用Cbc或者默认求解器先跑通小算例。第一次配置完Yalmip后直接在命令行输入yalmiptest看到所有求解器状态OK就说明环境没问题。如果只想验证衰减建模逻辑可以先把问题全部设成线性用Gurobi跑验证完再考虑加整数变量。别一开始就上多时段MILP那样报错都不好定位。4.2 算例参数设置不要照抄论文要能自洽复现论文代码最容易犯的错误是参数取值随意。我建议做一套自洽的参数哪怕数值不跟文献完全一致只要逻辑成立结果趋势就是可信的。下面是我用的模拟项目X的默认参数你可以直接替换成自己的数据。| 对象 | 参数 | 数值 | | 光伏 | 装机容量 | 40 MW | | 风电 | 装机容量 | 30 MW | | 负荷 | 峰值 | 60 MW | | 储能 | 容量 / 功率 | 20 MWh / 5 MW | | 储能 | SOC初值 / 下限 / 上限 | 0.5 / 0.1 / 0.9 | | 储能 | 初始SOH | 100% | | 储能 | 老化成本系数 | 0.3 元/kWh示意 | | 外购电 | 电价区间 | 0.4-1.1 元/kWh | | 弃风弃光 | 惩罚单价 | 1.0 元/kWh |场景设计建议至少三种平稳天气、大风多云天气、极端波动天气。平稳天气主要看正常调度逻辑大风多云天气能考验日内滚动修正能力极端波动天气则用来检验备用约束和储能衰减成本的取舍。我个人习惯把场景数据存成.mat文件主程序只负责读文件和跑模型后处理再单独写绘图脚本。4.3 核心代码路径与运行顺序工程化程度好一点的复现代码目录结构大概长这样main_VPP.m set_params.m load_scenario.m day_ahead_model.m intraday_model.m storage_degradation.m plot_results.m主程序先配参数再读场景然后进入日循环。每一日的调度结果是结构体包含储能充放电曲线、SOC曲线、备用利用率和各项成本。先把基础平台跑通再逐步加衰减建模和SOH反馈这是最稳的复现顺序。日前模型的核心Yalmip代码片段类似下面这样变量、约束、目标一目了然% 日前调度模型示意 T 24; Pch sdpvar(T, 1); Pdis sdpvar(T, 1); SOC sdpvar(T, 1); u_ch binvar(T, 1); u_dis binvar(T, 1); C []; % SOC初值与迭代 C [C, SOC(1) 0.5 * params.ess.Ecap]; C [C, SOC(2:T) SOC(1:T-1) (params.ess.eta_ch * Pch(1:T-1) - Pdis(1:T-1) / params.ess.eta_dis) * 1 / params.ess.Ecap]; % 充放电互斥 C [C, Pch 0, Pch params.ess.Pmax * u_ch]; C [C, Pdis 0, Pdis params.ess.Pmax * u_dis]; C [C, u_ch u_dis 1]; % SOC限值 C [C, 0.1 * params.ess.Ecap SOC 0.9 * params.ess.Ecap]; % 节点功率平衡等约束略 objective sum(c_buy .* Pbuy) sum(price_curtail .* Pcurtail) lambda_deg * sum(Pch Pdis); ops sdpsettings(solver, gurobi, verbose, 2, gurobi.TimeLimit, 300); optimize(C, objective, ops);求解完成后直接value(SOC)就能取到SOC曲线value(Pdis)取放电功率曲线。日内模型结构类似只是预测时域缩短每15分钟滚动一次目标函数里额外加了跟踪日前计划的偏差惩罚。5. 复现中踩过的坑收益、振荡和结果怎么读5.1 衰减系数过小或过大结果都会失真我第一次跑模型把老化成本系数lambda_deg设得很低结果储能几乎全程满充满放弃电率很低算出来的运行成本好像很优秀。但把SOH反馈打开看一年之后SOH掉到80%第二年模型直接可用容量大幅缩水前期的“优秀”全是透支未来换来的。反过来把系数调高到每kWh 2元储能就基本不动作了所有灵活性都靠天然气机组和外购电扛系统成本反而升高储能成了摆设。这说明衰减系数不能拍脑袋定要做敏感性分析让系数从0开始逐渐增大画出储能年吞吐量、弃电率和系统总成本三组曲线在吞吐量开始快速下降的位置附近取拐点值。这个操作虽然基础但对最终结论的可信度提升非常大。5.2 多时间尺度模型的收敛与求解时间问题另一个常见问题是求解时间失控。日内模型每15分钟执行一次如果有24个时段还带二进制变量一天下来要跑近百次优化任何一次超时都会拖慢整体仿真。我处理这类问题的经验有三条。第一尽量让约束线性化。衰减成本不用绝对值而是拆成Pch和Pdis两个变量再配合互斥约束而不是直接写abs(Pess)更不要用一个二进制变量控制充放方向后就写Pess * (1 - u)之类的乘积项。第二减少日内模型的预测时域没必要滚动24小时4小时甚至2小时窗口足够覆盖超短期预测的有效信息。第三可以先跑连续松弛版本把二进制变量放开检验初值和约束是否合理确认模型不病态再切回整数版本跑正式结果。按照这三条我的单日仿真从十几分钟压缩到三分钟左右结论不发生变化。5.3 不同衰减模型下的调度差异结果对比要看什么复现完成后我做了三组对比无衰减模型、线性吞吐量衰减模型、半经验衰减模型。同一场景下结果趋势如下表所示具体数值会随参数变化但规律基本一致。| 模型 | 储能日均吞吐量 | 弃电率 | 全年SOH下降 | 系统日均总成本 | | 无衰减 | 很高 | 最低 | 最快 | 纸面上最低 | | 线性吞吐量 | 中等 | 略升高 | 中等 | 真实成本中等 | | 半经验衰减 | 降低约20% | 明显升高 | 明显放缓 | 综合最优 |最容易被带偏的读法是只看弃电率。如果为了把弃电率从8%压到4%让储能每天多跑好几个深度循环省下来的弃电惩罚可能还没有电池折旧多。正确做法是把SOH下降折算成等值成本画进系统总成本看不同灵活性裕度下总成本曲线的拐点。这个拐点对应的调度策略才是工程上真正应该用的方案而不是追求任何单一指标的最优。6. 从论文复现到工程应用这套模型还能怎么改6.1 从离线优化到在线滚动调度论文里的多时间尺度调度往往是离线仿真读历史数据、跑优化、统计结果但工程落地时需要做成在线调度系统。差别在于在线系统对求解时间更敏感还要接实时数据和下发指令的接口。我建议把日前模型和日内模型分别封装成函数输入输出全部标准化输入是预测曲线、当前SOH、当前SOC输出是储能出力计划、备用缺口提示。这样后续接入实际系统时只需要换数据接口不需要重写优化内核。在线滚动时还要注意数据时间对齐Matlab侧拿到的SCADA数据如果有时延优化结果下发就已经失效这是工程里比算法本身更容易翻车的地方。6.2 与市场机制衔接储能报价要跟着衰减成本走如果把这套模型放到电力市场环境里储能就不只是被调度的资产而是可以申报容量和价格的参与者。衰减建模的价值在于能给出动态报价浅充浅放的报价可以低一些深度充放要报价更高才能覆盖寿命损失。这个思路有点像出租车司机跑短途和跑长途的价格策略完全不同。具体实现可以把不同DOD区间对应的老化成本做成一张报价表日内模型每15分钟根据当前SOC位置自动选择最优报价区间。这个模块和当前很多聚合商的实际需求贴合得很紧也是论文模型向工程落地拓展时比较有说服力的一个方向。6.3 不确定性建模的进一步扩展如果还想在现有框架上做创新方向不外乎三条随机优化、鲁棒优化、学习型调度。随机优化用场景树描述预测误差两阶段决策自然适配日前和日内的两层结构。鲁棒优化把预测误差放进区间集合求最坏情况下的最优解解的结果偏保守但更扛揍。学习型算法可以用来调整柔性负荷补偿参数或者储能的衰减系数让模型自适应工况变化。我的实际体会是不管往哪个方向扩展先把衰减建模和SOH反馈的基础版本跑扎实再往上叠加不确定性处理否则出了问题很难分辨是优化模型本身的问题还是老化参数的锅。这套复现流程走完一遍后续加新模块会顺畅很多。我下一轮准备把温度对储能老化的影响也加进模型里看看全年收益对环境的敏感性会不会反过来影响日前调度策略。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑