尧图精选

考虑储能寿命衰减的虚拟电厂多时间尺度调度优化与Matlab实现

🕒 发布时间:2026/9/9 14:33:32 📁 来源:尧图网络
高比例可再生能源并网后电网的净负荷曲线变得又陡又不确定传统“按最大负荷留备用”的思路越来越撑不住。这两年做虚拟电厂VPP调度的项目我最大的体会是真正难的不是把风电、光伏、储能、可调负荷塞进一个优化模型而是怎么处理“灵活性需求”和“储能成本”这对天然冲突的指标——你越想压平净负荷波动储能循环次数就越高寿命衰减越快折算到度电成本反而可能更贵。这篇就围绕我复现的一个多时间尺度调度框架展开代码基于Matlab实现重点聊聊衰减建模是怎么影响调度决策的以及各时间尺度之间怎么衔接才不会让方案“看起来最优、实际没法执行”。内容适合正在做电力系统优化调度、储能配置或虚拟电厂相关课题的研究生和工程师。如果你已经能跑通基本的机组组合或经济调度程序但对多时间尺度协调和储能寿命建模还比较模糊这篇应该能帮你少走不少弯路。1. 高比例可再生能源并网本质是净负荷的“形状”变了先不急着上模型得先搞清楚我们在对抗什么问题。可再生能源渗透率上来以后电网调度面对的不再是“负荷曲线”而是“净负荷曲线”也就是原始负荷减去风电和光伏出力之后的剩余部分。这条曲线的形状和原来完全不同有几个特征直接影响调度策略设计。1.1 净负荷曲线的三个致命特征第一个特征是净负荷爬坡率极高。光伏在傍晚快速退出和风电突然增强会造成净负荷在几个小时内剧烈上升或下降。传统火电机组的爬坡速率一般在每分钟1%~3%额定出力如果净负荷爬坡率超过所有在线机组的爬坡能力之和就会出现所谓的“爬坡不足”事件必须靠储能或可调负荷来填补。第二个特征是被迫弃电和经济性矛盾加剧。午间光伏大发时净负荷可能降到极低甚至为负这时候如果储能容量不够要么弃光要么让火电深度调峰。弃光直接损失电量收益深度调峰则带来煤耗上升和机组寿命损耗两头都是成本。第三个特征是预测误差的尺度差异。风电和光伏的预测误差在日前尺度可能达到装机容量的15%~20%但到了日内滚动预测和实时阶段会逐步收敛。这意味着你不能指望用一个单一时间粒度的模型解决所有问题日前做太细预测误差大没意义实时才做调整机组响应又来不及。这三个特征放在一起结论就很清晰调度策略必须分尺度储能必须承担“削峰填谷爬坡弥补”的双重角色而储能一旦被高频使用寿命衰减就不能再当固定参数处理。1.2 灵活性与成本为什么是一对直接冲突电网对灵活性的需求说白了就是“时刻能跟上净负荷变化的能力”。储能是当前响应速率最快、调节精度最高的灵活性资源但它的成本结构很特殊初始投资高循环寿命有限而且循环次数和放电深度DOD直接决定了实际使用寿命。这里有个容易忽略的换算逻辑。假设一套储能系统标称循环寿命6000次100% DOD总容量1MWh初始投资150万元折算到每次满充满放循环的成本就是150万除以6000等于250元/次。如果你在调度中让它频繁做浅充浅放比如20% DOD循环寿命可以延长到几万次但单次循环提供的电量也少了——所以不能简单说“浅放更划算”关键要看单位电量的全生命周期成本。更麻烦的是调度策略本身会影响储能的实际衰减路径。你让储能做深度充放衰减快你让它高频浅充浅放循环次数多但每次循环的“磨损”也不完全一样。这就形成了一个闭环调度策略决定储能的运行方式运行方式决定衰减速率衰减速率的加剧又反过来推高下一次调度中的成本。如果不把这个闭环建模进去优化出来的“最优方案”很可能是在透支储能寿命。2. 虚拟电厂的核心结构聚合建模与分层优化框架虚拟电厂自己不发电它把一个区域内的分布式光伏、分散式风电、储能系统、可控负荷聚合起来对外表现为一个可调度的整体。建模的关键在于不同单元的时间常数和调节能力完全不同必须在同一个框架下表达但又不能混为一谈。2.1 各类资源的建模粒度怎么选我在项目里把VPP内部的资源分成四类每一类的建模粒度差异很大。分布式光伏和风电属于不可控电源建模时通常只取预测出力曲线可以作为可削减量弃光、弃风纳入优化。可控负荷分两种可中断负荷和可平移负荷。可中断负荷就是你说停就停给补偿就行建模上用一个二元变量加最小中断时间约束可平移负荷则需要跟踪等效能量转移过程比如工业电炉、温控负荷要记录运行状态持续时间。储能是最特殊的单元因为它具备时间耦合特性——当前时段的充放电决策会改变SOC状态进而影响后续所有时段的可行域。所以储能建模必须包括SOC递推方程、充放电功率上下限、充放电状态互斥约束以及循环寿命相关的累计变量。这部分我后面专门用一节讲因为衰减建模的细节直接决定模型复杂度。2.2 目标函数不止是钱还要给“灵活性”定价调度目标不能只设成“运行成本最小”或“收益最大”这种单目标。实际做VPP调度时我建议把目标函数写成多部分加权系统运行成本包括向主网购电成本、机组启停成本、燃料成本、负荷中断补偿。然后加上储能运行惩罚项可以是充放电切换惩罚也可以是衰减成本。这里有一个关键设计衰减成本怎么转化为目标函数里的金额项。如果每个时段因为充放电而产生的寿命损耗折算成钱优化器就能自动权衡“用储能”和“不用储能”的代价。更进一步的灵活性约束可以加在净负荷波动率上。比如限制相邻时段净负荷变化率不超过一定阈值或者对净负荷方差加惩罚项。这类约束会主动“购买”灵活性调度结果会更平滑但代价是成本上升——这个trade-off需要在灵敏度分析里量化出来别凭直觉拍脑袋设。2.3 三层递进框架为什么非得拆成多时间尺度只做一个时间粒度的模型在实践中一定出问题。原因前面讲了预测误差随时间尺度变化。我实际采用的结构是典型的日前-日内-实时三层递进日前调度D-1时间粒度为1小时优化周期24小时基于日前预测数据确定机组启停计划、储能日前SOC基准曲线、可中断负荷调用计划。这层的目标是“粗框架”不需要追求每个时段的精确出力但必须保证全天能量平衡在大概率下成立。日内滚动调度时间粒度为15分钟滚动优化周期通常4小时每15分钟滚动一次基于更新的超短期预测结果修正机组出力、储能充放电功率。这层的核心是“跟偏差”日前计划已经锁定了启停和SOC基准日内只调整功率分配。实时控制层时间粒度1~5分钟只做一件事——把实际功率偏差分配给响应最快的资源主要是储能和可中断负荷。这一层通常不跑优化而是用规则或简化MPC因为计算时间窗口太短。这三层的信息流是单向传递又带反馈的。日前计划是日内的“参考轨迹”日内结果又成为实时的“基线功率”。任何一层都不能独立存在这就解释了为什么很多论文里的“单层优化模型”看起来漂亮工业上却没法部署。3. 日前-日内衔接滚动优化与协调变量的设计细节三层框架里最容易出问题的是“衔接”。很多复现者把日前和日内各写一个优化模型以为跑完就完事了结果发现两层结果互相矛盾日内优化修正后的出力已经偏离了日前SOC基准线但储能又没考虑这个偏离导致实时阶段根本无法执行。3.1 协调变量层与层之间传什么我的做法是定义一个“协调变量”集合层与层之间只传这些变量其他自由。日前层向下传递的有火电机组启停状态日内层固定不变因为启停决策需要长提前量、储能SOC基准轨迹日内层可以在一定偏差范围内修正、可中断负荷的调用时段和容量。日内层向实时层传递的则包括各机组有功出力设定值、储能充放电功率设定值、VPP与主网交换功率计划。关键在SOC基准轨迹的处理。如果日内层完全自由优化SOC实时层的调节空间可能不够如果完全锁定SOC日内层又无法响应超短期预测的偏差。折中方案是设置SOC带约束日内优化的SOC必须落在日前SOC曲线的上下界区间内比如±10%。这样既给了日内修正的灵活性又保证了后续时段的调节空间。3.2 滚动窗口的滚动步长该设多少日内滚动的步长设计直接影响计算负担和效果。我做过的测试里15分钟步长配4小时窗口是比较均衡的选择。窗口太长超短期预测后半段的精度优势就没了窗口太短又无法覆盖储能跨时段的调节需求比如夜间低谷充电、早峰放电的完整过程。还要注意滚动优化里的“只执行第一步”原则。每15分钟滚动一次但真正下发执行的只有下一个15分钟的决策更远时段的决策只是参考。这个原则看起来简单实际很多人忽略了——他们把整个窗口的决策都执行了等到下一次预测更新时发现已经偏离太多了。3.3 一个容易踩的坑日前启停和日内出力的时标匹配火电机组启停是小时级的日内出力是15分钟级的。如果代码里日前层用24个时段日内层用96个时段两者之间的变量映射就要格外小心。我见过不少复现代码在这里出bug日前说1号机组在8点到10点开机日内层却从8点15分开始强制让1号机组出力导致爬坡约束直接崩溃。解决方法是在数据接口层统一处理日内层的96个时段先映射到日前的24个时段每个日前时段对应4个日内时段启停状态在这4个时段内保持不变。代码里写清楚这个索引映射不要在原模型里一个个改约束条件否则调试起来特别痛苦。4. 储能衰减建模从简化寿命模型到调度闭环这一节是整篇的“重头戏”。储能衰减建模很多人一开始都觉得“不就是容量乘个衰减系数嘛”但实际做进调度模型后会发现怎么把衰减过程转化为可优化的数学表达式才是真正的难点。4.1 为什么会衰减来自老化和循环的双重压力储能衰减分为日历老化和循环老化两种。日历老化是随时间自然发生的与环境温度、SOC水平有关循环老化是随充放电循环发生的与放电深度、充放电倍率、循环次数有关。在VPP调度的时间尺度内一天到几天日历老化变化很小基本可以当作常数项忽略重点建模循环老化。循环老化的核心规律是放电深度越大单次循环造成的容量衰减越大但反过来同样累计放电量下浅充浅放的总衰减更小。这个关系在锂电池里常用“循环次数-DOD曲线”来描述。比如某型电池在100% DOD下循环寿命是6000次在50% DOD下约15000次在20% DOD下约40000次。需要提醒的是这个关系不是线性的。100% DOD循环6000次如果按线性折算成50% DOD应该有12000次但实际是15000次说明浅放电有“收益”。这个非线性恰恰说明在调度中优先让储能浅充浅放是有数学依据的而不是只觉得“温柔用电池比较省”。4.2 两种实用的衰减建模方法在Matlab代码里我试过两种衰减建模方式各有适用场景。第一种是线性累计退化模型也是最容易落地的。思路是给储能定义一个“等效循环次数”变量每次充放电依据当前DOD折算成等效满循环次数累计后乘以单次满循环的容量衰减率就得到累计衰减。数学上可以写成线性约束适合嵌入混合整数线性规划MILP。缺点是精度一般但对调度决策而言足够了——关注的不是电池精确衰减曲线而是“多用储能会多产生多少成本”。第二种是雨流计数法耦合模型把充放电功率序列提取成一个个完整的充放循环再对每个循环按DOD查表计算损耗。这种方法精度高但麻烦在于雨流计数是离线算法不能直接放进优化模型里。实际用法是“迭代式”的先跑一次不含衰减的调度用结果做一次雨流计数得到衰减估算值把衰减成本加进目标函数再跑一次迭代几次直到收敛。我实测过通常两到三次就能稳定计算时间也还能接受。如果你追求论文级别的精度第二种方法更站得住脚如果只是工程评估或方案对比第一种线性累计方法已经能很好地反映调度策略对储能寿命的影响了。4.3 衰减成本怎么落到目标函数里无论用哪种衰减建模最后都要转化为成本项放进目标函数。我常用的做法是一个折算公式单次循环衰减成本 电池初始投资成本 / 等效总循环寿命 × 衰减等效系数其中等效总循环寿命可以按标准DOD下的循环次数来取衰减等效系数则根据实际充放电过程计算。在MILP框架下这部分可以做成分段线性函数根据DOD区间映射到不同斜率。这里有个权重设置的细节衰减成本在总目标中的占比不能太小否则优化器会为了省几块钱电费疯狂调用储能把电池用废也不能太大否则储能完全闲置灵活性需求全部推给火电和切负荷VPP的优势就没了。我在案例里的做法是把储能衰减成本设置为系统平均电价的1.5~2倍权重再通过灵敏度分析微调最终确定符合项目目标的值。5. Matlab实现代码结构、求解器选型与关键参数调优讲完模型到落地环节。这一节我会按实际的代码组织方式说不是贴完整代码而是讲清楚每个模块做什么、选什么工具、容易在哪儿翻车。5.1 代码框架模块划分和数据流我习惯把一个VPP调度程序拆成这样几个文件或函数data文件夹存放负荷、风电、光伏预测数据机组参数、储能参数、分时电价。model/interface.m定义VPP的系统规模、时段数、机组数量、储能配置等基础参数。model/build_model.m构建优化模型包括变量定义、目标函数、约束条件。model/solve_model.m调用求解器并整理结果。utils/包括数据预处理、结果可视化、性能指标计算。这么拆的好处是日后换数据集、改储能参数、调整时间尺度都只需动对应的模块不需要整个重写。5.2 求解器选型不是所有模型都适合上CPLEXMatlab里做优化调度常用的组合是YALMIP工具箱 CPLEX/GUROBI求解器。YALMIP负责建模CPLEX/GUROBI负责求解这个组合对MILP问题效率很高。我用的版本是YALMIP R2021新版本配CPLEX 12.10或者GUROBI 9.5都能良好兼容Matlab 2020以后的版本。如果你的模型是纯线性规划LP或者二次规划QP可以直接用Matlab自带的linprog和quadprog速度也够快还能省去装第三方求解器的麻烦。但一旦涉及储能充放电状态互斥需要二元变量、机组启停需要整数变量就变成MILP/MIQP问题了自带的intlinprog能解但大规模问题求解时间很难看还是建议上CPLEX或GUROBI。求解器参数里有一个特别值得调MIP gap。默认的1e-4在24小时96时段的大模型里可能跑很久。我一般设为1e-3甚至5e-3调度结果不会有明显差别但求解时间能缩短一半以上。工业场景里与其等一个“理论上最优但晚了2小时”的解不如要一个“近似最优但5分钟内出来”的解。5.3 储能衰减模块的代码实现思路下面给一个线性累计退化模型的伪代码思路方便你理解模块怎么嵌进优化模型% 储能参数 E_rated 2; % MWh cycle_life 6000; % 100% DOD 循环次数 cap_degradation_per_cycle 0.2 / cycle_life; % 假设20%容量衰减对应6000次 % 决策变量 P_ch sdpvar(T, 1); % 充电功率 P_dis sdpvar(T, 1); % 放电功率 SOC sdpvar(T, 1); % 荷电状态 % DOD 的线性段处理 DOD_var sdpvar(T, 1); degradation_cost 0; for t 1:T % SOC递推约束 SOC(t) SOC(t-1) (P_ch(t)*eta_ch - P_dis(t)/eta_dis) / E_rated; % 根据SOC与DOD的关系计算等效循环损耗这里简化为线性关系 DOD_var(t) SOC(t-1) - SOC(t); % 放电过程近似 degradation_cost degradation_cost alpha * DOD_var(t) * cap_degradation_per_cycle; end实际用的时候需要把DOD和SOC变化的关系写成更严谨的线性约束避免自由变量带来的不精确性。公式不复杂但边界条件处理不好优化器会钻空子出现“伪造高频充电再放电”来分循环次数的情况。一个有效的防护是加入最小充放电持续时间约束限制单位时段内的充放电转换次数。5.4 参数调优几个影响结果的关键旋钮实际跑模型时有几个参数对结果影响最大拿出来单独说。储能初始SOC值很关键。如果设为0.5模型在第一个时段就有大量放电空间前几个时段的调度结果会偏乐观如果设为0.2前几个时段储能基本只能充电灵活性受限。我建议做一次“初始SOC灵敏度扫描”分别设置0.1到0.9观察不同初始值对总成本和储能寿命损耗的影响。这个分析结果放在论文里会很好看而且确实有实用价值。充放电效率。锂离子电池的往返效率通常在90%~95%但你要分清是“电芯效率”还是“系统效率”。系统效率还包括PCS转换效率、变压器损耗、辅助用电实际可能只有85%~88%。我在项目里一开始用了92%的电芯效率结果调度结果和工程实际对不上后来统一改成85%的系统效率才合理。爬坡约束的松弛惩罚。日前层和日内层之间的爬坡约束如果设得太紧会频繁导致模型不可行。一个常见的做法是把爬坡约束做成软约束违反时支付惩罚费用而不是直接禁止。这样即使用户上报的预测数据有跳变模型也能给出一个可执行的方案而不是直接报错“infeasible”。6. 案例结果解读衰减建模带来的调度策略差异纯讲模型太干了拿一个实际算例来看衰减建模对调度结果的影响。案例配置某个区域VPP包含50MW风电、30MW光伏、10MW/20MWh储能以及若干可调负荷同时从主网购电补充缺额。日前层24时段日内层96时段储能初始SOC设为0.5。6.1 场景一完全忽略衰减成本如果目标函数里没有储能衰减项优化器会把储能当成“免费”资源使劲用。结果很有意思储能在光伏大发时段充满电下午高峰时段放完电晚间低谷再充电凌晨又放电。全天等效满循环次数接近2.9次按6000次循环寿命折算相当于储能寿命消耗了0.048%当天容量衰减约0.0096%。折算成成本不小但画面很好看——净负荷曲线被压得非常平滑VPP对外表现为一个几乎完全“听话”的友好型电源。问题是这个方案不可持续。按这个用法储能大约在5年出头就用完了标称循环寿命而项目的储能设计寿命通常要求10年。这意味着你虽然每年报表好看实际上第四五年就要掏钱换电池全生命周期算下来很不划算。6.2 场景二计入衰减成本后加入衰减成本项后优化结果明显变了。储能全天等效循环次数从2.9次下降到1.4次左右净负荷波动率稍微变大但系统总成本购电运行衰减折算反而下降了约12%。原因是储能每次深度充放电产生的“寿命损失费”已经被计入优化器自动倾向于“能少用就少用要用了就浅充浅放”。这背后反映了一个很本质的道理储能不是电网里“免费”的灵活性来源它只是把成本在时间上“转移”了。你不在调度模型里显式建模这个转移成本优化结果就会用未来的运维支出补贴今天的调度表现。6.3 净负荷波动和总成本的双目标权衡我还做了一个双目标分析横轴是净负荷波动的最大允许变化率纵轴是最优总成本。结果是一条典型的“肘形曲线”当允许波动率从20%缩紧到10%时总成本上升缓慢继续缩紧到5%以下成本急剧上升因为储能必须高频深度调用寿命损耗成本暴涨。这个肘形点就是工程上的最优运行点。往下压波动灵活性提升了但多花的钱是不值得的往松放波动成本省不了多少VPP的友好性却明显下降。我建议所有做VPP调度项目的朋友都做一次这个分析因为最终方案不应该是“成本最低”或“波动最优”而是“在可接受成本范围内的最优波动”。7. 调试经验与Matlab实现的几个隐藏细节最后分享几个我在复现过程中踩过的坑和调试经验。这些很难从论文里看到但实战中非常影响效率。7.1 求解器报“infeasible”的排查顺序模型不可行是MILP调试里最常见也最磨人的问题。我的排查顺序是先检查数据单位是否统一MW和kW混用是最常见的坑再检查约束是否过度约束比如同时要求SOC在某个时段必须达到0.8又要求这个时段只能放电就可能冲突最后检查是不是爬坡约束和启停时间约束冲突。有一个很实用的技巧把模型里的整数约束全部松弛成连续变量转成LP问题再解。如果LP问题可解说明问题出在整数组合上需要检查启停逻辑和爬坡逻辑如果LP问题也不可解那就是基础约束和数据的问题用“逐条追加约束法”就能定位到是哪条约束导致不可行。7.2 为什么你的日内层结果总是抖振日内滚动优化的结果非常容易出现相邻时段出力大幅度跳变也就是工程上说的“抖振”。原因通常是日前层的SOC基准轨迹没有传递到日内层日内层每个滚动窗口各自优化前后窗口之间没有记忆自然衔接不上。解决办法是给日内层加“基线偏移惩罚”——目标函数中加入与日前计划偏差的二次惩罚项偏差越大代价越高。这样日内层可以有调节能力但不会偏离日前太远。7.3 数据预处理的隐藏细节风电和光伏的预测数据时间戳对齐是个大坑。有些数据是整点采样有些是半点采样还有些数据集少了一段比如夏令时切换的日子。在Matlab里处理时我建议一律统一成“距离当天零点的小时数”格式不要直接用字符串时间戳参与循环比较否则索引错位很难被发现。还有一个细节参与日前的预测数据用D-1上午的预测结果参与日内滚动预测的用当天的超短期预测。两类数据的误差分布不同如果你混用了数据来源模型评估的“预测误差”就失真了后续所有结论都会受影响。7.4 结果验证的通用做法拿到优化结果后不要只看总成本或者SOC曲线好不好看我建议做三件验证第一逐时段检查功率平衡是否满足净负荷购电风电光伏储能放电可控负荷削减这类基础校核能发现大多数数据映射问题。第二检查储能SOC的日终值是否回到初始值附近。如果不允许日内存量转移比如要求每天SOC清零日终SOC应该等于初始值如果允许跨日调度也应该记录清楚日终SOC的归属否则长期运行评估会出错。第三做一次蒙特卡洛模拟把预测误差随机抽样加到日前输入里看日内层能否在绝大多数场景下保证系统不越限。这一步能真正检验多时间尺度方案的鲁棒性而不只是“单组数据上的仿真好看”。我在实际项目里就碰到过一次日前方案在单组预测数据下表现完美但随机生成100组预测误差场景后有将近30%的场景日内层无法在允许范围内完成修正——最后追查发现是日前层没有给日内层留足够的储能调节裕度把SOC带约束设得太窄了。调宽之后日内成功率从70%提升到了95%以上。8. 关于代码扩展的一点想法这套多层调度框架还有一个容易扩展的方向把需求响应也做成柔性资源在日内层加入价格弹性系数让可控负荷在电价高峰时段主动削减。加进去之后衰减建模依然通用只是目标函数里多了一项需求响应补偿成本。如果你的研究点偏向市场机制或需求侧管理这个扩展能快速用上现成的代码框架。另外一个值得尝试的方向是考虑风光出力的相关性。不同地区的风电场、光伏电站之间并不是完全独立的如果只是用独立预测曲线进模型会低估总出力的波动范围导致备用容量配置不足。在Matlab里可以用copula函数或者场景树来生成相关性场景再嵌入到日内滚动优化的场景集合中。这会增加不小的计算量但结果会稳健很多。用这套框架时建议不要一上来就追求“把所有细节都建模进去”。我的经验是先跑通三层框架用固定效率和固定成本参数把整个链路调顺之后再逐步加入储能衰减模型、不确定性场景、需求响应等复杂因素。一步到位只会让你的调试周期无限拉长而且出了问题你根本分不清是哪一层引入的。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →