微电网调度优化的MPC滚动优化:Matlab实现与避坑指南
发布时间:2026/10/6 4:15:00 作者:尧图编辑部 阅读量:1,286

做微电网调度优化的时候我一开始还迷信开环最优——给定一整天的光伏、负荷预测曲线一次性求解出每个时段的储能充放电计划和柴油机出力计划认为只要预测够准这个方案就行得通。直到某次仿真中我故意给光伏预测注入30%的偏差结果彻底翻车储能SOC被顶到下限联络线长时间越限柴油机爬坡跟不上整个调度计划完全失效。从那次之后我把研究重心转向了基于模型预测控制MPC的微电网调度优化并且在Matlab里完整搭建了一套滚动优化的调度框架。这篇文章不是教科书式的原理复述而是我从建模、编码到仿真验证全流程走下来之后把真正有效、可复现的做法和踩过的坑整理出来给正在做微电网调度优化的同学一个可直接参考的路线。1. 为什么微电网调度绕不开MPC先看看传统做法卡在哪1.1 微电网调度不是简单的经济调度微电网和常规大电网最大的区别就一个字小。规模小、惯性小、可再生能源占比高、可调度资源少。常规电网里一台机组出力波动几个兆瓦基本看不出来微电网里一阵云飘过来遮住光伏出力可能瞬间掉一半这时候储能和柴油机必须立刻兜住。微电网调度本质上解决的是这样一个问题在满足负荷需求的前提下如何分配光伏、储能、柴油机和联络线的功率让运行成本最低、约束全部满足。听起来和传统经济调度很像但有几个特点让它比常规调度棘手得多。调度单元的动态特性差异巨大。我把典型并网型微电网里的单元列一下单元类型可控性响应速度主要约束光伏/风电不可控分钟级波动预测误差大、出力上限储能系统双向可控秒级响应SOC上下限、充放电功率上限柴油发电机可控但有延迟分钟级出力上下限、爬坡速率、最小启停时间联络线半可控较快传输功率上限、购售电价负荷部分可调取决于需求响应可中断量、舒适度约束在这些单元里储能是最灵活的调节资源但它的SOC有记忆性——今天多放一度电明天就少一度可用。柴油机虽然可以随时调但爬坡速率慢而且一启一停成本很高。联络线虽然可以买电卖电但购电价和售电价通常不对等还有功率上限。这些动态约束叠加在一起使得调度问题必须考虑时间上的耦合而不能只看某一个时刻。1.2 确定性优化的天真假设传统的微电网经济调度绝大多数做法是先做光伏和负荷的超短期预测得到一条确定性的全天曲线然后把一天划分成若干个时段比如15分钟一个点共96个点一次性求解出一个完整的调度计划。这种做法本质上是开环的——所有决策都建立在预测是准确的这个假设上。问题在于这个假设在微电网场景下站不住脚。分布式光伏的功率密度大、波动快阴天时预测误差可以轻松超过20%负荷预测也常常因为用户行为随机性出现明显偏差。一旦预测和实际不符开环计划就完全失效该充电的时候没充该放电的时候储能在下限卡着柴油机因为爬坡限制无法临时顶上……我见过不止一个项目在测试时因为一个突发阴天联络线越限直接被考核罚款。你可能会说那我在实时运行的时候根据当前状态手动调整不就行了这是很多现场的实际做法但问题是人工调整没有全局最优性——你只知道这一刻缺电了要让柴油机顶上去却不知道储能该不该在这一刻把最后的电量放出来因为你还得考虑未来两小时可能出现的晚高峰。这种边走边看的决策本质上就需要一个能同时兼顾当前状态和未来预测的控制器。1.3 MPC的核心是滚动地做最优决策MPCModel Predictive Control之所以适合微电网调度因为它把决策方式从一次算全局改成了三步一循环预测基于当前实测状态和最新的光伏、负荷预测推算未来一个有限时域内的系统动态优化在当前状态下求解一个带约束的有限时域优化问题得到未来N步的最优控制序列反馈校正只执行控制序列里的第一步等到下一个采样时刻用实测状态重新校正后再次重复预测和优化。这就像开车导航你不会在出发前规划好一条路线就闷头开到底而是根据实时路况每隔几分钟重新规划一次路线。每次重新规划的时候都会把当前位置作为起点重新计算这就是滚动优化和反馈校正的朴素逻辑。MPC带来的直接好处是即使预测有误差每个控制周期都会用实测状态修正一次误差不会被无限制累积。储能SOC偏低了下一周期优化就会发现并调整光伏突然变少了下一周期优化就会安排柴油机和联络线多出力。这种边算边改的机制让MPC在处理微电网这种高不确定性场景时天然比开环调度更有优势。2. 微电网MPC调度建模状态量、约束与目标函数的取舍2.1 状态空间模型怎么搭用MPC做微电网调度第一件事就是把微电网的动态行为抽象成一个状态空间模型。我用一个简化并网型微电网为例光伏储能柴油机联络线固定负荷。这个系统可以写成标准形式$$ x_{k1} A x_k B u_k E d_k $$其中状态向量、控制向量、扰动向量的选取需要仔细思考。我的做法是状态量 $x [SOC, P_{dg}]^T$储能荷电状态和柴油机当前出力。SOC是储能动态的直接体现柴油机出力作为状态是为了施加爬坡约束控制量 $u [P_{ch}, P_{dis}, P_{dg,ref}]^T$储能充电功率、放电功率、柴油机出力设定值扰动 $d [P_{pv}, P_{load}]^T$光伏预测出力、负荷预测值这两个不可控作为已知扰动序列输入。储能SOC的动态方程是$$ SOC_{k1} SOC_k - \frac{\eta_c \cdot P_{ch,k} \cdot T_s}{E_{cap}} \frac{P_{dis,k} \cdot T_s}{\eta_d \cdot E_{cap}} $$其中$\eta_c$和$\eta_d$分别是充放电效率$T_s$是采样周期小时$E_{cap}$是储能额定容量。这里我把充电和放电拆成两个非负变量而不是用一个带符号的$P_{bat}$主要有两个考虑一是充放电效率不同合并变量没法准确建模二是后续在YALMIP里写约束时更清晰。有人会担心充电和放电变量同时为正既充又放的情况这其实不需要额外加互补约束——目标函数里给充放电功率加一个很小的损耗惩罚项求解器就会自然避免这种物理上不合理的操作。柴油机用一个一阶惯性模型近似$$ P_{dg,k1} P_{dg,k} R_{dg,k}, \quad -R_{max} \le R_{dg,k} \le R_{max} $$这个$R_{dg}$不单独作为决策变量而是通过约束间接表达爬坡限制。实际建模时你既可以把爬坡量$R$写成决策变量也可以用$P_{dg,ref}$作为控制量再加斜率约束两种方式等价。2.2 目标函数与约束条件的工程化设计MPC的优化问题可以抽象为$$ \min_{u_0, u_1, ..., u_{N-1}} \sum_{k0}^{N-1} J_k(x_k, u_k, d_k) J_N(x_N) $$在微电网调度场景下目标函数$J_k$通常包含这几部分购电成本从主网购电的费用按分时电价$c_{grid}(k)$乘以联络线功率$P_{grid}$计算燃料成本柴油机出力对应的燃料费用$c_{dg} \cdot P_{dg}$储能损耗成本充放电过程中的能量损耗和管理成本$c_{bat}\cdot(P_{ch}P_{dis})$这个项还有防止充放电同开的额外作用松弛惩罚对约束越限的惩罚后面会详说控制动作惩罚$\Delta u^T R \Delta u$防止储能充放电指令频繁跳变对实际设备寿命不友好。联络线功率$P_{grid}$不用单独设决策变量可以直接用功率平衡等式表达$$ P_{grid} P_{load} - P_{pv} - P_{dg} - (P_{dis} - P_{ch}) $$然后把$P_{grid}$代入目标函数和联络线约束里。这样变量数更少求解更快。约束条件方面我把它们分成三个层级第一层硬约束。功率平衡等式是必须满足的因为微电网内功率不平衡就意味频率波动甚至失稳。这一约束没有任何商量余地。第二层物理极限。储能的SOC范围比如0.2~0.9、充放电功率上限、柴油机出力上下限、爬坡速率。这些约束来自设备物理特性大部分也必须满足。但我建议SOC和联络线功率这两个约束做成软约束加松弛变量原因后面在踩坑部分细说。第三层末端约束。预测时域结束时SOC不应该太低否则这一轮优化会倾向于把储能放空下一轮就没法用了。常见做法是加SOC末端约束或末端惩罚项。2.3 预测模型的两种处理方式这里要澄清一个特别容易混淆的点。MPC里的模型其实有两层含义一层是描述系统动态的控制模型也就是状态方程另一层是提供未来扰动序列的预测模型光伏和负荷预测。很多人以为MPC里要做预测模型就是用神经网络、ARIMA做光伏预测其实在MPC框架里光伏和负荷预测只是作为已知的外生输入序列传入优化问题重点在优化而不在预测。处理预测信息有两种常见方式。第一种是直接把预测序列当已知量。在每个滚动周期用一个独立的预测模块可以是持久模型、ARIMA、神经网络甚至是调度系统里的气象预报给出未来N步的光伏和负荷预测然后传入MPC优化问题。这种方式灵活预测模块可以随时替换。第二种是考虑预测误差的鲁棒MPC。把预测误差建模为一个扰动集合在优化时保证集合内所有情形都满足约束。这个方法理论上更严密但计算负担大、解往往偏保守我建议入门阶段不要碰先把标准的滚动优化跑通再说。3. Matlab实现方案工具箱与自编码求解器的对比3.1 Model Predictive Control Toolbox的快速原型Matlab自带的Model Predictive Control Toolbox可以快速搭建简单的MPC控制器。它对线性时不变系统支持很完整你只需要定义状态空间矩阵$A$、$B$、$C$设定MV操纵变量、MO测量输出、MD测量扰动然后就能生成MPC对象。下面是一个最简单的示例框架% 定义微电网线性状态空间模型 A [1, 0; 0, 1]; % 实际需要根据系统参数计算 B [...]; % 控制输入矩阵 C [1, 0; 0, 1]; D 0; sys_dt ss(A, B, C, D, Ts); % 创建MPC对象 mpcobj mpc(sys_dt, Ts); mpcobj.PredictionHorizon 24; mpcobj.ControlHorizon 8; % 设定变量属性 mpcobj.MV(1).Min -500; mpcobj.MV(1).Max 500; % 储能功率 mpcobj.MV(2).Min 100; mpcobj.MV(2).Max 600; % 柴油机出力 mpcobj.MV(1).RateMin -800; mpcobj.MV(1).RateMax 800; mpcobj.OV(1).Min 0.2; mpcobj.OV(1).Max 0.9; % SOC约束用工具箱的好处是代码量少、和Simulink联合仿真方便非常适合快速验证算法逻辑。但它有几个缺点在微电网调度场景下很致命一是自定义目标函数非常麻烦工具箱的目标函数权重矩阵虽然可以设置但很难加入分时电价这种时变函数二是预测序列的更新接口不够灵活你要模拟预测误差随预测时长逐渐增大这类真实情况很费劲。所以我的建议是工具箱适合做Demo真正做研究或工程验证自己用YALMIP写。3.2 YALMIP求解器研究级自由度的做法我的主力方案是用YALMIP建模搭配求解器求解。YALMIP是一个Matlab的工具箱它最大的价值不是求解优化问题而是把建模和求解解耦——你只需要用%sdpvar声明决策变量用constraints写约束和objective定义目标函数最后调用optimize时再指定具体求解器。这样换求解器只需要改一行参数非常方便。求解器方面微电网调度问题通常是线性约束下的二次规划QP或者纯线性规划LP。我推荐以下选择求解器类型许可适用场景OSQP开源QP求解器免费中等规模、需要快速求解Gurobi商业LP/QP有学术许可大规模、鲁棒性强CPLEX商业LP/QP有学术许可大规模、工业标准quadprogMatlab内置随Matlab小规模、快速验证如果只是学习验证用osqp就够了如果要做严谨的对比实验建议用Gurobi——它的数值稳定性远好于osqp尤其当你的模型里同时存在数量级差异很大的参数时。3.3 滚动更新闭环代码的关键结构一个完整的MPC微电网调度主循环核心框架如下% 参数设置 Ts 15; % 采样周期(分钟) N 24; % 预测时域步数 E_cap 2000; % 储能容量(kWh) soc_min 0.2; soc_max 0.9; % SOC边界 P_bat_max 500; % 储能最大充放电功率(kW) P_tie_max 800; % 联络线功率上限(kW) P_dg_max 600; P_dg_min 100;% 柴油机出力范围(kW) ramp_max 120; % 爬坡速率(kW/周期) ops sdpsettings(solver,osqp,verbose,0); T_total 96; % 一天96个采样点 for t 1:T_total % 第1步读取当前实测状态 x_meas [soc_meas(t); p_dg_meas(t)]; % 第2步获取未来N步的预测序列光伏、负荷 d_pred [pv_pred(t:tN-1); load_pred(t:tN-1)]; % 第3步构造优化问题的决策变量 U_pc sdpvar(1, N); % 储能充电功率 U_pd sdpvar(1, N); % 储能放电功率 U_dg sdpvar(1, N); % 柴油机出力 X_soc sdpvar(1, N1); % SOC轨迹 S_slack sdpvar(1, N); % 联络线松弛变量 % 第4步约束条件 constraints [X_soc(1) x_meas(1)]; % 初值用实测SOC constraints [constraints, U_dg(1) x_meas(2)]; % 初值用实测柴发出力 for k 1:N % 储能SOC动态 constraints [constraints, ... X_soc(k1) X_soc(k) - (U_pc(k)/0.95 - 0.95*U_pd(k))*Ts/60/E_cap]; % 储能功率和SOC约束 constraints [constraints, 0 U_pc(k) P_bat_max]; constraints [constraints, 0 U_pd(k) P_bat_max]; constraints [constraints, soc_min X_soc(k1) soc_max]; % 柴油机出力与爬坡约束 constraints [constraints, P_dg_min U_dg(k) P_dg_max]; if k N constraints [constraints, ... -ramp_max U_dg(k1) - U_dg(k) ramp_max]; end % 功率平衡与联络线约束软约束 P_grid d_pred(2,k) - d_pred(1,k) - U_dg(k) - (U_pd(k) - U_pc(k)); constraints [constraints, ... -P_tie_max - S_slack(k) P_grid P_tie_max S_slack(k)]; constraints [constraints, S_slack(k) 0]; end % 第5步目标函数 % c_grid(t:tN-1)是未来N步的分时电价 % P_grid是上面算出的联络线功率sdpvar表达式 objective sum(c_grid(t:tN-1) .* P_grid) ... c_dg * sum(U_dg) ... c_bat * sum(U_pc U_pd) ... M * sum(S_slack); % 第6步求解并判决 status optimize(constraints, objective, ops); if status.problem ~ 0 warning(Time step %d: solver failed, t); end % 第7步只施加第一个控制量其余丢弃 p_bat_cmd(t) value(U_pc(1)) - value(U_pd(1)); p_dg_cmd(t) value(U_dg(1)); % 第8步把控制指令传给被控对象仿真模型更新状态 [soc_meas(t1), p_dg_meas(t1)] plant_step(soc_meas(t), p_dg_meas(t), ... p_bat_cmd(t), p_dg_cmd(t), pv_actual(t), load_actual(t)); end这段代码我故意保留了很多细节因为每一个被省略的细节都可能是后面调试两小时的根源。比如U_dg(1) x_meas(2)这一步很多人会漏掉——柴油机出力是状态量如果不把当前实测出力作为优化初值第一次爬坡约束就会失真。再比如S_slack的取值要非负否则求解器会通过减小松弛来优化目标而没有任何代价。3.4 与仿真模型解耦的关键认知这里要强调一个MPC里特别重要的概念MPC控制器内部使用的模型和仿真里被控对象的模型不应该是同一个模型。控制器里的模型预测模型是简化近似仿真里的模型是真实世界的代表可以更精细、包含效率曲线、非线性环节等。这个区分在工程上很重要因为MPC的反馈校正机制本来就能容忍一定程度的模型失配如果控制器和仿真用同一模型反而掩盖了实际运行时可能出现的模型误差。我在编码时习惯把这两套模型分开写控制器内部的predict_model.m只做简单的线性递推仿真里的plant_step.m则加上了储能效率随SOC变化的非线性特性、柴油机的最小启停时间等细节。这样跑出来的结果才更接近真实场景也更符合论文里对MPC鲁棒性的论证逻辑。4. 仿真验证与结果分析MPC比开环优在哪里4.1 典型日场景设置我在验证MPC效果时构造了一个典型的并网型微电网测试场景参数如下参数数值光伏装机容量800 kW储能额定容量2000 kWh储能最大充放电功率±500 kW储能SOC范围0.2 ~ 0.9柴油机额定功率300 kW可出力100~300 kW柴油机爬坡速率120 kW/周期联络线功率上限±800 kW采样周期15 min预测时域24步6小时分时电价设置为峰段10:00-14:00、18:00-21:001.2元/kWh平段0.8元/kWh谷段23:00-次日7:000.4元/kWh。柴油机燃料成本按0.9元/kWh折算。这一天里光伏出力呈典型的早晚低、中午高形态负荷呈现两个高峰上午和晚间。预测误差的注入方式很关键。我没有用一次性预测也就是在t0时生成全天预测然后不再更新而是模拟了更真实的情况在每个采样时刻根据当前实测值重新生成未来预测序列预测误差随预测距离增大而增加即$d_{pred}(tk|t) d_{actual}(tk) \epsilon_k$其中$\epsilon_k$的标准差随$k$增大。我在测试中采用的均方根误差在第1步约5%、在第24步约15%这是光伏短期预测的典型水平。4.2 三种策略的调度结果对比我对比了三种策略开环完美预测作为性能上界参考、MPC完美预测、MPC带预测误差、开环带预测误差。开环策略就是一次性求解全天96步的优化问题用完就不改了。结果如下策略总运行成本元SOC越限次数联络线越限次数负荷缺供次数开环完美预测12680000MPC完美预测12720000MPC带预测误差13150000开环带预测误差14580431先说MPC完美预测和开环完美预测的对比。两者成本差得很小约0.3%说明MPC滚动优化在完美预测下不会比开环最优差很多。多出来的那点成本来自末端效应——预测时域只有24步最后几个时段优化器看不到未来会做出一些短视决策。这是MPC的固有特性不是bug。但带预测误差的场景就完全不同了。开环带误差时因为计划是基于错误预测算出来的实际运行时光伏出力低于预期储能被反复过度充放SOC在傍晚时段连续4次越限晚间负荷高峰时联络线两次顶到上限不得不切掉一部分可中断负荷。而MPC带误差时虽然成本比完美预测高3.4%但所有约束都满足没有发生失负荷。这就是反馈校正的价值——每一步都在用实测状态修正轨迹误差只影响接下来一个控制周期而不会累积成全天性的崩溃。4.3 SOC轨迹和联络线功率的动态差异如果去看SOC轨迹曲线差异非常直观。开环调度在完美预测下的SOC是一条平滑的充电-放电曲线谷段充电、峰段放电、晚高峰前留有余量。但带误差时因为光伏没有达到预测值储能的实际放电深度比计划深得多傍晚时SOC一路跌破0.2的下限而此时距离晚高峰还有两个小时储能已经没有余量了。柴油机虽然想顶上但爬坡速率限制决定了它不可能瞬间从100kW加到300kW。MPC带误差的SOC轨迹虽然也有波动但始终被控制在0.25~0.85之间且没有触碰边界。这是MPC的一个微妙之处它并不是让SOC更平稳而是让SOC在有偏差时能提前调整。比如光伏在某段时间低于预测时下一轮优化立刻减少放电指令甚至在低谷时段提前充电为后续高峰留出余量。这种提前量为未来负责的能力是任何基于固定计划的方法都给不了的。5. 把MPC调度落地时踩过的坑5.1 预测时域长度的选择太短了储能沦为近视眼预测时域$N$的选择直接影响调度性能。我最初为了减小优化规模把$N$设为8步2小时结果发现储能调度完全是近视眼行为晚上12点到早上5点的低谷电价时段因为看不到6小时后才会到来的早高峰储能总是充电不足到了峰段储能很快放空柴油机长期高负荷运行成本反而比开环调度还高。这里的问题出在储能的时间尺度上。储能的完整充放循环横跨低谷到高峰至少需要6到10个小时。如果预测时域小于这个周期优化器就看不到完整的电价差做出的决策自然短视。我最终把$N$设为24步6小时成本明显下降。经验法则是预测时域至少覆盖一个完整的充放电周期或者覆盖未来6~8个小时。当然$N$也不是越大越好超过一定步数后优化求解时间急剧上升且远期预测误差大到无意义。5.2 数值尺度不归一化求解器直接罢工这是我在自编码求解时遇到的最诡异的坑。刚跑通MPC时用OSQP求解经常出现求解成功但结果明显不合理的情况——SOC轨迹锯齿状跳变、柴油机出力震荡。排查了很久最后发现是数值尺度问题。模型里储能容量是2000kWh、功率是500kW、电价是0.4~1.2元/kWh、SOC是0.2~0.9、爬坡约束是120kW/周期这些量数量级差异太大导致约束矩阵的条件数很差求解器在数值容差范围内做决策时会牺牲那些数值上看起来很小的约束比如SOC精度。解决方法很朴素把物理量换算到统一量级。我的做法是功率全部改用MW表示储能容量改用MWh电价保持元/kWh不变这样模型中最大的数值也不会超过几千。换算之后同样的模型用OSQP求解结果立刻稳定了。后来我遇到过一次类似问题是目标函数里M系数松弛变量惩罚系数设得过大导致数值病态把M从100000降到1000就好转了。这提醒我在Matlab里做MPC代码逻辑只是第一步数值卫生同样决定成败。5.3 求解耗时与热启动技巧虽然微电网调度的控制周期通常是5分钟或15分钟看似不需要极速求解但如果你做的是硬件在环测试或者实时仿真求解耗时依然重要。我在测试中发现模型在预测时域24步、决策变量约72个的规模下冷启动求解需要约0.8秒OSQP这其实已经可以接受。但如果把预测时域加到48步或者增加更多控制单元求解时间会飙升到2秒以上。一个很有效的优化手段是热启动。MPC滚动优化有一个天然优势上一轮的最优解和这一轮的最优解非常接近因为只是时间窗平移了一步状态变化很小。把这个先验信息充分利用起来可以让求解器从接近最优解的位置开始迭代大幅减少迭代次数。在YALMIP里实现很简单% 第一次求解后保存结果 sol optimize(constraints, objective, ops); % 下一周期求解前把上一周期的解赋为初值 for i 1:length(U_pc) assign(U_pc(i), value(U_pc(i, prev_sol))); end assign(X_soc(1), x_meas(1)); optimize(constraints, objective, ops, sol); % 注意ops后面可以传sol实测用上热启动后单步求解时间从0.8秒降到了0.3秒左右而且不需要牺牲精度。如果用的是Gurobi它的自带WarmStart机制会更方便连手动assign都不用。5.4 硬约束与软约束的哲学允许无解比约束越限更糟我第一次做MPC时把所有约束都设成硬约束包括SOC界限和联络线功率上限。结果在一个预测误差特别大的场景里优化返回了问题不可行infeasible的提示。这时候我的代码直接崩了——但真实系统里MPC的崩意味着这一轮没有控制指令输出储能可能维持上一周期的指令继续运行而系统状态其实已经严重偏离预期。在工业场景里这是绝对不能接受的。正确做法是把那些可能会因为预测误差而被逼到极限的约束设成软约束即添加松弛变量让约束在极端情况下可以稍微越界但越界要付出代价。在目标函数里加的惩罚项$M \cdot s$$M$要足够大——大到正常情况下求解器不会主动选择越界但又不能大到让数值病态。我实践下来$M$取正常运行成本量级的1000倍左右比较合适。这里还有一个容易踩的坑切负荷惩罚和购电价格的相对关系。如果切负荷惩罚设得比购电价低那么求解器在峰段可能倾向于选择切负荷而不是高价购电这在微电网场景中是违背运行原则的失负荷的代价远高于电价。所以目标函数里的惩罚系数排序应该是切负荷罚 储能SOC松弛罚 联络线越限罚 柴油机燃料成本 储能损耗成本。5.5 预测更新的建模细节最后分享一个关于测试方法论的细节。很多人在仿真MPC时习惯把所有时段的预测数据事先算好然后每个滚动周期直接读取对应时间段的预测值。这种做法的本质是离线预测在线优化虽然也能跑通MPC但它没有模拟出预测模块在线更新的过程MPC的鲁棒性优势会被大大低估。正确的做法是让预测序列在每个采样时刻动态生成——每次滚动时用当前实测值作为最新信息重新计算未来预测序列哪怕只是简单的持续性预测未来k步的预测值等于当前实测值加一个衰减的趋势项也要保证每一步的预测序列都不同。这样才能真实反映预测误差随时间的演变也能让你在分析结果时区分清楚MPC的性能提升是来自滚动优化还是来自预测算法的准。最后聊几句实际感受做完这个MPC微电网调度项目我最深的体会是MPC不是一个高深莫测的算法它只是把走一步看一步、看一步修正一步的朴素逻辑用数学形式固化了下来。它在微电网里的成功不是因为预测模型有多准而是因为每个控制周期都在用实测状态修正轨迹让误差始终被限制在可控范围内。如果让我给后来者一条最实用的建议那就是不要急着追求复杂的模型和昂贵的求解器。先用YALMIP搭一个最简版本的滚动优化框架——线性模型、完美预测、单个储能加柴油机——把这个框架跑通再逐步加入预测误差、软约束、效率非线性这些细节。框架对了后面的问题基本都是调试问题框架不对换再好的求解器、再精细的模型也救不了。另外一个细节是测试MPC时一定要分清楚完美预测下的MPC和带误差下的MPC前者验证算法本身的收敛性后者验证方法在真实场景下的鲁棒性——两者的意义完全不同但很多初稿论文都栽在这两者的混淆上。