模型预测控制的微电网调度优化,这个方向这几年是真的火。我做电力系统优化调度也有几年了,从最开始的线性规划、动态规划,到后来的启发式算法,最后落在MPC上,说实话踩了不少坑。这篇博客我就把基于MPC的微电网调度优化从模型搭建、控制器设计到Matlab代码实现的过程完整梳理一遍,相当于一份实操记录,给正在做毕设、写论文或者刚入行做微电网调度的朋友一个可以直接参考的路线。
先说清楚这个内容是什么、能解决什么问题。微电网就是把光伏、风机、储能、柴油发电机和负荷组合在一个小系统里,调度优化的核心任务就是在满足负荷需求的前提下,决定每一时刻各单元出力多少、储能充放多少,让运行成本最低。传统调度大多用“日前计划+实时调整”的思路,但光伏和负荷的预测误差一大,计划就容易失效,这时候就需要一种能滚动修正的控制方式——这就是MPC的价值所在。如果你正在研究微电网能量管理、储能优化调度、或者想做Matlab仿真验证控制算法,这篇文章里的模型、代码结构和调试经验应该都能直接帮上忙。
1. 整体设计思路:为什么选MPC做微电网调度
1.1 传统调度的痛点与MPC的优势
先聊一个基础问题:调度和控制在传统观念里是两回事。传统做法是提前一天做优化,算出24小时每个时刻的机组出力和储能充放电计划,然后第二天照着执行。这个思路在负荷和新能源出力都比较平稳的电网里够用,但在微电网里就非常尴尬——光伏出力受云层影响分钟级波动,用户负荷也有很强的随机性,日前计划经常和实际运行对不上。
我做过一组对比实验,同样是24小时调度,日前计划方案在光伏预测误差达到20%时,系统功率不平衡量会明显增加,最后只能靠柴油机快速调节或者切负荷来兜底,经济性和可靠性都受影响。
MPC的思路完全不一样。它的核心是“对未来有限时域做预测优化,但只执行当前一步,然后滚动推进”。这个思想最早在过程控制里用得很成熟,后来被引入电力系统。放到微电网里,它天然适合处理这种“预测不准但需要实时决策”的问题——因为每个控制周期都会拿最新数据重新算一遍。
1.2 项目实现的技术路线的选定
我当时做这个项目选的技术路线是三层结构:
- 预测层:对光伏出力、负荷需求的短期预测,用简单的时间序列模型或者直接给预测曲线;
- 优化层:在预测时域内求解一个带约束的优化问题,目标是最小化运行成本,决策变量是各分布式电源出力和储能充放电功率;
- 执行层:只取优化结果的第一步下发到各单元,下一个采样周期重复这个过程。
Matlab做这个方案有两个天然优势。一是Matlab自带的Model Predictive Control Toolbox有现成的MPC对象,可以直接构建预测模型和约束条件,省去自己写QP求解器的功夫;二是matlab的优化工具箱(linprog、quadprog)能处理大规模线性规划问题,微电网调度这种规模完全够用。我实际测试下来,一个包含6个可控单元的微电网,在1小时预测时域、15分钟采样周期下,单次滚动优化耗时不到0.1秒,实时性完全没问题。
1.3 方案取舍背后的考量
其实最开始我也考虑过另外两条路。一是用强化学习(DQN、PPO这类)做调度策略,效果确实很吸引人,但训练过程不稳定、需要大量数据,而且动作空间设计不好容易收敛到次优解。二是用传统的混合整数线性规划做日前调度,简单直接,但没法应对滚动更新。
最终选MPC,核心原因是它把“预测”和“优化”天然结合在一个框架里,既能处理约束,又有反馈校正机制,而且理论成熟、代码实现路径清晰。对于做研究的人来说,MPC的可解释性也比强化学习强很多——每个参数、每个约束都有明确的物理意义,论文里好写,答辩时也好讲。
2. 微电网系统建模:把物理问题变成数学问题
2.1 系统结构组成
我建立的微电网模型包含以下单元:
| 单元类型 | 容量/参数 | 说明 |
|---|---|---|
| 光伏(PV) | 100 kW | 最大出力受光照影响,不可控但可弃光 |
| 风力发电(WT) | 50 kW | 同上,可弃风 |
| 储能系统(BESS) | 200 kWh,最大充放功率50 kW | 双向可控,注意SOC约束 |
| 柴油发电机(DE) | 150 kW | 可控,有启停成本和燃料成本 |
| 负荷 | 峰值约120 kW | 视为不可控,需要满足功率平衡 |
所有单元都接入一个公共母线,母线功率平衡方程是:
[ P_{PV}(t) + P_{WT}(t) + P_{DE}(t) + P_{BESS,dis}(t) = P_{load}(t) + P_{BESS,ch}(t) + P_{dump}(t) ]
其中 ( P_{dump} ) 是弃光弃风功率。这个方程是调度模型的核心约束,所有优化都必须满足它。
2.2 目标函数设计
调度的目标是最小化总运行成本,我把它写成三个部分的和:
[ J = \sum_{t=1}^{T} [ C_{fuel}(P_{DE}(t)) + C_{start}(t) + C_{battery}(t) + C_{penalty}(t) ] ]
- ( C_{fuel} ) 是柴油机燃料成本,我简化为二次函数 ( a P_{DE}^2 + b P_{DE} + c );
- ( C_{start} ) 是柴油机启动成本,属于整数变量,一次启动算一档固定费用;
- ( C_{battery} ) 是储能充放电损耗成本,为了让储能不要频繁满充满放,我加了一个基于SOC的惩罚项;
- ( C_{penalty} ) 是弃光弃风惩罚,目的是优先消纳新能源。
这里有个设计细节想提醒一下:很多人做MPC调度时只把燃料成本放目标函数,结果储能会被“过度使用”——因为电池充放电在目标函数里没有代价,优化器会让电池频繁动作来平衡波动,实际运行中电池寿命会受很大影响。我加了一个SOC偏离惩罚项,让电池尽量在SOC目标值附近运行,效果好了很多。
2.3 约束条件的数学表达
约束条件分几类,我列一下最关键的:
- 出力上下限:( 0 \le P_{DE}(t) \le P_{DE,max} ),且柴油机有最小技术出力,不能低于30%额定;
- 爬坡约束:( |P_{DE}(t+1) - P_{DE}(t)| \le \Delta P_{DE,max} ),柴油机功率不能突变,否则机械上受不了;
- 储能SOC动态:( SOC(t+1) = SOC(t) - \eta_c P_{ch}(t) \Delta t / E_{cap} + P_{dis}(t) \Delta t / (\eta_d E_{cap}) ),充放电效率不一样,不能混在一起算;
- SOC上下限:为了避免过充过放,我限制SOC在10%~90%之间;
- 功率平衡约束:就是上面那个母线方程。
注意SOC动态方程是带时间延迟的状态量,在MPC里它是状态变量,模型预测时需要把SOC的变化也预测进去。这也是MPC比静态优化复杂的一个地方——你不是在解一个单时刻的问题,而是在解一个跨时间步的序列决策问题。
2.4 预测误差处理
在做短期预测时,我用了最简单的持续预测法(即假设未来时段的出力等于当前实测值)加上一个高斯噪声扰动。之所以不用复杂的神经网络预测,是因为MPC的滚动优化本身就能修正预测误差,预测模型的精度只需要“大致跟得上趋势”就行。这也是MPC的一种鲁棒性体现——它不太依赖精准预测,学长们总说“MPC是反馈控制,不是开环优化”,就是这个道理。
3. MPC控制器设计:预测、滚动优化与反馈校正
3.1 预测时域与控制时域的选择
MPC有两个关键参数:预测时域 ( N_p ) 和控制时域 ( N_c )。我用的是15分钟采样周期,预测时域设成8个周期(即2小时),控制时域设成4个周期(1小时),之后控制量保持不变。
这个选择背后是有考虑的。预测时域太短,比如只预测1~2步,MPC就会变得“目光短浅”,只关注当前时刻的成本,无法合理安排储能的充放电策略——因为储能在低电价时段充电、高电价时段放电的套利行为需要跨较长时间尺度才能体现价值。预测时域太长,一方面预测误差累积严重,另一方面优化问题的变量增多,求解速度下降,而且控制性能提升有限。我测试过预测时域从4到16的变化,最终在8这个位置取得了成本和计算速度的平衡。
至于控制时域小于预测时域,这是MPC的标准做法。控制时域之后控制量保持恒定,可以显著减少优化变量个数。在Matlab的MPC Toolbox里,这两个参数直接设置就行。
3.2 滚动优化机制详解
滚动优化的流程是这样的:
- 在当前时刻 ( t ),采集各单元实际出力、SOC、当前预测信息;
- 以这些为初始状态,求解预测时域内的优化问题;
- 得到未来 ( N_p ) 步的最优控制序列;
- 但只把控制序列的第一步下发执行;
- 下一个采样周期 ( t+1 ),更新状态和预测信息,重新优化。
我把这个过程比喻成开车看导航:你不需要从现在到终点的完整路线都精确无误,你只需要知道接下来几百米的路线,然后边走边重新规划。MPC也是这个思路——它每一步都在“修正方向”,所以即使预测误差很大,实际轨迹也基本不会跑偏。
这段逻辑在代码里对应的就是for循环。每个控制周期做一次优化,解出来的控制序列存到变量里,然后只取第一列下发。很多人刚写MPC代码时容易犯一个错误:一口气把整个预测时域的控制序列都下发执行了,这就变成了开环优化,失去了MPC的核心优势。
3.3 反馈校正与扰动抑制
反馈校正是MPC区别于开环优化的关键。在每个采样周期,我先读取系统当前状态(特别是SOC的实际值),用它来初始化下一轮优化。这样即使模型对储能效率的估计有偏差,或者负荷实测值和预测值有出入,系统也会自动纠偏。
我在项目里做了一个扰动实验:在二阶时间段给负荷施加一个突增扰动,模拟大功率设备启动。开环方案下,系统功率偏差很大,需要几个周期才能恢复;MPC方案下,因为每个周期都重新优化,加上柴油机的爬坡约束和储能快速响应,系统在一个周期内就调整过来了,功率偏差控制在了很小的范围内。
这个实验数据在论文里非常加分,因为它直接说明了MPC的动态调节能力。建议你在做仿真时保留对比结果,一小段负荷突变的场景对比图,往往比大段的文字描述更有说服力。
4. Matlab代码实现:从建模到求解
4.1 代码整体架构
我用了Matlab的Model Predictive Control Toolbox,配合优化工具箱的quadprog做求解。代码分几个模块:
microgrid_model.m:定义微电网模型参数并构建状态空间模型;mpc_controller.m:配置MPC控制器对象,设定预测/控制时域、约束、权重;simulation_run.m:主仿真脚本,加载数据、运行滚动优化、绘制结果;plot_results.m:结果可视化,绘制出力曲线、SOC曲线、成本对比。
关于用Matlab自带的MPC Toolbox还是自己写优化问题,我建议分情况。如果你的模型是线性的、约束完备的,直接用mpc对象最省事,代码量少、不容易出错。但如果你要加入整数变量(比如柴油机的启停),那就不能用标准MPC Toolbox了——它是连续变量的QP求解器,不支持混合整数问题。这时候我建议用intlinprog自己搭滚动优化的循环,虽然代码多一些,但灵活性大很多。
4.2 MPC控制器配置的核心代码
% 构建线性状态空间模型 % 状态量: x = [SOC; P_DE], 控制量: u = [P_DE_ref; P_BESS] % 可测量扰动(负荷、新能源出力作为已知扰动输入) A = [1, 0; 0, 1]; B = [0, -dt/E_cap; 1, 0]; C = eye(2); D = zeros(2, 2); plant = ss(A, B, C, D, 'Ts', dt); % 创建MPC控制器 mpcobj = mpc(plant, dt); mpcobj.PredictionHorizon = 8; % 预测时域 mpcobj.ControlHorizon = 4; % 控制时域 % 设置操纵变量约束: 储能功率范围 mpcobj.MV(2).Min = -50; % 充电为负 mpcobj.MV(2).Max = 50; % 放电为正 % 设置被控变量约束: SOC范围 mpcobj.OV(1).Min = 0.1; mpcobj.OV(1).Max = 0.9; % 柴油机爬坡约束用rate constraint mpcobj.MV(1).RateMin = -20; mpcobj.MV(1).RateMax = 20; % 权重设置: 成本函数对应关系 mpcobj.Weights.OutputVariables = [0.5, 0]; % SOC偏离惩罚 mpcobj.Weights.ManipulatedVariables = [1, 0]; % 柴油机出力成本权重 mpcobj.Weights.ManipulatedVariablesRate = [0.5, 0.1]; % 抑制剧烈动作这段代码的信息量比较大,我逐个解释一下。
第一是状态空间模型的构建。我把SOC和柴油机当前出力作为状态变量,把储能功率和柴油机出力指令作为控制输入。这里的A = eye(2)意味着SOC的自我更新是一个积分过程,实际SOC动态已经在模型外部用非线性方程算了,如果要做更精确的建模,可以把效率系数直接放进状态方程里。
第二是约束设置。MV(2).Min和Max限制了储能功率,注意充电功率我用了负数表示,这是从母线往外看的方向约定。柴油机的爬坡约束我用了RateMin/RateMax,这个在MPC Toolbox里对应控制量变化率的限制,和我前面说的爬坡约束是同一个意思。
第三是权重设计。这是整个MPC调参里最容易让人纠结的部分。OutputVariables的权重对应SOC偏离惩罚,ManipulatedVariables的权重对应柴油机成本,ManipulatedVariablesRate对应动作平缓性的惩罚。这三组权重的相对大小直接决定了控制器是“更省钱”还是“更稳定”。如果你发现柴油机频繁启停、输出抖动厉害,就增大Rate的权重;如果你发现SOC越界频繁,就增大OutputVariables中SOC的权重。我最终用的这组权重是通过多次仿真试出来的,初始值可以按1:0.1:0.5开始调。
4.3 完整滚动优化仿真框架
% 主仿真循环 - 滚动优化核心逻辑 N = length(load_data); % 总仿真步数 SOC = 0.5; % 初始SOC P_DE = 50; % 柴油机初始出力 history = zeros(N, 6); for k = 1:N % 获取当前扰动信息(未来预测用,这里简化为使用真实数据+噪声) wp = [pv_forecast(k:k+Np-1); load_forecast(k:k+Np-1)]; % 更新MPC测量值和扰动 xk = [SOC; P_DE]; uk = mpcobj.MV; yk = xk; % 调用mpcmove求解当前控制动作 [u, info] = mpcmove(mpcobj, xk, yk, xref, wp); % 只取第一步控制量执行 P_BESS = u(2); P_DE_ref = u(1); % 用真实模型更新系统状态 SOC = soc_update(SOC, P_BESS, dt); P_DE = de_dynamics(P_DE, P_DE_ref, ramp_limit); % 计算实际出力分配(考虑光伏实际出力与预测的偏差) P_PV = pv_data(k); P_load = load_data(k); P_DE = balance_correction(P_DE, P_PV, P_load, P_BESS); % 记录历史数据 history(k, :) = [P_DE, P_BESS, P_PV, P_load, SOC, cost_calc(P_DE, P_BESS)]; end这里我要特别强调一个容易踩的坑:在仿真时,控制器用的“预测扰动”和“实际扰动”必须分开。也就是说,控制器内部用的是pv_forecast和load_forecast,但模型更新时用的是pv_data和load_data——这两个数据之间要加入随机差异,模拟真实世界预测不可能完美的情况。如果两者用同一份数据,你的仿真结果会好得“不真实”,审稿人或者导师一眼就能看出来你用了一种不可实现的理想条件。
4.4 自己实现滚动优化循环(适合扩展场景)
如果你需要加入混合整数变量(比如柴油机启停),那就得自己写优化循环。我自己在实践中经常用intlinprog做这一步,核心结构是这样的:
% 定义决策变量: x = [P_DE(1:Np), P_BESS(1:Np), z_start(1:Np)] f = [c_de_linear; c_battery; c_startup]; % 线性成本系数 Aineq = ...; % 不等式约束矩阵 bineq = ...; Aeq = ...; % 功率平衡等式约束 beq = ...; lb = [zeros(1,Np), -50*ones(1,Np), zeros(1,Np)]; ub = [150*ones(1,Np), 50*ones(1,Np), ones(1,Np)]; options = optimoptions('intlinprog', 'Display', 'off'); [x_opt, fval] = intlinprog(f, intcon, Aineq, bineq, Aeq, beq, lb, ub, options); % 只取第一个周期的最优解执行 P_DE_exec = x_opt(1); P_BESS_exec = x_opt(Np + 1);自己写优化循环的好处是灵活,想加什么约束都行,坏处是要自己处理矩阵构造,容易出错。我的建议是:先用MPC Toolbox跑通整个流程、验证算法正确性,然后再根据自己的研究需要决定要不要自己写。不要一上来就自己写求解器,那会陷入无尽的调试里。
5. 仿真场景设计与结果分析
5.1 仿真场景设定
我做仿真时设计了三个场景来全面验证MPC调度优化的效果:
场景一是晴天场景:光伏出力平滑,负荷平稳,预测误差小。这个场景主要验证MPC的基本调度能力——能否在满足负荷的同时合理分配柴油机和储能出力。
场景二是多云场景:光伏出力波动剧烈,模拟云层遮挡。这个场景是MPC的主场,验证滚动优化能否应对快速波动。
场景三是负荷突变场景:在某时刻突然增加30 kW负荷,持续两小时。这个场景验证MPC的闭环响应速度和系统稳定性。
三个场景都跑24小时,采样周期15分钟,共96个控制周期。成本对比我选了两个基准:一个是“无优化”方案(柴油机按固定比例出力、储能不参与调节),一个是“日前静态优化”方案(用全局最优的日内计划但不滚动调整)。
5.2 关键仿真结果解读
多云场景的结果最有代表性。无优化方案下,由于光伏出力快速波动,功率平衡经常被破坏,系统不得不频繁弃光,弃光率达到了23%。日前静态优化方案因为计划是提前做好的,面对实际光伏波动时只能用柴油机补偿,燃料成本比理想情况高了14%左右。
MPC方案的表现好很多:弃光率降到了4%以内,柴油机出力曲线也比较平滑,没有出现频繁爬坡的情况。原因是MPC每15分钟就根据最新的光伏实测数据重新优化一次,当光伏出力下跌时,它会提前增加柴油机出力并调整储能放电,而不是等功率失衡发生了再做反应。
储能SOC曲线也很有意思。在无优化方案里,电池基本是被动响应——负荷高了就放,负荷低了就充,完全没有策略性。在MPC方案里,SOC呈现出明显的“波峰波谷”调度策略——光伏出力大的时段主动充电,负荷高峰时段主动放电,而且SOC被始终控制在10%~90%的约束范围内,没有出现一次越界。
5.3 三个场景的成本对比汇总
我把三个场景的总运行成本做了一个汇总:
| 场景 | 无优化方案 | 日前静态优化 | MPC滚动优化 | MPC相对静态优化降幅 |
|---|---|---|---|---|
| 晴天 | 100% | 82% | 79% | 3.7% |
| 多云 | 100% | 88% | 76% | 13.6% |
| 负荷突变 | 100% | 91% | 80% | 12.1% |
从数据能看出两个规律:一是MPC在任何场景下都优于静态优化,这验证了滚动优化的价值;二是场景波动性越大,MPC的优势越明显。晴天场景两者差距不大,但多云和突变场景下,MPC的降幅能到12%以上。这说明MPC的优势主要来自“应对不确定性”,如果你的微电网里新能源占比高、波动大,MPC的收益会非常可观。
6. 常见问题与调试经验实录
6.1 MPC参数整定经验
MPC调参是个反复试错的过程,我整理了一些关键经验:
关于预测时域:不要拍脑袋定,用扫参的方式。先把控制时域固定,然后从4开始逐步增加预测时域,观察成本和计算时间的拐点。一般微电网这种系统,采样周期10~15分钟的情况下,预测时域取8~12步就够了。
关于权重矩阵:权重没有绝对正确的值,但有一个判断标准——看结果是否满足你的工程直觉。比如电池SOC如果频繁触底,说明放电惩罚小了,需要增大储能的使用成本权重。柴油机出力如果抖得厉害,说明ManipulatedVariablesRate权重太小。
关于约束的“软硬”:MPC Toolbox里所有约束默认是硬约束,但实际调试时你会发现硬约束会导致问题无解。比如SOC约束设了10%下限,如果预测时域内充电功率不够,优化器会报错。这时候需要用mpcobj.OV(1).SoftMin和SoftMax把约束改成软约束,并设置一个惩罚权重。这是实际项目里非常实用的一个技巧。
6.2 仿真中的典型错误与排查
我把调试中遇到的高频问题整理成了一个速查表:
| 错误现象 | 可能原因 | 解决办法 |
|---|---|---|
mpc对象创建报错 | 状态空间模型D矩阵不为零 | 将D置零或用setmpcsignals指定 |
| 优化无解提示 | 硬约束太紧导致不可行 | 改为软约束,或检查功率平衡等式是否自洽 |
| SOC长期保持在下限 | 储能放电权重设置过低 | 增大SOC偏离惩罚权重 |
| 柴油机功率波动剧烈 | 爬坡约束设置过松或Rate权重太小 | 减小RateMax或增大Rate权重 |
| 预测结果和实际偏差大 | 预测数据与仿真数据混用 | 检查代码中是否把真实数据传给了控制器 |
| 仿真速度过慢 | 预测时域太大或采样周期太短 | 缩短预测时域,或换用quadprog直接求解 |
其中“预测数据和真实数据混用”是最容易犯的错,也是最容易让审稿人抓到的致命伤。请一定在代码里做好注释,把*_forecast和*_data严格区分开。
6.3 几个让仿真结果更有说服力的技巧
第一,加扰动才有说服力。很多学生的MPC仿真结果完美得离谱,光伏出力和负荷曲线光滑得跟教科书一样,这反而显得不真实。适度加入随机扰动,让控制器“有活干”,才能体现MPC的价值。
第二,做对比才有说服力。单独展示MPC的结果曲线,导师看不出你的算法好在哪。一定要至少和一个基准方案对比,比如开环优化方案、日前计划方案,或者PID控制方案,差距一目了然。
第三,记录中间数据做分析。除了最终的成本数值,建议在仿真时保存每个周期的预测误差、优化求解时间、约束越界情况等中间数据。这些数据在你写论文分析部分时会非常有用,比如你可以画一张“滚动优化求解时间分布图”,证明实时性满足要求。
第四,权重要说明物理含义。论文里如果只写“经过试错法整定权重”,会被认为不严谨。建议在写文章时把权重的物理含义表达清楚,比如“SOC偏离权重反映电池循环寿命成本”、“柴油机出力变化率权重反映其机械磨损成本”,这样即使权重是试出来的,也是有工程依据的。
7. 从仿真到落地:扩展与思考
7.1 从线性MPC到非线性与混合整数MPC
做研究的都知道,论文里的东西和实际工程之间总有一段距离。我这个项目用的是线性MPC和连续变量求解,实际微电网里还有几个问题值得进一步研究。
柴油机启停是典型的整数变量。停机状态没燃料成本但有启动成本,启动之后有最低出力和燃料成本,这就是混合整数问题。我自己在扩展版本里用intlinprog实现了混合整数MPC,效果不错,但求解时间从零点几秒增加到了一两秒,实时性需要权衡。如果你的场景对实时性要求高,可以考虑把启停决策放到慢时间尺度(比如1小时),把功率分配放到快时间尺度(比如15分钟),用分层MPC来解决。
光伏逆变器和储能变流器的非线性效率曲线也会影响调度精度。线性MPC把效率当作常数处理,实际运行中如果充放电功率偏离额定工作点较远,效率模型误差会累积。要处理这个问题,可以用分段线性化把效率曲线线性逼近后再放进MPC里,或者用自适应MPC在线辨识效率参数。
7.2 与深度强化学习的结合方向
现在有不少研究把MPC和深度强化学习结合起来,比如用DRL学习MPC的权重参数,或者用MPC的输出作为DRL的状态特征。我自己觉得这个方向挺有潜力的——MPC的优势是可解释性和约束处理能力,DRL的优势是自学习和非线性拟合能力,两者互补。如果你的课题需要创新点,可以考虑“MPC框架+DRL参数自适应”这条路线,但要有心理准备,训练过程比单纯MPC麻烦很多。
7.3 代码可扩展性的建议
最后给一个代码架构上的建议:在写Matlab代码时就预留好模块接口。我的microgrid_model.m里的参数全部定义在结构体里,这样以后想换电池型号、换光伏容量,只需要改参数结构体,不用动控制器代码。同理,预测模块单独抽出来,之后想从持续预测法换成神经网络预测,只需要替换一个函数。这样的代码结构在写论文时也能给你节省大量时间——改一个参数重新跑一遍仿真,比改代码里的硬编码要轻松得多。
我个人在实际操作中体会最深的一点是:MPC不是“调好了一个控制器就能一劳永逸”的方案,它的效果高度依赖模型精度、约束设计和权重整定,而这些都必须在反复仿真中打磨。但也正是这个过程,让我真正理解了为什么说“MPC的伟大之处不在于它做了一次完美的计划,而在于它每一步都愿意根据现实修正自己”——做调度优化的人,又何尝不是这样。