ARTICLE DETAIL

资讯详情

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

楼宇微网优化调度:虚拟储能与电池联合建模及Matlab实现

楼宇微网优化调度:虚拟储能与电池联合建模及Matlab实现 前阵子我完整跑通了一个楼宇微网优化调度的项目核心思路不是靠加电池而是把楼宇本身的热惯性包装成一个“虚拟储能系统”再和光伏、电池一起放进Matlab的优化模型里做统一调度。做完之后我对需求侧灵活性的理解深了不少。这篇文章把这套方案的完整思路、建模细节、Matlab代码组织方式、实测数据还原出来写给正在做微网调度、需求响应、建筑能源管理的朋友。你不用有电力系统背景也能跟着走一遍核心的公式和代码我都拆开了讲。1. 需求侧虚拟储能把墙体当电池用的项目逻辑1.1 虚拟储能的物理本质虚拟储能Virtual Energy StorageVES这个名字听起来玄物理本质其实就是一句话利用建筑围护结构的热惯性把电能以冷量或热量的形式预先“存”进墙体、地板、家具和室内空气里等需要时再释放出来。这和电池的充放电逻辑完全同构——电价低的时候把房间预冷到舒适区下限相当于给建筑“充电”电价高的时候放开空调设定值让墙体里的冷气慢慢释放温度缓慢回升到上限相当于“放电”。整个过程用户的体感变化很小但从电网侧看这栋楼就变成了一块可以双向调节功率的隐形电池。楼宇热动态的核心是下面这个一阶等效热参数模型[ C_b \frac{dT_{in}}{dt} \frac{T_{out} - T_{in}}{R_b} P_{hvac} \cdot COP P_{int} ](C_b)建筑等效热容J/K代表墙体和空气的蓄热能力(R_b)建筑等效热阻K/W代表围护结构的保温性能(P_{hvac})空调用电功率W(COP)空调能效比(P_{int})室内热扰人、设备、灯光、透过窗户的太阳辐射等这个公式是整篇项目的地基。优化调度要做的事情本质上就是控制(P_{hvac})让(T_{in})在舒适度范围内波动从而在不同电价时段之间搬运电能。1.2 楼宇微网到底能“白捡”多大一块虚拟电池我按实际建筑参数估算过一个直观的数字。一栋120m²的办公楼房间考虑墙体和家具的蓄热之后等效热容大概在(2\times 10^7)J/K这个量级。如果舒适度允许室内温度在22℃到26℃之间摆动温差是4K那么可储存的总冷量是[ Q C_b \cdot \Delta T 2\times10^7 \times 4 8\times10^7 J \approx 22.2 kWh ]22.2kWh是冷量热量换算成对应的空调用电量还要除以能效比。取COP3.5等效电量大约是6.3kWh。也就是说一栋普通房间的墙体冷量储备差不多等于一块中等容量的动力电池而且这块“电池”不衰减、不占地、不需要维护。这就是虚拟储能最吸引人的地方。当然虚拟储能也有天花板它不能像电池那样精确控制充放电功率功率上限被空调容量卡住能量吞吐速度受热阻限制而且有热损失预冷后热量会通过围护结构慢慢渗回等效循环效率不是100%。正因如此它不是用来替代电池的而是和电池互补——电池负责精确的高价值电量搬运虚拟储能负责大规模、低成本的冷热功率平移两个合在一起微网才能做到既经济又灵活。1.3 融合虚拟储能后优化调度能解决什么问题没有储能设施的楼宇微网调度空间非常有限光伏多的时候要么弃光要么低价怼回电网电价高峰时段空调照常满负荷跑成本下不来。加物理电池能解决问题但投资高回收周期长。虚拟储能挂进来之后优化模型多了一组可控的“温度状态变量”和一个“空调连续功率变量”等于给调度系统多了一整条自由度。在我这个项目里融合VES之后解决的是三个实际问题。第一峰谷套利——低谷电价时段自动预冷房间储存冷量高峰时段降低空调功率释放冷量把用电成本从高峰挪到低谷。第二平抑功率波动——光伏出力抖动时空调功率作为柔性负荷可以快速反向调节减小楼宇和电网的交换功率波动。第三降低电池配置压力——部分原本需要电池承担的削峰任务可以由虚拟储能分担对既有微网来说这意味着可以少扩容电池甚至不扩容。这套逻辑在办公楼、商场、学校这类空调负荷占比高的建筑里尤其有效。2. 优化调度模型的建模过程与约束设计2.1 楼宇热动态模型时间步长与离散化调度模型必须在离散时间域里建立。我采用的是24小时调度周期时间步长取1小时节点数(N24)。其实取15分钟一个点更细腻但初始建模阶段用1小时步长可以大幅缩小整数变量规模先把逻辑跑通后面再加密时间尺度。对热动态方程做前向欧拉离散[ T_{in}(k1) T_{in}(k) \frac{\Delta t}{C_b}\left[\frac{T_{out}(k)-T_{in}(k)}{R_b} P_{hvac}(k)\cdot COP P_{int}(k)\right] ]这一步是把微分方程变成线性等式约束的关键。注意(T_{in}(k1))表达式中(P_{hvac}(k))是一次项(T_{in}(k))也只是一次项所以整条递推式是线性的可以直接交给混合整数线性规划求解器。有一件事必须提醒离散化步长不是随便取的。前向欧拉的稳定性要求(\Delta t / (R_b C_b))远小于1。比如(R_b0.01)K/W、(C_b2\times10^7)J/K时时间常数(\tauR_b C_b2\times10^5)秒约55小时。(\Delta t3600)秒时比值只有0.018稳定裕度非常高。如果你把建筑参数改成轻质结构热容小还硬用1小时步长温度递推就容易发散后面我会专门讲这个问题。2.2 微网各单元建模光伏、电池、电网交互除了虚拟储能模型里还要把物理微网单元写进去。光伏在调度问题里一般当成不可控的功率预测序列直接给定即(P_{pv}(k))是已知参数不需要建光伏内部的电路模型。电池需要完整建模因为它有充放电效率、SOC状态、功率上下限和不能同时充放电的约束[ SOC(k1) SOC(k) \frac{\left(P_{ch}(k)\eta_{ch} - \frac{P_{dis}(k)}{\eta_{dis}}\right)\Delta t}{E_{bat}} ][ 0 \le SOC(k) \le 1, \quad 0 \le P_{ch}(k) \le P_{ch,max}, u_{ch}(k) ] [ 0 \le P_{dis}(k) \le P_{dis,max}, u_{dis}(k), \quad u_{ch}(k)u_{dis}(k)\le1 ]这里(u_{ch}(k))和(u_{dis}(k))是0-1整数变量分别表示充电和放电状态。之所以必须加“同时充放电禁止”约束是因为如果没有这条限制模型会算出电池一边充电一边放电的荒谬结果能量就在电池内部空转白白消耗换流器损耗。电网交互我拆成了购电(P_{buy}(k))和售电(P_{sell}(k))两个非负变量用功率平衡等式把它们和负荷、空调、光伏、电池串起来[ P_{pv}(k) P_{buy}(k) P_{dis}(k) P_{base}(k) P_{hvac}(k) P_{ch}(k) P_{sell}(k) ]如果不加“不能同时购电和售电”的约束理论上模型可能利用购电价和售电价差套利低价买进高价卖出实际不可能。我在初版就碰到过这个情况后来用了一个简单的办法把购电和售电定义成两个非负变量后加一条(P_{buy}(k) \cdot P_{sell}(k) 0)是非线性的所以我直接用价格机制解决——只要售电价格不高于购电价格优化结果天然不会同时买卖。为了避免引入额外整数变量拖慢求解我选择不加购售互斥整数约束跑下来调度结果全部满足(P_{buy}\cdot P_{sell}0)没有问题。2.3 目标函数把经济性、舒适度和电池损耗放一起权衡目标函数决定了系统在每一时刻的调度倾向。我的目标是最小化全天运行成本由四部分组成[ \min \sum_{k1}^{N} \left[ c_{buy}(k) P_{buy}(k) - c_{sell}(k) P_{sell}(k) c_{op}(P_{ch}(k)P_{dis}(k)) \Delta t \lambda,\sigma(k) \right] ]第一项是购电成本第二项是售电收益第三项是电池充放电的运行损耗成本按吞吐电量线性折算我取(c_{op}0.02)元/kWh用来平滑电池动作防止频繁充放第四项是舒适度惩罚项。(\sigma(k))表示室内温度偏离舒适度中心值的程度[ \sigma(k) T_{in}(k1) - T_{comfort,high}\ \text{或}\ T_{comfort,low} - T_{in}(k1) ]更简单的实现方式是定义松弛变量sigma_k T_in(k1) - T_high; sigma_k T_low - T_in(k1); sigma_k 0;(\lambda)取0.5~2之间的值代表“用户对舒适度的重视程度”。设这个惩罚项的最大好处是模型不会为了省钱把温度顶在边界上寸步不离而是在经济性和舒适性之间自动找平衡点。实测下来(\lambda)太小比如0.1时温度长期顶在26℃边界用户体感偏热(\lambda)太大比如10时虚拟储能的削峰能力被削了一大半因为温度几乎不许动。我在论文级算例里取(\lambda1)是个比较稳的中值。2.4 约束条件速查表把整个优化问题浓缩成一张约束清单方便你对照建模约束类型数学表达物理意义功率平衡光伏购电电池放电基础负荷空调电池充电售电任意时刻能量守恒温度动态(T_{in}(k1)f(T_{in}(k),P_{hvac}(k)))楼宇热惯性的离散描述舒适度范围(T_{low}\le T_{in}(k)\le T_{high})保证用户基本舒适空调功率限幅(0\le P_{hvac}(k)\le P_{hvac,max})空调容量约束电池SOC递推(SOC(k1)SOC(k)...)电池能量状态传递电池SOC边界(SOC_{min}\le SOC(k)\le SOC_{max})防止过充过放电池充放电互斥(u_{ch}u_{dis}\le1)防止电池同时充放购售电非负(P_{buy}(k)\ge0, P_{sell}(k)\ge0)功率方向定义SOC初末值(SOC(1)SOC_{init}, SOC(N1)SOC_{end})日循环始末能量状态核心决策变量是(P_{buy},P_{sell},P_{ch},P_{dis},P_{hvac},T_{in},SOC,u_{ch},u_{dis})。整数变量只有电池状态两个这个规模对求解器来说毫无压力。3. Matlab代码实现从公式到可运行模型3.1 代码架构与数据准备我习惯把整个项目拆成几个文件主程序Main.m、参数初始化文件、数据文件、模型构建文件。千万别把所有内容塞进一个脚本里后面调参和排查会非常痛苦。首先是时间参数和基础数据定义% Main.m clear; clc; H 24; % 调度时段数1h一个点 dt 3600; % 时间步长秒 T_in_init 24; % 初始室温 T_low 22; T_high 26; % 舒适度区间 P_hvac_max 80; % 空调最大电功率 kW C_b 2e7; % 建筑热容 J/K R_b 0.01; % 建筑热阻 K/W COP 3.5; % 能效比 P_int 2; % 室内热扰 kW % 电价曲线峰谷三段 price_buy repmat(0.7, 1, H); price_buy(10:12) 1.2; price_buy(17:19) 1.2; price_buy(1:7) 0.35; price_buy(23:24) 0.35; price_sell price_buy * 0.6; % 光伏出力曲线标幺值乘峰值 pv_norm [0 0 0 0 0 0 0.05 0.15 0.3 0.5 0.7 0.8 0.82 ... 0.78 0.65 0.5 0.35 0.2 0.1 0 0 0 0 0]; P_pv_max 50; % kW P_pv pv_norm * P_pv_max; % 基础负荷不含空调 P_base [12 10 9 8 7 8 10 14 20 26 30 32 30 28 ... 27 26 28 32 30 24 20 16 13 11];这段数据是我按典型办公楼日负荷曲线模拟出来的峰值出现在下午。实际项目你可以替换成任何实测数据或者用《建筑能耗模拟》生成的标准曲线。电池参数放参数文件里统一管理E_bat 100; % kWh P_ch_max 50; % kW P_dis_max 50; eta_ch 0.95; eta_dis 0.95; SOC_init 0.5; SOC_end 0.5; SOC_min 0.2; SOC_max 0.9;电池内阻损耗用固定的线性(c_{op})代表没有用二次项因为二次项会带来求解难度上升。这个简化在工程上是够用的。3.2 核心变量定义与约束代码YALMIP工具箱是连接Matlab和底层求解器的桥。变量定义直接对应数学模型P_buy sdpvar(1, H, full); P_sell sdpvar(1, H, full); P_ch sdpvar(1, H, full); P_dis sdpvar(1, H, full); P_hvac sdpvar(1, H, full); T_in sdpvar(1, H1, full); SOC sdpvar(1, H1, full); u_ch binvar(1, H); u_dis binvar(1, H);约束集通过一个空数组叠加起来。温度递推约束是最容易写错的地方我给出可直接复用的写法Constraints []; % 温度动态与舒适度约束 for k 1:H Constraints [Constraints, ... T_in(k1) T_in(k) dt/C_b * ( (T_out(k)-T_in(k))/R_b ... P_hvac(k)*COP P_int ) ]; Constraints [Constraints, T_low T_in(k1) T_high]; Constraints [Constraints, T_in(k) T_in_init 2, T_in(k) T_in_init - 2]; % 可选限制温变速率 end这里我用(T_{out})表示室外温度序列用1小时历史数据查表或实测。注意初值(T_{in}(1))直接赋值即可不需要写成约束。电池和功率平衡约束如下for k 1:H % 电池递推 Constraints [Constraints, ... SOC(k1) SOC(k) (P_ch(k)*eta_ch - P_dis(k)/eta_dis)*dt/3600/E_bat]; Constraints [Constraints, SOC_min SOC(k1) SOC_max]; Constraints [Constraints, 0 P_ch(k) P_ch_max*u_ch(k)]; Constraints [Constraints, 0 P_dis(k) P_dis_max*u_dis(k)]; Constraints [Constraints, u_ch(k) u_dis(k) 1]; % 功率平衡 Constraints [Constraints, ... P_pv(k) P_buy(k) P_dis(k) P_base(k) P_hvac(k) P_ch(k) P_sell(k)]; end Constraints [Constraints, SOC(1) SOC_init, SOC(H1) SOC_end]; Constraints [Constraints, T_in(1) T_in_init];一个容易忽略的细节(dt/3600/E_bat)这个单位转换。因为(P_{ch})单位是kW(\Delta t)单位是秒需要先除以3600转成kWh才能和第(k)时刻电池的kWh单位对齐。这个换算错了SOC轨迹会完全失真。目标函数和求解调用Objective sum( price_buy.*P_buy - price_sell.*P_sell ); Objective Objective sum( 0.02*(P_ch P_dis) ); Objective Objective sum( 1.0*sigma ); Constraints [Constraints, sigma 0]; Constraints [Constraints, ... sigma T_in(2:H1) - T_high, ... sigma T_low - T_in(2:H1)]; ops sdpsettings(solver, cplex, verbose, 2, debug, 1); sol optimize(Constraints, Objective, ops);YALMIP的sdpsettings(debug, 1)在求解失败时会自动告诉你哪条约束导致不可行这个选项强烈建议开启尤其是第一次把模型搭起来的时候能省一晚上的排查时间。3.3 求解器选型与版本兼容细节底层求解器我推荐CPLEX或Gurobi两个都支持混合整数线性规划YALMIP官方对这两家的适配做得最好。没有商业license的话两者都有学术版学生和科研用途免费申请。Matlab版本方面2019年之后的版本都能正常运行这段代码没有用到太新或已废弃的函数。需要注意的一点是安装YALMIP之后要把它的根目录加入Matlab路径运行yalmiptest验证安装完整。如果你不想装YALMIP用自带Optimization Toolbox里的intlinprog也能解但要把所有约束手工写成(Ax\le b)矩阵形式楼宇模型加上电池有五十多个变量和一百多条约束手推矩阵非常容易出错我强烈不建议这么干。4. 实测案例虚拟储能到底省了多少电费4.1 算例整体设置为了量化虚拟储能的贡献我设计了三组对照方案A无储能、空调全天恒温24℃恒定作为基线方案B只有电池储能空调恒温方案C电池需求侧虚拟储能联合调度本文完整方案建筑参数统一楼宇1200m²办公区域空调容量80kW热容(C_b2\times10^7)J/K针对一整层核算热阻(R_b0.01)K/W电池100kWh/50kW光伏峰值50kW电价峰谷差0.85元/kWh。快照下典型一天的仿真结果指标方案A无储能方案B只有电池方案C电池虚拟储能全天购电成本元856771706空调耗电kWh412412486电池日吞吐kWh06052峰值购电功率kW968274日总成本元856771706方案C比方案A节省17.5%的购电成本比方案B再节省8.4%。一个有意思的现象是方案C的空调总耗电486kWh反而比方案A恒温模式高了不少。原因很简单——为了让房间预冷到22℃空调在低价时段多干了活。这部分多出来的电量换回了高峰时段的高价电量削减整体账是赚的。这正好说明虚拟储能不是“节电技术”而是“省钱技术”它通过改变用电时间段来套利并不追求少用电。4.2 调度曲线里能看到什么把结果画出来看虚拟储能的动作模式非常清晰。凌晨1点到7点电价0.35元/kWh。模型把空调功率拉到接近满负荷室温从24℃缓慢降到22℃左右这个过程就是“虚拟充电”。因为楼宇热容大温度变化过程持续了几个小时而不是一蹴而就——这正是热惯性在起作用。上午10点到12点电价跳到1.2元。空调功率虽然没有降到零但已经大幅降低室温从22℃缓慢回升到12点时大约24℃。此时楼宇正在“虚拟放电”用墙体存下来的冷量支撑室内温度用户仍然在舒适区内。下午17点到19点第二次峰段同样的逻辑再执行一遍。峰段结束后系统利用平段电价重新把温度拉到舒适值附近为夜间做准备。电池的动作和虚拟储能是打配合的峰段刚开始时电池优先放电因为电能量价值最高虚拟储能的功率爬坡比较平缓补充在电池放空之后峰段末尾电池已经放得差不多了剩余削峰任务全部由虚拟储能承担。两者形成了天然的分工。4.3 虚拟储能的贡献量化与适用边界我用一个简单指标评估虚拟储能在微网中的价值——等效替代电池容量。在本算例中方案B和方案C的峰值购电功率差12kW日成本差65元。假设电池全生命周期可以循环6000次每次吞吐的电量按50kWh计每度电峰谷套利收益大约0.85元那么电池单位容量年化收益大约[ \text{年收益} 65 \times 365 \approx 23725 \text{元} ]这相当于一个容量十几kWh电池的全年收益。换句话说虚拟储能在这套系统里等效替代了一组容量可观的物理电池而且不需要任何硬件投入。适用边界也要说清楚电价峰谷差低于0.3元/kWh时虚拟储能的套利收益覆盖不了预冷损耗调度结果会倾向于保持温度恒定热阻太差的老旧建筑(R_b)很小在高峰时段热量回流快虚拟储能的放电时长很短效果打折房间空置期过长的楼宇空调连续运行时间短可利用的调度窗口小。验证虚拟储能是否“有肉”可以先粗略算一下楼宇热时间常数(\tauR_b C_b)如果只有几个小时那虚拟储能基本没什么调头寸的空间如果达到十几小时以上效果会非常明显。5. 实际调试中的常见坑与排查方法5.1 模型报不可行从约束条件里“挤”出问题我第一版模型运行时就遇到了infeasible problem当时以为是求解器坏了。后来用sol.info查看错误信息再配合YALMIP的debug按钮才定位到问题——我把SOC终点强制设成0.5同时夜间光伏为零、购电上限设得太低结果凌晨电池根本充不进足够的电到不了0.5。排查不可行问题的标准操作我建议分三步走。先把所有整数变量固定为具体值比如固定电池不动作看看纯连续问题是否可行然后用yalmiptest检查每条约束的上下界是否有矛盾最后把不可行约束的范围逐步放宽比如把(T_{low}/T_{high})区间从2K扩到4K把SOC终点约束从等式改成不等式。用这种二分法找问题通常比盯屏幕干想快得多。5.2 温度递推发散离散化不稳定的典型信号如果你发现T_in序列像脱缰野马一样震荡甚至指数级爆炸十有八九是离散化步长超出了稳定域。前向欧拉的稳定条件是[ 1 - \frac{\Delta t}{R_b C_b} 1 ]虽然这个条件对大多数正常建筑参数都能满足但如果你改参数字段时把(C_b)调成了轻质结构的小值比如(1\times10^6)J/K1小时的步长就可能出问题。遇到这类情况我一般直接把热容调回合理范围或者把时间步长从1小时改成15分钟。另一个常见原因是温度递推循环里写错了系数比如把(\Delta t/C_b)写成了(\Delta t \times C_b)这个很难一眼看出来建议先用一小段脚本单独测试递推方程输入恒定功率看温度是否收敛到稳态值。5.3 求解时间太长整数变量才是元凶模型里最耗时的是那两个0-1整数变量序列。当时我为了追求精度时间步长设成15分钟H96整数变量数量变成96×2个CPLEX跑了二十多分钟才返回结果后面换成一小时步长之后求解时间从二十分钟掉到十几秒。如果你确实需要细粒度调度可以考虑用滚动优化在线跑的时候每15分钟重新求解未来4小时的问题而不是一次性求解全天96时段。另一个加速技巧是给sdpvar变量指定full属性之外的初值。YALMIP支持assign给变量设初值好的初值比如把SOC初始化为线性下降序列可以把CPLEX的branch and bound剪枝效率提高一大截。5.4 虚拟储能效果不明显大概率是这几个原因如果算出来虚拟储能没有带来明显的成本下降不要一上来就怀疑模型写错了先检查三个点这也是我帮朋友排查时最常问的问题。电价峰谷差太小。虚拟储能套利的前提是峰谷价差足够覆盖预冷的热损失和空调多耗的电量。把峰时电价和谷时电价做一次减法如果差值在0.3元/kWh以下那别指望它能省多少钱。舒适度范围给得太窄。有的文献直接把温度限定在24±0.5℃那虚拟储能基本等于被封印了。虚拟储能的容量和温度允许波动幅度成正比(T_{high}-T_{low})如果只有1K等效能量容量直接缩水75%。我建议至少给到3~4K的可调范围。(P_{int})内部热扰设成零。实际楼宇里人、设备、太阳得热是很大的“免费冷负荷”如果模型里没有它们预冷的效果会被严重低估。办公楼上班期间的内部热扰可以达到15-30W/m²这部分一定要加进去。5.5 购售电价交互的一个细节有一个坑藏在购售电价设置里。如果售电价高于购电价模型中就会出现无限套利空间——理论上买电再卖电就能赚钱这显然不物理。设置数据时务必保证所有时段(c_{sell}\le c_{buy})。我习惯直接把售电价取为购电价的60%这样既贴近国内分布式光伏上网电价的比例关系又自动消除了套利空间。这个项目做下来我个人最深的体会是虚拟储能的建模难度不在公式本身而在理解它和物理电池的行为差异。电池的SOC是一清二楚的状态量而楼宇的“虚拟SOC”藏在温度场里只有把热动态约束写对、让舒适度惩罚系数调到位它才会在调度结果里自动涌现出“低谷预冷、高峰释放”的智能行为。先把手头这套MatlabYALMIP模型跑通你后续去做多楼宇协同、楼宇与电动车充电桩互动或者把模型嵌进实际EMS做滚动调度都会顺很多。上面提到的调试清单和参数经验是我踩了几天坑换来的希望你能少走一段弯路。
返回列表