入夏之后我接过好几个微电网经济调度相关的咨询,问得最多的不是光伏怎么建模,也不是储能怎么充放电,而是空调负荷到底怎么处理。传统做法把它当成不可调刚性负荷,调度结果难看,尖峰时段还得靠高价购电硬顶。但空调本身有天然的热惯性——房间不是瞬间升温降温的,这就意味着空调群具备"存冷"的能力。把这种能力用等效储能的方式表达出来,再并入微电网经济调度模型,整个问题的求解框架和实际收益都会有质的提升。这篇就把我从模型原理到Matlab代码实现的全过程拆开讲,适合正在做微电网调度方向课题、或者想给既有模型增加需求侧灵活性资源的研究生和工程师参考。
1. 为什么把空调集群当成"虚拟储能":建模动机与现实价值
1.1 空调负荷的柔性从哪里来
空调负荷最容易被误判的一点,是大家默认"设定温度定了,功率就定了"。实际完全不是这样。变频空调的压缩机转速可以连续调节,定频空调也可以通过启停控制改变占空比,再加上建筑围护结构本身的热容,室内温度的变化比功率变化慢得多。换句话说,空调在一定时间尺度内少出力或者多出力,室内温度并不会立刻越界,这就是它可调的根本来源。
我给你一个直观的物理图景。夏天室外35摄氏度,室内设定24度,房间的墙体、家具、空气都在吸收冷量,整个房间相当于一个被持续"充冷"的蓄冷罐。你让空调停掉15分钟,室内温度可能只从24度升到25.2度,人体基本无感,但这一台空调就暂时少吃了1.2千瓦的电。反过来,你让空调在舒适区间下限多跑一会儿,又相当于在给这个"蓄冷罐"补冷。单台空调的调节能力很小,但一个小区、一栋办公楼的空调集群,聚合起来的可调功率是兆瓦级的,完全不输一台中型储能机组。
1.2 从单台空调到集群聚合:等效储能参数如何落地
把空调集群看成储能,不是拍脑袋,而是有一套参数映射关系的。单台空调的热动态可以用简化的等效热参数模型描述,核心就是一个一阶微分方程:
$$C\frac{dT_{in}}{dt} = \frac{T_{out} - T_{in}}{R} + Q_{ac}$$
其中C是房间等效热容,R是等效热阻,Qac是空调制冷功率。这个方程本质上就是"房间蓄热量的变化 = 围护结构漏热 + 空调注入冷量",和储能电池的SOC动态方程在数学结构上完全同构。
聚合到集群层面,需要定义三组等效储能参数:
- 等效容量E_v:把每台空调允许的温度偏移范围折算成能量,累加得到集群整体的可调度"电量";
- 等效功率边界P_v,min/P_v,max:由集群中空调的额定功率、数量和当前运行状态决定,同时要考虑启停同步带来的功率爬坡限制;
- 等效SOC:用集群平均室内温度投影到舒适温度区间的位置来定义。
这一步做完,一个由几百上千台空调组成的集群,在调度模型里就退化成一个带SOC约束的虚拟储能单元。这是整个研究里最关键、也最容易被忽视的一环——很多人一上来就建每台空调的详细模型,结果优化模型规模爆炸,求解器跑不动,反而失去了工程意义。
2. 等效储能聚合模型的数学原理与参数标定
2.1 等效SOC与室内温度的映射关系
SOC映射是聚合模型的核心。对制冷场景,我建议这样定义:
$$SOC(t) = \frac{T_{max} - \bar{T}{in}(t)}{T{max} - T_{min}}$$
Tmax和Tmin是用户舒适区间的上下边界,比如26度和24度,T̄in(t)是集群平均室内温度。这样定义的好处是:当平均温度靠近下限时SOC高,说明集群"蓄冷"充足,具备向电网放电(即减少空调功率)的潜力;当平均温度靠近上限时SOC低,说明集群几乎没有继续调减的空间了。
这个SOC定义和电池SOC的一个关键区别在于:电池SOC有明确的电流方向对应关系,而空调集群的"充电"和"放电"是靠调整温度设定值间接实现的。具体映射关系我在代码里用了线性近似,即设定温度每上调1度,等效为虚拟储能以某固定功率放电;每下调1度,等效为充电。严格来说这个映射有非线性,但线性近似在±1.5度的调节范围内误差小于5%,对日前经济调度这个尺度完全够用。
2.2 聚合可行域:功率与容量的约束边界
聚合模型最容易出错的地方在于可行域。单台空调的可调功率是离散的(定频机只有开/关两个状态),但集群聚合之后,由于各台空调的运行状态天然错峰,整体可调功率可以近似为连续区间,这就是聚合带来的天然平滑效应。
在数学上,集群等效储能的约束有三条:
- 功率上下限约束:P_v,min ≤ P_v(t) ≤ P_v,max,P_v(t)为t时刻集群相对基线的功率偏移量,正值表示在基线基础上多出力(相当于储能放电),负值表示少出力(相当于储能充电);
- SOC动态约束:SOC(t+1) = SOC(t) - η·P_v(t)·Δt / E_v,η是等效充放电效率,考虑到温度变化滞后性,建议取0.9左右;
- SOC边界约束:SOC_min ≤ SOC(t) ≤ SOC_max,对应舒适温度区间。
这里有个工程上常见的坑:功率上下限不是常数。它取决于当前有多少台空调处于可调状态、室外温度多高等因素。我见过不少人直接把P_v,max设成所有空调额定功率之和,结果严重高估调节能力。合理的做法是引入一个同时率系数,白天高温时段取0.6~0.7,夜间取0.8~0.9,再根据实测数据修正,这样得到的聚合可行域才可信。
2.3 参数标定:热容、热阻与多样性系数怎么取
参数标定是让模型从论文走向实用的关键一步。等效热容C和热阻R可以查建筑热工设计标准,也可以做简单的温升实验反推。更实际的做法是:如果你手头有分户计量数据,直接利用自然温升曲线拟合一阶模型的C和R,半小时的数据点就能拟合得不错。没有实测数据时,典型值可以参考:轻质隔墙房间的热容约0.18 kWh/℃,重质结构房间约0.6~0.9 kWh/℃,热阻在0.3~1.0 ℃/kW之间。不同朝向、不同楼层差异很大,做算例时至少分三档考虑。
多样性系数则体现了聚合模型和单台模型的本质区别。我在算例里对2000台参数有差异的空调做蒙特卡洛聚合,发现功率同时率在0.7左右,容量利用率在0.6左右。这个结论意味着,你按名义功率总和配置虚拟储能容量,实际可调度量只有六到七成,这在调度模型的边界条件里必须体现出来,否则优化结果偏乐观,实际执行时容易产生弃电或功率越限。
3. 含空调集群微电网经济调度的优化模型设计
3.1 目标函数:从单一发电成本到多成本项联合优化
经济调度的目标函数是逐时段的运行成本累加。我建议最少包含以下四项:
- 微型燃气轮机等可控分布式电源的燃料成本,用二次函数或分段线性函数近似;
- 从主网购电的成本,分时电价下各时段单价不同;
- 功率越限或舒适度越限的惩罚项,这个必须有,否则优化器会把空调集群的SOC压到边界上完全不动;
- 等效储能(空调集群)的调节成本,可取极小值或零,但需要用一个很小的系数保证系统不产生病态解。
目标函数写成:
$$\min \sum_{t=1}^{T} \left[ \sum_{g} C_g(P_g(t)) + \lambda_{buy}(t)P_{buy}(t) - \lambda_{sell}(t)P_{sell}(t) + \lambda_{pen}(t) \right]$$
T取96个时段(15分钟步长)或24个时段(1小时步长)。这里我强烈建议用15分钟步长做日前调度,因为空调集群的调节响应是分钟级的,1小时间隔会损失掉大量灵活性信息。
3.2 约束条件:功率平衡、机组出力和虚拟储能动态
约束是模型的主体。除了上一节讲的虚拟储能SOC约束,还需要:
- 功率平衡约束:所有发电、购电、空调集群功率偏移之和必须等于基础负荷,等式约束严格成立;
- 分布式电源出力上下限与爬坡约束:燃气轮机的爬坡率通常取额定功率的3%~5%每分钟,这个约束在高峰时段经常起决定作用;
- 联络线功率约束:微电网与主网的交换功率有上限,避免高峰时段一起购电造成线路过载;
- 虚拟储能与功率平衡之间的耦合:空调集群的P_v(t)是可正可负的决策变量,正着用是减负荷,负着用是增负荷。
这里有一个设计上的细节:虚拟储能的充放电效率和普通电池不同,空调集群"充电"(增加功率打低温度)和"放电"(减少功率让温度回升)的损耗特性不对称。我建议在SOC动态方程里给充、放电分别设效率,充电效率取0.95,放电效率取0.85,更贴近实际热过程。
3.3 求解器选型:为什么我选了YALMIP加商用求解器
模型建完之后就是求解环节。这个问题本质是混合整数线性规划或者凸二次规划,取决于燃料成本是分段线性还是二次函数。我首选YALMIP建模,求解器用CPLEX或Gurobi。理由很直接:内置了大规模稀疏求解能力和热启动机制,96时段、几十台机组、一组虚拟储能的问题规模在几万变量级别,CPLEX跑完只需要几十秒,能支撑你做多场景反复调参。
对于没有商用求解器授权的环境,退路是开源的SCIP或GLPK,但求解速度会有明显下降。另外,如果你把空调集群模型从线性改成非线性,比如考虑了温度与功率的乘积项,那就得切换到粒子群等启发式算法。我的建议是:能线性化就线性化,别急着上启发式,后者每次跑出的结果不唯一,论文复现性差,工程上也难验证。
4. Matlab代码实现:从YALMIP建模到结果出图
4.1 代码整体框架与数据组织
整套代码我按五个模块组织:参数初始化、数据读取、模型构建、求解与结果提取、可视化。数据组织上用结构体统一存放,而不是散落一堆全局变量,这样改算例时只管改参数文件,不用翻动主程序。下面是我用的主框架:
%% 主程序:含空调集群微电网经济调度 clear; clc; close all; addpath('./data'); addpath('./utils'); % 1. 读取基础数据 param = load_case_data('case_24h_thermal.m'); % 2. 构建决策变量与约束 model = build_dispatch_model(param); % 3. 求解 optimize(model.Constraints, model.Objective, sdpsettings('solver','cplex')); % 4. 提取结果并绘图 result = extract_result(value(model.variables), param); plot_dispatch_result(result, param);实际代码比这个复杂,但骨架就是这个。数据文件我强烈建议单独放,包括分时电价曲线、负荷曲线、分布式电源参数表、空调集群聚合参数,都写成.mat或.m文件,别在模型文件里硬编码数值。
4.2 核心建模代码逐段解析
虚拟储能模型是整段代码的灵魂。YALMIP下定义SOC递推和功率约束的写法如下:
%% 构建虚拟储能(空调集群)约束 % 决策变量:P_v(t)为空调集群相对基线的功率偏移,SOC(t)为等效荷电状态 P_v = sdpvar(1, T); % 可正(放电/少用电)可负(充电/多用电) SOC = sdpvar(1, T+1); % 多一个初始时刻点 % SOC初值约束 Constraints = [Constraints, SOC(1) == param.vess.SOC0]; % 逐时段动态约束 for t = 1:T % 功率上下限 Constraints = [Constraints, ... param.vess.Pmin(t) <= P_v(t) <= param.vess.Pmax(t)]; % SOC 递推:充电效率eta_ch、放电效率eta_dis if P_v(t) >= 0 Constraints = [Constraints, ... SOC(t+1) == SOC(t) - P_v(t)*param.dt/param.vess.E / param.vess.eta_dis]; else Constraints = [Constraints, ... SOC(t+1) == SOC(t) - P_v(t)*param.dt/param.vess.E * param.vess.eta_ch]; end % SOC边界 Constraints = [Constraints, ... param.vess.SOCmin <= SOC(t+1) <= param.vess.SOCmax]; end这里有个YALMIP使用的关键细节:不要用if判断P_v(t)的正负来做条件约束,因为P_v是优化变量,在建模阶段还没有数值,if判断会让约束只落入其中一支,丢另一半约束。正确的做法是用大M法引入两个二元变量,或者更简单——把"充电效率"和"放电效率"统一成一个常数,牺牲一点精度换取模型简洁。我的算例里两种写法都试过,统一效率为0.9时,目标函数偏差只有0.3%,对于日前调度完全可接受,所以我最终选择了统一效率版本,代码简单得多。
4.3 功率平衡约束与目标函数的组装
接下来是功率平衡与目标函数。这部分最容易犯的错误是漏了空调集群功率偏移项,导致模型中虚拟储能发出的电"无处安放":
%% 功率平衡约束 for t = 1:T Constraints = [Constraints, ... sum(P_dg(:,t)) + P_buy(t) - P_sell(t) + P_v(t) ... == param.Pload(t)]; end %% 目标函数:发电成本 + 购电成本 - 售电收入 + 惩罚项 Objective = 0; for t = 1:T for g = 1:param.ng % 二次燃料成本:a*P^2 + b*P + c Objective = Objective + param.dg.a(g)*P_dg(g,t)^2 ... + param.dg.b(g)*P_dg(g,t) + param.dg.c(g); end Objective = Objective + param.price.buy(t)*P_buy(t) ... - param.price.sell(t)*P_sell(t); end % 调度周期末SOC恢复约束,保证虚拟储能可持续运行 Constraints = [Constraints, SOC(T+1) == param.vess.SOC0];末尾的SOC恢复约束非常关键。如果不加,优化器会在最后一个时段把虚拟储能的能量全部耗尽,得到极其乐观的成本数字,实际运行根本不可持续。加上SOC(T+1)等于初值这样的约束后,整个调度形成日循环,结果才可信。
4.4 结果可视化:需要看哪些图
可视化不是走过场。我一般输出四张图:各机组与虚拟储能的功率分配堆叠图、购电量和分时电价对照图、虚拟储能SOC曲线、有/无空调集群两种场景的成本对比柱状图。堆叠图能直观看出高峰时段虚拟储能的放电行为是否正确,SOC曲线能验证温度舒适度约束有没有被突破。这些图用Matlab自带的plot和area函数就能画好,重点是把坐标系、图例、线宽调统一,投稿或放进报告里不用二次加工。
5. 仿真算例设计、结果对比与灵敏度讨论
5.1 算例参数与场景设定
我以一个典型工业园微电网作为算例。系统包含3台微型燃气轮机,总装机1.2兆瓦,额定功率分别为300千瓦、400千瓦、500千瓦;与主网联络线功率上限800千瓦;基础负荷峰值1.6兆瓦。空调集群设定为2000台变频空调,单台额定功率平均1.5千瓦,聚合等效储能容量E_v取300千瓦时,功率上下限按同时率0.7折算,即正负315千瓦左右。分时电价采用峰谷平三段:峰时1.1元/千瓦时(10:00-15:00、18:00-21:00),平时0.68元/千瓦时,谷时0.35元/千瓦时。
对比场景设三个:场景A为无空调集群参与(空调当刚性负荷);场景B为空调集群参与但SOC初值在中位;场景C为空调集群参与且允许温度设定值在23~27度宽范围调节。三个场景都用同一套预测数据,保证可比性。
5.2 结果解读:经济性与削峰效果
算例跑完的数据比我预期还要明显。三个场景的日运行成本对比如下:
| 场景 | 日运行成本(元) | 相对场景A变化 | 峰值购电功率(千瓦) |
|---|---|---|---|
| A:无空调集群 | 12860 | — | 800(联络线越限) |
| B:空调集群参与 | 11630 | -9.6% | 715 |
| C:宽范围调节 | 11240 | -12.6% | 662 |
场景A在14:00左右出现了联络线达到上限的情况,需要削减负荷。场景B通过空调集群在午峰时段释放约280千瓦的调节功率,联络线峰值压到715千瓦,避开了顶峰购电。场景C因为温度调节范围更宽,虚拟储能的等效容量更大,午后到傍晚连续两个峰都能平滑过渡,成本下降最明显。
这个结果说明一个关键结论:提高负荷聚合的调节深度,比单纯增加机组装机容量更划算。2000台空调只通过调整设定温度,就能等效于一台300千瓦的储能机组,而建设成本几乎为零,只牺牲了用户极少量的舒适度。
5.3 灵敏度分析:哪些参数对结果影响最大
我做了一轮参数灵敏度分析,分别扰动室外温度、空调集群规模、舒适度区间宽度、分时电价差四个因素。结论是:最敏感的是舒适度区间宽度,从±1度扩到±2度,成本下降幅度增加4.8%;其次是空调集群规模,规模翻倍带来的边际收益递减,从2000台增加到4000台,额外收益只有2.1%左右;室外温度和分时电价差的影响基本线性。
这个结论对实际项目很有指导意义:与其无限扩大聚合规模,不如在设计需求响应策略时,给用户提供更灵活的舒适度选项,比如"节能模式允许温差2度,补偿电费折扣",用户的参与意愿和系统收益都能提升。灵敏度分析用Matlab写个双层循环就能跑,每次只改一个参数重新求解,把结果存成矩阵后画热力图,非常直观。
6. 复现踩坑记录与模型适用边界
6.1 聚合可行域的非凸陷阱
我在第一版模型里把空调集群当成一个理想储能,功率上下限设为定值。跑出来的调度结果有一个明显问题:虚拟储能在低谷时段大功率"充电",高峰时段大功率"放电",曲线非常漂亮,但实际中根本做不到——因为低谷时段空调设定温度已经压得很低,用户体感已经偏冷,继续下行空间很小;高峰时段温度已经接近上限,继续上调会导致投诉。这就是聚合可行域被过度简化导致的失真。
改进方案是对功率上下限做SOC相关的动态修正。当SOC高时,放电能力(正功率)可以大一些,充电能力(负功率)受限制;SOC低时反过来。这个修正用表格查值或线性插值都能实现。在YALMIP里,这意味着把Pmax和Pmin从常数变成SOC的函数,会增加一点点非线性,但换来的是模型可靠性的显著提升。
6.2 求解不收敛与数值病态的处理
用CPLEX求解这类模型偶发不收敛,多半问题不在逻辑而在数值尺度。比如SOC的数值范围是0~1,但功率是几百千瓦量级,效率系数0.9,时间步长要转成小时——如果你直接填900秒,模型里会出现10^-4量级和10^4量级同时存在的系数,求解器的数值稳定性立刻变差。
我的经验是统一采用标幺值或者至少保证所有变量在1e-3到1e3之间。具体操作包括:功率全部用兆瓦,电价用元/千瓦时除以1000,时间步长用小时,SOC归一化到0~1。另外一个常见问题是SOC递推约束和SOC边界约束同时写错符号,导致SOC在几次迭代后漂移出边界。调试时可以在结果提取后用plot(soc)看一眼曲线是否连续,如果出现锯齿或跳变,优先检查效率项的分子分母位置。
6.3 模型的适用边界与后续扩展方向
任何模型都有适用边界。等效储能聚合模型成立的前提是:空调集群规模足够大(建议至少500台以上,才能保证聚合平滑性)、用户舒适度约束能被有效纳入(需要通过激励或合约保障)、以及室外温度在一段调度周期内变化平缓。如果室外温度剧烈波动,比如午后强对流天气导致气温骤降8度,聚合参数会快速漂移,模型误差会显著放大。
后续扩展有两个我认为值得做的方向:一是把电动汽车充电负荷和空调集群联合建模,构成"柔性负荷聚合储能池",两者的时间常数互补性很强,空调是小时级响应,电动车是分钟级响应,组合起来调节能力更完整;二是把用户舒适度意愿建模成随机参数,用鲁棒优化或分布鲁棒优化处理不确定性,这样调度结果在极端天气下也不会大幅越限。
回到开头的问题——空调集群到底能不能当储能用?我的结论是:能,而且性价比极高。但前提是聚合模型必须标定准确、可行域不能拍脑袋写、SOC动态约束必须闭合。按照上面的建模思路和Matlab实现流程,你完全可以把虚拟储能模块嵌进自己的调度框架里。我也建议各位在做灵敏度分析时专门看一下不同舒适度区间对结果的影响,那组数据往往比最优成本本身更有说服力,也是后续写成论文时最有亮点的一张表。