ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

储能辅助火电机组二次调频控制策略及容量优化Matlab/Simulink仿真

储能辅助火电机组二次调频控制策略及容量优化Matlab/Simulink仿真 做火电AGC调频搞了几年的同行基本都清楚一个痛点机组爬坡速率、锅炉热惯性、调节死区这些硬件上限死死卡着调频性能尤其碰上负荷波动又快又勤的时候二次调频根本腾不出手。这几年电池储能大规模落地之后一个很自然的思路就是把储能堆到火电厂里让它去顶那些火电机组“反应不过来”的部分。这套“储能辅助火电机组二次调频控制策略及容量优化配置研究”说白了就是用Matlab代码和Simulink仿真把“储能怎么配合火电机组响应AGC指令”和“储能到底配多大功率、多大容量才划算”这两个问题做成一套能跑、能算、能出结果的整体方案。这类课题在电网调度、电厂技改、储能项目投资评估里都经常出现我自己也拿它跑过不少实际负荷曲线。适合谁参考呢一类是研究AGC调频策略的研究生和工程师另一类是做储能容量规划、可研报告的从业者还有一类是刚接触Simulink、想把控制策略和优化算法搭到一起的入门选手。下面我按自己做这套方案时的完整思路把控制策略设计、容量优化建模、代码与仿真实现、以及实际跑数据时踩过的坑全部摊开讲。1. 为什么二次调频要用储能来补位1.1 火电机组调频能力的天花板先看火电机组在二次调频里的实际表现。AGC系统每几秒到十几秒下发一个区域控制偏差ACE信号折算成功率指令后机组需要快速增出力或减出力。问题是燃煤机组的真实响应链条很长汽轮机调门动作算快的但锅炉侧蒸发量、汽压重建、燃烧调整都有明显滞后。典型600MW亚临界机组的负荷变化率如果达到每分钟2%额定功率已经算爬坡能力不错的遇到AGC指令频繁反向变化时实际出力曲线经常滞后指令一两分钟以上。更尴尬的是调节死区。为了保持机组稳定调速器系统一般会在频率偏差小于某个阈值时限制动作二次调频的负荷指令也设置了调节死区。储能恰恰能解决这两个问题响应速度快毫秒到秒级调节精度高不存在爬坡速率和锅炉热惯性限制。不过储能的问题也很明显持续能力有限能量不可能无限释放所以不能全部替代火电只能做“辅助”和“短时补位”。1.2 储能补位的核心角色定位在设计控制策略之前要先想清楚储能在这套系统里到底承担什么角色。第一种角色是高频分量吸收器。把AGC指令或者电网频率偏差信号看成时变信号火电负责变化缓慢的低频部分储能负责变化快、幅值小的高频部分。这种分工最直观也是大多数论文的默认做法。第二种角色是瞬时功率缓冲器。火电厂经常遇到单台机组AGC指令突然大幅跳变的场景储能先顶住最初的冲击给锅炉汽压重建争取时间然后逐步把功率转移给火电机组。这个场景下的储能更多是“救火队”功率需求大但每次工作的时间不长。第三种角色是调频性能增强器。通过储能的高精度快速响应减小火电机组实际出力与AGC指令之间的偏差提高CPS1、CPS2等考核指标同时减少汽轮机调门反复动作带来的机械损耗。我的经验是一套实用的控制策略不应该只选一种角色而是把“高频吸收”和“瞬时缓冲”融合在一起同时把电池荷电状态SoC的管理放在最高优先级。任何策略如果不管SoC仿真跑个几分钟没问题跑个把小时电池就会因为过充过放退出运行结果完全失真。2. 控制策略与容量优化配置的设计思路2.1 控制策略整体框架这个项目里的控制策略可以拆成三层功率分配层、SoC恢复层、指令限幅层。功率分配层解决“储能出多少力”的问题。我用的是最经典的一阶低通滤波分配法。AGC综合指令P_AGC先进入一个低通滤波器滤波后的平滑分量给火电参考原始指令减去平滑分量剩下的差值作为储能功率参考。数学上可以理解为P_fire_ref 低通滤波(P_AGC) P_storage_ref P_AGC - P_fire_ref低通滤波器的关键参数是时间常数T_filter。T越大火电拿到的指令越平滑储能承担的高频部分越多T越小储能出力越少火电响应压力越大。这个参数没有绝对标准我一般从60s左右开始试再根据储能功率约束和火电爬坡能力反向调整。SoC恢复层解决“电池电量被掏空”的问题。因为储能长时间承担高频波动净能量交换虽然不一定很大但统计上看有很多微小充放电累积。如果滤波时间常数设计得不合理储能会一直偏向充电或放电方向SoC慢慢漂到边界。我的做法是在SoC偏离目标区间时叠加一个恢复功率分量通过比例积分控制器根据SoC偏差形成恢复功率叠加到储能功率参考上。注意恢复功率的方向要正确SoC低时强制让储能少放电甚至多充电SoC高时让储能多放电。指令限幅层解决“储能功率越限”的问题。任何时候储能参考功率都不能超过额定功率上下限。同时为了延长电池寿命我会在SoC靠近上边界时提前降充电功率靠近下边界时提前降放电功率。这一步看起来很基础但很多新手会漏掉导致仿真里出现储能实际功率突破额定值的不合理结果。2.2 容量优化配置的建模思路容量配置的目标很简单在满足调频性能要求的前提下让一套储能系统的全生命周期净收益最大。需要优化的变量是哪两个一种是储能额定功率P_rated单位MW另一种是储能额定能量E_rated单位MWh。两者共同决定了电池系统的规模和投资成本。我需要设定目标函数里面包括三块收益、投资成本、运行成本。收益部分我按两类来源建模。第一类是调频性能奖励通过储能接入前后AGC调频效果指标比如CPS1、考核合格率的提升量来估算。第二类是容量收益或辅助服务补偿按不同省份调频市场规则差异很大但一般可以简化成“单位调频里程价格×调频里程”。在仿真中我把调频里程近似为储能实际充放电功率绝对值的累计量。成本部分包括初始投资成本单位功率成本加上单位容量成本、年运行维护成本、以及电池更换成本。电池循环寿命可以近似地与累计吞吐电量挂钩当累计吞吐电量达到某阈值时认为需要更换。这个寿命模型比较粗糙但用于方案比选完全够用。约束部分比较关键。储能功率在任何时刻都不能超过额定功率SoC必须保持在合理区间比如10%到90%同时响应速率、响应延迟都要能满足调频市场准入要求。另外还有火电机组爬坡约束和AGC指令跟踪的精度约束。一句话总结整个优化是在“调频性能要达标”和“储能不要过度投资”之间找平衡。2.3 容量优化的求解方法优化问题的决策变量只有两个P_rated、E_rated但目标函数里嵌入了仿真过程也就是每一组储能配置都要跑一遍Simulink仿真来获取调频收益。这个问题用解析法很难处理我用的是粒子群优化算法PSO。一群粒子代表不同的“功率容量”组合每个粒子跑一次仿真根据目标函数值的好坏更新群体位置迭代几十次就能收敛到不错的配置方案。粒子群算法的参数设置我有一个个人习惯种群数量30到50个迭代次数60次左右学习因子c1和c2都设为1.5惯性权重从0.9线性降到0.4。这些参数不是固定死的如果目标函数曲面特别崎岖可以适当增加种群数量而不是盲目增加迭代次数。在我的算例里大概跑到第15代到第20代最优值就基本稳定了。3. Matlab代码与Simulink仿真实现全过程3.1 仿真模型整体结构我搭的Simulink模型整体分五个子模块。第一个子模块是AGC指令发生器。可以直接让Matlab工作区里生成好的负荷指令信号作为输入也可以在Simulink里用Signal Builder或者Repeating Sequence造一段包含阶跃、斜坡、正弦波动和随机噪声的组合信号。我的实测经验是指令信号必须包含高频随机波动成分否则储能永远无活可干仿真结论会严重偏向“少配储能”。第二个子模块是火电机组动态模型。这里不需要非常精细的锅炉汽轮机全场模型用传递函数近似就够了。常用的做法是一个典型的锅炉-汽轮机-发电机简化模型输入负荷指令输出实际功率。我用的是一个一阶惯性加延迟环节的组合参数根据某600MW机组的实际阶跃响应特性辨识出来。注意延迟环节在连续仿真里可以用Transport Delay模块但总仿真步长必须保证这个延迟的采样精度。第三个子模块是储能系统模型。为了配合容量优化我用的是“功率-能量”简化模型核心就是一个积分器用来累计电池的SoC变化再加一个带功率限制的比例环节。模型公式很简单SoC的变化率等于储能的充放电功率除以额定能量同时充放电功率要乘以充放电效率系数。第四个子模块是控制策略模块内部封装了我上面提到的低通滤波、SoC恢复和功率限幅逻辑。第五个子模块是性能统计模块实时计算功率跟踪误差、调频里程、储能SoC均值、电池累计吞吐量等指标最后输出到Matlab工作区。3.2 关键代码实现我习惯把主代码放在Matlab脚本里用sim()函数调用Simulink模型而不是在Simulink里写一堆回调函数。这样做的最大好处是方便批量跑参数扫描和PSO寻优。以下是核心脚本的大致结构% 载入负荷指令数据 load(AGC_command_600MW_24h.mat); T_sim length(AGC_command) * dt; % 仿真总时长 % 设定储能候选容量参数 P_rated 30; % 储能额定功率MW E_rated 15; % 储能额定能量MWh SOC_init 0.5; % 初始荷电状态 % 运行Simulink仿真 simOut sim(storage_fire_AGC_model.slx, ... StopTime, num2str(T_sim), ... LoadExternalInput, on, ... ExternalInput, AGC_command); % 从仿真结果中提取指标 performance_metrics calc_metrics(simOut);这里有个特别要注意的点ExternalInput的时间向量起点必须和模型内部信号对齐否则会造成AGC指令错位。我通常把仿真起始时间固定为0负荷指令数据也从0时刻开始。控制策略模块我在Simulink里直接用基础元器件搭建没有用自定义Matlab Function。理由有二一是基础元器件更容易排查数值问题二是Coder生成代码时更稳定。低通滤波我用一阶Lag环节SoC恢复用PID Controller或手动搭的PI功率限幅用Saturation模块。% PSO主循环伪代码 for iter 1 : max_iter for i 1 : pop_size P_rated_i particles(i, 1); E_rated_i particles(i, 2); [fitness(i), constr_violated] eval_fitness(P_rated_i, E_rated_i); if constr_violated fitness(i) fitness(i) * penalty_factor; end ... % 更新个体最优和全局最优 end ... % 更新粒子速度和位置 endeval_fitness函数内部完成“调用sim、提取指标、计算目标函数”的全过程。这里提醒一句每次sim仿真都相当耗时一定要在模型里设置合理的求解器步长不要用默认的变步长无限细分。3.3 控制参数怎么调才不打架在仿真里我遇到过比较典型的问题滤波时间常数T_filter和SoC恢复PI参数之间有强耦合。T_filter取得越大储能承担的任务越重SoC漂移得就越快SoC恢复PI的积分作用就必须相应减弱否则两个环节会互相较劲储能功率指令产生明显振荡。我采用的调参顺序是先固定SoC恢复环节为关闭状态单独整定T_filter让储能功率正好稳定在额定功率附近一个合理的利用率区间然后打开SoC恢复环节先用较小的恢复系数试跑观察SoC均值是否回到目标区间最后再微调PI参数使SoC恢复过程中储能功率没有剧烈冲击。整个过程有点像先让一个新人干活再逐步教他在干活的同时管理自己的精力急不得。3.4 典型仿真结果的判读方法仿真实测下来储能加入前后的对比非常直观。以某600MW机组、30MW/15MWh储能配置为例火电机组独立调频时AGC跟踪延迟大约在20到40秒频率偏差的均方根值大约在0.04Hz附近加入储能后跟踪延迟压到2秒以内频率偏差均方根值能下降到0.012到0.018Hz。调频性能提升的背后是储能承担了大量高频功率火电出力曲线明显平滑了许多。容量优化结果通常呈现一个规律储能功率和能量的最优配置不是越大越好。太小的储能没起到补位作用调频性能不达标太大的储能投资成本过高边际收益下降飞快。在收益模型参数固定的情况下最优配置往往出现在“刚好覆盖AGC指令高频波动幅度的主要范围”附近。所以做容量配置之前先做一波负荷指令的频谱分析看看高频波动的幅值集中在多少MW这会给你一个非常有用的配置直觉。4. 实际操作中容易踩的坑与排查实录4.1 电池模型过细反而不稳定我刚开始做这个项目时尝试过给电池搭一个完整的二阶RC等效电路模型还把温度、老化系数全加了进去。结果仿真速度慢了非常多而且调频策略和电池内部状态形成了双重反馈系统出现非线性振荡排查了半天才发现是电池模型的时间常数和控制策略的滤波时间常数凑一起形成了共振。后来我换成功率-能量简化模型把电池内部动态等效成一个带效率的功率约束积分器系统立刻稳定了。需要高精度电芯级仿真时再用详细模型在做系统级调频策略和容量配置时简化模型更合理。4.2 SoC漂移是所有策略的隐形杀手如果你发现仿真跑到一半储能频繁出现限功率输出先别急着怀疑控制逻辑直接看SoC曲线是不是早就顶到边界了。我踩过最典型的一次AGC指令里有大量的不对称波动储能平均放电功率略高于充电功率六个小时后电量全部耗尽控制策略再怎么计算储能也拿不出实际功率整个仿真中后期等于储能直接退出。解决方案就是在SoC恢复层叠加一个前馈偏置让储能平均功率重心稍微偏向充电侧让SoC围绕目标值长期稳定。4.3 优化算法打分函数的方向搞反容量优化里最容易犯的方向性错误是把目标函数写成“调频收益减成本”。听起来没错但如果没有把收益函数和调频性能指标挂钩优化算法就可能钻空子只要把储能配得非常小成本很低目标函数值反而不错。正确做法是把“调频性能达标”设成硬约束在性能不达标时不参与候选解或者在目标函数中加一个足够大的惩罚项。我的做法是CPS1指标低于某个阈值时直接把目标函数值赋成一个极大正数让粒子群自动放弃这种配置。4.4 仿真求解器设置不当导致结果虚假Simulink里默认的求解器对带Transport Delay和快速开关特性的系统有时会采用非常小的步长仿真半天跑不完一步。我建议使用固定步长求解器步长视信号特性而定。比如AGC指令采样周期是0.1s固定步长选0.01s到0.02s能兼顾精度和速度。另外一个细节是当储能功率快速切换时Simulink会报过零检测错误。可以在Saturation模块前加一阶惯性小时间常数既保留物理意义又能规避数值振荡。4.5 常见问题速查表现象可能原因排查与解决仿真发散变量输出NaN代数环或积分步长过大检查控制策略模块是否存在直接反馈环调小固定步长储能SoC长期不变SoC计算中能量单位不一致核对储能功率单位MW与能量单位MWh换算确认是否漏乘时间步长PSO结果每次运行差异巨大随机种子的差异未控制在PSO初始化时固定随机数种子让结果可复现调频性能反而变差滤波时间常数过小储能补偿过度增大T_filter重新调整火电参考指令的平滑度电池循环寿命过低SoC恢复层频繁深度充放缩小SoC工作区间加入SoC边界软约束仿真时间过长模型步长过小或储能模型过复杂换用固定步长并考虑简化电池模型这类问题表在实际复现时特别有用建议直接贴在项目文档里省得每次重新排查。5. 容量优化结果的敏感性分析心得容量优化不能只出一组结果就收工。储能投资决策里单位投资成本、调频里程补偿价格、储能循环寿命这三个参数变化非常大不同区域、不同时间点差异能有数倍。我通常会对这三个参数做敏感性分析各自在基准值基础上变动正负20%和正负50%看最优配置怎么移动。实测下来储能单位能量成本对最优功率容量比影响最大。因为调频收益主要取决于功率能力而投资成本很大程度取决于容量大小当单位容量成本下降时最优配置会明显往“大容量化”方向走储能参与调频的可持续性变得更强。调频里程补偿价格则主要影响储能规模的整体量级补偿价格越高最优配置规模越大。循环寿命参数影响比较微妙它主要改变的是“储能是否需要在中途更换电池”的结论进而影响全生命周期净收益的计算口径。在做项目汇报时我建议除了给出基准结果再附上一张敏感性分析表。决策者最关心的往往不是最优值本身而是“如果外部条件变了这个配置还能不能用”。说实话这比把目标函数调得再精细都有说服力。6. 仿真模型的扩展方向整套方案里我目前最常被问到的是“能不能适配其他控制策略”。完全可以。这个模型框架把控制策略模块相对独立出来你可以把低通滤波替换成模型预测控制或者模糊控制器只需要更换控制策略子模块内的逻辑即可。但要注意一点任何复杂控制算法在调频这种高频小扰动场景下都可能跑不过一个调好参数的经典控制器。模型预测控制如果采样周期跟不上AGC指令下发周期预测优势根本发挥不出来。另外容量优化目标函数里也可以加入一次调频的贡献或者把储能参与调峰、备用等多元化收益场景纳进来模型框架不用大改只需要增加收益项就行。如果关注点变成“储能和新能源场站联合调频”也可以沿用这套仿真模型框架把火电模型替换成新能源出力模型再重新整定滤波参数和SoC恢复参数即可。我个人的体会是这类研究真正的价值并不在于把控制策略和优化算法做得多么花哨而在于把“电网要求、火电能力、储能特性、投资收益”这四个维度放进同一套仿真环境里进行量化权衡。把模型搭好之后很多从经验出发的直觉判断都会在仿真数据面前得到更清晰的印证或者修正。最后再分享一个小技巧仿真项目做到后期务必把所有关键参数集中到一个Matlab脚本文件的最前面用统一的前缀命名比如P_rated、E_rated、T_filter、SOC_ref。我早期吃过一次亏参数散落在十几个地方改一个漏一个调优时出了好几组完全没法解释的“异常结果”排查下来全是参数没同步。这个习惯养成了整套复现流程会顺很多。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进