
做微电网调度的人绕不开MPC这个词。今天想聊聊我搭的一套基于模型预测控制MPC的微电网调度优化方案纯Matlab代码实现不依赖商业仿真软件也能跑起来。这套东西解决的是一个非常实际的问题光伏和负荷都带不确定性储能和电网交互功率怎么跟着波动走而不是死板地照搬昨天算好的24小时计划。文章里我会把MPC的核心逻辑、微电网各元件建模、Matlab实现细节、仿真结果分析以及我踩过的坑都过一遍。适合正在做相关课题的研究生、本科毕设或者想快速把MPC用起来的工程师哪怕你之前只懂一点线性规划也能按着步骤复现出来。1. 项目到底在做什么——先拆解微电网调度问题1.1 微电网调度到底在调什么微电网可以理解为一套迷你版的大电网系统屋顶铺了光伏板配电房里放了几组储能柜下面挂着一批居民或商业负荷。调度要回答的问题其实很朴素——储能什么时候充电、什么时候放电、什么时候从外部电网买电电价合适的时候能不能反向卖一点给电网。本质上这是在满足用电需求的前提下让运行成本尽量低的连续决策问题。但现实比教科书复杂得多。光伏出力看天吃饭一片云飘过来功率可能瞬间掉两成负荷也是实时变化的早高峰、晚高峰、周末和工作日完全两样。储能虽然能搬运电量但容量有限且不能无限快充快放与大电网的联络线功率还有上限。这些硬约束叠在一起就成了一个带约束的优化问题。如果只做一次性的全局最优计算那其实是运筹学课程里的标准题。难点在于系统状态一直在变约束在变所谓最优也在变。你算出来的调度计划建立在预测之上而预测天生就会出错。这时候MPC的价值就体现出来了——它不做一次性的全局最优而是滚动地、带反馈地做局部最优把不确定性一口一口吃掉。1.2 为什么放着现成优化不用非要选MPC很多人会问我用线性规划或整数规划做一个日前调度不就行了为什么非要上MPC我举一个很典型的场景。昨天做日前计划时预测今天中午12点光伏能发150kW于是调度安排储能少放电、把电量留到晚上用。结果今天中午云层压过来光伏实际只有100kW。到下午负荷爬升时储能电量不够只能临时从电网高价买电。一次性算好的计划遇到预测偏差就只能硬扛。MPC的思路完全不同。它以当前时刻为基准只滚动预测未来有限步比如未来24小时在这个预测时域内求最优但只执行第一步。等到下一个采样时刻重新测量当前状态刷新预测再从头求解一遍。这就是滚动优化。预测错了没关系因为每一步都在用实测数据修正所以 MPC 在业界常被描述为自带纠错能力的优化控制方法。更重要的是MPC天然处理带约束的问题。SOC上下限、充放电功率限幅、购电功率上限都能直接写进优化模型里。这一点比PID这类经典控制器舒服得多——你不需要反复调增益只需要把业务约束写清楚剩下的交给求解器。尤其是针对微电网这种多输入多输出、强约束、慢动态的系统MPC几乎是为它量身定做的。1.3 这套研究代码的定位和适用场景这套Matlab实现不是什么商业级能量管理系统定位明确方法论验证和教学骨架。代码里包括完整的MPC闭环——预测模型、滚动优化、反馈校正、约束处理以及一套仿真数据生成模块。你可以拿它做论文里的对比实验也可以当课程设计的起点往上加电池老化模型、需求响应、多场景鲁棒扩展等。我做这套代码时给自己定的目标是少废话、能复现只用Matlab自带的优化工具箱就能跑数据结构尽量扁平参数集中放一个文件里方便替换。接下来我从建模开始讲把每一步为什么这么设计说清楚。2. MPC调度架构与微电网元件建模2.1 MPC三件套预测模型、滚动优化、反馈校正MPC不是一个孤立公式而是一套闭环控制框架。任何MPC逃不开三个部分预测模型、滚动优化、反馈校正。预测模型描述的是如果我现在给你一个控制动作系统未来会怎样演化。在微电网调度层面最关键的动态是储能SOC的变化。不用管光伏逆变器内部的电磁暂态调度级只需要一个离散状态方程SOC(k1) SOC(k) - ( P_b(k) * Δt ) / E_capacityP_b是储能输出功率放电为正充电为负Δt是采样步长E_capacity是电池容量严格一点还要把充放电效率η放进去。这个方程的意思是电池电量不能跳变你用掉一度电SOC就往下走一格。滚动优化是在每个采样时刻k以当前SOC为初值在未来Np步内求解一个优化问题得到一串控制序列但只执行第一步。为什么要只执行第一步因为未来的预测不可靠后面那几步的参考价值有限不如等下一时刻拿到新测量值再重新算。反馈校正就是让系统真实运行时SOC被实测值更新下一步优化就从最新的状态出发。这一步是MPC和开环优化的本质区别计划算得再漂亮实际状态一旦偏了MPC立刻感知并重新出发。2.2 微电网里的元件建模细节在调度层面最常见的就是光伏、储能、负荷、电网联络线四类元件。建模原则是够用就好不贪多。光伏很简单它就是一个预测扰动。控制器不能控制光伏但可以根据预测值安排其他资源。代码里只需要准备一条时间序列P_pv_pred然后在功率平衡方程里把它当作已知量。注意MPC中光伏预测误差会直接影响调度质量所以仿真时一定要在预测序列上叠加扰动否则无法体现MPC的优势。储能要同时建两个维度能量维度的SOC动态功率维度的充放电限幅。入门阶段用常数充放电效率足够如果做更深入的论文再扩展成查表效率或多项式效率。SOC的上下限通常设为0.2到0.9这个范围既保护电池寿命也留有一定调节裕度。负荷和光伏一样也当成预测扰动处理。这里有个容易踩的坑光伏预测和负荷预测的误差可能相关——大晴天负荷相对小阴天负荷相对大。做研究时要明确说明误差是怎么生成的否则结果不可复现。电网联络线模型取决于微电网并网还是孤岛。并网模式里P_grid有上下限且可正可负正为买电、负为卖电还需要分时电价曲线。孤岛模式没有电网兜底约束更苛刻任何时刻储能和光伏必须覆盖全部负荷MPC的滚动优势其实更明显。2.3 目标函数和约束条件怎么设计这是整个项目最核心的环节。目标函数至少要包含运行经济性和储能SOC合理性两块。我推荐用这个形式J sum_{tk}^{kNp-1} [ C_buy(t) * max(P_grid(t), 0) - C_sell(t) * min(P_grid(t), 0) λ * (SOC(t) - SOC_ref)^2 ]第一项是购电成本第二项是卖电收益第三项是SOC偏离参考值的惩罚项。λ是权重系数SOC_ref一般取0.5左右。为什么要加SOC惩罚项因为纯经济优化会把电池当免费搬运工——只要电价有峰谷差就拼命充放SOC在一天内剧烈抖动既伤电池调度指令也不稳定。加一个SOC跟踪惩罚相当于给储能装上约束带让它在电价差不足够大时老老实实待在健康区间。约束方面功率平衡等式是核心P_pv(t) P_b(t) P_grid(t) P_load(t)。储能要写SOC上下限和充放电功率上下限电网交互要写联络线功率上下限。特别注意SOC约束必须逐时刻满足不能只约束终点SOC否则优化器会在最后时刻紧急充电产生非常不现实的调度指令。3. Matlab代码实现与核心函数拆解3.1 代码模块怎么组织我建议把代码拆成五个文件千万别把所有东西塞在一个大脚本里。这样调试和扩展都会舒服很多。主脚本microgrid_mpc_main.m负责整个仿真流程初始化参数、循环调用控制器、记录状态、最后绘图。参数文件parameters_init.m放所有可以改的数比如容量、功率限制、Np、λ。mpc_controller.m是MPC核心输入当前SOC和预测序列输出这一步的控制量。plant_simulation.m模拟微电网真实运行重点是把预测值和真实值区分开。plot_results.m负责画图。这种分模块方式有个额外好处当你想把MPC换成别的算法做对比比如PID或者日前开环调度只需要替换controller函数其他模块完全不用动。3.2 MPC主循环的逐行逻辑核心循环不复杂麻烦的是把优化问题整理成Matlab能直接求解的标准格式。我以手写quadprog方案为例讲解。% microgrid_mpc_main.m 主循环片段 Np 24; dt 1; horizon 7 * 24; SOC zeros(horizon1, 1); SOC(1) 0.5; for k 1:horizon % 采样当前真实SOC SOC_now SOC(k); % 获取未来Np步的预测序列 pv_pred pv_data(k : kNp-1); load_pred load_data(k : kNp-1); price_buy price(k : kNp-1); % 调用MPC控制器得到本时刻控制指令 [P_b_cmd, P_grid_cmd] mpc_controller(SOC_now, ... pv_pred, load_pred, price_buy, params); % 模拟真实执行可加入执行偏差 P_b_real P_b_cmd 0.02 * randn; SOC(k1) SOC(k) - P_b_real * dt / params.Ecap; end在mpc_controller内部关键是构造标准二次规划。设优化变量为 x [P_b(1:Np); P_grid(1:Np)]目标函数中的SOC惩罚项用状态方程展开后会变成关于P_b的二次项从而组装出H矩阵和f向量。等式约束P_b(t) P_grid(t) load(t) - pv(t)则对应Aeq*x beq每行只有两个非零系数1。储能和电网的功率限幅直接用lb、ub指定。这部分最容易出错的是索引。Np步预测变量长度是2*Np功率平衡约束对应Np个时刻Aeq的行数就是Np。你要想清楚x向量的排列顺序索引一乱就会得到完全错误的结果而且调试时特别隐蔽。如果装了YALMIP代码会更简洁直接用sdpvar定义变量、写约束、写目标optimize一行搞定。但为了通用性我这里用自带quadprog实现毕竟不是每个人科研环境里都有额外工具箱。3.3 参数整定预测时域、控制时域、权重怎么试MPC里有几个参数直接决定系统行为预测时域Np、控制时域Nc、采样时间Δt、SOC权重λ。我没有银弹公式但有一套先粗后细的调参流程。采样时间Δt通常取调度颗粒度日级调度取1小时日内滚动可以取15分钟。Np如果是日级MPC取24如果是日内滚动取8到12也够。Np越大看到的未来越长但问题规模和对预测精度的依赖也越大。控制时域Nc我一般设成1。让求解器每次只输出一个控制动作然后下一时刻重新算这是MPC反馈性能最强的配置。如果你把Nc也设成24那MPC就慢慢退化成开环优化了。λ的调试建议从0开始扫描。λ0时是纯经济调度看SOC曲线是否合理然后λ从小到大增加观察SOC是否被拉向参考值同时记录总成本的变化。选一个SOC偏差满足要求、成本损失可接受的折中点。这里有个重要细节λ需要做归一化处理让SOC偏差平方项和电价成本处于同一数量级否则权重会失去意义。我的做法是先跑一次λ0记录成本项的大致数值范围再反推λ的数量级。4. 仿真设计、结果分析与算法对比4.1 仿真场景与数据怎么准备做仿真最怕随便给个数据就开跑最后自己也解释不清结果。我给出一个可以直接用的基准场景微电网包含额定200kW的光伏、500kWh储能、峰值负荷300kW的用户群并网运行分时电价0.3到1.0元/kWh。储能SOC范围0.2到0.9初始SOC为0.5充放电功率限幅±100kW。光伏和负荷曲线的生成很关键。如果手头没有实测数据惯用做法是构造典型日曲线作为真值再让控制器里看到的预测值由真值叠加扰动生成。扰动用正态分布标准差取真值的10%到20%。这样才能公平地比较MPC和开环日前控制在预测误差下的表现。必须固定随机种子否则实验不可复现。写论文时这一条是底线审稿人一旦发现你换了随机种子结果就对不上基本直接毙掉。4.2 仿真结果怎么读跑完仿真我习惯先看四张图负荷与光伏功率曲线、储能SOC曲线、储能充放电功率与电网交互功率曲线、累计运行成本曲线。这四张图覆盖了所有关键信息。看SOC曲线时重点观察有没有触界。MPC约束生效时SOC应该在0.2到0.9之间平滑波动。如果SOC长期贴在边界上说明储能配置偏小或目标函数权重不合理。看功率图时观察有没有尖峰抖动。MPC因为滚动优化控制变量偶尔会出现步步跳变这通常意味着预测误差处理或代价函数加权需要调整。成本对比也有讲究不要只看总成本还要看成本随时间的累积曲线。MPC的阶段性成本可能比日前调度高因为它在每一步都在为纠正预测偏差付一点纠错费但最后的总成本通常更低——它避开了高电价时段的高价购电。4.3 和日前调度的对比要抓住什么这是论文里必须出现的对比实验。对比双方MPC滚动调度 vs 开环日前优化提前算好24小时计划之后不更新直接执行。对比维度日前调度开环MPC滚动调度计算时机提前一天算一次每个采样时刻滚动求解预测误差适应性无反馈偏差硬扛每步用实测状态修正约束处理一次性全局满足每步重新满足计算量低高但可接受预测误差为零时MPC理论上不会优于开环全局优化因为开环已经把未来全看清楚了。但误差一旦出现开环就漏出马脚。比较时抓三个指标总运行成本、SOC越限次数、电网功率越限次数再增加一个误差灵敏度分析——从5%扫到30%看两种方法总成本的爬坡速度。我自己的仿真结果里误差20%时MPC总成本通常比开环优化低5%到10%SOC越限和功率越限几乎降为零。具体数值不普适但方向非常稳定预测越不准MPC优势越明显。论文里报告数字时记得把随机种子和扰动标准差的定义写清楚。5. 常见问题与排查技巧实录5.1 约束不可行是最大的坑MPC仿真中最常见的报错是quadprog提示the problem is infeasible。原因通常是预测序列与当前状态冲突导致功率平衡等式或SOC边界无法同时满足。比如SOC已经压到下限0.2未来几小时负荷很大而光伏很小储能功率又有上限功率平衡方程无论怎么配都凑不出来。解决办法有两个。第一是做预检查在求解前判断当前状态是否会导致无解不过我更喜欢第二种——把功率平衡等式从硬约束改成带松弛变量的软约束。给等式加正的松弛项目标函数里给松弛项一个相当大的权重。这样就算物理上暂时不可行优化器也会优先保等式成立宁可让SOC轻微越界也不中断仿真。这在工程里很常用也是MPC软约束设计的基本操作。5.2 SOC曲线振荡、功率指令抖动如果你看到储能功率一个采样步为正、下一步为负频繁换向多半是SOC惩罚项权重太小或者预测误差里的高频成分太多。可以先固定随机种子排除随机性干扰然后调大λ。也可以对SOC参考轨迹做平滑处理或者对P_b输出做一阶低通滤波。滤波会引入相位滞后MPC的滚动校正能容忍一定滞后但截止频率别调太低否则控制器会变得迟钝。还有个小技巧把λ从零开始慢慢增加观察目标函数里各项的数值占比。如果SOC惩罚项占比低得离谱比如不到总目标的1%那它对优化结果基本不起作用。5.3 求解器性能不够怎么办当Np增大到24甚至48步加上松弛变量后问题规模上百维quadprog默认内点法可能每步要几十毫秒甚至更久。离线仿真问题不大将来要转到实时在线运行时就得优化。这里有个非常实用的技巧H矩阵和Aeq等不变矩阵在循环外计算好循环内只更新beq、f、lb、ub这些随时间变化的向量能省掉一半以上时间。如果还想更快可以考虑换Gurobi或Cplex这类商业求解器或者把MPC问题写成显式MPC——离线把解分区计算好在线查表。不过对于论文级的微电网调度仿真自带的quadprog完全够用没必要为性能过早优化。5.4 预测序列的边界索引在Matlab里最常见的报错就是索引越界k循环到T-Np那一步时kNp-1超出了预测矩阵的行数。处理办法很老土但有效预测矩阵生成时预留足够的冗余行主循环上限设为T-Np1。另外建议用时间轴对齐光伏曲线负荷数据也统一好单位跨时区实验对不上号的问题虽然不常发生发生的时——一旦发生极难排查。5.5 预测数据从哪来很多初学者卡在我没有预测数据上。学术研究中不一定要上来就上机器学习做预测。最常用的做法是真实曲线加高斯噪声。你可以设两种场景预测误差5%和20%分别跑MPC和开环对比。想增加说服力可以在噪声里加入一个与光伏相关的常数偏置模拟天气预报系统性低估的情况。总之预测数据本身不是目的目的是测试控制器在不确定性下的表现。如果你的论文重点在调度算法预测部分用简单扰动模型就够如果重点在预测方法那得另写一套预测模块但我们的项目标题核心是MPC调度优化别把重心带偏。最后分享一点个人体会。把MPC用在微电网调度里最大的收获不是记住了一个算法公式而是理解了在不确定性面前好的控制策略要懂得认错和纠偏。代码层面的经验就是先从纯经济调度的最简版本跑通再逐步加入SOC惩罚、预测误差、软约束每加一层就对比一次结果。千万别一上来就堆一堆高级模型出了问题你根本分不清是建模错、参数错还是代码错。顺着这条路跑熟了后面的扩展方向也就清楚了比如把单层MPC升级成双层滚动结构或者往目标函数里加电池老化成本论文的层次自然就出来了。