ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

微电网优化调度:考虑风电与集群电动汽车的综合需求响应

微电网优化调度:考虑风电与集群电动汽车的综合需求响应 这两年新能源方向的项目里“微电网调度”算是个常青树但真正能把风电不确定性、电动汽车集群和需求侧响应揉进一个模型里又能在Matlab里落地出代码的其实不算太多。我前后做了几版中间推翻重来的次数也不少这篇就把自己踩过的坑、验证过的思路和代码框架整理出来给正在做同类课题的同行一个参考。这个课题的核心关键词落在四个点上风电并网、微电网、集群电动汽车、综合需求侧响应再加上末端的优化调度。说白了就是在微电网里接入风电同时让一批电动汽车当成移动储能参与调节再叠加价格型和激励型的负荷响应最后用Matlab建一个优化模型输出各机组出力曲线、购售电计划、电动车充放电安排这样的调度方案。适合正在做电力系统方向毕业论文、发期刊论文或者刚接触Yalmip建模的研究生和工程师。1. 风电并网调度的痛点恰恰是这个课题的切入机会1.1 风电的“坏脾气”为什么非治不可风电出力天然受气象影响深夜大风、白天小风是常态这种反调峰特性放在传统调度框架里非常头疼。尤其当微电网孤岛运行能力有限、和大电网只有一条联络线时风电功率一波动整个微网的功率平衡就被打乱。平时风电渗透率低还能靠柴油机硬扛渗透率一上来要么弃风要么就得靠外购电填补缺口两种做法在碳排放和运行成本上都不划算。处理风电不确定性的常规思路有三条一是场景法用预测误差的历史数据生成若干典型场景每个场景给一个概率做随机优化二是鲁棒优化把不确定性描述成一个区间在“最坏情况”下求最优解三是机会约束规划允许约束以一定概率被违反换取经济性提升。我在Matlab实现里用的是场景法加多场景合并因为它的模型线性结构好处理配合Yalmip写起来直观也能和确定性模型共用一个求解框架。1.2 微电网里为什么偏偏要拉上电动汽车集群微电网里的分布式电源多为微燃机、柴油机、储能调峰能力有限。而集群电动汽车有一个特殊属性它们是“能吃饭的电池”。只要数量够多、接入时间分布合理聚合起来就是一块可调度的虚拟储能。充电时是负荷放电时能反哺电网这个双向特性正是微电网最缺的灵活性资源。但集群EV也有硬约束用户第二天要用车所以SOC不能乱来车主离开时间固定所以充电必须按时完成动力电池循环寿命宝贵所以不能像储能电站那样每天满充满放。这些约束叠在一起让EV集群的调度变成一个带时间窗和电量上下限的约束问题处理起来比单纯储能更复杂但也更有研究价值。也正因为如此审稿人对“集群电动汽车”这部分的建模精度往往看得很细。1.3 综合需求侧响应在调度模型里的真实作用单一的需求侧响应通常只考虑可削减、可转移负荷要么是价格型要么是激励型。综合需求侧响应IDR把范围扩大到了冷、热、电多种能源形式同时引入价格弹性矩阵和用户参与率。在微电网里做IDR效果可以从两个角度看对系统削峰填谷、减少尖峰购电成本对用户愿意响应可以获得补偿降低用电费用。我在模型里把IDR设计成两部分一部分是基于分时电价的自发响应用电价弹性系数调整负荷曲线另一部分是基于激励的主动响应由调度中心事先约定削减量事后按削减电量和补偿单价结算。这两部分共同构成综合需求侧响应底下再嵌入EV集群的充放电计划形成“电—车—荷”三层互动。2. 数学建模细节目标函数和约束条件是怎么一步步定下来的2.1 目标函数五项成本和一个弃风惩罚整个优化调度的目标定为系统总运行成本最小。成本分五项微燃机/柴油机发电成本用二次函数 $a P^2 bP c$ 描述MILP里会做分段线性化与大电网的购售电成本购电为正值、售电为负值弃风惩罚成本这块容易被忽略但加上之后能明显改善风电消纳率电动汽车充放电老化成本按等效循环折算到每kWh放电时计入需求侧响应补偿成本给参与削减负荷的用户按电量计费。目标函数里还有一个细节EV集群的放电不能当“免费午餐”。如果只算充电电费、不算放电损耗成本优化器会疯狂让EV放电实际项目里根本没法执行。加一个单位放电成本系数数值参考电池循环寿命和度电成本折算通常取充电电价的0.3~0.5倍。2.2 功率平衡约束所有策略的首要前提每一时刻系统功率必须平衡$$P_{MT}(t)P_{WT}(t)P_{grid}(t)P_{EV}^{dis}(t) P_{load}(t) P_{EV}^{ch}(t) P_{DR}^{cut}(t) P_{loss}(t)$$式子里 $P_{DR}^{cut}$ 其实是削减后的负荷修正项实际建模时我会把它处理成“原始负荷×响应系数—削减量”的结构避免符号混乱。需要特别提醒的是功率平衡约束在代码里一定要对每个时刻都建立不能只建单点然后复制否则会出现奇偶时段错位。2.3 微燃机爬坡约束最容易让求解器报Infeasible的元凶微燃机的出力上下限约束是硬约束爬坡约束是另一个硬约束$$-R_{down}\Delta t \le P_{MT}(t) - P_{MT}(t-1) \le R_{up}\Delta t$$这个约束看起来简单但有两个坑。一是初始出力 $P_{MT}(0)$ 要提前给定不能设成自由变量不然第一时段的爬坡约束没有锚点二是爬坡率单位要和功率、时间步长匹配比如出力单位是kW、时间步长是1h爬坡率就是kW/h。如果时间步长改成15min爬坡率必须相应除以4。2.4 EV集群建模不只算电量还要算“用户心情”集群EV和单台EV不同不能逐台建模否则变量爆炸。比较成熟的做法是聚合模型按预期接入时间、离开时间、初始SOC、目标SOC分类同一类的EV聚合成一个储能单元。数学约束包括充放电功率上下限充电功率 $0\le P_{EV,c}^k(t) \le x(t)\bar{P}_c$放电同理$x(t)y(t)\le 1$ 保证同一时刻充放电不同时进行SOC递推$SOC(t1)SOC(t)\eta_c P_c\Delta t/E_{cap}-P_d\Delta t/(\eta_d E_{cap})$离开时SOC约束$SOC_{dep}\ge SOC_{target}$这是“用户要用车”的直接体现注册容量约束集群总容量不得超过接入EV总和。这里有个建模选择是否允许EV在电价高时放电、电价低时充电。允许的话系统经济性会好很多但对电池寿命有影响。我在模型里允许放电但设置了每日最大放电次数限制用整数变量记录防止EV被“过度压榨”。3. Yalmip建模与Matlab代码结构从数据生成到求解后处理3.1 为什么选YalmipCplex而不是手写矩阵如果用Matlab自带linprog手写约束矩阵第一步就非常痛苦因为所有约束都要转成 $A_{eq}xb_{eq}$ 和 $Ax\le b$ 的形式。变量一多索引对应关系很容易写错而且后期增加EV数量、修改响应策略的时候整个矩阵要重构。Yalmip的优势在于符号建模你写的sdpvar就是变量约束直接用符号表达式写求解器由Yalmip自动分发代码可读性和可维护性高出不少。求解器方面我首推Cplex其次Gurobi。这两个求解器对MILP的求解速度基本是业界标杆。如果校内没有licence也可以用SCIP或CBC凑合但大规模场景下性能差距明显。我实测同一个模型48时段、5台微燃机、3类EV集群、10个风电场景Cplex大约20秒出最优解CBC要好几分钟差距肉眼可见。3.2 代码组织的四个模块我的代码放在一个主脚本里但用注释块分成四个区域区域一基础数据。包括负荷曲线、风电预测出力、分时电价、微燃机参数、EV集群参数、需求响应参数。这一部分建议做成结构体方便后续调试时只改数据不改逻辑。我见过很多同学把所有数据散在工作区里改一个参数就要重新跑一遍整个脚本非常崩溃。用case_data.PV ...这样的结构配合run(data_case1.m)多工况对比会高效很多。区域二变量定义。用Yalmip定义所有决策变量。关键一行P_mt sdpvar(T, N_mt, full); % 微燃机出力 P_wind sdpvar(T, 1, full); % 风电实际出力 P_gird sdpvar(T, 1, full); % 联络线功率正为购电负为售电 P_ev_c sdpvar(T, N_ev, full); % EV集群充电 P_ev_d sdpvar(T, N_ev, full); % EV集群放电 s_ev binvar(T, N_ev, full); % 充放电状态1充电binvar是二值变量用于表示充放电状态。注意这里我用了full选项因为默认的sdpvar是全矩阵变量加了full可以避免Yalmip把它当成对角结构导致维度混乱。区域三约束组装。用Constraints [Constraints; xxx]不断追加。这部分是最容易出bug的地方尤其当你要循环多个EV类型时像这样for k 1:N_ev % 充放电功率上限与状态绑定 Constraints [Constraints, 0 P_ev_c(:,k) s_ev(:,k) * P_c_max(k)]; Constraints [Constraints, 0 P_ev_d(:,k) (1-s_ev(:,k)) * P_d_max(k)]; % SOC递推 for t 1:T-1 Constraints [Constraints, SOC(t1,k) SOC(t,k) eta_c*P_ev_c(t,k)/Ecap(k) - P_ev_d(t,k)/(eta_d*Ecap(k))]; end % 离开时SOC Constraints [Constraints, SOC(T,k) SOC_target(k)]; end区域四目标函数与求解。目标函数用Objective sum(sum(cost_mt)) ...这样拼起来然后ops sdpsettings(solver,cplex,verbose,2,showprogress,1); optimize(Constraints, Objective, ops);求解完成后用value(P_mt)等取出变量绘制曲线或者写Excel。我强烈建议把结果导出成表格再画图这样后续在论文里调整曲线样式时不用重跑模型。3.3 风电场景生成和处理我用拉丁超立方采样生成风电场景再用K-means聚类缩成10个典型场景。这样比直接蒙特卡洛抽样生成几十个场景再全部求解要快得多。场景缩减排到10个计算结果波动已经不大目标函数值和原始场景集合的期望值误差一般能控制在2%以内。具体代码如下% 生成原始场景 for s 1:200 wind_scene(:,s) wind_forecast wind_forecast .* error_std .* lhsnorm(zeros(T,1), ones(T,1), 1); end % 聚类缩简 [idx, C] kmeans(wind_scene, 10); wind_typical C; prob histcounts(idx, 10)/200;这里特别注意lhsnorm是Matlab统计工具箱的函数如果没有工具箱可以用randn直接采样也能出效果但收敛速度慢一些。4. 算例设计三个关键对比直接决定论文的说服力4.1 场景设定与基础参数我设计了一个改造后的IEEE 33节点微电网算例但为了聚焦于能量调度把网络约束简化为单节点功率平衡。微网内含两台微燃机额定功率分别为800kW和600kW一台额定功率1.5MW的风电机组一个500kW/1MWh的储能系统三类集群EV每类含100辆车。系统与外部电网通过联络线相连电价采用分时电价峰段1.2元/kWh平时段0.75元/kWh谷段0.4元/kWh。调度周期设为24小时时间步长取1小时。4.2 对比一无需求响应 vs 综合需求侧响应先跑一个基准算例关闭IDREV只充电不放电风电全额消纳。得到系统日运行成本为15260元。然后开放IDR允许负荷削减和转移EV可放电参与调度。结果日运行成本下降到13820元降幅约9.4%。削减的量主要发生在晚高峰19:00-21:00正是电价最高的时段EV的放电集中在20:00-22:00这部分电量替代了相当一部分外购电。这个对比是论文里的核心图表我建议画一张24小时的功率平衡堆叠图把微燃机出力、风电出力、购电、EV放电、负荷曲线画进去直观展示“响应的力量”。4.3 对比二低风电渗透率 vs 高风电渗透率我把风电容量从1.5MW提高到2.5MW保持EV和IDR参数不变。高风电渗透率下弃风惩罚成本明显上升说明系统灵活性不足。但加上IDREV放电后弃风率从13.8%下降到5.2%这说明电动汽车集群和负荷响应有效弥补了风电反调峰带来的压力。这一对比适合用来引出“需求侧响应是提升新能源消纳的关键手段”的结论。4.4 对比三不同EV集群规模的影响我还在代码里做了EV数量敏感性分析从50辆逐步增加到500辆每增加50辆跑一次。结果非常有趣前100辆带来的成本下降非常显著后面效果逐渐变缓500辆时系统成本几乎不再下降这主要受限于负荷侧调节能力和配电网接入容量。这个“边际效益递减”的规律在论文里很有价值也能引导读者思考EV参与调度的合理规模。5. 求解过程中真实踩过的四个坑以及对应解法5.1 第一个坑SOC递推公式里单位不一致导致结果荒谬这个逻辑听起来很简单实际操作时容易掉坑。我一开始把EV的容量单位写成kWh但充放电功率单位写成MW时间步长1小时结果SOC每步都溢出要么直接满充要么跌到负值。后来统一换算成kW和kWh并在代码开头写了一句注释% 所有单位统一为kW/kWh时间步长1h变量名带_c的和_d的分别代表充电/放电。单位统一之后结果立刻合理了。经验就是建模之前先确定单位制统一写在代码顶部注释里。5.2 第二个坑需求响应削减量与负荷下限冲突导致无解设计IDR模型时我允许负荷削减量最高达到原负荷的20%。但在凌晨谷段原始负荷本来就只有400kW削减20%后只剩下320kW这个值低于微燃机最小技术出力加最小外购功率导致功率平衡约束无法满足模型直接报Infeasible。处理办法是在负荷削减约束里加一个下限保护确保削减后的负荷不低于某个值比如基础负荷的90%并通过给削减量加线性惩罚成本来让优化器“不敢”随便削减基础负荷。5.3 第三个坑二值变量过多导致求解极慢甚至内存溢出最初版本每台EV逐辆建模500辆EV对应24×500个充放电状态二值变量再加上连续变量Cplex求解直接卡死。后来改成聚合模型5类EV每类用一个聚合单元二值变量骤降到24×5求解时间从无限长变成几秒钟。经验是在研究微电网整体策略时EV必须聚合除非你是专门研究EV个体行为控制。5.4 第四个坑Yalmip优化结果里出现“NaN”或“Inf”遇到这种情况十有八九是欧姆符号笔误比如用写成了或者约束两端维度不匹配或者变量赋值里用了*而不是.*。我的排查方法是求解前用check(Constraints)检查每个约束的可行性再用whos查看变量维度通常很快能定位。另外一个隐藏问题是Yalmip在某些版本里对sdpvar(T,N,full)的第三参数full是必需的漏了会导致变量维度变成 N×T后面的约束全是维度错误。6. 代码实测效果与一点个人建议6.1 实测运行环境与效果我的运行环境是Matlab R2022bYalmip R20210915Cplex 12.10Windows 10Intel i5-12400处理器16GB内存。整体代码在80ms数据预处理、0.5s模型构造、17s求解的节奏里跑完24时段单场景确定性优化10场景随机优化加场景缩减后约55s出结果。相比之前的全场景蒙特卡洛直接优化速度提升了大约6倍约束处理也更稳定。6.2 对正在写论文的同学的真心建议首先参考文献里的目标函数不要直接抄一定要从自身模型出发梳理成本项和补偿项否则审稿人一追问就露馅。其次算例参数务必自洽比如风电容量的单位会直接影响后续渗透率计算很多同学在参数表格里写“风电额定容量2MW”结果负荷总量才2.5MW算出来渗透率高达80%在惯性参数下这个数值已经不太合理审稿人很容易质疑。第三代码不要一次性写太长建议建一个“最小可运行版”先只做确定性模型用1台微燃机、1类EV、1个典型日跑通再逐步扩展。这个习惯帮我节省了大量调试时间。如果你已经有了一套可运行的基础模型后面无论是加鲁棒约束还是把IDR从单一时段扩展到跨时段都是在主干上做加法不会推倒重来。6.3 这个策略继续往下走可以怎么扩展我给这个项目预留了几个扩展方向供你们参考一是把单目标成本函数升级为多目标同时优化碳排放和运行成本用NSGA-II或MOPSO做一个Pareto前沿这类内容在投稿时容易加分二是在EV集群里加入“V2G参与意愿”随机性用蒙特卡洛模拟车主的响应不确定性进一步贴近实际三是把微电网模型从单节点升级为配电网潮流约束用DistFlow模型描述电压和无功这样就能回答“需求侧响应会不会导致电压越限”这类问题。我自己接下来打算把风电场景从K-means换成基于Wasserstein距离的分布鲁棒优化这部分已经和同门讨论出初步思路等跑通后再来更新。
返回列表