ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MPC微电网调度优化:Matlab建模、滚动时域与参数整定实践

MPC微电网调度优化:Matlab建模、滚动时域与参数整定实践 如果你也做微电网的调度优化研究MPC模型预测控制这个名字八成绕不开。我最近把一套完整的MPC微电网调度优化方案用Matlab跑了一遍从建模、代码实现到调参踩坑完整走下来发现网上讲原理的多讲实际落地细节的少。本文会结合我自己写的代码和实验数据把MPC怎么做调度、目标函数和约束怎么列、滚动时域怎么实现、参数怎么调、哪些坑绝对不能踩一次性说清楚。适合正在做微电网方向研究的学生也适合想从规则控制转向优化控制的一线工程师参考。1. 为什么微电网调度要用MPC规则控制、单点优化都不够1.1 先看传统做法差在哪微电网调度说白了就是要决定“每一时刻储能充多少、从电网买多少电、售多少电”。很多现场项目还在用规则控制电价低就充电价高就放光伏出力大于负荷就优先自用。这套逻辑简单但有个致命问题——它只看当前时刻不看未来。午间光伏大发储能如果上午已经充满到了午后只能眼睁睁看着光伏白白弃掉晚高峰电价最高时储能又因为之前放得太猛而没电可放。规则控制只能保证“当前合理”无法保证“全天最优”。单点优化则是另一条路把一天24小时作为一个整体一次性求出所有决策变量的最优值。这种方法在“计划完美”的前提下确实能找到全局最优解可一旦光伏预测偏差大、负荷突增或者电价临时波动计划就失效了必须重新求解而重新求解后的结果往往会和上次的调度计划冲突。这两种方法的本质问题是一样的——缺少对“未来不确定性”的闭环处理机制。MPC正好弥补这一点。1.2 MPC的“预测滚动反馈”是怎么工作的MPC的核心思想可以概括为三句话预测未来、优化当前、反馈校正。用导航软件来类比最直观你从A开车去B导航每5分钟根据实时路况重新规划一次路线而不是出发前把一整天的路线定死。MPC也是这样——在当前时刻基于预测模型推算未来一段时间的系统状态求解一个有限时域的优化问题但只执行第一步控制动作下一时刻用实际测量到的系统状态更新模型重新优化再执行第一步。这个过程叫滚动优化Receding Horizon。在微电网里这个“系统状态”通常就是储能电池的SOC控制动作就是储能充放电功率、购售电功率预测模型就是SOC的状态转移方程未来信息就是光伏出力、负荷需求、分时电价。每一步都基于最新数据重新算天然具有抗预测误差的能力。1.3 MPC在微电网里的三个硬优势我实际做过对比后对MPC的优势有了很直观的认识。第一是约束处理能力。储能SOC必须在20%到95%之间充放电功率不能超过额定值变压器容量有限制烟煤机组出力有爬坡限制——这些在传统比例控制器里很难系统化处理但在MPC里就是一个个线性约束不等式求解器直接帮你算进去。第二是前瞻性。正是因为能“看到未来”MPC会主动在午间光伏大发时预留储能容量在电价低谷提前储电而不是等事情发生了再纠正。第三是鲁棒性。单点优化一步到位MPC走一步看一步预测偏差会导致它每一步都在修正所以即便光伏预测误差达到20%实际运行曲线也不会差得离谱。2. 把调度问题变成数学状态、目标、约束怎么列2.1 微电网调度场景的基本架构建模之前先明确物理结构。我用的算例是一个典型的光储微电网光伏发电单元PV、储能系统ESS、本地负荷通过公共连接点PCC与配电网交互另外配了一台柴油发电机作为备用电源。这个结构在Matlab代码里就对应几组变量光伏出力序列P_pv、负荷序列P_load是外部给定的扰动输入储能充放电功率、柴油机出力、购售电功率是待优化的控制变量。调度周期设为24小时采样时间Ts1小时。为什么要选1小时因为光伏和负荷的预测数据通常以小时为粒度电价时段划分也是小时级太细了数据跟不上太粗了储能状态转移失真严重。如果你做日内滚动可以把Ts设为15分钟结构完全一样。2.2 列目标函数花钱最少还要平抑波动目标函数是整个优化问题的“指挥棒”。我用的是运行成本最小化加上惩罚项具体分为四部分贡献。第一部分是购电成本也就是从电网买电花的钱sum(price_buy(k) * P_buy(k) * Ts)price_buy是分时购电价P_buy是购电功率单位一致化后求和。第二部分是售电收益微电网光伏出力超出负荷时可以向电网售电收益为sum(price_sell(k) * P_sell(k) * Ts)。注意售电价格通常低于购电价格中间有价差。第三部分是电池健康度管理用SOC偏离目标值的二次惩罚来表示sum(w_soc * (SOC(k) - SOC_ref)^2)。电池过度充放会显著缩短寿命这个惩罚是必要的。第四部分是功率波动惩罚用储能功率变化的二次项sum(w_fluct * (P_es(k) - P_es(k-1))^2)来限制充放电功率突变避免控制动作“抖”得太厉害对设备寿命和电网冲击都不好。把这几项加权组合就得到了MPC每一步要求解的二次规划QP目标函数。为什么是二次规划而不是线性规划因为SOC惩罚项和波动惩罚项本身是平方项而且二次目标函数能保证控制量平滑工程上更好用。2.3 约束条件电量平衡、SOC、功率上下限、交互钳制约束条件决定了优化结果是否物理可行。我常用的约束如下表所示约束类型表达式形式物理含义功率平衡P_buy - P_sell P_pv P_dch - P_ch P_load任意时刻微网内功率守恒SOC状态转移SOC(k1) SOC(k) (η_ch * P_ch(k) - P_dch(k) / η_dis) * Ts / E_cap储能动态特性SOC上下限SOC_min ≤ SOC(k) ≤ SOC_max保护电池防过充过放充放电功率限幅0 ≤ P_ch ≤ P_es_max0 ≤ P_dch ≤ P_es_max储能功率不超过额定值电网交互限幅0 ≤ P_buy ≤ P_grid_max0 ≤ P_sell ≤ P_grid_max变压器容量限制充放电互斥P_ch * P_dch ≈ 0可通过目标函数隐式约束不允许同时充放电这里有个细节值得提一下充放电互斥约束在严格建模时需要引入0-1整数变量变成混合整数规划但实际工程中只要购电价和售电价之间存在正差价优化结果天然不会出现同时买卖的情况所以大多数情况下用线性约束就够了。如果你的场景出现价格倒挂售电价高于购电价那就必须加二值变量了。2.4 离散状态空间形式与Matlab表示MPC标准形式要求把系统写成状态空间表达式。在这里状态变量选SOC控制变量选P_buy、P_sell、P_ch、P_dch、P_diesel扰动输入选P_pv和P_load。离散状态方程可以写成SOC(k1) SOC(k) [η_ch*P_ch(k) - P_dch(k)/η_dis] * Ts / E_cap写成矩阵形式就是x(k1) Ax(k) B_uu(k) B_d*d(k)。A是单位矩阵B_u是充放电系数对应的控制矩阵B_d对应光伏和负荷扰动的影响。注意P_pv和P_load不是控制变量而是外部输入必须放到B_d里这样求解器才能把它当作已知序列带入预测模型。在实际Matlab代码里我的做法是直接用循环结构表达状态迁移不用手推矩阵系数这样更直观改参数也好改。矩阵表达更多用于推导和论文书写。3. Matlab代码实现从单步优化到滚动时域3.1 开发环境与求解器选型实现MPC的Matlab方案有两种主流选择。一种是直接用Model Predictive Control Toolbox里的mpc对象适合标准场景配置起来快但定制程度有限加自定义惩罚项很麻烦。另一种是用YALMIP或CVX作为建模层搭配通用二次规划求解器灵活度最高。我推荐后者因为微电网调度问题的约束和成本项往往高度定制化用通用建模框架反而省力。求解器我用的是OSQP一个开源的一阶QP求解器处理几百个变量的小规模问题速度极快单步求解在毫秒级。如果你的Matlab版本没有自带OSQP用内置的quadprog也行就是大规模时略慢一点。安装YALMIP很简单把下载的文件夹加入Matlab路径即可。3.2 预测模型怎么写下面是我整理过的核心代码结构可以直接套用%% 参数定义 Ts 1; % 采样时间小时 Np 24; % 预测时域长度 E_cap 500; % 储能容量kWh eta_ch 0.95; % 充电效率 eta_dis 0.90; % 放电效率 SOC_min 0.2; SOC_max 0.95; P_es_max 100; % 储能额定功率kW P_grid_max 500; % 变压器容量上限kW %% 每个采样时刻调用一次优化 for k 1:24 % 读取当前时刻实测SOC、未来光伏预测、负荷预测、分时电价 SOC_now SOC_measured(k); P_pv_future P_pv_forecast(k : kNp-1); P_load_future P_load_forecast(k : kNp-1); price_buy_future price_buy(k : kNp-1); % 定义决策变量 P_buy sdpvar(Np, 1); P_sell sdpvar(Np, 1); P_ch sdpvar(Np, 1); P_dch sdpvar(Np, 1); SOC_var sdpvar(Np1, 1); % 目标函数与约束 Objective 0; Constraints []; Constraints [Constraints, SOC_var(1) SOC_now]; for t 1:Np % SOC状态转移 Constraints [Constraints, ... SOC_var(t1) SOC_var(t) ... (eta_ch * P_ch(t) - P_dch(t)/eta_dis) * Ts / E_cap]; % SOC上下限 Constraints [Constraints, ... SOC_min SOC_var(t1) SOC_max]; % 功率平衡 Constraints [Constraints, ... P_buy(t) - P_sell(t) P_pv_future(t) P_dch(t) - P_ch(t) P_load_future(t)]; % 储能功率限幅 Constraints [Constraints, ... 0 P_ch(t) P_es_max, 0 P_dch(t) P_es_max]; Constraints [Constraints, ... 0 P_buy(t) P_grid_max, 0 P_sell(t) P_grid_max]; % 目标函数累加 Objective Objective ... price_buy_future(t) * P_buy(t) * Ts - ... 0.85 * price_buy_future(t) * P_sell(t) * Ts ... 0.1 * (SOC_var(t1) - 0.5)^2; end % 求解并只执行第一步 ops sdpsettings(solver, osqp, verbose, 0); optimize(Constraints, Objective, ops); P_es_out(k) value(P_ch(1)) - value(P_dch(1)); P_grid_out(k) value(P_buy(1)) - value(P_sell(1)); % 更新下一时刻真实SOC这里默认模型无误差实际应加入测量值 SOC_measured(k1) value(SOC_var(2)); end这段代码的关键点在于每个时刻都定义一个新的Np步优化问题求解后只取P_ch(1)和P_dch(1)作为实际执行量后面Np-1步全部丢弃。这看起来“浪费”但正是滚动优化的精髓——每走一步就用最新实测状态修正模型不会把预测误差一路累积到底。3.3 滚动优化的主循环逻辑主循环里有一个容易被忽略的细节SOC_var(1) SOC_now这个约束用的是当前时刻的实测值而不是上一轮优化计算出的SOC_var(2)。这一步是反馈校正的关键一定要写对。如果直接把模型计算值代入就退化成开环优化了失去了MPC闭环控制的优势。另外我建议把P_pv_forecast向量在每一步都重新赋值而不是一次性把24小时的预测值全部读进来。这样之后的扩展才能自然支持“滚动预测”也就是未来预测序列随时间更新的场景。3.4 一组日调度结果对比MPC vs 规则控制我在同一组数据下分别跑了一个“低电价充电、高电价放电”的规则控制器和一个Np24的MPC控制器全天运行结果对比如下指标规则控制MPC控制日购电成本包含售电收益3186元2698元储能日均等效循环次数1.21次0.94次最大功率波动幅值62 kW31 kW弃光率7.3%1.8%MPC在成本上省了约15%储能循环寿命压力更小功率波动也明显平缓。成本节省主要来自两个场景第一规则控制在下午4点就把SOC放到了最低但晚高峰电价更高MPC会算着未来电价趋势留一部分电量到19点到21点再放第二午间光伏大发时规则控制因为光伏不足以为整个储能充满而不敢充太多MPC却知道下午还有一段时间光伏出力会维持高位果断提前充电弃光量大幅下降。上述场景是我为了对比效果设置的典型算例预测数据无误差时MPC确实能达到这种效果。如果引入实际预测误差MPC的滚动机制仍能维持大部分优势。3.5 扩展思路日前日内两级MPC如果你继续深入研究你会发现单层MPC在24小时预测时域下计算负担偏大而且全天预测数据在上午预测夜间的光伏精度很差。我实际试下来比较好的做法是两级调度日前层用MPC求一个24小时的经济最优计划时间颗粒度1小时主要决定“哪天充多少、什么时候放”的宏观策略日内层用MPC做15分钟级别的滚动修正预测时域只取4到8步根据最新光伏实测数据调整储能功率跟踪日前计划的偏差尽量小。两层之间的协调在代码里就是两个循环嵌套的问题外层算完把SOC参考值传给内层作为软约束。这个小改动能使实时响应速度大幅提升也更能贴近现场控制器节拍。4. 参数整定与避坑心得4.1 预测时域Np和控制时域Nc怎么选Np是MPC调度里最敏感的参数之一。Np太小MPC变成“近视眼”只看得到眼前一两步无法为晚高峰预留电量退化成规则控制Np太大预测后期数据精度极差而且求解规模变大在线计算时间会变得不可接受。我给出的经验值对于小时级Ts的日前调度Np选24到36覆盖完整的一天对于15分钟级Ts的日内滚动Np选4到8覆盖未来1到2小时即可。控制时域Nc在标准的调度类MPC里一般取和Np相同因为微网调度每个时刻只有一个决策批不需要像轨迹跟踪那样刻意缩短控制时域。如果Np24导致求解偏慢可以先检查约束是否写得过于冗余或者把SOC_idle约束松弛成软约束。多数情况下问题不在求解器性能而在于规模没有控制好。4.2 目标权重怎么给成本系数、SOC惩罚、波动惩罚权重设置是MPC最容易翻车的地方比算法本身还容易出问题。总结下来有三条经验值得记住。第一经济成本项的权重必须和真实电价对齐这是主目标其他惩罚项的权重以“不干扰主目标大方向”为原则。设得太大会出现“该买的电不买、该放的电不放”的怪事。第二SOC惩罚项里的SOC_ref不能定得太理想我最初设0.5固定值结果优化器为了让SOC全程保持在0.5附近而牺牲了大量经济效益。后改成动态参考值把日前计划算出的SOC序列当作参考基准效果立刻好很多。如果你只要经济最优甚至可以把SOC惩罚权重设成很小的值只留上下限约束。第三波动惩罚系数w_fluct要量级匹配。我用的是充放电功率二阶差分系数设在0.1到1之间具体数值需要做参数扫描实验来确定大一个数量级就会让储能动作迟缓电价峰谷都来不及反应。4.3 关键参数速查表参数典型值调参影响Ts1小时/15分钟越小响应越快计算量越大Np24/8越大前瞻性越强数据精度要求越高SOC_min/SOC_max0.2/0.95放宽可提升经济性缩小可延长寿命SOC_ref日前计划SOC偏离过大影响经济性购/售电价差系数0.85控制套利积极性w_fluct0.1~1同样影响控制量平滑度和经济性平衡5. 踩坑实录5个典型问题与排查方法5.1 求解器报infeasible怎么办infeasible是所有接触MPC的人最先遇到的坑意思是约束集合互相矛盾找不到可行解。最常见的诱因有两个一是SOC状态转移约束和SOC上下限约束冲突比如SOC在0.2但储能最小充电时段内模型要求它升到0.95而该时段功率上限又不够解就不存在二是功率平衡约束和储能功率上限冲突某个时刻负荷很高同时变压器容量又被限制得很紧储能又饱和或没电平衡方程无解。排查方法也简单先检查所有约束对应的物理量纲是否统一kW和kWh混用是最常见的隐蔽问题。其次把SOC_min放宽到0.15、P_grid_max加到800看看问题是否消失如果消失就说明约束过紧。最后建议在代码里输出求解器返回的diagnostics结果把yalmip的“relaxed solution”打开能看到是哪条约束被破坏。5.2 控制量一抖一抖储能功率持续往复这是个很经典的MPC毛病。滚动优化每走一步都重新计算得到的是一个全局最优轨迹但每一段的第一点拼起来可能不是平滑曲线尤其在电价临界点附近MPC会在“充电还是放电”之间反复横跳导致储能功率频繁换向。有三个办法可以压住这个问题。第一把波动惩罚系数加大这是最直接的手段。第二增加约束限制两次决策之间储能功率的最大变化量比如|P_es(k)-P_es(k-1)|≤20 kW相当于给控制量加了“变化率约束”。第三把充放电动作设置滞回区间SOC低于0.4才允许从放电切到充电高于0.6才允许从充电切到放电。5.3 结果对初值SOC特别敏感这个问题在单次仿真里不明显但在连续调度里很突出。如果初值SOC从0.5改成0.8MPC给出的当日调度策略会完全不一样前几小时的充放电行为差异巨大。原因在于当前SOC直接决定了后续可行域而MPC只往前看有限步无法像全局优化一样从全天角度“纠偏”。解决办法是强化SOC惩罚项让优化器在满足经济效益的前提下尽量往SOC_ref靠拢或者把终端状态约束加上——在预测时域末端强制SOC在某个范围内避免调度结束能量耗尽。在工程应用中建议给SOC_ref做一个缓慢过渡的变化序列不要突然大跳变。5.4 仿真很漂亮接入系统却不对仿真结果好实际接入系统就表现异常这个问题在MPC落地时太常见了。多数原因出在预测数据和实测数据的衔接上仿真时用的是同一组历史序列反复预测实际运行时预测模型却在持续更新如果预测更新频率和优化执行频率不一致控制器就会“精准备优化一个错误未来”。我在代码里专门加了一段逻辑用当前时刻实测的光伏出力替换预测序列的第一个点而不是直接使用预测值。这个小改动让整个闭环仿真稳定了很多。如果你也在做闭环仿真一定要把“实测反馈”显式建模进去否则验证结果没有参考价值。5.5 在线计算时间太长调度步长1小时单次优化即使跑几十秒也还勉强能接受但如果要做日内15分钟滚动单步超过3秒就会积压。我实测下来Np24规模的QP问题在普通笔记本上用OSQP求解不到50毫秒真正耗时的反而是YALMIP建模部分。YALMIP每次调用都需要重建整个优化对象这部分时间开销远大于求解本身。如果建模耗时成了瓶颈可以考虑把常数矩阵离线提取出来用matlab自带的quadprog直接求解标准二次规划省掉YALMIP的建模开销速度能快两个数量级。前提是你已经调试好目标函数和约束不再需要频繁修改结构。我在实际做调度项目时最大的体会是MPC的代码实现本身并不难难的是把模型、约束、目标、参数这一整套系统工程问题理顺。核心算法跑通只是第一步跟预测数据、电池模型、控制器节拍形成闭环才是真正有价值的工程工作。如果后续你想继续扩展可以从鲁棒MPC、随机MPC、以及与深度学习的结合方向入手但先把本文这套基础跑稳比什么都重要。
返回列表