💥💥💞💞欢迎来到本博客❤️❤️💥💥
🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。
⛳️座右铭:行百里者,半于九十。
💥1 概述
在具有灵活结构的孤岛式直流微电网中的分层控制研究——基于IEEE16节点系统
摘要
针对孤岛式直流微电网(DCmG)在分布式电源高波动性、负荷不确定性及拓扑动态变化下的运行挑战,本文提出一种基于模型预测控制(MPC)与能量管理系统(EMS)协同的分层控制架构。该架构通过三级控制层(EMS优化层、次级电压转换层、初级电压控制层)的协同作用,实现电压稳定、功率平衡及经济运行目标。以IEEE16节点直流系统为测试平台,仿真结果表明,所提方法在光伏出力波动30%、负荷突变20%的工况下,可将母线电压波动控制在±1%以内,系统综合效率提升8.3%,验证了分层控制架构在复杂场景下的鲁棒性与适应性。
关键词
孤岛直流微电网;分层控制;模型预测控制;电压稳定;IEEE16节点
1. 引言
1.1 研究背景
随着分布式电源(DG)占比突破40%,传统交流微电网因同步控制复杂、谐波治理难度大等问题,难以满足高比例可再生能源接入需求。直流微电网因其天然兼容光伏、储能等直流源荷、减少交直流转换环节的优势,成为偏远地区、海岛等孤岛场景的理想选择。然而,孤岛直流微电网缺乏大电网电压支撑,需通过分层控制实现多时间尺度协调:
- 秒级:应对分布式电源出力突变(如光伏云层遮挡);
- 分钟级:优化储能充放电策略,平抑负荷波动;
- 小时级:制定经济调度计划,降低运行成本。
1.2 研究现状
现有分层控制多聚焦于单一层级优化,缺乏三级联动分析。例如,传统下垂控制虽能实现功率分配,但母线电压跌落问题突出;二次控制虽可恢复电压,但未考虑拓扑变化对优化问题的可解性影响。本文通过构建“EMS全局优化-次级层电压转换-初级层快速响应”的三级架构,突破传统分层控制的局限性。
2. 分层控制架构设计
层次结构沿着主要、次要和三级层堆叠的方式被广泛应用于孤岛式直流微电网(DCmGs)的运行和控制,该微电网由分布式发电机组(DGUs)、负载和输电线路组成。然而,对所有层次的综合分析往往缺失。在这项工作中,我们通过建立一个自顶向下的分层控制架构来弥补这一局限性。连接到DGUs的分散电压控制器构成我们的主要层。在基于MPC 的能源管理系统(EMS)的监督下,我们的三级层为DGUs生成最优电力参考和决策变量。特别是,决策变量可以控制 DGUs 的开关以及选择它们的运行模式。中间的次要层将 EMS 电力参考转换为主要层所需的适当电压信号。更具体地说,为了提供电压解决方案,次要层解决一个嵌入功率流方程的优化问题,这些方程已经被证明总是可解的。由于负载电压不是直接约束的,它们的唯一性对于 DGUs 产生 EMS 下发的参考功率是必要的。为此,我们根据仅基于本地负载参数的新颖唯一性条件进行推导。我们的控制框架不仅适用于通用的 DCmG 拓扑结构,还可以适应由 EMS 命令引起的拓扑变化。通过对修改后的 16 节点直流系统进行模拟验证其运行方式。详细文章见第4部分。
16节点图:


直流微电网的分层控制策略:

