楼宇微网优化调度这个方向我接触了一段时间后最大的感受是多数人刚上手时都把注意力放在光伏和储能的容量配置上但真正让调度策略落地变复杂的往往是楼宇里那一大堆“活的”负荷。所谓“融合需求侧虚拟储能系统的楼宇微网优化调度”说白了就是把楼宇中的空调、热水、蓄热装置这类需求侧资源当成一块不用买电池的“虚拟储能电池”来用配合光伏、物理储能和电网购电在Matlab里搭建优化调度模型用Yalmip配合Cplex这类求解器给出24小时各设备的出力曲线和启停计划。这篇文章就把这套东西从建模到仿真、从踩坑到调参完整讲清楚适合正在做微网调度、建筑能源管理或者毕业设计里涉及楼宇侧优化的小伙伴直接参考。1. 为什么楼宇微网调度需要虚拟储能1.1 楼宇负荷的“可平移”潜力商业楼宇或者大型公共建筑的负荷构成里暖通空调系统HVAC往往是绝对的大头夏天最热的时候空调负荷能够占到整栋楼用电的40%到50%。这一块负荷有个非常特殊的性质它不像工厂里的电炉、机床那样要求“随开随停、功率刚性”而是只要求室内温度维持在一个舒适区间内比如24±1摄氏度的范围。温度本身的这种“弹性”天然就给用电时间平移留下了空间。我举个直观的例子。下午2点是电价尖峰时段也是太阳辐射最强、光伏出力最大的时段。如果楼宇的空调系统在这个时间前提前把室内温度预冷到23.5摄氏度那么在2点到4点之间哪怕空调压缩机降功率运行甚至短暂停机室内温度也不会立刻突破26摄氏度的上限。这期间少用的电量相当于在电价最高的时候“少买”了一部分电这就是负荷平移。而负荷平移背后的承载介质是室内空气、墙体围护结构、家具乃至空调水系统里储存的冷量这种“储冷”的能力不需要专门买电池所以叫虚拟储能。1.2 虚拟储能和传统储能的定位差异做微网调度的人经常会陷入一个定式思维要考虑储能就必须有电池、有PCS、有容量限制和SOC轨迹。虚拟储能的思路完全跳出了这个物理限制它把“储能”这个概念抽象成“允许功率和能量的时间转移”的能力。从调度模型的角度看虚拟储能和物理储能的差异非常明显维度物理储能锂电池需求侧虚拟储能空调热惯性初始投资高约上千元每千瓦时几乎为零利用现有设备能量载体电化学介质室内空气、围护结构、蓄热水箱响应速度毫秒级到分钟级分钟级受热惯性限制容量特征固定额定容量动态变化取决于当前温度、舒适度约束循环寿命有限充放电循环损耗大无限反复利用不产生额外损耗控制难度容易直接控制DC/DC变换器较难依赖建筑热过程模型这里最关键的一点是虚拟储能并不是要替代物理储能而是和它互补。物理储能容量有限、投资高承担的是秒级到分钟级的快速响应和短时能量支撑虚拟储能容量大、成本低适合做小时级的能量搬移。比如说某栋楼在下午光伏出力高峰时物理储能电池可能两个小时内就充满了多余的光伏只能白白限发但要是进一步利用空调系统预冷把相当于几百千瓦时的冷量储存在楼体里就等于把电池容量扩容了光伏消纳率自然就上去了。这也是为什么这个题目里的关键词是“融合”——你只有把物理设备侧的虚拟储能空调、蓄水、蓄热和传统微网优化调度模型放在同一个优化框架里去求解才能让两者的时间尺度、功率响应配合起来。分开做效果一定打折扣。2. 模型骨架目标函数、约束与虚拟储能动态表达2.1 设备拓扑与决策变量定义在动手写Matlab代码之前先把模型里的“零件”列清楚。我一般会把楼宇微网抽象成这样的拓扑光伏阵列通过逆变器接在交流母线上储能电池通过PCS接入楼宇空调系统作为柔性负荷电网通过公共连接点PCC向楼宇供电或接受楼宇馈电。整个系统在调度周期内需要满足电功率平衡同时各设备有自己独立的运行约束。决策变量按类型分储能电池各时段充电功率P_cha(t)、放电功率P_dis(t)、SOC(t)空调系统制冷/制热功率P_ac(t)以及室内温度T_in(t)联络线从电网购电功率P_buy(t)向电网售电功率P_sell(t)光伏P_pv(t)通常按预测值处理不作为优化变量这里有个容易搞混的点虚拟储能的“SOC”是什么对应到空调系统上它就是室内温度与设定值之间的偏差。温度越低相当于“存储”的冷量越多温度越靠近上限相当于虚拟储能快放空了。所以虚拟储能状态量的核心就是T_in(t)。2.2 目标函数经济性优先兼顾运行约束楼宇微网优化调度最常见的诉求是运行成本最小化模型的目标函数可以写成J Σ_t [ C_buy(t) * P_buy(t) - C_sell(t) * P_sell(t) C_om * (P_cha(t) P_dis(t)) λ * T_in_violation(t) ]其中第一项是购电费用第二项是售电收益第三项是储能电池的运行维护成本最后一项是温度越限的惩罚项。考虑到峰谷电价的激励目标函数里天然会引导系统在电价低谷时段多购电给储能充电、让空调把楼宇预冷在电价高峰时段释放功率。有一点必须提醒目标函数里如果没有对“舒适度”的合理约束或惩罚优化结果很容易走向极端。比如为了省钱让室内温度一直贴着26摄氏度的上限白天住户体验会非常差。所以温度约束必须进入约束条件而不是只在目标函数里加个惩罚系数。惩罚项可以作为软约束的兜底但硬约束才是舒适度的保障。2.3 虚拟储能的线性化建模虚拟储能的核心是一阶等值热参数模型ETP用热容和热阻模拟室内空气与围护结构的热动态。连续时间形式是C_th * dT_in/dt (T_out(t) - T_in(t)) / R_th η_ac * P_ac(t)这里的C_th是楼宇等效热容R_th是等效热阻η_ac是空调能效比的折算系数——你可以把它理解成空调每消耗1度电向室内注入多少“冷量”或者“热量”。离散化之后就变成了非常清爽的线性差分约束T_in(k1) T_in(k) (Δt / C_th) * ( (T_out(k) - T_in(k)) / R_th η_ac * P_ac(k) )为什么强调这是线性约束因为所有变量都是一次幂没有T_in和P_ac相乘这种非线性项。这样一来整个优化调度问题就可以用一个混合整数线性规划MILP来求解而不是去啃一个大规模非线性规划。决策变量里其实可以进一步把P_ac设为连续变量如果真的需要处理空调启停状态、备用容量等再增加0-1整数变量这样MILP仍然高效。把温度上下限写进去T_min(k) ≤ T_in(k1) ≤ T_max(k)就完成了一个非常直观的虚拟储能容量限制。从物理意义上看T_in(k)在上下限之间的浮动空间乘以热容C_th再除以空调能效比就是这段时间虚拟储能可以“充放电”的能量余量。再说远一点很多做项目的人把虚拟储能局限在空调上其实楼宇里蓄热水箱、地板辐射采暖、甚至电梯的势能回收都可以做类似建模。本质都是找到一种能在时间维度上搬移能量的介质再用一条差分方程去刻画它的动态。同一套Matlab框架换成蓄热水箱的时候只需要把状态量从T_in换成水箱温度T_w把输入从空调电功率换成电锅炉功率P_eb公式骨架完全不变。3. Matlab实现过程与代码结构3.1 求解工具的选型逻辑楼宇微网优化调度的规模一般是24个时段、几个设备决策变量大概在几十到一两百个约束条件几百个。这种规模用什么优化算法我看到有同学一上来就写粒子群、遗传算法不能说错但实际工程中我建议优先考虑数学规划求解器。原因很简单MILP求解器比如Cplex、Gurobi在有全局最优解的问题上能够给出确定性的最优结果而且求解速度非常快楼宇级模型通常几秒到几十秒内就能收敛。启发式算法虽然有“写起来自由、不用推导线性化”的优势但每次求解结果可能不一样而且无法保证全局最优。在调度类问题里我们最需要的是“可复现”和“可解释”的结果。我在Matlab里最顺手的组合是Yalmip建模加Cplex求解。Yalmip是一个建模工具箱最大的优势是把符号化的优化变量和约束写成几乎和数学表达式一样的形式代码可读性很高换求解器也只需要改一行代码。当然如果电脑上没有学术版Cplex换成Gurobi或者Matlab自带的intlinprog效果也完全可以接受只是Yalmip写起来最省事。3.2 整体代码模块划分我建议把代码按模块拆分不要全塞在一个脚本里。我的工程习惯是这样的% main.m —— 主程序 % 1. 读取基础数据电价、光伏预测、负荷预测、室外温度 % 2. 设置模型参数热容、热阻、储能容量、温度上下限 % 3. 定义优化变量Yalmip的sdpvar或binvar % 4. 构建约束条件 % 5. 设置目标函数 % 6. 调用求解器求解 % 7. 提取结果并绘图这种结构清晰尤其是后面要改场景、调参数的时候不需要满文件翻变量。3.3 约束条件代码示例下面给出一段简化的Matlab代码演示核心约束怎么写。注意这是模型的核心片段不是全部代码。% 定义变量24时段为例 T_in sdpvar(24, 1); % 室内温度 P_ac sdpvar(24, 1); % 空调功率 P_cha sdpvar(24, 1); % 储能充电功率 P_dis sdpvar(24, 1); % 储能放电功率 SOC sdpvar(24, 1); % 储能电量状态 P_buy sdpvar(24, 1); % 购电功率 P_sell sdpvar(24, 1); % 售电功率 P_pv pv_data; % 光伏预测外部输入 % 约束容器 Cons []; % 空调虚拟储能动态一阶等值热参数模型 % T_in(k1) T_in(k) dt/C_th * ((T_out(k)-T_in(k))/R_th eta_ac * P_ac(k)) for k 1:23 Cons [Cons, T_in(k1) T_in(k) dt / C_th * (... (T_out_data(k) - T_in(k)) / R_th eta_ac * P_ac(k))]; end % 舒适度温度限值工作时段与非工作时段可以设置不同限值 for k 1:24 if is_working_hour(k) Cons [Cons, T_min_work T_in(k) T_max_work]; else Cons [Cons, T_min_idle T_in(k) T_max_idle]; end end % 储能SOC动态与容量约束 SOC(1) SOC_init; for k 1:23 Cons [Cons, SOC(k1) SOC(k) dt * (eta_ch * P_cha(k) - P_dis(k) / eta_dis) / Cap_bat]; end for k 1:24 Cons [Cons, 0 P_cha(k) P_cha_max * u_cha(k)]; Cons [Cons, 0 P_dis(k) P_dis_max * u_dis(k)]; Cons [Cons, u_cha(k) u_dis(k) 1]; % 防止同时充放电 Cons [Cons, SOC_min SOC(k) SOC_max]; end % 功率平衡约束 for k 1:24 Cons [Cons, P_pv(k) P_dis(k) P_buy(k) ... P_load_fixed(k) P_ac(k) P_cha(k) P_sell(k)]; end这里我特别想强调几个细节。第一个是功率平衡约束里虚拟储能空调功率是作为一个可调的负荷直接参与平衡的这是它区别于固定负荷的根本所在。第二个是温度动态约束初始温度T_in(1)需要给定否则从第一个时段开始就缺少锚点。第三个是储能同时充放电的互斥约束这在实际系统中非常关键不加这条约束优化器会在电价套利的驱使下让充放电同时进行出现大量无效功率循环。3.4 目标函数代码示例目标函数用Yalmip表达非常直接Objective sum(c_buy .* P_buy * dt/1000) - sum(c_sell .* P_sell * dt/1000) ... sum(c_om * (P_cha P_dis) * dt/1000); % 求解 optimize(Cons, Objective, sdpsettings(solver, cplex, verbose, 2));注意单位换算。我见过太多人在这里算错数如果功率单位是千瓦时间步长是小时那么能量单位是千瓦时如果电价单位是元每千瓦时那么购电费用就是P_buy(k) * c_buy(k) * dt。如果dt用秒表示那么费用就会变成普通数值的3600倍目标函数各量纲全乱了。建议在建模一开始就统一单位功率用千瓦、电量用千瓦时、时间步长用小时这样后面所有参数都不会出问题。4. 仿真场景与结果解读4.1 测试场景设置为了把虚拟储能的价值看得清清楚楚我一般会设计三个对比场景场景A纯基础调度空调功率按固定用能曲线运行没有任何灵活性场景B普通微网调度只加入物理储能空调仍为固定负荷场景C融合虚拟储能空调参与优化调度物理储能和虚拟储能同时工作取一个典型夏季日的实测数据光伏出力曲线在中午12点到14点达到峰值约80千瓦楼宇固定负荷照明、插座、电梯等在白天维持在120千瓦左右空调峰值负荷约60千瓦。峰谷电价采用典型的商业峰谷电价尖峰时段在14点到17点电价大约是谷段的4倍。室外温度曲线取夏季30到36摄氏度。4.2 调度结果对比直接看关键结果指标指标场景A基础场景B仅物理储能场景C物理虚拟储能日运行成本元约2850约2560约2180从电网购电峰值千瓦210178152光伏消纳率%829499室内温度舒适达标率%不参与调度不参与调度97场景C的效果非常直观日运行成本比基础方案降了约23%购电峰值从210千瓦压到152千瓦光伏基本做到了全消纳。数字背后的机理值得说说。在场景C里优化器在凌晨电价的谷段让空调持续工作把一整栋楼的温度拉到舒适下沿附近这个过程相当于以谷电价格给虚拟电池“充电”到了下午尖峰时段空调功率被大幅压低室内温度慢慢上浮到舒适上沿相当于虚拟储能释放能量。光伏午间出力充裕时空调的用电需求被本地光伏直接满足多余的电再给物理储能充电两块“储能”各司其职。把温度曲线拎出来看会更清楚T_in在上午缓慢下降14点到17点之间开始爬升但始终没有越过26摄氏度的上限。这就是有约束优化的效果而不是靠人工拍脑袋设一个固定预冷时长。所有决策都是求解器自己权衡出来的结果该预冷多少、什么时候开始预冷完全由电价差、光伏出力和热动态共同决定。4.3 虚拟储能的等效容量分析有一个很有意思的视角是把虚拟储能的能量规模算出来。假设楼宇等效热容C_th 55千瓦时每摄氏度温度允许波动的范围是23.5摄氏度到26摄氏度这个2.5摄氏度的窗口对应的蓄冷量是55 * 2.5 137.5千瓦时。再除以空调能效比约3.5也就是说虚拟储能等效的“电量容量”约39千瓦时。这个数字单独看不算大但在楼宇场景里它对应的是395千瓦时温度缓冲空间热容量而这块容量不需要买电池、不需要维护、不需要担心循环寿命。如果换一块同样有效放电量的锂电池按当下价格也是一笔不小的开支而且这块电池在充放电过程中的容量衰减还得算进寿命成本。虚拟储能的容量大小直接取决于舒适度窗口的宽窄在实际运行中只要运维人员允许温度稍微拉宽0.5摄氏度虚拟储能等效容量就能显著增加这种“零成本扩容”的特性是物理储能完全比不了的。5. 常见问题与排查技巧实录5.1 求解结果不可行问题多半出在温度约束我在这个项目上踩过最典型的一个坑温度约束设置成全天24小时同一个上下限初始温度又设得比较低加上空调最大功率限制结果在凌晨时段优化器根本找不到可行解。原因很直观——夜间室外温度低楼宇散热快如果温度下限设得太高空调必须整夜运行才能把温度抬上去而空调功率又有上限室内温度就会失守。解决办法是分时段设置温度限值。工作时段严格一点比如23到26摄氏度非工作时段或者说夜间人员很少的时段把下限放开甚至不设下限让楼宇自然降温。这一步对求解可行性的影响极大。另外要提醒的是初始温度T_in(1)最好通过一个简洁的“预测”步骤获得比如先让模型保持恒定功率运行24小时得到稳态温度分布再把它作为调度周期的起点这样比随便拍一个初始值科学得多。5.2 虚拟储能容量千万别高估热容C_th这个参数看着简单实际上门道很大。把空气的热容直接乘楼宇体积算出来的值往往偏大因为真实房间里的空气温度并不均匀家具、墙体、地板的热容虽然大但响应速度很慢在一个小时级的调度周期里它们能贡献的“灵活储能量”是有限度的。如果C_th设得过大模型会认为室内温度很容易保持在舒适范围于是调度结果会让空调频繁预冷实际工程中室内温度却会明显越限。我常用的做法是用典型日实测数据做参数辨识获取空调功率和温度变化曲线用最小二乘法反推等效热容C_th和等效热阻R_th而不是直接用物理公式估算。如果实在没有实测数据宁可把C_th设得保守一点比如取理论值的60%到70%也要保证调度结果在实际系统中不出问题。5.3 求解器参数和数值尺度问题楼宇微网模型涉及的量级差异很大温度是20多摄氏度功率是几十到几百千瓦电价是每千瓦时几毛钱到一块钱。把这些数量级相差很大的量放在同一个约束里数值稳定性很容易出问题。比如SOC的范围如果是0到1而温度是23到26功率是0到200这种尺度差异在求解时可能让部分约束的容差判断出问题。我习惯做归一化处理把功率基准取为100千瓦温度偏移量用相对值表示SOC保持不变目标函数里的费用按1000元做基准缩放。这样求解器的数值表现会稳定不少。另外在求解器设置里可以适当放宽MILP的MIP间隙容忍度比如设置MIP gap为1%而不是0.01%楼宇调度这种场景下1%以内的次优解完全够用但求解时间可能从几分钟缩短到几秒。5.4 从离线优化到实时调度的衔接很多人做完24小时离线调度之后以为把结果拿去执行就行了。实际运行时光伏实际出力、真实负荷和预测值一定有偏差空调的实际制冷效果也会因为开门、人员流动而变化。所以现实工程里24小时优化模型往往和模型预测控制MPC配合使用每15分钟或者1小时滚动一次用最新的实测状态当前温度、当前SOC作为初始值重新求解未来24小时的优化问题只执行第一个时段的结果。滚动优化的好处是能够持续修正预测误差而且每次求解的效率很高完全满足实时性要求。在Matlab里实现MPC也不复杂把主程序包在for循环里每个循环更新外部输入数据和状态初值即可。前面建立的模型代码可以原封不动地复用这也是离线模型一定要把数据输入独立成函数的原因。5.5 调试时的经验速查现象可能原因排查方向求解结果不可行温度限值过紧、初始温度不合理放宽限值检查T_in(1)充放电同时发生缺少互斥约束加u_cha u_dis 1SOC一直不变化储能容量标幺化错误检查Cap_bat和dt的单位空调功率恒为0温度约束过松检查舒适区间是否太宽目标函数为负数异常售电价格设置高于购电价格检查电价数据方向求解时间很长整数变量过多尝试减少0-1变量、收紧MIP gap这里再补充一个容易被忽略的坑初始SOC和温度初值如果不与优化模型的第一个时段严格一致调度结果前几个时段可能出现剧烈的功率调整——这是模型在“纠正”一个不存在的错误状态实际执行时就会看到楼宇开关负荷剧烈波动。所以每轮滚动优化都要把最新实测SOC和室内温度赋值给模型的初始状态变量。写在最后这个项目做下来我自己最大的体会是需求侧虚拟储能不是一个“锦上添花”的优化选项而是楼宇微网经济性提升的关键抓手——前提是你得有一块能准确描述楼宇热动态的模型。Matlab加Yalmip这套组合足够把调度逻辑完整跑通但在实际项目里真正拉开差距的往往不是算法多玄乎而是对楼宇热过程的理解有多深、对温度舒适度边界拿捏得有多准。如果后续你想往下扩展方向其实也明确把节点电价引入目标函数做需求响应激励或者把蓄热水箱这类多类型柔性资源统一纳入同一个优化框架再往上就是把楼宇群的多个微网协同调度。底层建模思路都是相通的核心还是那几条差分方程和约束条件。先把这个基础框架吃透后面怎么扩展都不会走偏。
阅读完成 · 觉得有帮助?