在孤岛微电网的仿真研究里,最常被问到的两类问题:一是下垂控制怎么搭,二是二次控制怎么才能在不依赖高速通信的情况下把电压、频率恢复到额定值。如果做的是基于事件触发机制的孤岛微电网二次电压与频率协同控制Simulink仿真模型,那还要再加上一问:触发逻辑到底怎么跟逆变器控制放一起仿真才不崩、不乱、不出现代数环。这篇就把整套方案从头到尾拆开,讲清楚控制原理、模型结构、Simulink实现方法,以及我在实际搭建过程中踩过的一些坑。
这套模型本质上是一个带通信层的微电网仿真平台:主电路层是由多台分布式电源(DG)和负载组成的孤岛微电网;控制层包含一次下垂控制和二次协同控制;通信层则用事件触发机制替代传统的周期通信。它的用途很直接——验证事件触发机制能不能在保证电压频率恢复精度的前提下,明显降低分布式电源之间的通信次数。适合正在做微电网分布式控制、事件触发控制、多智能体一致性算法相关课题的研究生,以及想从论文公式走向可运行Simulink模型的工程师参考。
1. 模型要解决的核心问题:一次下垂控制留下的“稳态偏差”
没有电网同步支撑的孤岛微电网,频率和电压必须由内部的分布式电源自己稳住。每个DG通过逆变器并联到公共母线上,最常见的控制方式就是P-f/Q-V下垂控制,模仿同步发电机的功频静特性:负载增加时,有功功率分配变多,频率就降下来;无功功率增加时,端电压幅值也相应下降。这个机制能保证多台逆变器之间不打架,功率能按容量比例分摊,但它有一个绕不开的缺陷——下垂控制本质上是有差调节,负载变化以后频率和电压会停在偏离额定值的新稳态上。
这时候就需要“二次控制”出来做无差恢复。为什么叫二次?因为它在时间尺度和控制层级上都排在一次下垂之后:一次控制先让系统稳定下来,二次控制再慢慢把稳态偏差调回零。传统做法是在微电网中央控制器里完成频率和电压的计算,然后统一把补偿量广播给各DG。但中央控制器依赖全局通信网络,一旦通信链路出问题,全部DG的恢复任务都会受影响。所以现在更受关注的是分布式协同二次控制,让每个DG只跟相邻的几个DG交换信息,大家通过一致性算法最终把频率和电压恢复到一个共同的目标值。
1.1 下垂控制到底是怎么让系统“稳定但有偏差”的
一次下垂控制在dq旋转坐标系下通常写成下面这种形式:
- 频率下垂:ω_i = ω_nom + Δω_i - m_i * P_i
- 电压下垂:E_i = E_nom + ΔE_i - n_i * Q_i
其中ω_i是第i台DG输出的角频率,E_i是电压幅值参考,P_i和Q_i是输出的平均有功、无功功率,m_i和n_i是下垂系数,Δω_i和ΔE_i是二次控制给出的修正量。如果没有二次控制,Δω_i和ΔE_i就是0,系统只能按照下垂线运行。假设两台DG额定参数一样,负载变重以后P_i增大,ω_i就会按m_i的比例下降;想让频率回到额定值,唯一的办法就是把整条下垂曲线平移上去,也就是让Δω_i变成正值,抵消m_i * P_i造成的压降。这正是二次控制要做的事。
下垂系数的选取是有讲究的,不是随便填。额定输出为10kW的逆变器,如果允许频率从50Hz跌到49.5Hz,那么m大约就是0.5Hz / 10kW = 5e-5 Hz/W;换算成角频率大约是π*1e-4 rad/s/W。无功下垂系数也一样,由无功容量和允许电压偏差决定。系数选太大,负载扰动后的一次稳态偏差就大;选太小,功率分配精度会下降。Simulink里可以先按上面的估算给初值,然后看有功分配效果微调。
1.2 频率是“全局量”,电压是“局部量”,控制设计必须分开对待
很多刚接触微电网建模的同学容易犯一个错误,就是把电压二次控制和频率二次控制当成同一件事处理。实际上两者的物理特性差别很大。稳态下孤岛微电网的频率在全网是同一个值,所有DG的转速或输出频率最后都会同步一致,二次频率控制只需要把“这个共同的频率偏差”恢复掉即可。但DG1和DG3如果处在不同的馈线上,线路阻抗不同,末端电压压降也不同,它们的端电压幅值天然就存在差异。所以电压二次控制要解决的不单是“电压幅值偏低”,还包括“各DG出口电压分布不均”的问题。
这就是题目里“协同”二字的含义:不能让每个DG自己单独闭环恢复到额定值,那样可能因为线路压降不一致、各自调节互相抵消而振荡;也不能让中央控制器给所有DG发同一个补偿量,因为这样解决不了局部电压差异。正确的做法是每台DG只处理自己的误差,同时参考邻居的信息,最终让全网频率一致地回到额定值,让各DG端电压在可接受的范围内趋于一致并接近额定值。在数学模型里,频率层和电压层通常是两条独立的一致性协议,只是它们共用同一个通信拓扑。
1.3 协同控制与中央控制的取舍
很多论文里会把分布式协同控制和传统集中式控制做个对比,这里我也用一张表辅助理解:
| 方案 | 通信依赖 | 单点故障风险 | 电压差异性处理 | 扩展性 | Simulink实现难度 |
|---|---|---|---|---|---|
| 集中式二次控制 | 每个DG都连中央控制器 | 高,中央节点故障全盘失效 | 中央无法精确感知每条线路压降 | 一般,新增DG要重新配置 | 低 |
| 周期性分布式协同 | 只与邻居通信,稀疏但持续 | 较低,单条链路故障影响有限 | 每个DG根据本地和邻居信息分别修正 | 较好,即插即用 | 中 |
| 事件触发分布式协同 | 只在触发时通信,通信量最少 | 较低 | 与协同一致,兼顾本地与全局 | 较好 | 较高,需要额外处理触发逻辑 |
Simulink里集中式方案最简单,信号线直接从中央控制器拉到每个DG子系统就行;周期性分布式协同麻烦在通信拓扑的整理,但只要建立清晰的端口也不难。事件触发分布式协同最难的地方在于“通信状态”需要保持上一触发时刻的值,不能在每个仿真步长都刷新,否则就退化成了连续通信。这也是事件触发机制和普通分布式控制本质区别的体现。
2. 事件触发机制:通信从“周期性广播”变成“有事才发”
在传统分布式控制里,每个控制周期采样之后,DG都会把自己的状态发给邻居,本质上是一种时间触发机制。它的优点是机理简单、稳定性分析方便,缺点是大量通信其实是浪费的——系统进入稳态以后,状态几乎没有变化,但还是每隔几毫秒就发一次数据。通信网络带宽、控制器计算资源都消耗在这些冗余信息上。事件触发机制的思想是:只有当本地状态和上次发出状态之间的偏差达到某个阈值时,才让DG向邻居发起一次通信,其他时间保持静默,邻居侧的控制器暂时沿用上一次收到的最新值。
2.1 协同控制需要交互的信息是什么
在微电网孤岛模型里,每台DG的运行状态可以表示成一组本地变量。一次控制需要采集本地的P_i、Q_i、电压电流反馈;二次协同控制层则要额外知道邻居的频率、电压幅值等信息。比如DG1通过通信链路连接到DG2,DG2的控制方程里有一个关于DG1的误差项,这个误差项里包含DG1的频率值。在连续通信假设下DG1每一刻都把最新频率发给DG2;但引入事件触发后,DG2使用的可能还是DG1在0.3秒前发来的“旧值”,只要DG1判断自己和0.3秒前比没差多少,就不需要再发一次。
实际模型里,DG之间交互的信息不一定要把三相瞬时值都发出去,通常发的是计算后的低维状态量:角频率ω_i、电压幅值V_i、有功无功功率或归一化后的控制误差。这就像两个操作同一个设备的师傅对讲机联系,只需要报“当前读数”,不需要把整个控制面板的画面都传过去。通信网络理想化时,在Simulink里用信号线直接连接即可;如果想模拟通信延时,可以在信号线上串一个Variable Time Delay模块。
2.2 触发条件的设计原则与推荐初值
事件触发的核心是触发条件。假设第i台DG上次广播出去的状态是x_i(t_k),当前时刻的状态是x_i(t),定义本地误差e_i(t) = x_i(t) - x_i(t_k)。触发条件可以写成:
| e_i(t) | ≥ σ_i * | x_i(t) | + ε_i
其中σ_i是阈值系数,ε_i是一个很小的正常数,用来防止系统状态过零时触发条件异常敏感。当上面的不等式成立时,DG就把当前状态x_i(t)广播出去,同时把保存的上次发送值更新为x_i(t);如果不成立,则继续保持沉默。
这个条件看起来简单,但Simulink里有一个容易混淆的点:触发判定比较的是“当前真实状态”和“本地上次广播状态”的差,而不是直接比较控制器输出误差。如果你在模型里把一致性协议的积分器输出直接连到触发模块,很容易因为信号波动频繁而出现触发风暴。我建议在触发模块前端加一个零阶保持器ZOH,让状态先离散化到采样时刻再进入触发判定,这样逻辑清晰,也利于后续统计触发次数。
参数初值方面,我给的推荐范围是σ_i取0.01到0.1之间,ε_i取1e-4到1e-3之间。σ_i越小,系统越接近连续通信,收敛越快,但通信优势不明显;σ_i越大,通信次数越少,但收敛速度会变慢,甚至可能震荡。一开始做对比实验时,可以先从σ=0.02开始,跑一次仿真统计触发次数,再逐步增大,观察电压频率恢复曲线和触发次数的变化趋势。
2.3 为什么推荐“周期采样事件触发”而不是纯事件触发
纯事件触发是连续监测状态,一旦条件满足立刻触发更新。理论上很漂亮,但实际仿真中有一个隐患叫Zeno现象——如果相邻两次触发之间的时间间隔趋近于0,就相当于在有限时间内发生无限次触发,仿真步长会不断被压缩,最终导致模型停止或计算出错。孤岛微电网是连续动态系统加逆变器PWM控制,本身就存在高频开关纹波,用连续事件触发很容易被噪声干扰,触发频率可能高到没有实际意义。
所以工程上更常用的是周期采样事件触发机制PETC:设置一个固定的采样周期Ts,每隔Ts判断一次触发条件,只有满足条件才发送状态。Ts通常取5倍左右的内环控制周期,比如逆变器PWM开关频率是10kHz,内环周期是1e-4秒,触发采样周期可以取1e-3到5e-3秒。这样既保留了事件触发的“按需通信”优点,又天然避免了Zeno现象。我在Simulink里实现的也是这种机制:一个固定步长的离散模块,里面维持一个“上次发送值”的持久变量,在每个Ts时刻比较误差。
3. 整体方案设计与数学模型:微电网、控制器、事件触发如何咬合
在动手搭Simulink之前,我建议先花一晚上把系统结构和数学方程写清楚。事件触发协同控制容易出问题,往往不是Simulink操作问题,而是控制方程本身没有理顺。一个完整的孤岛微电网仿真模型通常分成三层:主电路层、一次控制层、二次控制层。事件触发机制放在二次控制的通信发送端,它决定“什么时候把本机状态传给邻居”,而不是直接参与功率计算。
3.1 主电路结构选型与电气参数设计
为了验证协同算法,最少需要3到4台DG。我实际做的时候用的是4台DG加3个负载,构成一个简单的辐射状微电网,其中DG1和DG2靠近母线A,DG3和DG4靠近母线B,负载分别挂在两条馈线上。如果只用两台DG,通信拓扑和线路压降差异都体现不出来;用4台则可以方便地构造环形或链式通信拓扑,也便于后面做通信链路断开的故障分析。
主电路电气参数可以参考下面这组典型值:
| 参数 | DG1 | DG2 | DG3 | DG4 |
|---|---|---|---|---|
| 直流母线电压 | 800V | 800V | 800V | 800V |
| 滤波电感 Lf | 1.8mH | 1.8mH | 1.5mH | 1.5mH |
| 滤波电阻 Rf | 0.1Ω | 0.1Ω | 0.1Ω | 0.1Ω |
| 滤波电容 Cf | 50μF | 50μF | 40μF | 40μF |
| 线路阻抗(至母线) | 0.2Ω+0.8mH | 0.3Ω+1mH | 0.25Ω+0.9mH | 0.4Ω+1.2mH |
| 额定有功容量 | 10kW | 10kW | 8kW | 8kW |
| 额定无功容量 | 5kVar | 5kVar | 4kVar | 4kVar |
滤波参数不是随便选的,LC滤波器的截止频率一般取开关频率的十分之一到五分之一。如果PWM开关频率是10kHz,LC截止频率大约控制在1kHz到2kHz之间。用Lf=1.8mH、Cf=50μF,截止频率大约在1.7kHz左右,是比较稳妥的起点。线路阻抗的差异是故意设置的,目的是让各DG的端电压和功率分配产生差异,这样才能在仿真结果里看出协同二次控制的效果。
3.2 一次控制的内环设计:电压电流双闭环
每台DG的控制器内部,下垂控制计算出的ω_i和E_i并不会直接去控制IGBT,它们只是给内环提供参考电压。逆变器输出经过LC滤波后,需要把电容电压稳定在正弦参考值上,所以常规做法是电压外环加电流内环的双闭环结构。在dq旋转坐标系下,电压外环通常用PI控制器跟踪V_d和V_q参考值,输出作为电流内环的参考;电流内环再通过PI调节器生成调制波。
需要注意的一点是,下垂控制算出的E_i是电压幅值参考,一般默认给定到d轴分量,让q轴参考值设为0。这样电容电压的d轴分量会跟踪E_i,q轴分量趋于0,合成幅值自然就是E_i。如果模型里还加入虚拟阻抗,用来改善线路阻抗呈阻性时的功率耦合问题,则需要在电压参考值上减去虚拟阻抗的压降:V_ref = E_i_ref - R_v * i_od + X_v * i_oq。这个补偿量很小,但在低压微电网里对功率解耦帮助很大。
频率参考ω_i则送到一个积分器生成相位角度θ_i,所有dq变换都基于这个θ_i进行。每台DG有自己独立的θ_i,不需要在模型里强制共享某一个全局角度;只要频率同步,各DG之间的相位差就会稳定在固定值,三相线路自然能把功率从A点送到B点。如果你强行给所有DG用同一个θ,反而会掩盖自治微电网的同步特性,尤其在做负载突变仿真时会得到不真实的功率响应。
3.3 二次协同控制的控制方程与事件触发量代入
二次控制的目标是补偿一次下垂造成的频率和电压偏差。我用的是带领导节点的领导-跟随一致性协议,其中只有一台DG能收到额定频率/电压的参考信号,这个DG叫领导者,其他DG通过邻居通信间接跟随。设定系统额定角频率为ω_nom,额定电压幅值为E_nom。每台DG的二次修正量用积分器实现:
- 频率修正量积分方程: u_dot_ωi = c_ω * [ Σ_j∈Ni a_ij * (ω_j_hat - ω_i) + g_i * (ω_nom - ω_i) ]
- 电压修正量积分方程: u_dot_Ei = c_E * [ Σ_j∈Ni a_ij * (V_j_hat - V_i) + g_i * (E_nom - V_i) ]
然后把积分得到的u_ωi和u_Ei叠加到下方程中,作为一次下垂控制的新参考:
- ω_i_ref = ω_nom + u_ωi - m_i * P_i
- E_i_ref = E_nom + u_Ei - n_i * Q_i
其中ω_j_hat和V_j_hat是邻居DG最近一次事件触发时发来的状态值。在传统连续通信方案里,ω_j_hat等于ω_j的实时值;在事件触发方案里,ω_j_hat只在邻居DG触发时被更新,其余时间保持不变。
从公式能看出一个关键逻辑:控制目标不是直接让某台DG的电压调到额定值,而是通过一致性协议让所有DG的修正量相互协调,直到邻居之间的状态差和与领导者之间的状态差都消失。g_i只有领导者那台DG为1,其他为0,这样只要最终满足u_dot_ωi=0且u_dot_Ei=0,就有ω_i收敛到ω_nom、V_i收敛到E_nom。这个结构在Simulink里可以很自然地用积分器模块加求和模块搭出来。
需要特别强调,上面那组方程是我用于仿真验证的基本形式。如果是要发表论文,还需要针对具体的事件触发条件做稳定性证明,证明在触发条件下系统仍然收敛到期望平衡点。仿真模型里可以先用这组方程跑通,但做理论分析时不能跳过稳定性验证这一关。
4. Simulink搭建实操:从主电路到事件触发模组
整个模型中,最耗时间的不是主电路搭建,而是通信逻辑和触发逻辑的协调。Simulink里凡是涉及“事件触发”和“记忆上一次值”的地方,都要特别小心模型的执行顺序。下面按我建议的搭建顺序,从底到顶讲实际操作。
4.1 顶层模型设计与子系统划分
我建议把模型分成这么几个层级:
- MG_4DG:顶层模型,放置四个DG子系统、交流母线、负载、测量模块;
- DG_Power:主电路,包括直流源、三相逆变器、LC滤波器、线路阻抗;
- DG_Controller:一次控制,包括功率计算、下垂、电压电流双闭环、PWM;
- Secondary_Control:二次协同控制,包含一致性积分器以及事件触发通信模块;
- Event_Trigger:每个DG内部的事件触发模块,用于决定本机状态是否广播。
子系统之间的数据流要预先定义清楚。DG_Power输出电气测量量,DG_Controller输出PWM脉冲和参考频率,Secondary_Control输出修正量。事件触发模块放在通信发送端口,输入是本机状态和触发参数,输出是“是否触发”和“本机广播状态”。邻居收到的状态来自远方DG的Event_Trigger输出,而不是直接连测量信号。
4.2 主电路搭建:逆变器、滤波、负载
主电路我使用的是Simscape Electrical模块库里的三相逆变器。这种建模方式比简单电压源模型更接近真实,能反映电压电流动态和谐波信息。当然,如果模型的目的是纯控制算法验证,也可以用受控电压源代替逆变器,运行速度会快很多,但看不到PWM开关纹波,对触发阈值的设置也有影响。我的建议是:初次调试用受控电压源模型跑通逻辑,最后再替换成完整逆变器模型做正式仿真。
三相逆变器的直流侧用一个直流电压源代替光伏或储能电池,这样可以暂时忽略新能源出力的随机性;如果以后要加入光伏波动场景,可以把直流电压源替换成光伏模型加Boost电路,但主电路和控制器的接口基本不变。逆变器交流侧接LC滤波器,滤波后通过线路阻抗连接到公共母线。公共母线上并联负载,负载用三相串联RL支路实现,便于设置有功和无功功率比例。
4.3 功率计算模块和下垂控制
功率计算不能直接用瞬时值,否则下垂环会因为功率波动而输出抖动的参考值。常用做法是先通过Park变换把三相电压电流变换到dq轴,再计算瞬时功率:
- P = 1.5 * (v_d * i_d + v_q * i_q)
- Q = 1.5 * (v_q * i_d - v_d * i_q)
得到的P和Q再用一阶低通滤波器平滑,滤波器时间常数一般取0.01到0.05秒。时间常数太小,功率波动大;太大会让动态响应变慢,与二次控制的恢复时间产生耦合。
下垂控制部分是纯数学运算,用Gain和Sum模块就能搭。频率参考ω_i_ref经过积分得到θ_i,同时把ω_i_ref送入二次控制作为本地频率反馈。需要注意,这里最容易出现的错误是直接把pwm生成器需要的载波频率和下垂控制的ω混淆。下垂控制的ω是工频角频率,也就是大约314rad/s,而载波频率是10kHz或更高,两者差了几个数量级,互不相关。
4.4 电压电流双闭环与PWM调制信号生成
电压电流双闭环也放在dq旋转坐标系中。电压外环PI输出的限制范围要合理,否则电流参考过大,会导致PWM调制波饱和,逆变器输出畸变。电流内环的输出是调制波v_d_ref和v_q_ref,经过反Park变换得到三相正弦调制波,送给PWM发生器。PWM发生器可以用三相PWM Generator模块,也可以自己搭三角波比较器。
搭建时我习惯在电流环输出后加一个限幅模块,把调制比限制在0.9以内,给线性调制留出余量。如果调制波饱和,逆变器输出电压会产生大量低次谐波,一次控制测到的功率会产生波动,触发模块可能会因为状态波动频繁误触发,到那时你很难判断是算法问题还是调制饱和问题。
4.5 事件触发模块的Simulink实现
这是整套模型的核心,也是最难在Simulink里表达清楚的部分。我采用MATLAB Function加离散采样实现周期采样事件触发。基本思路是:该模块以Ts为采样步长运行,内部维持一个持久变量last_sent,记录上次广播的状态;每个采样时刻计算当前真实状态与last_sent的差,若不满足触发条件则继续保持last_sent不变,且flag置0;若满足触发条件,则更新last_sent为当前状态,并flag置1。
MATLAB Function内部的伪代码如下:
function [flag, state_out] = event_trigger(state_in, sigma, eps) % 周期采样事件触发模块 % state_in:本地需要广播的状态,例如频率或电压幅值 % sigma:触发阈值系数 % eps:防止零状态误触发的小正数 persistent last_sent if isempty(last_sent) last_sent = state_in; end error = state_in - last_sent; if abs(error) >= sigma * abs(state_in) + eps flag = true; last_sent = state_in; else flag = false; end state_out = last_sent;在Simulink里把该函数配置为离散模块,采样时间设成Ts。输入state_in必须经过一个零阶保持器,保证每个仿真步长看到的都是一致的数据。flag可以作为触发记录送入Scope,用于统计触发次数;state_out则送入一致性控制器,作为本机对外广播的状态。
这个模块我用过两种变体。如果希望邻居DG的一致性控制器中,直接使用“本机最近一次广播状态”,可以在这个模块内部再输出一个state_broadcast,也就是last_sent本身。如果还想模拟通信延时,可以再串联一个Variable Time Delay。注意,延时加得太大容易导致系统不稳定,初始调试建议先把延时设成0,跑通再逐步增加。
4.6 通信拓扑在Simulink中的信号连接
通信拓扑不需要真的建一个通信网络,只需要在顶层模型里把各DG的state_out信号连到对应邻居的端口。例如环形拓扑DG1连接到DG2,DG2连接到DG3,DG3连接到DG4,DG4连接到DG1,再加上DG1作为领导者接收额定参考信号。每个DG的一致性控制器内部,要用一个“接收状态”端口接收邻居最近发来的状态。
这里最容易出现的问题是多DG之间的信号线交叉,久了容易混乱。建议在顶层模型里用Bus或Goto/From命名管理,比如把DG1广播出去的频率命名为DG1_w_send,DG2控制器内部用From模块接收这个信号。这样模型结构清晰,排查通信故障时一眼就能看出信号链路。
有一次我把状态信号意外连接成了“连续处处更新”的形式,也就是直接把对方DG的实时状态接进了自己的控制器,导致触发模块形同虚设。排查了半天,最后发现是Bus Creator内部的数据源引错了端口。建议每次改动信号连接后,把仿真步长调短跑一小段时间,检查触发Scope里是否出现了应有的静默段,以此快速判断事件触发是否真的在起作用。
5. 仿真工况设计、结果对比与指标计算
模型搭好以后,下一步不是直接看波形,而是先设计一套能区分一次下垂、二次恢复、事件触发效果的仿真工况。如果工况设计得不好,模型可能看起来“跑起来了”,但并没有真正验证到你想验证的核心问题。
5.1 推荐的一组时间序列工况
我常用的一组工况如下:
| 时间段 | 事件 | 目的 |
|---|---|---|
| 0 ~ 0.2s | 系统启动,二次控制先不投入 | 观察初始启动动态 |
| 0.2s | 投入二次协同控制 | 观察频率电压从带偏差状态恢复到额定值 |
| 0.5s | 增加有功负载 | 观察频率跌落及二次恢复能力、触发次数变化 |
| 0.8s | 增加无功负载 | 观察电压跌落及二次电压恢复能力 |
| 1.2s | 切除部分负载 | 观察反向动态响应 |
| 1.2s以后 | 持续运行到2s结束 | 统计总触发次数和稳态精度 |
调试时可以把二次控制的投入时间设成一个可切换的阶跃信号,方便对比“不加二次控制”、“加周期二次控制”、“加事件触发二次控制”三种模式。负载切换幅值建议为额定负载的20%到40%,过大容易导致第一次仿真就跑飞,过小则偏差不明显。
5.2 需要观察的关键波形和预期结果
最重要的输出波形是四台DG的输出频率、端电压幅值、有功功率、无功功率,以及每台DG的触发信号。以我做的4台DG模型为例,如果初始频率由于负载原因跌到49.8Hz左右,0.2s投入二次控制后,频率应当在0.3s到0.5s内逐步恢复到50Hz附近,稳态误差小于0.01Hz。四台DG的端电压幅值也会在各自参考值附近趋于一致,稳态误差在1V以内。每条DG的触发信号不会像周期通信那样密集,而是集中出现在负载切换后的动态过渡段,稳态阶段基本静默。
如果发现频率能恢复但电压恢复得不好,通常是电压一致性系数c_E太小或领导节点参考电压信号没有正确接入。如果发现触发次数异常多,比如每秒触发几百次,要优先检查是不是触发阈值σ取得太小、采样周期Ts太小,或者状态信号没有经过ZOH处理,导致PWM纹波直接进入了触发判断。
5.3 通信负担指标的计算与对比方法
事件触发机制最核心的卖点就是降低通信次数,因此仿真结束后要算出“通信资源占用率”这个指标。方法很简单:在Event_Trigger模块内部用计数器累加flag为1的次数,仿真结束时把总数导出。周期通信对照组中,同一台DG在Ts周期内每次采样都会发一次数据,所以周期通信次数就等于仿真时长除以Ts。
假设仿真时长为2s,Ts=2ms,周期通信次数就是1000次。事件触发在稳态时基本不发,只在突加负载后的0.2s内发几十次,那么总触发次数可能只有100次到300次,资源占用率在10%到30%之间。这个数字直观地说明事件触发机制的价值。做学术汇报或者论文时,我还会画一个触发时刻的阶梯图,横轴时间,纵轴每台DG是否触发,能很清楚地看出触发集中发生在动态阶段。
5.4 稳定性视角下的微调要点
事件触发协同控制虽然降低了通信量,但代价是邻居状态信息滞后。滞后越大,一致性积分器的增益c_ω、c_E就越要保守一些。如果c取值太大,事件触发模式下容易在触发后的更新瞬间产生控制量跳变,进而引起电压电流波动;如果c太小,恢复速度太慢,负载突变后频率长时间回不到额定值。
我的调试经验是:在连续通信模式下先把c_ω和c_E调到一个能使系统快速稳定恢复的值,然后切换到事件触发模式,通常需要把c下调30%到50%,再重新观察恢复速度和触发次数。如果系统出现轻微振荡,优先增大触发阈值σ而不是盲目降低增益,因为σ增大会让通信进一步减少,反而有助于消除高频抖动带来的触发干扰。
6. 常见问题与排查实录
Simulink模型在搭建过程中一定会遇到一些跟算法本身无关的工程问题。这里把我在复现过程中踩过、以及帮别人排查过的高频问题集中列出来,很多问题其实就是模块使用不当造成的。
6.1 仿真速度很慢,甚至跑不动
如果模型里用了完整IGBT逆变器和Simscape电气模块,仿真速度慢是正常的。这时优先检查是不是用了过小的最大步长,比如把max step size设成1e-7秒,PWM频率10kHz下会跑得非常痛苦。逆变器和控制回路之间的时间尺度跨度很大,建议在控制算法验证阶段先把开关器件等效成平均模型,或者使用PWM发生器但把开关频率降到5kHz,等所有逻辑跑通后再恢复精确模型。
另一个常见原因是触发判断模块的采样周期Ts设置得太小,MATLAB Function每个仿真步长都被调用,计算量暴增。Ts不需要跟PWM周期一致,可以放宽到PWM周期的10倍甚至20倍,只要不影响电压频率恢复精度即可。
6.2 报错“LAPACK加载错误: mllapack.dll”
这个错误在Windows系统上偶发,通常不是模型本身的问题,而是MATLAB运行库的加载路径