前几天有个做微网调度的朋友问我:共享储能加入之后,原来的日前优化还有什么要改?我当时的回答是,改的不是“要不要优化”,而是“怎么把一次性计划改成能随时修正的闭环”。后来我花了两周时间,把一套基于MPC的微网共享储能优化调度框架从建模跑到了仿真验证,踩了不少坑,也攒了不少心得。今天就把这套探索过程完整展开,聊聊日前日内两级调度到底在解决什么问题、MPC怎么跟共享储能结合、模型和参数怎么定,以及真正落地上有哪些绕不开的细节。适合正在做园区微网、区域综合能源、虚拟电厂调度的同行,也适合刚接触这个方向、想找个可落地框架参考的研究者。
1. 微网共享储能的调度问题到底难在哪
1.1 “自己的储能”和“共享储能”是两码事
自己做微网储能调度时,储能资产是自己的,容量固定,成本自己承担,想怎么充放电基本是内部事务。但共享储能不一样:储能站是别人的,你通过租赁容量、按次结算或者服务费分成来获得使用权。这就带来两个本质变化。第一,控制权不是完全的,你申报的充放电计划要经过储能运营商确认才执行,调度指令不是“我说了算”而是“我要提前告诉别人”。第二,成本结构变了,除了能量费用,还有容量费用、度电服务费,甚至还有最小使用时长、违约惩罚。如果只是把共享储能当成一个“可以放电的电源”,忽略费用结构和容量约束差异,算出来的计划要么执行不了,要么成本虚低。
我在实际项目里最大的体会是,共享储能调度本质上是“资源租赁+能量优化”的耦合问题。租赁计划决定你在这个月或者这一天能用的最大容量,这是战略层;能量优化决定在这些容量下怎么充放电,这是战术层。两者时间尺度不一样,不能塞进同一个简单模型里硬解,必须分层处理。这也是为什么我说微网调度不是变简单了,而是变得更需要结构化设计。
1.2 源-荷预测不准是调度最大的敌人
微网里的光伏和风电都有强随机性,负荷也不安分。传统日前优化基于一个点预测,比如预测明天中午光伏满发,实际发现中午云飘过来,出力只剩一半;下午负荷又突然涨了一波,这时候储能如果已经按计划在上午充满电,下午就没有调节空间了。这种问题不是预测模型不够好,而是“一次性求解+一次性执行”的机制天然脆弱。
很多教材会讲鲁棒优化、随机规划来处理不确定性,我也试过。鲁棒优化太保守,最坏场景下代价太大;随机规划的典型场景生成和求解复杂度又很高,而且对概率分布假设敏感。相比之下,MPC的思路更像是“走一步看一步”:不要试图一次定好全天的每个动作,而是每到一个新时刻,看看当前状态、重新预测未来一小段,再决定当前这一步。预测误差的影响被限制在滚动窗口内,不会因为一个中等偏差拖垮全天计划。这个机制说起来简单,但真正把模型写好、把约束理清,需要下功夫。
1.3 传统静态优化为什么撑不住
静态日前优化输出一组调度曲线,计划明天某个时段充电100千瓦、放电150千瓦,都是固定值。如果实际运行和预测完全一致,这组曲线没问题;可现实是我们永远活在预测误差里。偏差出现后,要么调度员人工手动调整,要么重新跑一遍优化。重新跑优化其实有点MPC的意思,但如果没有处理好状态初值、约束相容性,容易出现上一步计划和下一步计划“打架”:把SOC初值弄对,把储能状态变量继承过来,还要保证新解不会颠覆之前的整体经济性。这些细节处理不好,计划就会来回跳,储能设备会被折腾得频繁启停。
MPC从机制上就允许计划“滚着往前走”,每步只执行第一个动作,后面都是参考,下一步再基于新状态重新优化。这天然避免了传统重优化导致的大幅跳跃。所以,微网调度从静态优化走向MPC,不是追逐时髦,而是被不确定性和设备物理约束逼出来的选择。
2. 用MPC做日前-日内两级调度:整体设计思路
2.1 MPC的本质:滚动优化+反馈校正
说句实在话,MPC刚接触时容易觉得高深,但把外壳拆掉后,内核就两件事:滚动优化和反馈校正。滚动优化就是每次只优化一个有限时域的决策序列,但只执行第一步;反馈校正是用最新实测状态去修正模型初值和预测输出。为了便于理解,可以类比开车:你不需要一次性规划出到目的地的每一米路线,只需要看前方几百米的路况,打当前这一步方向盘,到了新的位置再看前方,再调整。共享储能调度也是这样,每个采样时刻,系统读取当前光伏出力、负荷、储能SOC和电价,调用预测模型生成未来数小时的“路况”,然后求解一个有限时域优化问题,得到未来的充放电序列,但只执行当前一刻的动作,等下一个采样时间再重复。
这里有个容易混淆的点:MPC内部说的“预测模型”不是天气或者负荷预测算法,而是描述系统动态的方程,比如SOC的递推关系、功率平衡关系。负荷预测和光伏预测是MPC的输入,不是MPC本身。做方案时如果把这两个概念混在一起,后面会很痛苦。我的建议是在架构图里明确分三层:数据预测层、MPC优化层、物理执行层,别把预测算法塞进MPC控制器内部。
2.2 日前层和日内层各自干什么
我习惯把调度框架拆成两层。日前层的任务是在运行前一天,基于次日负荷和光伏预测,优化共享储能租赁容量、各时段的充放电计划、可调负荷计划,目标是次日总运行成本最小。时间分辨率通常取1小时,因为租赁容量和合同申报往往以小时或天为颗粒度,太细没有意义。日内层的任务是当天实际运行,每15分钟滚动优化一次,利用未来2到4小时的超短期预测,修正储能功率和可调负荷,补偿日前计划与实际偏差。
两层分工的逻辑是:日前层负责“粗略但完整”的经济计划,比如要不要租容量、租多大,这决定了下限;日内层负责“精细但局部”的安全修正,比如光伏突然少发、负荷突然变了,储能怎么应对,这决定了上限。共享储能的容量租赁必须提前申报,当日难以变更,所以必须放在日前;实时充放电功率可以在合同约束内动态调整,所以放在日内。还有一点,日前计划不能随便扔掉:如果日内完全忽略日前计划,共享储能运营商的容量申报和收益核算会乱套,因此在日内优化里要加一项“计划跟踪”目标,让修正幅度尽量小,只在必要的时候偏离。
2.3 共享储能在MPC框架里怎么建模
共享储能不是“某个微网自己的电池”,建模之前要先确认角色。我做过两种模式。第一种,微网作为用户,向共享储能运营商租赁部分容量,获得充放电权利,支付容量费和度电服务费。这时储能模型可以简化成“外部可控设备”:限制自己申报给运营商的充放电功率不能超过租赁容量对应的功率限值,用“等效SOC”跟踪自己在租赁期内充了多少能量,保证最终归还时能量守恒。第二种,微网聚合商运营共享储能,服务多个微网。这时需要完整保留储能模型,目标函数中加入储能收益或者多主体费用分摊,问题复杂度提升很多。
第一次做探索性项目,我建议先按第一种模式来。因为多主体共享储能的博弈本身就够复杂,如果直接上来就做联合优化,很容易被线性化、分解算法和分摊规则淹没,反而忽略了MPC本身的滚动修正价值。先用“外部可控设备”把MPC跑通,再看怎么扩展成多微网联合,路径更清晰。
3. 实操细节:建模、约束与目标函数怎么写
3.1 日前层的决策变量与目标函数
把一套可复用的MPC框架跑起来,第一关就是把模型写成标准优化问题。我给的日前层目标函数是这样一个形式:最小化各时段从电网购电成本、向电网售电收益、共享储能服务费、容量租赁费用,以及弃光惩罚。用简单公式表达就是:
[ \min \sum_{t} \left( c_{buy,t}P_{buy,t} - c_{sell,t}P_{sell,t} + c_{use}(P_{cha,t}+P_{dis,t}) + c_{rent}\frac{R}{30} + c_{curtail}P_{curtail,t} \right) ]
其中,(P_{buy,t})是时段t从主网购电功率,(P_{sell,t})是反送功率,(P_{cha,t})和(P_{dis,t})是共享储能充电和放电功率,(R)是租赁容量,按天折算租金时除以30,(P_{curtail,t})是弃光功率。注意充放电不要写成同一变量取正负,因为MPC求解器中符号变量处理起来容易出不等式冲突,最好拆成两个非负变量,并加互斥约束。
约束条件包括:功率平衡约束(光伏+购电+放电=负荷+充电+售电+弃光);共享储能SOC递推;SOC上下限;购售电不能同时进行;充放电上限与租赁容量挂钩。这里有个容易被忽略的陷阱:共享储能作为外部资源,微网没有义务把SOC恢复到某个指定值,但实际结算通常要求“当日充电量基本等于当日放电量”,否则你会多算或漏算费用。所以我在日前模型里加了“SOC起止相等”的终端约束:一个调度周期结束时,等效SOC与开始相等,让系统自己决定是先充后放还是随机充放。这样不会出现为了省钱而充满不放电的投机解。
3.2 日内层的预测模型与滚动窗口
日内层的时间分辨率我取15分钟,预测时域取2到4小时。为什么是15分钟而不是5分钟或者1小时?因为共享储能和微网通信的指令周期通常就是15分钟级别,太短了频繁调整会让储能EMS系统疲惫,也太长了追踪不了快速变化。预测时域2到4小时能覆盖光伏午间波动和电价拐点,又不至于让求解规模太大。如果把预测时域拉到8小时,超短期预测后半段基本是猜,反而给优化引入噪声。
日内MPC每15分钟触发一次的流程是这样:读取当前微网实际功率、储能SOC、实际负荷和光伏;调用最新超短期预测(比如未来4小时,每15分钟一个点,共16个点);以上一时刻实际SOC作为当前状态,求解所在滚动窗口内的优化问题;执行第一个动作,丢弃后面的结果,等待下一轮。目标函数与日前相似,但多了日前计划跟踪项。我常写成:
[ \min \sum_{k=0}^{N} \left( C_{cost,k} + \lambda |P_{s,k} - P_{s,k}^{DA}|^2 \right) ]
其中(P_{s,k}^{DA})是日前计划中对应时刻的储能功率,(\lambda)是跟踪权重。用罚函数而不是硬约束,是为了给日内优化留出足够灵活性,尤其当出现极端天气时,硬约束会把问题逼到无解,罚函数至少还能给出一个牺牲跟踪精度的可行解。
3.3 共享储能功率/容量约束与SOC动态
等效SOC递推公式很直白:
[ E_{t+1} = E_t + \eta_c P_{cha,t}\Delta t - \frac{P_{dis,t}\Delta t}{\eta_d} ]
其中(\eta_c)是充电效率,(\eta_d)是放电效率,(\Delta t)是时间步长,单位小时。(E_t)表示微网在共享储能中“用掉”或者“储存”的能量额,单位kWh。约束条件是:(0 \le E_t \le R \cdot h),这里(h)表示租赁容量对应的储能时长,比如租0.5 MW/2 MWh,R=500kW,h=4h;充放电功率要满足(0 \le P_{cha,t} \le P_{cha,max}),(0 \le P_{dis,t} \le P_{dis,max}),而这上下限与R直接相关,比如按0.5C倍率,则每个设备最大充放电功率=0.25 MW。
实战中有一个细节:共享储能运营商常常对最小连续充放电时间有要求,因为频繁切换会加速电池循环老化,增加运维压力。理论上可以在MPC里加最小运行时间约束,但引入0/1变量后问题从LP变MILP,求解时间可能从毫秒级变成秒级甚至更久。探索阶段我不建议一开始就加,先把无最小运行时间的模型调通,再把这一约束作为扩展选项,否则你很难区分“优化结果不合理”是MPC参数问题还是整数约束问题。
还有一个我踩过的坑:不要把储能的额定效率直接当成模型效率。共享储能长期运行后,电池充放电效率会下降,运营商一般会定期测试但不会每天通报。我在模型里把充放电效率设为可配置参数,并在仿真中做了敏感度分析:当效率从95%降到88%时,最优充放电策略会发生明显变化。如果一直用95%,实际执行时可能储能会提前放完电,导致后半天无电可放。所以有条件的话,定期从运营商拿实际充放电数据来校准效率。
4. 关键参数选择与调试经验
4.1 预测时域和控制时域怎么定
“预测时域取多长”是我回答咨询最多的问题,也是MPC能不能出效果的关键。如果预测时域太短,控制器看不到远处的低谷电价或者高峰负荷,容易短视;如果太长,后半段的预测精度差,优化反而被垃圾输入带偏。我的调试方法是:先在完美预测下测试,改变预测时域,观察目标函数值和SOC轨迹是否平滑。比如对同一仿真数据,分别用2小时、4小时、8小时预测时域,看日内修正后的成本差异。我到后期发现4小时是性价比最好的选择:成本与8小时几乎一样,但求解时间少了一大半。
控制时域则基本固定在1步。因为MPC是滚动执行的,执行第一步后就会重新优化,没必要一次输出一长串指令。特别对储能这种响应速度快的设备,多步执行会放大模型误差。我见过有人把MPC生成的前三小时功率曲线直接发给储能执行,这就是把MPC用成了开环优化,一旦第三小时预测不准,控制效果还不如固定计划。正确的习惯是:MPC求解结果中的未来序列只作为“参考导轨”,真正下发执行的永远只是当前时刻的动作。
4.2 权重系数怎么调才不“顾此失彼”
MPC目标函数里有多项需要平衡:购电成本、共享储能服务费、日前计划跟踪、功率波动惩罚。权重系数代表了决策偏好,没有绝对标准,但可以按套路调。我先给经济成本项权重设为1,然后单独调跟踪系数(\lambda):如果设定值太小,日内结果会大幅偏离日前计划,导致共享储能的容量合同难以核算;如果设定值太大,日内就变成死板追计划,失去修正意义。经验法则是把(\lambda)调到“极端场景下修正幅度不超过30%、正常场景不超过10%”。
调权重时还要注意尺度。因为购电成本单位是“元”,功率偏差单位是“kW”,两者差几个数量级,直接把(\lambda)设为1会失效。我会做归一化:先把各项都折算成标幺值,再用权重表示优先级。功率波动惩罚也一样,如果设置过严,MPC会频繁调整充放电功率,看起来SOC曲线很平滑,但对储能实际寿命不友好。我后来加了个“单步功率变化率限制”,比单纯惩罚更有效,比如限制相邻两步的储能功率变化不超过额定功率的10%每分钟。这样既能抑制过调,又能减少通信指令的抖动。
4.3 求解器选择与计算耗时
MPC的求解器选择直接影响实时性。如果模型是纯连续线性,LP或QP就可以快速求解;如果加了充放电互斥变量、最小运行时间整数约束,就需要MILP求解器。我的环境中,日前MILP(24个时段,几百个约束)求解时间大约2到5秒,日内15分钟窗口(16个时段,几十个变量)求解时间通常小于1秒,完全满足15分钟周期。但如果把共享储能的最小运行时间约束加上,变量数量会翻倍,求解时间可能涨到5到10秒。这时有两个选择:一是放宽时间分辨率到30分钟,二是对整数变量做启发式初始化,先用LP松弛结果给MILP一个热启动值,能显著加速。
关于求解器选择,我建议先不用纠结开源还是商业。探索阶段可以直接用开源求解器跑LP,熟悉MPC流程;等真的要做实时控制,再评估商业MILP求解器的部署成本和性能。还有一点,MPC的实时性不只是求解速度,还包括数据读取、状态估计和指令下发整个回路。我做过一个耗时统计,求解只占30%时间,通信和IO占了50%,剩下的20%是数据对齐和预处理。所以不要只盯着求解器优化。
5. 常见问题与实战避坑
5.1 模型失配:MPC也怕“预测永远错”
MPC思路再好,也依赖模型准确性。有次做日内仿真,我用了比较好的光伏超短期预测,但实际出力还是比模型高出一大截,MPC每步都在重新优化,却一直“追不上”偏差。后来我仔细看了一眼,发现问题出在超短期预测算法本身有系统性滞后:它的预测曲线整体比实际晚一个采样周期。这个滞后通过MPC反馈也没法消除,因为MPC把预测值当作输入,输入就错了,控制自然不对。
解决办法是在MPC外面加一个“误差校正器”:统计最近几轮实际值与模型预测值的误差均值,用这个均值对未来预测做平移修正。类似天气预报里的MOS订正。我把这个误差校正加到了日内MPC的前端,效果立竿见影。从此以后,我再也不默认预测模型是无偏的了。同时,建议定期校准储能效率,前面提过这一点,这里再强调一次:效率衰减会让SOC轨迹整体偏移,表现为MPC预测的放电能力比实际多。
5.2 通信延迟与数据同步
共享储能是外部系统,它的SOC、功率数据通过通信接口上报,延迟可能从几百毫秒到几秒不等。如果MPC用了过期的SOC作为状态初值,最优解可能要求储能继续放电,但实际SOC已经接近下限,执行时就会越限。我在验证阶段做过一个测试:把SOC更新延迟设置成5分钟,MPC结果直接出现了80多次越限警告。
解决这个有几层。第一层,数据接口侧做超时保护,如果连续超过3个周期没有收到新SOC,就标记数据失效,切换到一个保守估算值。第二层,MPC侧在SOC约束里加“安全边界”,比如下限不设0而设5%,上限不设100%而设95%,给通信延迟留缓冲。第三层,在目标函数里加SOC偏离惩罚,尽量避免运行轨迹贴边。这三层叠加后,就算通信偶尔抽风,也不会导致系统崩溃。真实项目中还会遇到时间戳不同步的问题,要确保所有数据以同一个时钟为基准,否则SOC变化量和功率积分对不上。
5.3 储能寿命与充放电次数约束
如果共享储能运营商按“循环次数”向微网收费,那么MPC需要把充放电次数纳入考虑。最简单的做法是在目标函数中增加“状态切换惩罚”:每从充电变为放电,或者从放电变为充电,加一个固定成本。这相当于给开关动作“贴价签”,MPC会自动权衡是少赚一点还是减少开关。实测下来,加了开关惩罚后储能日循环次数从12次降到8次,而总成本只增加了不到3%,效果很划算。
如果运营商限制最大循环次数,比如每天最多10次,那么可以在日内层加入一个“当天已循环计数”约束。但这个约束会和滚动优化耦合:当前时刻无法准确知道未来还会切换多少次。我的处理是把最大循环次数作为软约束,在目标函数中加入边际成本递增的惩罚。比如前8次免费,第9次开始每次的惩罚成本线性增加。这样既不会因为硬约束导致无解,又能有效限制次数。还有一点经验:不要为了追求成本最优,让储能频繁在充电和放电之间跳变,即便没有直接经济惩罚,也要考虑设备本身。我对单步功率变化率的限制和开关惩罚同时使用,效果比只用其中一种好很多。
6. 一次完整的仿真实践复盘
6.1 案例配置:微网拓扑与共享储能参数
为了让这套方法能复现,我搭建了一个紧凑的仿真案例。微网拓扑是一个园区,光伏装机1.0 MW,最大负荷1.2 MW,另外有一台柴发作为备用但优先级很低。共享储能可租容量为0.5 MW/2 MWh,也就是功率0.5 MW、容量2 MWh、对应储能时长4小时,运行倍率0.25C。充放电效率设定为95%,容量月租金按30元/kWh/月计算,度电服务费0.1元/kWh。峰谷电价来自某工业分时电价曲线,峰谷差约0.7元/kWh。日前层时间分辨率1小时,日内层15分钟,预测时域4小时。我故意给超短期预测加了标准差5%的高斯噪声,来模拟现实中的不完美预报。
这个案例规模不大,但已经能覆盖共享储能的核心特征:需要租赁决策、需要跟踪计划、需要应对实时偏差。跑通之后,后续扩展多微网、多储能时可以把同样的MPC框架复制并行。
6.2 实施步骤与结果对比
第一步,运行日前优化。输入是次日全天预测的光伏曲线和负荷曲线。模型输出的结果包括:建议租赁容量R=0.5 MW,说明该微网值得租满;当日充放电计划大致为中午前充电、下午放电、晚高峰前放电。第二步,以这个日前计划为参考,运行日内MPC。从当天0点开始,每个15分钟采样一次,读取当前实际光伏和负荷,调用带噪声的超短期预测,求解滚动优化,仅执行第一步。第三步,对比两个策略:一个是“日前计划开环执行”,另一个是“日前计划+日内MPC修正”。为了公平,两者使用相同的天气场景数据。
结果数据让我很有底气:MPC策略的日运行成本比开环策略低约9%,光伏弃光率从7.3%降到2.1%,SOC越限次数为0。原因是MPC在日内发现午间光伏实际出力比预测强时,会提前增加充电功率,多存一些电到下午和晚高峰放电,减少高价购电;反过来,如果发现光伏突然变弱,它会及时减少充电,并微调放电计划,避免柴发启动。这些操作靠开环日前计划完全做不到。
6.3 从仿真到工程落地的补丁
仿真通过后,落地还有很多“最后一公里”要打通。第一,求解器通常运行在控制器或者边缘计算设备上,License部署、编译器版本、内存限制都要事先验证。我在某X86工控机上测过,MILP求解时间在0.5秒左右,没问题;但如果是ARM平台,性能会差很多,需要考虑用C++重写优化模型。第二,共享储能运营商的指令接口往往不支持每15分钟一个点的实时指令,而是希望接收一整条计划曲线。我的对策是:每次MPC求解后,把滚动窗口内的整条功率序列作为“建议曲线”发给储能EMS,储能EMS再结合自身约束执行。这样既满足接口习惯,又保留MPC的滚动修正效果。第三,必须增加“应急模式”:如果MPC连续多次求解失败,立即切换到一个本地规则控制器,例如根据SOC高低和当前电价决定充放电。这个应急控制器不需要最优,只需要稳定,给运维人员留出处理时间。
我个人在实际操作中的体会是,MPC的两级调度不是越复杂越好,而是要把不确定性按时间尺度消化:日前负责“经济预算”,日内负责“偏差修正”。共享储能的引入确实让问题复杂了,但只要把租赁容量作为日前决策、把充放电功率作为日内修正、把运营商的接口约束作为边界,整个框架就能稳定推进。最后再分享一个习惯:每次跑仿真之前,先跑一次完美预测的确定性优化作为性能上界;然后再用带噪声的场景调试MPC。这个对照习惯能帮你很快定位问题到底是出在预测环节还是优化模型本身。这套探索后续还可以往多微网构成共享储能联盟、参与电力现货市场申报等方向延伸,但先把MPC两层框架扎实跑通,才是所有扩展的基础。