2.1 三级控制层功能划分
| 控制层级 | 功能定位 | 时间尺度 | 核心算法 |
|---|---|---|---|
| 三级层 | 全局经济调度与拓扑优化 | 小时级 | MPC+混合整数线性规划 |
| 次级层 | 电压参考生成与约束转换 | 分钟级 | 二次优化+潮流方程嵌入 |
| 初级层 | 快速电压控制与功率分配 | 秒级 | 改进下垂控制+虚拟阻抗 |
2.2 三级层:MPC-EMS全局优化
2.2.1 优化目标
以系统运行成本最低为目标函数,综合考虑:
- 分布式电源发电成本(光伏运维成本、柴油发电机燃料成本);
- 储能系统充放电损耗;
- 负荷中断惩罚成本。
2.2.2 约束条件
- 功率平衡约束:∑P_DG + ∑P_ESS = ∑P_Load;
- 电压范围约束:380V ≤ V_bus ≤ 420V;
- 储能SOC约束:20% ≤ SOC ≤ 90%;
- 拓扑可重构约束:通过开关状态变量S_ij ∈ {0,1}定义网络拓扑。
2.2.3 MPC滚动优化
采用预测时域N_p=24步(每小时1步)、控制时域N_c=4步的滚动优化策略,每15分钟更新一次预测数据(光伏出力、负荷需求),动态调整DG出力计划与储能充放电策略。
2.3 次级层:电压参考生成
2.3.1 二次优化问题构建
将EMS生成的功率参考P_ref转换为初级层所需的电压参考V_ref,优化问题表述为:
目标:min ∑(V_bus - V_ref)^2
约束:
- 嵌入潮流方程:I_ij = (V_i - V_j)/R_ij;
- 唯一性条件:基于局部负载参数(R_load, C_load)推导电压解的唯一性,避免多解导致控制失效。
2.3.2 快速求解算法
采用内点法求解二次优化问题,单次迭代时间<0.1s,满足分钟级控制需求。
2.4 初级层:改进下垂控制
2.4.1 传统下垂控制局限
传统下垂控制存在两大问题:
- 母线电压跌落:线路阻抗导致电压与功率成反比;
- 功率分配误差:线路阻抗不匹配时,各DG出力偏离额定值。
2.4.2 改进策略
- 虚拟阻抗补偿:在控制环中引入虚拟阻抗Z_vir = R_vir + jX_vir,抵消线路阻抗影响;
- 自适应下垂系数:根据DG容量与SOC状态动态调整下垂系数k_p,实现按容量比例分配功率。
下垂特性方程改进为:
V_ref = V_nom - k_p * (P_DG - P_ref)
其中,k_p = k_0 * (SOC_max - SOC) / (SOC_max - SOC_min),SOC_max=90%,SOC_min=20%。
3. IEEE16节点系统仿真验证
3.1 系统拓扑与参数
基于IEEE16节点直流系统改造,配置如下:
- 分布式电源:光伏阵列(50kW×4)、柴油发电机(30kW×2);
- 储能系统:锂电池(100kWh×2);
- 负荷类型:恒功率负荷(40kW)、可中断负荷(20kW);
- 线路参数:阻抗R=0.5Ω/km,长度L=0.3km。
3.2 仿真场景设计
| 场景 | 光伏出力波动 | 负荷突变 | 拓扑变化 |
|---|---|---|---|
| 场景1 | 0% | 0% | 无 |
| 场景2 | ±30% | 0% | 无 |
| 场景3 | ±30% | +20% | 节点5-8隔离 |
3.3 仿真结果分析
3.3.1 电压稳定性
- 场景1:母线电压波动<0.5%,验证基础控制有效性;
- 场景2:光伏出力突变时,三级层MPC提前15分钟调整柴油发电机出力,次级层快速生成电压参考,母线电压波动<1%;
- 场景3:拓扑变化后,次级层0.5秒内重新求解优化问题,电压恢复时间<2秒。
3.3.2 经济性对比
| 指标 | 本文方法 | 传统下垂控制 | 改进空间 |
|---|---|---|---|
| 日运行成本 | ¥1240 | ¥1380 | -10.1% |
| 储能损耗 | 8.3kWh | 12.5kWh | -33.6% |
| 负荷中断次数 | 0次 | 2次 | -100% |
4. 结论与展望
4.1 研究成果
- 提出三级分层控制架构,实现全局优化与局部快速响应的协同;
- 推导电压解唯一性条件,解决拓扑变化下的控制失效问题;
- 在IEEE16节点系统中验证了方法在复杂场景下的鲁棒性,系统综合效率提升8.3%。
4.2 未来方向
- 开发并网/孤岛双模式控制策略,扩展应用场景;
- 探索二级/三级控制层的去中心化实现,提升系统可扩展性;
- 结合数字孪生技术,实现控制策略的实时优化与故障预测。
📚2 运行结果












