这些年我在电力电子仿真里接触最多的一类需求,就是把IEEE期刊上的控制算法搬到Simulink里验证。其中“基于混合有限集模型预测控制(FCS-MPC)的模块化多电平换流器(MMC)整流电路仿真模型”这个题目,几乎每隔一阵就会在技术社区里出现一次。标题每个词都认识,真动手才发现:FCS-MPC到底怎么和MMC结合?整流器控制目标和逆变器有什么不同?Simulink里的子模块如何搭才不会爆内存?这中间每一步都藏着不少细节。
这篇文章就按我自己复现这类项目的完整路线来讲——从控制架构拆解、数学模型离散化,到Simulink主电路搭建、预测控制器内部逻辑,再到调试路径和结果验证。目标是让正在复现SCI二区论文、或者想从传统PI+PWM切到模型预测控制的人,能少走几段弯路。
1. FCS-MPC和MMC整流器凑在一起,到底解决什么问题
1.1 为什么MMC整流器不能只用传统PI加PWM
MMC整流器和逆变器的区别,一句话就能说清楚:逆变器直流侧电压相对稳定,控制核心是把直流能量变成交流;整流器则反过来,交流侧提供能量,直流侧需要维持电压恒定。所以整流控制天然就是一个双闭环结构——直流电压外环给出有功电流指令,电流内环负责跟踪。
传统做法是内环PI控制器加载波移相PWM,再加独立的电容电压排序算法。问题在于MMC的桥臂电流里有二倍频环流分量,交流电流跟踪、环流抑制、子模块电容电压均衡这三件事在频域上相互牵扯。PI控制器设计时要在带宽和稳定性之间反复权衡,参数分散在三四个独立环路里,调起来非常痛苦。
FCS-MPC的核心思路完全不同:建立系统的离散预测模型,枚举所有可选的开关状态,对每个状态用代价函数评估未来一个控制周期内的响应,然后直接选择最优的一组开关信号输出。电流跟踪、环流抑制、电容电压偏差三项指标全被塞进同一个代价函数里,不再需要分别设计三个控制器。这个思路在理论上一旦跑通,控制结构会简洁很多。
1.2 “混合有限集”这几个字背后的真实含义
很多初学者卡就卡在“混合”上。纯开关级的FCS-MPC在MMC上推不开,原因是开关组合数量爆炸。一个桥臂有N个子模块,上、下桥臂各N个。如果直接枚举每个IGBT的通断组合,每个桥臂有2^N种可能,六个桥臂就是(2^N)^6。N取6时,这个数超过10的10次方,现场控制器在一个控制周期内根本算不完。
“混合”的意思,第一层是把控制量从“具体哪个子模块投入”降维成“每个桥臂投入几个子模块”。单桥臂的投入数取值范围是0到N,一共N+1种有限状态,这就是“有限集”的来由。六个桥臂的全集遍历是(N+1)^6,N=6时约11.8万次评估,仿真阶段完全能跑。如果再做逐桥臂独立评估,每拍只需要6×(N+1)=42次,实时性也足够了。
第二层含义是分工混合。预测控制器只负责选出每个桥臂的投入数量,而“具体投入哪几个子模块”交给经典的电容电压排序算法去解决。MPC管宏观最优,排序管微观均衡,两者各干各的,却比一堆PI控制器互相协调要省心。
2. 开工前必须想清楚的控制架构与数学模型
2.1 主电路结构和两个关键电流分量
MMC整流器主电路的三相结构对称,每相有上、下两个桥臂,每个桥臂由N个半桥子模块串联,再串一个桥臂电感L_arm。交流侧通过网侧电感L_s接到三相交流电源,直流侧接负载电阻。逆变器是直流到交流,整流器则是交流电源通过MMC给直流负载供电。
分析MMC时,每个桥臂电流都能分解成两个分量。以A相为例,设上桥臂电流i_pa、下桥臂电流i_na,那么:
- 交流侧线电流 i_a = i_pa - i_na,这是受控目标,希望它是正弦波且功率因数接近1。
- 桥臂环流 i_cir_a = (i_pa + i_na)/2,它主要包含直流分量和二倍频分量。直流分量用于传递有功功率,二倍频分量是有害的,会在子模块电容里引起额外波动,必须抑制。
电容电压平衡、环流抑制、交流电流跟踪这三大控制目标,本质上都是针对这两个电流分量的。
2.2 预测模型怎么离散化
FCS-MPC的预测模型分两部分:交流电流模型和环流模型。
交流电流方程在dq同步旋转坐标系下写,整流器的等效方程为:
L_s · di_d/dt = u_d - v_d - R_s · i_d + ωL_s · i_q L_s · di_q/dt = u_q - v_q - R_s · i_q - ωL_s · i_d其中u_d、u_q是交流电源电压的d、q分量,v_d、v_q是MMC交流端口输出电压的d、q分量。用前向欧拉法离散化,步长取控制周期T_s:
i_d(k+1) = i_d(k) + T_s/L_s · [u_d(k) - v_d(k) - R_s·i_d(k) + ωL_s·i_q(k)] i_q(k+1) = i_q(k) + T_s/L_s · [u_q(k) - v_q(k) - R_s·i_q(k) - ωL_s·i_d(k)]这里v_d(k)、v_q(k)是决策量,由候选的桥臂投入数映射得到。常用近似是:某相上桥臂投入n_p个、下桥臂投入n_n个,则该相交流输出电压近似为:
v_j ≈ (n_n - n_p) / N · V_dc_avg_jV_dc_avg_j是该相所有子模块电容电压的总和。这个近似在稳态时误差不大,即使有偏差,下一拍的代价函数评估也会自动修正。
环流模型从上、下桥臂的回路方程推。上、下桥臂电流叠加后,环流回路的等效电感为2L_arm,方程写成:
2L_arm · di_cir_j/dt = V_dc - (v_p_sum + v_n_sum) - 2R_arm·i_cir_jv_p_sum和v_n_sum分别是上、下桥臂当前所有投入子模块电压之和。离散化后就能预测下一拍的环流值,环流的参考值取i_dc/3,也就是三相均分直流电流。
2.3 代价函数三项权重怎么定
典型代价函数包含三项:
J = λ1 · (电流预测误差平方和) + λ2 · (环流预测误差平方和) + λ3 · (子模块电容电压偏差平方和)权系数调整是复现里最玄学的部分。我的建议是先把电流项单独调通,再依次加入环流项和电压项。λ2从0.1起步,λ3从0.05起步,逐步加大直到对应波形满足要求。不要上来就三个权重一起调,出了问题根本不知道是哪一项干扰的。
3. Simulink里从主电路到控制器的落地过程
3.1 半桥子模块封装与桥臂搭建
主电路我建议用Simscape Electrical里的Specialized Power Systems库。不要图省事用平均模型直接跑到底,因为最终复现结果需要看到IGBT开关动作和电容电压的真实纹波。当然,调试阶段可以先用平均模型验证控制逻辑,最后再换成开关模型跑结果。
半桥子模块用两个IGBT加反并联二极管,中间并联一个电容。推荐把四个半桥子模块建在一个子系统里,方便复制。建好一个子模块后,注意方向:电容正极接上桥臂电流流入端,电容负极接下一子模块的正极,串联方向必须一致,否则排序算法下的电压均衡逻辑会乱掉。
每个桥臂结构是:N个子模块串联,再接一个桥臂电感L_arm。六条桥臂在顶层用总线连接,上桥臂的输出端接入直流正极,下桥臂的输出端接入直流负极,上下桥臂的交汇点就是交流输出端。
搭建顺序上,先把三相交流电源、网侧电感、六条桥臂、直流负载全部接好,再逐一检查各相上、下桥臂电流测量方向。方向接反会导致排序算法给电容反向充电,波形会非常难看。
3.2 测量与信号调理
控制器需要这些测量量:
- 三相交流电压u_a、u_b、u_c,用于PLL锁相和坐标变换。
- 三相交流电流i_a、i_b、i_c。
- 每个桥臂的电流i_p、i_n,用于计算环流i_cir。
- 每个子模块的电容电压v_c。
- 直流侧电压V_dc和直流电流i_dc。
子模块封装里要额外引出一个电压测量端口,把这个N维向量直接输出到控制器。很多人嫌线多,只用平均值,结果排序算法根本没法对各子模块做电压均衡——这是排序算法实现的硬前提。
测量信号不需要额外滤波。FCS-MPC要求的是一拍之内的实时量,滤波带来的相位延迟反而会破坏预测准确性。
3.3 控制器里的数据流与坐标变换
控制器内部按这个顺序处理:
- PLL锁定三相电源相位θ。
- 对交流电流做Park变换,得到i_d、i_q。
- 由直流电压外环PI算出id_ref,iq_ref设0(单位功率因数整流)。
- 把当前状态量送入FCS-MPC函数,遍历候选投入数,计算J,选出最优的n_p、n_n。
- 排序算法根据投入数和桥臂电流方向生成各子模块IGBT驱动信号。
- 驱动信号延迟一个控制周期输出,模拟数字控制器的实际执行延迟。
第6步很容易漏掉。理论上FCS-MPC假设当前拍的开关状态能立即作用于系统,但真实控制器一拍之后才切换。复现论文时必须在输出路径上加一个Unit Delay,否则仿真结果会偏乐观,现场控制器却跑不出这个指标。
4. 预测控制器内部实现的关键细节
4.1 枚举策略:全集遍历还是逐臂独立
N小于6时,六个桥臂的全集遍历每秒能跑几百拍,没问题。N再大就要用逐桥臂独立评估,否则仿真速度会拖到无法忍受。
两种方案的算力对比可以直观看出问题:
| 控制策略 | 单拍枚举空间 | 实时可行性 |
|---|---|---|
| 纯开关级FCS-MPC | (2^N)^6 | N=4时已经天文数字 |
| 投入数全集遍历 | (N+1)^6 | 小N仿真可行 |
| 逐桥臂独立评估 | 6×(N+1) | 可用于现场级控制器 |
我的仿真模型里N取6,用的全集遍历加轻微剪枝:先粗算每相的期望投入数,只在期望值±2的窗口内搜索,把11.8万次砍到几千次。仿真时间和结果质量能兼顾得很好。
4.2 排序算法与开关信号生成
排序算法是“混合”架构里负责微观均衡的部分,逻辑不复杂:
- 如果桥臂电流方向是给电容充电,投入子模块里电容电压最低的n个。
- 如果桥臂电流方向是给电容放电,投入子模块里电容电压最高的n个。
实际执行时,如果每个控制周期都把子模块排序重排一次,IGBT开关频率会飙得很高。我通常加一个滞环:只有当前桥臂最大电容电压偏差超过设定阈值(比如额定电压的3%)才触发重新排序,否则沿用上一拍的开关组合。这样开关频率能降下来,电容电压均衡度也不会差。
4.3 启动与预充电处理
这部分是复现时最容易炸的地方。
直接启动时电容电压为零,直流电压外环瞬间输出很大的电流指令,FCS-MPC为了压低电流误差会强制投切大量子模块,结果就是仿真发散或电流爆表。比较稳的做法是:
- 给所有子模块电容设置初始电压,取V_dc_ref/N,让系统起点接近稳态。
- 直流负载侧并联一个小的预充电电阻,启动后再旁路。
- 直流电压参考值用斜坡从0斜坡到设定值,避免阶跃。
- id_ref输出加限幅,比如限制在额定电流的1.2倍。
预充电阶段可以把MPC输出封锁几个周期,让二极管先自然整流完成初始充电。这条路径我在仿真里验证过,对收敛非常有帮助。
5. 参数设定、调试路径与常见坑位
5.1 推荐参数与仿真步长设置
按桌面仿真级别的规格,这套参数可以直接用:
| 参数 | 数值 |
|---|---|
| 交流线电压有效值 | 380V / 50Hz |
| 网侧电感L_s | 5mH |
| 桥臂电感L_arm | 10mH |
| 子模块数N | 6 |
| 子模块电容C | 2mF |
| 子模块额定电压 | 150V |
| 直流电压参考 | 900V |
| 控制周期T_s | 50μs |
| 仿真求解器 | 定步长ode3,步长5μs |
| Powergui模式 | Discrete,采样率与仿真步长一致 |
MATLAB Function里要严格区分控制周期T_s和仿真步长。仿真步长取5μs,控制周期50μs,意思是每10个仿真步执行一次MPC计算。Simulink里的Rate Transition模块或者Sample Time设置能实现这个节奏,直接让MATLAB Function按连续步长跑MPC的话计算量太大。
5.2 从易到难的调试顺序
直接一步到位接上FCS-MPC,是新手最常见的错误。我自己复现时是按四条线往下推的:
第一条线,先把主电路开环跑通。用固定投入数让每个桥臂恒投入3个子模块(N=6),此时不接MPC、不接排序,观察直流电压能否建立、交流电流波形是否正常。这一步能验证所有接线和测量方向正确。
第二条线,接上排序算法。固定投入数不变,只加电容电压排序。此时子模块电压应该从初始电压逐渐趋于均衡,交流电流谐波明显下降。排序算法逻辑对不对,看电容电压波形就能判断。
第三条线,接上直流电压外环PI。电流内环暂时用最简单的PI或滞环跟踪,维持直流电压稳定。
第四条线,才把FCS-MPC接进来。先只开电流项,再加环流项,最后调节电压项权重。每加一项都要记录波形变化,方便回溯。
5.3 常见报错与处理建议
仿真过程中最常遇到的几个问题,我列成表格方便对照排查:
| 现象 | 常见原因 | 处理 |
|---|---|---|
| 启动立刻发散 | 电容无初始电压,电流指令过大 | 设电容初值、斜坡给定、限幅 |
| 电流正弦但直流电压上不去 | 排序算法方向反了 | 检查桥臂电流符号与排序逻辑 |
| 电容电压发散 | 排序触发过于频繁或方向错误 | 加滞环,核对充放电方向 |
| 高频振荡 | 权系数过大或一拍延迟丢失 | 降低λ2、λ3,补Unit Delay |
| MMC有规则谐波 | Powergui离散步长过大 | 仿真步长降到1μs~5μs |
| 仿真速度极慢 | 开关模型加全集遍历 | 减小枚举窗口,或改平均模型调试 |
这里特别强调一下“开关频率不固定”的问题。FCS-MPC没有固定载波,IGBT的开关动作由代价函数决定,实测下来不同工况开关频率可能差出两三倍。散热设计、损耗评估都很难做,这也是“混合”架构里排序滞环设计更受重视的原因——它比代价函数更能直接影响开关频率上限。
6. 复现结果怎么算成功:判据与个人实操体会
6.1 波形和指标要到什么程度
论文复现的最终目标不是把图贴得一模一样,而是复现控制逻辑的性能量级。我给自己定的验收标准如下:
- 直流电压稳态误差小于1%,纹波小于1%。
- 交流电流THD小于3%,波形正弦。
- 子模块电容电压最大偏差不超过平均值的5%。
- 环流中的二倍频分量幅值相比不加抑制时下降30%以上。
- 直流负载从半载突跳到满载,0.1秒内直流电压恢复稳态。
这几项全部达标,基本可以认为FCS-MPC的预测模型、代价函数、排序算法三者配合正确。注意SCI论文里很多波形是稳态截图,动态响应过程往往被裁掉了,复现时多关注动态段,那里才能看出整条控制链路是否真正收敛。
6.2 我在复现过程中踩过的几个坑
第一个坑是预充电。最初我照着论文给的“电容电压初值”抄进去,但直流侧负载没有预充电电阻,仿真前几个周期PI外环饱和输出,MPC直接发散。后来改成二极管整流预充电加斜坡给定,问题才解决。
第二个坑是权重系数扫描。我一度试图用公式直接算出λ2、λ3的最优值,浪费了大量时间。实际上这类非线性预测控制的代价函数权重几乎都要靠仿真扫描确定。我自己的做法是固定电流项权重建1,环流项从0.1、1、10三档扫,电压项从0.05、0.2、0.8三档扫,跑完一轮基本就能锁定量级,再微调。
第三个坑是排序触发频率。最初排序算法每个控制周期都重新排列,仿真结果里电容电压均衡得漂亮,但IGBT动作频率高得离谱,损耗和散热根本没法接受。加上滞环之后,开关频率降了一大截,电容电压波动只增加了一点点,这个折中在工程上非常值得。
最后一个建议是:如果手头有详细模型和平均模型两个版本,平时调试控制器用平均模型,最终出图用详细模型。平均模型跑一次只要几十秒,详细模型往往要十几分钟,先粗后细能节省大量重复劳动。等控制逻辑完全稳定下来,再让详细模型跑最后一轮结果,这样既保证了复现可靠性,又不至于每天干等仿真。
这套路径跑通之后,MMC整流器的FCS-MPC控制架构基本就立住了。后续想扩展的方向很多——换到三相不平衡电网、加入冗余子模块容错、甚至把MATLAB Function里的控制逻辑用Embedded Coder生成C代码做硬件在环,都是顺着这个框架往下走的事。不过那部分就留给下一次折腾了。