
从白天的光伏大发、夜间的电价低谷到傍晚的用电尖峰楼宇微网里最让人头疼的从来不是“电不够用”而是“每个时段都在用钱买电却没有把楼宇自身的调节能力用起来”。我一开始接手“融合需求侧虚拟储能系统的楼宇微网优化调度”这个课题时以为重点肯定在电池和光伏的配合上结果跑了几轮仿真后才发现真正的宝藏其实藏在楼里的暖通系统、热水器和那些可以灵活搬移的用电任务里——它们合在一起就是一套不花一分钱硬件成本、却拥有可调度容量的“虚拟储能系统”。这篇博文就把我的完整建模思路、Matlab代码实现过程、以及调参时踩过的坑一次讲清楚适合正在做微网优化调度、需求响应或虚拟电厂方向的研究生和工程师参考。1. 为什么我要在楼宇微网里加一套“虚拟储能”1.1 楼宇里真正的“储能宝藏”暖通系统的热惯性先看一组我实测统计过的数据典型商业楼宇中暖通空调系统HVAC的耗电量能占到楼宇总用电的40%到60%电热水器、地暖、电梯、照明和各类插座负荷又吃掉一大部分。大家谈微网优化调度时注意力几乎都集中在屋顶光伏和配电房里的电池柜上这没有错但有一个非常明显的事实被忽略了楼宇本身就是一个巨大的热能缓冲区。这么说吧把一间办公室的空调在午后电价最贵之前提前开大功率运转半小时室内温度、墙体温度和家具温度都会被“拉低”到了晚高峰电价飞涨的时候即使空调降频运行甚至停机一阵子室温也不会立刻反弹到让人难受的程度。放个直观的数值一栋建筑面积1万平方米的办公楼其室内空气、混凝土楼板、隔墙、家具的综合等效热容量相当于至少几兆瓦时级别的冷量/热量储存能力——这个数量级已经能轻松覆盖一两块电池的容量。关键是这种“容量”不需要买电池、不需要占地、不需要维护它天然就嵌在建筑物理特性里。所以所谓需求侧虚拟储能系统Virtual Energy Storage, VES就是把这类具有热惯性或时间弹性的用电设备通过建模和调度算法让它们的实际用电行为表现出和电池储能类似的“充电-放电-容量-荷电状态”特征。从电网侧看这栋楼仿佛有一个看不见的储能站在参与调度实际上它只是把用电时间、用电功率稍微挪动了一下用户体感几乎无差别。1.2 虚拟储能和电池储能的本质区别为了把概念说得更清楚先给一张我经常用来向课题组新人解释的对比表特性电池储能虚拟储能HVAC/热水器等储能介质电化学物质热/冷量、时间弹性任务充放电响应速度毫秒级到秒级分钟级到小时级能量成本高需要购置、维护、更换极低边际成本几乎为0容量规模受投资预算限制受建筑热容量和舒适度范围限制能量衰减循环次数越多衰减越明显几乎不衰减但散热损失不可忽略主要约束功率/容量/SOC上下限室温舒适范围、任务截止时间从这张表能很明显地看出虚拟储能和电池是互补关系电池反应快适合秒级、分钟级的平滑和紧急支撑虚拟储能容量大、成本低但是响应慢适合小时级的削峰填谷和负荷转移。在优化调度这个时间尺度上一般15分钟到1小时一个决策点虚拟储能的价值往往比电池更突出。我最初单独用电池做楼宇微网调度得到的削峰率一直卡在18%左右后来把HVAC虚拟储能和可平移负荷一起加入模型削峰率直接跳到34%以上。这不是电池不行而是模型里压根没考虑楼宇自身可以提供的调节手段——相当于你手里明明有张王牌却一直没打出去。2. 虚拟储能建模从热力学方程到等效SOC2.1 一阶RC等效热参数模型ETP要把虚拟储能放进优化模型第一步是给它建立一个可计算的数学描述。楼宇热过程虽然是三维的、高度非线性的但在微网调度的15分钟/1小时时间尺度上业内最常用的是一阶RC等效热参数模型Equivalent Thermal Parameters, ETP。它的物理图景很简单把整栋楼或一个空调分区看作一个热容节点热容大小为C单位kWh/℃它和室外环境之间有一个等效热阻R单位℃/kW暖通系统提供的热功率为Q_HVAC得微分方程C · dT_in/dt (T_out - T_in) / R Q_HVAC Q_people Q_solar其中Q_people是人员散热Q_solar是透过窗户的太阳辐射得热这两个量在白天是不可忽略的。为了方便求解把上式在采样步长Δt下离散化得到室温递推形式T_in(t1) a · T_in(t) (1-a) · [T_out(t) - R·Q_total(t)]其中a exp(-Δt/(R·C))Q_total表示HVAC制冷/制热功率和其他得热之和。是不是觉得很眼熟这就是一个一阶惯性环节的离散形式。在实际的Matlab代码里这个公式会直接作为一组线性约束加进优化模型不需要任何非线性求解器。2.2 让虚拟储能拥有“SOC”的三大关键参数把ETP模型变成“虚拟储能”关键在于定义一组和电池SOC平行的变量。我习惯用以下三件套来刻画第一等效容量。虚拟储能的“容量”不是多少度电而是安全舒适范围内的温度区间。比如夏季工况室内温度允许在24℃到27℃之间波动那么等效容量就是C×(27-24)单位是kWh——这是楼宇能“储存”的冷量上限。第二荷电状态SOC_ves(t)。我定义 SOC_ves(t) (T_in(t) - T_min) / (T_max - T_min)注意这里的SOC越高代表室温越低也就是“储冷越多”。这个定义和电池SOC同方向越满越能在未来释放。当室温逼近T_max时相当于虚拟储能放空逼近T_min时相当于充电充满。第三充放电功率P_ves(t)。它的定义是额定制冷功率基准与实际耗电功率的差。如果空调在某一时刻比正常基准多开了功率那就是在“充电”临时降功率运行那就是在“放电”。方向符号只需要和SOC动态方程保持一致即可不用纠结。2.3 可平移负荷另一种形式的虚拟储能除了热惯性楼宇里还有一类天然具备“虚拟储能”特性的负荷——可平移负荷。典型的是洗衣机、洗碗机、预约定时热水器、电动汽车充电桩等。这类负荷的特点是一项任务总的耗电量固定但任务开始时间可以在一定窗口内自由选择。建模方法很标准对于任务i设置开始时段的二进制变量u_i(t)∈{0,1}满足整个调度周期内u_i(t_initial)到u_i(t_final)至少存在一段连续的“开启”时间总持续时间等于D_i任务必须在最早开始时间T_early和最晚完成时间T_late之间完成该项负荷在t时段的功率为P_i(t) P_rated_i × u_i(t)。这样一个需要1小时、额定功率3kW的洗碗机任务在保证晚上9点前洗完的前提下既可以在下午2点启动也可以挪到傍晚5点启动——从电网角度看到的用电量没变但用电时段变了。这就是“把电能储存到时间轴的不同位置”。3. 融合虚拟储能的微网优化调度目标函数与约束体系3.1 优化目标怎么定成本和舒适度如何并存调度模型的优化目标我建议不要只写“购电成本最小”这一项否则你会看到优化器为了省电把室温压到舒适下限甚至更低的极端操作。一个更完整的目标函数是min J Σ_t [ λ_grid(t)·P_grid_buy(t) - λ_sell(t)·P_grid_sell(t) ] Σ_t λ_bat·(P_ch(t)P_dis(t)) Σ_t λ_ves·ξ(t)第一项是向电网购电与售电的净费用第二项是电池充放电带来的等效损耗成本用一个很小的系数λ_bat来抑制电池的过度循环第三项是虚拟储能舒适度惩罚项其中ξ(t)是一个非负连续变量用来惩罚室温越限。这样目标函数仍然是线性的可以直接交给MILP求解器。为什么要引入舒适度惩罚而不是把室温设为硬约束经验告诉我硬约束在边界条件下容易导致整个问题无解infeasible。比如高温天室外38℃如果硬约束室温必须低于25℃而不允许空调超功率运行那么功率平衡约束和舒适度约束会发生冲突。引入松弛惩罚后求解器可以在极端场景下以很小代价打破舒适度边界保证至少得到一个可执行的调度方案。3.2 功率平衡、电网交互和储能运行约束完整的模型约束体系我按四层来讲。第一层是楼宇内部功率平衡这是微网模型的基石P_grid(t) P_pv(t) P_bat_dis(t) P_load_base(t) P_hvac(t) P_shiftable(t) P_bat_ch(t)其中P_load_base是不参与调度的刚性负荷P_hvac是暖通功率P_shiftable是可平移负荷的实时功率。这条约束在每个调度时段都必须严格成立——发用电永远是瞬时的。第二层是电网交互约束。实际项目中楼宇从电网取电不能超过变压器容量通常写为0 ≤ P_grid_buy(t) ≤ P_grid_max · u_grid(t)以及回送电网的功率限制、防倒送等约束。如果按分时电价结算还需要保证购电和售电不同时发生用一组二进制变量和Big-M约束隔离即可。第三层是电池约束包括充放电功率上下限、SOC递推和SOC边界SOC_bat(t1) SOC_bat(t) (P_ch(t)·η_ch - P_dis(t)/η_dis) · Δt / E_bat SOC_min ≤ SOC_bat(t) ≤ SOC_max P_ch(t) ≤ P_bat_cap · u_ch(t)P_dis(t) ≤ P_bat_cap · u_dis(t)第四层才是虚拟储能的关键部分包括室温递推方程、VES的SOC定义、舒适度边界以及可平移负荷的二进制变量约束。这四层写完后整个模型的规模在Matlab的Yalmip里大约是几百个变量和上千条约束对于现代求解器来说属于非常小的规模求解时间通常在几秒到几十秒之间。3.3 虚拟储能约束集成时容易踩的坑这一节是重点我踩过的坑基本都在这。第一个坑是时间步长太大导致室温递推发散。如果采样间隔取1小时而建筑时间常数R×C远小于1小时那么衰减系数a会迅速趋近于0递推方程的物理意义就丢失了。我的建议是至少取15分钟间隔对于热惯性较弱的分区要单独验证a的取值。第二个坑是虚拟储能的初始SOC被随意高估导致优化结果“凭空放电”。比如凌晨4点室温被优化器预冷到22℃到早上8点电价高峰时释放冷量看起来状态好但这个22℃从哪来凌晨就得先把空调打开耗电。如果模型没把初始时段之前的预冷成本算进去就会白白捡便宜。解决办法是在调度周期末尾加上终端SOC约束让室温在周期结束时回到初始状态附近避免把“冷量债”甩给下一个调度周期。第三个坑是舒适度边界太紧。如果把夏季室温范围设为[24,25]℃模型几乎没有任何调节空间虚拟储能的价值直接清零。实际工程中建议考虑人体舒适区ASTM标准允许1~2℃的摆动这样既不影响体验又能留出足够大的调度空间。4. Matlab代码实现架构、求解器和调试经验4.1 求解环境准备Yalmip 求解器Matlab侧实现优化调度我不推荐直接手写linprog或者intlinprog——因为模型里变量一多矩阵装配非常容易出错尤其是二进制变量和大M约束手写矩阵几乎等于给自己找罪受。我用的方案是Yalmip建模 Cplex/Gurobi求解。环境准备步骤很简单提前说几个容易卡住的地方确保Matlab是正式授权版本然后从Yalmip官网或GitHub仓库获取最新的yalmip-master文件夹把整个文件夹加入Matlab路径。求解器方面学术用户通常能拿到Cplex或Gurobi的免费授权如果拿不到也可以先在Yalmip中配置开源的SCIP求解器小规模算例完全够用。安装完成后在命令窗口执行yalmiptest屏幕上出现一系列“successful”就说明环境配置好了。如果某个求解器链接失败多半是求解器路径没加到Matlab。4.2 代码模块划分整个项目我建议按以下模块组织方便后续换参数、换数据main.m主脚本负责加载参数和数据、调用优化模型、保存结果data_param.m存放楼宇参数R、C、温度范围、空调功率上限、电池参数、分时电价、光伏预测出力、基础负荷曲线build_model.m用Yalmip定义变量、目标函数和所有约束返回Constraints和Objectiveplot_results.m绘制功率曲线、温度曲线、SOC曲线、费用对比表。这种模块化的好处是当你从单日调度扩展到多日滚动调度时只需要改main.py里的循环逻辑模型文件基本不用动。4.3 核心约束的Yalmip写法直接上一段关键代码展示怎么把虚拟储能的温度递推约束写进Yalmip。假设horizon为9615分钟间隔一天24小时用sdpvar定义室温序列和暖通功率% 变量定义 T_in sdpvar(1, Horizon); P_hvac sdpvar(1, Horizon); P_grid_buy sdpvar(1, Horizon); P_grid_sell sdpvar(1, Horizon); P_ch sdpvar(1, Horizon); P_dis sdpvar(1, Horizon); u_ch binvar(1, Horizon); u_dis binvar(1, Horizon); % 室温递推约束一阶ETP模型离散化 % T_in(t1) a*T_in(t) (1-a)*(T_out(t) - R*Q_total(t)) for t 1:Horizon-1 Constraints [Constraints, T_in(t1) a * T_in(t) (1-a) * (T_out(t) - R * (P_hvac(t) Q_internal(t)) ) ]; end注意这里的Q_total符号按制冷为正、放热为负来写如果你的项目是制热工况符号要反过来。VES的舒适度约束可以写成% 考虑舒适度松弛变量 xi sdpvar(1, Horizon); Constraints [Constraints, xi 0]; Constraints [Constraints, T_min - xi T_in(t) T_max xi]; % 目标函数中加入 xi 的惩罚项 Objective Objective 100 * sum(xi);这样即使碰到极端天气模型也不会直接报不可行优化器会自动在“稍微越限”和“花大钱启动额外冷源”之间做权衡。4.4 求解性能优化与常见报错我在调试过程中遇到的最烦人的报错是“Infeasible problem”。Yalmip本身不会直接告诉你是谁导致不可行我一般用“约束屏蔽法”定位先把舒适度约束注释掉如果问题可行了说明冲突在温度边界再把功率平衡约束注释掉如果又可解了那问题可能出在HVAC功率范围与刚性负荷叠加之后超过了变压器上限。逐个屏蔽通常十分钟内能锁定问题约束。另一个常见问题是MILP规模一大求解时间从几秒涨到几分钟。优化方向有两个一是把时间粒度从15分钟拉长到30分钟变量数减半二是将全天单次优化改为模型预测控制MPC滚动优化每次只考虑未来4到8小时然后把第一个时段的方案下发执行。第二种方式目前在实际工程里应用最广因为它同时具备鲁棒性和实时性。我还有一个实用技巧在求解前给所有sdpvar变量添加合理的边界范围例如T_in限制在10℃到40℃之间。看似多余的边界能大幅压缩求解器的搜索空间有些情况下能缩短30%以上的求解时间。5. 算例分析引入虚拟储能后省了多少电费5.1 仿真场景参数设置为了验证模型效果我搭了一个典型办公楼微网算例楼宇建筑面积8000平方米屋顶光伏装机300kW电池储能200kWh/100kWHVAC系统额定制冷功率150kW楼宇等效热阻R0.012℃/kW等效热容C800kWh/℃夏季室温舒适区间24~27℃分时电价低谷0.3元/kWh、平段0.7元/kWh、高峰1.2元/kWh光伏采用典型夏季晴天的预测曲线。对比三个方案方案A无储能光伏余电直接上网HVAC不参与调度方案B电池储能参与调度HVAC不参与调度方案C电池储能 HVAC虚拟储能 可平移负荷全部参与调度。5.2 三种方案对比结果方案日购电成本元峰时购电量kWh光伏消纳率A无储能6820286072.1%B电池储能5410214088.4%C电池虚拟储能4230139095.6%方案C与方案A相比日购电成本下降了38%与方案B相比成本又下降了约22%。背后的原理很清晰电池毕竟只有200kWh容量在晚高峰4个小时内只能支撑约100kW的放电功率而虚拟储能通过提前预冷在高峰期把HVAC功率从150kW降到60kW相当于多提供了一个小时的90kW放电能力而且这部分“放电”零成本。5.3 灵敏度分析热惯性和舒适度范围的影响我还做了一组敏感性测试结论很直观建筑等效热容C越大虚拟储能的调度空间越大成本下降越明显舒适度范围每放宽1℃虚拟储能的等效容量大约增加15%到20%但室温波动会相应变大。所以实际落地时别一上来就把舒适度范围拉满。我的建议是分阶段实施先允许1℃的室温摆动让HVAC参与削峰跑通后如果用户反馈良好再逐步放宽到1.5℃或2℃配合楼宇自动控制系统BA系统做无感调节。这种渐进策略既保证了项目收益的可预测性又不会因为舒适度问题引发投诉。最后说一个让我印象深刻的细节在Matlab里把虚拟储能模块从模型中拿掉时求解器给出的调度方案会立刻退化成“电池单独作战”加回虚拟储能后优化器会自动选择在下午1点到2点让空调满负荷运行、把室温降到25.2℃左右然后在下午4点到6点电价高峰段降低空调功率让室温缓慢回升到26.8℃。整条温度曲线像一首谱好的曲子每一个“蓄冷”和“放冷”的动作都精确踩在电价节点上——这是我在这个项目中最有成就感的一刻。如果你也准备在Matlab里搭这个模型我的建议是第一个版本先不要追求复杂只做HVAC虚拟储能 电池 分时电价跑通之后再去加可平移负荷、碳约束和不确定性。底层的ETP模型和MILP框架是通用的往后扩展只是往里面加约束的问题。这套代码跑熟之后你再去看需求响应、虚拟电厂聚合调度这些方向会发现所有问题都是同一个骨架换了几件衣服而已。