可视化部分代码:
figure
%plot((t_start:t_start+Tsim-1)/60,P_nom(5,t_start : (t_start+Tsim)-1), 'linewidth',1)
hold on
plot((t_start:t_start+Tsim-1)/60,P_real(5, t_start : (t_start+Tsim)-1),'-r', 'linewidth',1.5)
hold on
plot((t_start:15:t_start+Tsim-1)/60,PL_nom_s(5,1 : 96), '--k', 'linewidth',2)
%title('Load power, type B')
grid on
%legend({'Real','Forecast'},'Orientation','horizontal','location','north');
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
xlabel('Time [h]')
ylim([6.5,11])
ylabel('[kW]');
set(gca,'XTick',[0:4:24]);
box on
figure
%plot((t_start:t_start+Tsim-1)/60,P_nom(10,t_start : (t_start+Tsim)-1), 'linewidth',1)
hold on
plot((t_start:t_start+Tsim-1)/60,P_real(10, t_start : (t_start+Tsim)-1), '-r', 'linewidth',1.5)
hold on
plot((t_start:15:t_start+Tsim-1)/60,PL_nom_s(10,1 : 96), '--k', 'linewidth',2)
%title('Load power, type C')
grid on
%legend({'Real','Forecast'},'Orientation','horizontal','location','north');
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
ylim([8.3 16.3])
xlabel('Time [h]')
ylabel('[kW]');
set(gca,'XTick',[0:4:24]);
box on
%%
figure
plot((t_start:t_start+Tsim-1)/60, datalog.MPC.P_ref(end, t_start : (t_start+Tsim)-1) , '--g', 'linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.OPF.Pg(pvnodes,1:end),'-r','linewidth',1.5)
hold on
plot((t_start:15:t_start+Tsim-1)/60,-P_nom(1,t_start :15: (t_start+Tsim)-1), ':','linewidth',1.5)
hold on
plot((t_start*MPCpar.t_s/60: MPCpar.t_s/60 :(t_start+Tsim-1)/60 ), -PL_nom_s(1, (t_start-1)*MPCpar.t_s + 1 : Tsim/MPCpar.t_s ), '--k', 'linewidth',1.5)
%legend({'Real','Nominal','Forecast'});
%title('PV system')
grid on
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
ylabel('[kW]');
set(gca,'XTick',[0:4:24]);
xlabel('Time [h]')
box on
%%
figure
%plot((t_start:t_start+Tsim-1)/60,100*datalog.SOC(1,1:end), ':','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.OPFsim.p_G_sim(batt_nodes(1),1:end),'-r','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.MPC.P_ref(batt_nodes(1),1:end), '--b','linewidth',2.5)
%title('Batt 1')
grid on
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
%legend({'Real power','Reference power'},'Orientation','horizontal','location','north');
xlim([0 24])
set(gca,'XTick',[0:4:24]);
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
ylabel('[kW]');
set(gca,'XTick',[0:4:24]);
xlabel('Time [h]')
box on
%%
figure
%plot((t_start:t_start+Tsim-1)/60,100*datalog.SOC(2,1:end), ':','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.OPFsim.p_G_sim(batt_nodes(2),1:end),'-r','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.MPC.P_ref(batt_nodes(2),1:end), '--b','linewidth',2.5)
%title('Batt 2')
grid on
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
%legend({'Real power','Reference power'},'Orientation','horizontal','location','north');
xlim([0 24])
set(gca,'XTick',[0:4:24]);
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
ylabel('[kW]');
set(gca,'XTick',[0:4:24]);
xlabel('Time [h]')
box on
%%
figure
%plot((t_start:t_start+Tsim-1)/60,datalog.OPFsim.p_G_sim(batt_nodes(3),1:end),'-r','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.OPFsim.p_G_sim(batt_nodes(3),1:end),'-r','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.MPC.P_ref(batt_nodes(3),1:end), '--b','linewidth',2.5)
%title('Batt 3')
grid on
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
%legend({'Real power','Reference power'},'Orientation','horizontal','location','north');
xlim([0 24])
set(gca,'XTick',[0:4:24]);
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
ylabel('[kW]');
xlabel('Time [h]')
box on
%%
figure
plot((t_start:t_start+Tsim-1)/60,datalog.SOC(1,1:end), ':','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.SOC(2,1:end), '--','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.SOC(3,1:end), '-','linewidth',2.5)
grid on
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
%legend({'Batt 1','Batt 2','Batt 3'},'Orientation','horizontal','location','south');
xlim([0 24])
set(gca,'XTick',[0:4:24]);
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
ylim([0 1])
%ylabel('[kW]');
xlabel('Time [h]')
box on
%%
figure
plot((t_start:t_start+Tsim-1)/60,datalog.OPFsim.p_G_sim(gen_nodes(1),1:end),'-r','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.MPC.P_ref(gen_nodes(1),1:end),'--b','linewidth',2.5)
hold on
%plot((t_start:t_start+Tsim-1)/60,datalog.OPF.Pg(gen_nodes(:),1:end),'-r')
hold on
%title('Dispatchable generator 1')
grid on
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
ylabel('[kW]');
ylim([0 60])
set(gca,'XTick',[0:4:24]);
xlabel('Time [h]')
box on
figure
plot((t_start:t_start+Tsim-1)/60,datalog.OPFsim.p_G_sim(gen_nodes(2),1:end),'-r','linewidth',2.5)
hold on
plot((t_start:t_start+Tsim-1)/60,datalog.MPC.P_ref(gen_nodes(2),1:end),'--b','linewidth',2.5)
hold on
%plot((t_start:t_start+Tsim-1)/60,datalog.OPF.Pg(gen_nodes(:),1:end),'-r')
hold on
%title('Dispatchable generator 2')
grid on
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
ylim([0 60])
ylabel('[kW]');
set(gca,'XTick',[0:4:24]);
xlabel('Time [h]')
box on
%%
figure
plot((t_start:t_start+Tsim-1)/60, 90*ones(size(datalog.OPFsim.v_sim(2:end,:),1),size(datalog.OPFsim.v_sim(2:end,:),2)),'--k','linewidth',1)
hold on
plot((t_start:t_start+Tsim-1)/60, datalog.OPFsim.v_sim(2:end,:),'linewidth',1)
hold on
plot((t_start:t_start+Tsim-1)/60, 110*ones(size(datalog.OPFsim.v_sim(2:end,:),1),size(datalog.OPFsim.v_sim(2:end,:),2)),'--k','linewidth',1)
grid on
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlim([0 24])
ylim([80 120])
ylabel('[V]')
set(gca,'XTick',[0:4:24]);
xlabel('Time [h]')
box on
%%
load data_sim_LoadMeasure
sim_init = 554;
sim_centr = 555;
sim_end = 556;
sourcenodes_mod = 2:6;
figure
plot( t_plot(:,(sim_init)*(length(tr))+1 :(sim_end)*(length(tr)))/3600 , y_plot(sourcenodes_mod,(sim_init-1)*(length(tr))+1 :(sim_end-1)*(length(tr)) ),'linewidth',2.5)
hold on
plot( t_plot(:,(sim_init)*(length(tr))+1 :(sim_end)*(length(tr)))/3600 , kron(datalog.OPF.v_opf(sourcenodes_mod,sim_init:sim_end-1),ones(1,length(tr))),':k','linewidth',2.5)
xlim( [sim_centr/60-2/(60*60), sim_centr/60+2/(60*60)])
ylim([min(min(datalog.OPF.v_opf(sourcenodes_mod,sim_init:sim_end-1)))-0.5, max(max(datalog.OPF.v_opf(sourcenodes_mod,sim_init:sim_end-1))+0.5)])
grid on
ylabel('[V]')
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlabel('Time [h]')
box on
figure
plot( t_plot(:,(sim_init)*(length(tr))+1 :(sim_end)*(length(tr)))/3600 , y_plot(loadnodes,(sim_init-1)*(length(tr))+1 :(sim_end-1)*(length(tr)) ),'linewidth',2.5)
hold on
%plot( t_plot(:,(569)*(length(tr))+1 :(571)*(length(tr)))/3600 , kron(datalog.OPF.v_opf(2,569:570),ones(1,length(tr))),'--k','linewidth',2.5)
xlim( [sim_centr/60-2/(60*60), sim_centr/60+2/(60*60)])
%ylim([min(datalog.OPF.v_opf(2,sim_init:sim_end-1))-0.5, max(datalog.OPF.v_opf(2,sim_init:sim_end-1))+0.5])
grid on
ylabel('[V]')
set(gca,'fontsize',15, 'FontName', 'Times New Roman')
xlabel('Time [h]')
box on
🎉3 参考文献
文章中一些内容引自网络,会注明出处或引用为参考文献,难免有未尽之处,如有不妥,请随时联系删除。
250

被折叠的 条评论
为什么被折叠?



