
做MMC仿真的同行应该都有体会模型一搭跑两步就发散电容电压乱跳、环流大得离谱好不容易稳定了又发现直流侧电压往下掉。我在做模块化多电平变流器的VSG控制仿真时前前后后踩了不少坑。今天这篇就是我从零搭一个“MMC 虚拟同步发电机 MATLAB/Simulink”仿真模型的完整记录包含拓扑参数计算、VSG控制算法拆解、Simulink实操步骤和一堆真实踩坑经验希望能帮你少走点弯路。这个组合听起来有点“重”——MMC本身已经是电力电子里最复杂的拓扑之一VSG又涉及电力系统同步发电机机理两个放在一起很容易让人不知道从哪下手。但换个角度看它解决的恰好是当前并网变流器最头疼的问题MMC作为柔性直流输电和高压电能质量治理的主流拓扑缺的是对电网的“自觉”VSG作为模拟同步发电机外特性的控制策略缺的是一个能真正发挥它优势的物理载体。两者一结合既能发挥MMC大容量、低谐波、模块化的优势又能让变流器主动参与电网调频调压而不是当一个“哑巴”电流源。这篇内容适合正在做MMC或VSG相关毕业设计、工程项目预研、或者想搞懂“变流器如何友好并网”的工程师。我不讲那些教科书里翻得到的公式推导只讲我在仿真里真正跑通过的东西。1. 为什么非要把MMC和VSG凑在一起1.1 传统MMC控制的两个短板MMC的常规控制策略非常成熟外环控制有功无功内环控制电流加上环流抑制和电容电压均衡基本能把一个换流器稳定运行在某个工作点。但我做了几个项目后发现这套东西有两个天生的短板。第一个短板是“没有惯性”。传统控制是按电流源思路设计的锁相环盯住电网相位变流器瞬间就能响应功率指令。问题是当电网频率波动时它不会像同步发电机那样天然地释放或吸收转子动能来阻止频率变化。新能源占比越来越高之后系统的惯量越来越低这时候变流器能不能提供一点“虚拟惯量”就成了电网稳定性的关键问题。第二个短板是弱电网适应性差。我在仿真里把电网短路比从10调到2传统锁相环控制的MMC明显开始振荡甚至在电压扰动时出现锁相失败。原因很简单锁相环把电网相位当作刚性的电网一旦“软”了这套逻辑就不好使了。VSG控制恰恰补这两个短板它让变流器在控制层拥有一个“虚拟转子”通过模拟同步发电机的转子运动方程自主建立相位和幅值而不是盯住电网跑。电网频率掉一点它就自动多输出一点有功电网电压低一点它就自动多给一点无功。这套逻辑从根上就更贴近电力系统的思维方式。1.2 VSG本质上是给变流器装了“飞轮大脑”VSG的核心思想一句话就能说清楚把同步发电机的二阶运动方程放进变流器的控制算法里。同步发电机的转子有质量有转动惯量所以它的功角变化是渐进的不会瞬间跳变。VSG就把这个“渐进感”搬到变流器里——虚拟出一个转动惯量J让变流器输出电压的相位不再是锁相环给出的“跟随相位”而是通过积分自己“转”出来的相位。这样做的好处是从电网侧看过去这个变流器的外特性像一台同步机它参与调频、调压的响应过程是平滑的不会像传统控制那样突变。坏处也显而易见算法里多了一组可以调的参数J和D调不好就会像一台阻尼不足的发电机一样功角振荡甚至比锁相环控制更容易发散。我需要特别强调一个容易混淆的概念VSG并不是不要锁相环而是让锁相环从“主控”变成“测量工具”。VSG只是用它的测量值来做功率计算和并网同步相位生成完全由虚拟转子自己完成。这点在做仿真接线时非常关键接错了整个控制逻辑就是乱的。1.3 这套方案到底适合谁用从应用场景看这套组合目前最热的去处是柔性直流输电换流站。受端换流站如果采用VSG控制可以在交流侧电网发生频率扰动时提供惯量支撑这是传统定有功控制做不到的。另外一个实际场景是储能电站的PCS储能变流器。很多储能电站的变流器要求具备一次调频能力VSG控制是可以直接对标同步机调频特性的方案。而且MMC拓扑本身可以做成中高压直挂的储能变流器省掉升压变压器这时候MMCVSG的工程价值就非常明显。如果你只是做课程设计或者入门学习我强烈建议先跑一个小容量的验证模型比如几百伏、几千瓦级别的三相MMC逆变器配合VSG控制观察惯性响应和调频过程。等你把参数调明白了再往10kV、几十MW的工程级别模型上迁移否则一开始就用大系统调试很容易被仿真速度拖垮。2. 动手之前MMC拓扑选型和参数怎么算2.1 拓扑结构与子模块数量设计我下面用一套10kV/10MW的三相MMC逆变器作为贯穿全文的示例系统。直流侧额定电压正负10kV即总直流电压20kV交流侧线电压10kV电网频率50Hz。这套参数是典型的工程验证参数不算大但足够说明问题。每相桥臂的子模块数量N怎么定关键约束是子模块的耐压。直流母线总电压是20kV每相上下两个桥臂串联起来承担这个电压任意时刻每相投入的子模块数保持为N个上桥臂投K个下桥臂就投N-K个。如果取N20那么稳态时每个子模块电容电压就是Udc/N20kV/201000V。实际选IGBT时不能按1000V选。电容电压有波动一般允许±10%也就是最高到1100V再加上器件关断时的尖峰电压实际IGBT耐压至少要按2倍裕度选也就是1700V或2000V的器件比较合理。所以在做仿真模型时子模块电容参考电压按1000V设计而IGBT模型要设置能承受2000V左右的耐压。对于仿真验证我建议你可以先跑N4或者N6的小系统。子模块数量少模型跑得快控制逻辑是一样的只是输出电压谐波会差一些。等把VSG参数和控制环调稳了再换成N20的完整模型。2.2 子模块电容和桥臂电感怎么估算子模块电容和桥臂电感是MMC仿真里最影响性能的两个参数。电容太大储能多动态响应慢而且仿真初始化时间很长电容太小电容电压波动大均压算法容易出问题。桥臂电感同理太小时抑制不了环流太大时系统体积和损耗都上去了。工程上常用的方法是用储能常数H来估算电容。储能常数表示子模块储能与额定功率之比一般取20~40kJ/MVA。对10MVA系统H取30kJ/MVA时总储能就是E 30 × 1000 × 10MVA 300kJ这里的1000是单位换算系数1kJ/MVA乘以MVA得到kJ。接下来每个子模块电容C 2E / (N × Uc²) 2 × 300000 / (20 × 1000²) 600000 / 20000000 0.03F 30mF30mF这个电容在10kV等级工程上是偏大的实际产品中常见10~20mF。仿真的话我建议先按这个算出来然后根据电容电压波动仿真结果往下调。电容电压波动的经验公式是ΔUc/Uc ≈ (P × (1 - m²)) / (2 × N × C × Uc² × f) × (1/2) 的某种形式我不展开推导了直接给结论把电容波动控制在±8%以内就行。C取大一点均压压力小但动态响应慢C取小一点响应快但容易触发过压保护。桥臂电感按标幺值算。额定工况下交流侧相电压峰值约8.16kV电流有效值I P / (√3 × U线) 10MW / (√3 × 10kV) 577A阻抗基准值Zb U线² / S 10000² / 10e6 10Ω注意这里用的是线电压还是相电压要看基准定义方式按线电压和三相总功率定义基准阻抗就是10Ω。桥臂电感的标准范围是0.1~0.15p.u.取0.12p.u.则L 0.12 × 10 / (2π × 50) 1.2 / 314 0.00382H ≈ 3.8mH实际我做仿真的时候发现3.8mH偏小环流抑制压力大。在N20的模型中我最后用了15mH对应的标幺值是0.47p.u.虽然偏大但对环流抑制和弱电网适应性都有帮助代价只是动态响应略慢。如果你做小系统验证桥臂电感取5mH级别也能跑关键是环流抑制器的输出不能饱和。2.3 Simulink建模的路线选择这是很多新手绕不过去的坎。MMC在Simulink里有三条路线第一条是元件级建模。用Simscape Electrical里的IGBT、二极管、电容搭每个半桥子模块20个子模块就是120个子模块6个桥臂×20每个桥臂40个IGBT和40个二极管。这种模型最真实但仿真极慢跑几百毫秒都够喝一壶的。第二条是函数级建模。用Matlab Function或者S-Function实现子模块的开关等效电路把IGBT导通和关断等效成电阻切换。这种方法比元件级快很多但写代码工作量不小。第三条是平均值模型。用受控电压源和受控电流源替代整个桥臂或者整个MMC完全不建子模块细节。这种模型仿真最快适合验证VSG控制算法但看不到电容均压和环流这些内部特性。我个人的经验是验证VSG控制算法时用第三条路线直接拿一个等效变流器模型跑通VSG验证MMC内部特性均压、环流、调制时再用前两条路线。一上来就搭120个子模块的元件级模型去调VSG参数是纯纯浪费时间。3. VSG控制器的核心算法3.1 转子运动方程怎么变成控制代码VSG的物理基础是同步发电机的转子运动方程写成标量形式J × dω/dt Tm - Te - D × (ω - ω0)其中Tm是机械转矩Te是电磁转矩D是阻尼系数ω0是额定角速度。在变流器控制里我们把功率转成转矩来处理。机械功率来自有功指令Pref电磁功率来自实时输出的有功功率Pe则Tm Pref / ω0 Te Pe / ω注意我这里实际调试时发现Te用Pe/ω还是Pe/ω0会有微小差别工程简化用Pe/ω0更常见。然后转速指令变成ω_next ω (Tm - Te - D × (ω - ω0)) / J × Ts其中Ts是控制周期。相位角度直接积分θ_next θ ω × Ts这一步得到的θ就是变流器输出电压的相位指令。这个θ是“虚拟转子”自己转出来的不再依赖锁相环的瞬时相位这就是VSG和传统控制的本质区别。在离散化的时候有个细节容易出错控制周期Ts必须固定而且要和主电路仿真步长匹配。我在Simulink里用离散控制Ts取100μs仿真步长取10μs两者是整数倍关系避免采样抖动造成振荡。3.2 惯量J和阻尼D到底取多少这是VSG调参最核心的问题。我见过太多人卡在这里J和D瞎试一通模型一直在振荡。其实参数选取是有逻辑的。首先定义惯性时间常数H J × ω0² / (2 × S)它表示虚拟转子在额定转速下储存的动能对应变流器满功率运行多少秒。同步发电机H通常2~10s但变流器因为物理上没有真实转子H没必要取那么大一般0.5~3s就够了。我取H2sJ 2HS / ω0² 2 × 2 × 10e6 / (2π × 50)² 40000000 / 98596 ≈ 406 kg·m²这就是虚拟转动惯量J的初值。有了J以后阻尼系数D影响的是振荡衰减速度。阻尼比ξ和最自然振荡频率ωn有关系。VSG的功率环可以近似看成二阶系统J和D决定了它的阻尼特性。工程经验上让D约为10~20倍的J×ω0×0.01需要试凑。我这里给出一个调试方法先把D设成0跑一个阶跃响应看振荡频率。测出振荡频率fn后按期望阻尼比ζ0.7反推D。实际操作时我发现D的取值范围在1000~3000之间比较合适对这套10MW系统。我最后用了D2000响应比较快且几乎没有超调。还有一个比较容易忽视的问题J太大会让VSG响应变慢J太小又保留不了锁相环快速响应的优点。我建议你先用J400、D2000起步然后逐步把J减半或加倍观察频率动态曲线体会一下参数对惯性的影响这个调试过程本身就是理解VSG的最好方式。3.3 电压幅值指令和无功环VSG除了有功-频率环还要做无功-电压环。同步发电机有励磁系统维持机端电压VSG同样需要虚拟励磁。最简单的实现就是无功下垂控制E E0 kv × (Qref - Qe)其中E0是空载电动势指令Qe是实时无功功率kv是电压下垂系数。此外还可以加入虚拟阻抗来模拟同步电抗Eq Eref - Rv × id Xv × iq这里的Rv和Xv就是虚拟电阻和虚拟电抗作用是为了避免VSG直接控制理想电压源导致电流冲击。我在仿真里取Xv0.2Ω约0.02p.u.Rv0.01Ω效果很好。最后得到的电压指令是三相信号ea E × sin(θ) eb E × sin(θ - 2π/3) ec E × sin(θ 2π/3)这个三相信号作为MMC桥臂电压参考的输入交给下面的调制环节。注意这里已经不需要传统意义上的d/q轴电流内环了VSG本质上是直接控制输出电压的幅值和相位走的是“电压源”路线。如果你确实需要限制短路电流可以在VSG后面加电流限幅环但那是另一个话题。4. 从零搭仿真详细步骤记录4.1 整体架构搭法我把仿真模型分成四个大模块MMC主电路、VSG控制、调制与均压、测量与保护。整个模型的数据流是这样走的主电路输出的三相电压电流进入测量模块计算有功、无功和频率送给VSG控制器VSG输出三相参考电压送到调制模块调制模块结合均压算法生成每个子模块的投入/切除信号再送回主电路。在Simulink里我习惯用Bus对象来管理主电路的测量信号避免信号线绕成一团。VSG控制的内部信号比如P、Q、ω、θ要在调试时用Scope同时观察所以建议单独拉出一组总线连到Scope。4.2 主电路搭法细节搭建时注意两点直流电源要串一个小电阻模拟直流侧内阻否则预充电过程电流冲击极大交流侧电网用Three-Phase Source串联一个0.1Ω的电阻和2mH的电感模拟线路阻抗。子模块我建议用函数封装。每个半桥子模块接收“投入/切除”信号内部根据信号切换输出电压和电流旁路关系。核心函数大致是这个思路function [v_out, i_cap] half_bridge_submodule(v_cap, i_arm, insert) % 简单的半桥子模块等效 % insert1: 投入输出v_capinsert0: 切除输出0 if insert 0.5 v_out v_cap; % 电容电流等于桥臂电流 i_cap i_arm; else v_out 0; % 旁路电容电流为0 i_cap 0; end end实际仿真里还需要处理电容电压的动态function v_cap_next cap_dynamics(v_cap, i_cap, C, Ts) v_cap_next v_cap i_cap * Ts / C; end这两个函数配合起来放在For Each Subsystem里可以一次性处理6个桥臂×20个子模块的批量运算这是仿真的核心加速手段。要注意For Each Subsystem要求所有数组维度严格一致调试时数组转置问题特别容易出。4.3 均压与调制实现调制我用的载波移相PWMCPS-PWM。每桥臂20个子模块产生20个相位相差π/209°的三角载波每个载波和桥臂参考电压比较产生这一子模块的原始投入信号。桥臂参考电压来自VSG电压指令和直流母线电压的折算u_arm_ref Udc/2 - e_phase - u_cir_ctrl具体来说上桥臂参考电压是Udc/2减去交流电压指令再减去环流抑制补偿量下桥臂是Udc/2加上交流电压指令再减去环流抑制补偿量。这个符号关系搞错了输出电压就完全乱了。CPS-PWM的问题在于和均压算法是脱节的。每个子模块载波相位固定如果不做均压各子模块电容电压会越拉越大。我的做法是维持载波移相产生的基础开关时刻不变然后用排序算法微调“投入数量”——通过比较该桥臂每个子模块当前的电容电压排序结果决定哪个该投入、哪个该切除。经典排序法代码大概长这样function [insertion] sorting_balancing(v_caps, currents, sorting_freq_idx) % 每个排序周期内根据桥臂电流方向确定投入高压还是低压电容 N length(v_caps); [~, idx] sort(v_caps); insertion zeros(1, N); % 假设桥臂电流流入为充电需要投入电压低的电容 if currents 0 insertion(idx(1:ceil(N/2))) 1; else insertion(idx(ceil(N/2)1:end)) 1; end end这个函数是均压的核心。注意它必须在固定的排序周期执行排序过于频繁会增大开关损耗低于1kHz又会导致电容不平衡。我用10kHz的排序频率对10kV系统算是合理的折中。4.4 启动流程是成败关键很多人的MMC仿真炸在第一秒——上来就给直流侧加20kV电容根本没有初始电压冲击电流直接把仿真干崩了。我摸索出来的可靠启动流程是第一步不控整流预充电。所有IGBT闭锁让交流侧通过反并联二极管给子模块电容充电充到接近额定电压的2/3左右。在Simulink里我把初始电容电压设为目标电压的80%再通过不控充电快速稳定能省大量仿真时间。第二步解锁VSG控制。在t0.5s解锁控制指令先给一个很小的有功功率参考让系统平滑过渡。直接用额定功率启动无功和电流都会冲击。第三步有功和无功指令斜坡变化。我习惯设一个斜坡模块让Pref在0.5秒内从0升到5MW再在下一个1秒内升到10MW。VSG的转子运动方程本身有惯性斜坡输入能进一步降低冲击。这整个启动流程控制好模型的仿真失败率会大幅下降。我这边跑10kV/10MW模型在Simulink里用离散步长10μs大约要跑5分钟才能看到完整的2秒动态耐心点。5. 仿真中的典型问题与排查实录5.1 电容电压发散的几个真因这大概是MMC仿真里出现频率最高的问题。我在调试过程中排查过三次电容发散原因各不相同第一次是排序均压执行频率太低。我把排序周期对应成载波周期结果发现1kHz排序跟不上功率变化电容电压出现低频振荡。换成独立触发序列后解决。第二次是初始预充电不一致。各子模块初始电压我用随机数赋值但没有按中值约束导致初始不平衡量超过了均压环的调节能力。后来我把初始电压设为(0.8~1.0)×Uc均匀分布问题消失。第三次是电容电压测量延迟。For Each Subsystem里的电容电压更新如果和控制周期不同步均压算法会被“旧电压”误导。解决办法是让电容动态和排序处于同一个离散任务下保证时序一致。排查电容发散问题时我的建议是一口气同时画出6个桥臂的电容电压波形而不是只画一个。发散往往先出现在某一相或者某个桥臂单独看一个桥臂根本发现不了。5.2 VSG功率振荡的调参实录VSG参数不对最直观的表现是有功功率输出等幅或发散振荡。我在N20模型上遇到了持续振荡频率大约2.5Hz当时一度怀疑是环流抑制没调好。后来排查下来问题出在阻尼D太小。我把D从500调到2000后振荡从等幅变成了衰减大概三次振荡后就稳定了。如果你也碰到这个问题先检查两步第一步确认D不为零。很多仿真入门教程把D设成0这是为了突出振荡教学但在工程模型里D0基本是自杀式设置。第二步用阶跃响应来标定。我把Pref从5MW阶跃到6MW记录有功功率的超调量和振荡频率。按二阶系统的经验超调超过20%就加大D响应时间超过0.5s就适当减小J。反复三五次就能找到合适的参数组合。重要提醒VSG的振荡频率和电网强度强相关。弱电网下同样的J和D会更接近失稳边界。我建议你把短路比扫描和参数扫描放在一起做一次看清楚临界参数组合。5.3 仿真速度慢到崩溃怎么办20个子模块MMC的元件级模型跑1秒动态可能需要20分钟以上这对调参来说完全不可用。我采用了三级提速策略第一级用函数级子模块替代元件级子模块。前面提到的half_bridge_submodule函数让仿真提速大约5倍。代价是看不到IGBT的开关暂态但对控制验证来说完全够用。第二级控制环节全部用离散模块实现。把PI控制器、积分器、滤波器都换成离散版采样率设在100μs能避免连续求解器反复迭代拉低速度。第三级也是我推荐的手段先跑平均值模型。就是把MMC整个替换成受控电压源均压和环流模块先拿掉只保留VSG控制。等VSG参数完全跑通再换回函数级MMC。这个过程能节省80%的调参时间。5.4 常见问题速查表我把调试中遇到的高频问题整理成一张表方便你排查时快速对照。现象可能原因排查和解决手段电容电压从某一相开始发散排序触发序列与桥臂电流方向不匹配检查均压函数中电流方向的判断逻辑环流波形明显畸变且幅值大环流抑制器PI参数不当或桥臂电感偏小加大桥臂电感或降低PI积分时间常数有功功率出现低频等幅振荡VSG阻尼系数D过小逐步加大D观察振荡是否衰减启动瞬间电流冲顶崩溃电容初始电压过低或解锁过早预充电到80%额定电压后再解锁直流侧电压塌陷没有投入能量平衡控制增加额外的直流电压外环或调整有功参考仿真长时间无进展固定步长太小把固定步长从2μs改为10μs同时确认离散控制周期为100μs逆变器输出电压谐波大子模块数量N不足增加子模块数或改用最近电平逼近调制6. 最后补充的实操心得做完整套MMCVSG仿真后我最深的一条经验是这个项目最耗时间的地方不是控制算法设计而是把所有模块之间的信号时序和离散周期对齐。Simulink模型里最隐蔽的坑往往来自代数环和数据类型不匹配。比如电容电压信号传进排序函数时突然变成复数或者单精度这类问题报错提示非常模糊我排查最久的一次原因是Matlab Function的输入数组维度是6×20而排序函数内部用的是20×6问题很小但排查了大半天。另外建议你从第一天就把模型加注释和版本备份。MMC的仿真模型一旦跑通你很快会想尝试各种控制变体——下垂控制、双闭环、低电压穿越……每个版本都可能动到核心模块。没有清晰的版本管理到最后也不知道最优的结果对应的是哪一版模型。如果你准备在这个方向深入下去下一步可以考虑把环流抑制器和VSG的交互机制做更仔细的分析尤其是环流抑制器带宽和VSG惯量时间常数的配合。我目前还在试把虚拟阻抗也做成自适应调节的版本等有结果了再分享。这个项目确实复杂但只要你完成了整套仿真对MMC的每一相桥臂工作机理、对VSG的惯性支撑逻辑都会有非常扎实的理解。这些理解比仿真模型本身值钱得多。希望这篇记录能帮你顺利跑通自己的第一版MMCVSG仿真模型。