刚把这个模型跑通的时候,我其实松了一口气。这个标题对应的东西——基于混合有限集模型预测控制(FCS-MPC)的模块化多电平换流器(MMC)整流电路Simulink仿真——是电力电子方向很典型的SCI复现工作。控制对象是MMC,控制算法是FCS-MPC,应用场景是整流,平台是Simulink。单拆开每一项都不算冷门,但合在一起就有大量细节需要注意:子模块电容电压怎么平衡、环流怎么抑制、代价函数里几个目标怎么配权重、模型用等效建模还是开关器件建模、启动时怎么防电流冲击。这篇文章我会按实际复现的顺序,把控制原理、模型搭建、代码实现和调试经验全部过一遍,适合正准备复现同类论文、或者想把FCS-MPC搬到MMC上的读者参考。
1. 为什么MMC整流电路需要FCS-MPC:先理解控制难点
1.1 MMC拓扑与整流工况下的能量流动
先看被控对象。MMC三相拓扑由三个相单元构成,每个相单元分上下两个桥臂,每个桥臂由N个半桥子模块串联,再串一个桥臂电感。半桥子模块内部是两个IGBT加反并联二极管,出口并联一个直流电容。通过控制两个IGBT的开关组合,子模块要么被旁路(输出电压0),要么被投入(输出电压等于电容电压)。直流母线电压由所有投入子模块的电容电压共同支撑,所以稳态下每个电容电压基本被钳在 Vdc/N 附近。
整流工况的关键在于能量流向:交流侧三相电源通过桥臂电感向MMC馈入功率,MMC再把功率送到直流侧负载。控制目标有两个层面,一是把直流母线电压控在给定值,二是让交流侧电流保持正弦、功率因数可控。这比纯逆变要麻烦,因为直流电压不能直接给定,必须通过闭环从交流侧“吸”能量来维持,控制器的参考值会随负载和电网波动不断变化。
1.2 三大控制难题:电容电压平衡、环流、电流波形
搭好主电路之后,真正难的是控制。我大概梳理一下MMC在整流工况下绕不开的三个问题。
第一个是子模块电容电压平衡。MMC子模块电容没有硬件均压回路,同一时刻同一桥臂内哪些电容投入,完全由控制策略决定。如果一直让同一个电容投入,它的电压会越充越高或者越放越低,最后系统崩掉。所以算法必须在每个控制周期重新分配投切对象,让所有电容电压向同一个参考值收敛。
第二个是环流。上下桥臂电流可以分解为两部分:一部分是交流侧电流在桥臂间的分配,另一部分是同相上下桥臂之间循环流动的电流,也就是环流。环流分量主要是2倍工频,它不参与交流侧和直流侧的能量交换,但会在桥臂电感上产生压降、增加损耗,还会让电容电压纹波变大。整流工况下,环流抑制和内环电流控制同样重要。
第三个是交流电流波形质量。MMC本质上是一个多电平PWM变换器,整流时输入电流谐波取决于调制策略和电平数。N越大,电平越多,电流越接近正弦,但控制自由度也越多。用传统PI加调制器时,电流环参数、载波相位、调制方式都要逐一调;换到预测控制框架下,这些问题会被统一成一个优化问题,反而清爽很多。
1.3 FCS-MPC为什么适合MMC
传统线性控制的做法是:外环PI稳住直流电压,内环PI控制交流电流,再用载波移相PWM或最近电平逼近(NLM)把电压参考变成开关信号。这套方案很成熟,但参数多、动态响应受限,而且每个控制目标都要单独设计一条通路。FCS-MPC的思路完全不同:MMC的开关状态本来就是有限个离散集合,那干脆枚举这些状态,用系统模型预测每种状态下一拍的系统行为,再通过一个代价函数直接选出最优开关动作。
对MMC来说,FCS-MPC特别适合,因为它的多个控制目标天然能写进同一个代价函数,包括电流跟踪误差、电容电压偏差、环流抑制、开关频率惩罚。不需要调制器,不需要逐环整定PI参数,控制器的输出直接就是子模块开关信号。代价自然也有:在线计算量大,对模型参数比较敏感,每个采样周期都要做一轮预测寻优。但在Simulink里复现,重点就是把计算量和控制效果平衡好。
2. 混合FCS-MPC的控制原理与代价函数设计
2.1 “混合”到底混合了什么
“混合有限集模型预测控制”这个说法在不同论文里含义不完全一样,我复现时把它拆解成三个层次。
第一层是模型混合。MMC本身是连续时间系统,开关事件却是离散的,FCS-MPC要把连续电流动态和离散开关组合统一在一个预测框架里,用离散化模型逼近连续系统行为。
第二层是控制目标混合。电流跟踪、电容电压平衡、环流抑制、开关频率限制,这四个目标在传统控制里是分开处理的,在FCS-MPC里全部加权进同一个代价函数J。
第三层是执行策略的混合。直接枚举所有子模块组合不现实,所以实际实现时通常分两步:先用FCS-MPC选出每个桥臂应该投入多少个子模块(或者等效输出电平),再用底层的电容电压排序算法决定具体投入哪几个电容。也就是说,预测控制负责宏观寻优,排序算法负责微观均衡。
如果你的源论文里对“hybrid FCS-MPC”有专门定义,以论文为准;但从复现角度,上面这三层理解已经足够搭出可用模型。
2.2 离散化建模:交流侧电流与桥臂环流的预测方程
预测控制的基础是模型,必须先写出离散化的状态方程。对交流侧第 j 相(j = a, b, c),电压方程可以写成:
L·di_j/dt = v_sj − v_cj − R·i_j
其中 v_sj 是电网电压,v_cj 是MMC交流侧的等效输出电压,L 是交流侧电感(包含回路总电感),R 是等效电阻。
采用前向欧拉离散化,采样周期为 Ts,得到预测方程:
i_j(k+1) = i_j(k) + (Ts/L) · (v_sj(k) − v_cj(k) − R·i_j(k))
桥臂电流则需要拆开理解。设上桥臂电流为 i_pj,下桥臂电流为 i_nj,交流侧电流 i_j 和环流 i_cir_j 的关系是:
i_pj = i_j/2 + i_cir_j i_nj = i_j/2 − i_cir_j
环流的本质是上下桥臂之间的循环分量,受上下桥臂电压之和影响。为了在代价函数里加环流抑制项,需要预测下一拍的环流,通常用一阶模型:
i_cir_j(k+1) = i_cir_j(k) + (Ts/L_arm) · (v_cir_j(k) − 2·i_cir_j(k)·R_arm)
这里的 L_arm、R_arm 是桥臂电感和等效电阻,v_cir_j 是桥臂差模电压分量。实际实现时,也可以简化为直接把环流预测偏差作为代价项。
电容电压的动态也要离散化。对某个子模块电容,其电压变化满足:
C·dv_c/dt = i_sm(t) · s(t)
离散化后,如果该子模块在下一拍投入(s = 1),则:
v_c(k+1) = v_c(k) + (Ts/C) · i_sm(k)
这里 i_sm 是流经该子模块的桥臂电流。投入时电容被充电或放电,取决于电流方向;旁路时电容电压保持不变。这一步是后面做电容电压排序的基础。
2.3 代价函数:多目标如何量化比较
FCS-MPC的核心是代价函数。我用的代价函数形式可以写成:
J = λ1·J_i + λ2·J_cir + λ3·J_vc + λ4·J_sw
各项含义如下:
- J_i 是三相交流电流跟踪误差的平方和。整流器需要一个电流参考,通常由直流电压外环生成,J_i 惩罚预测电流与参考值的偏差。
- J_cir 是三相环流预测偏差的平方和,用于抑制2倍频环流。参考环流一般取 0 或直流分量。
- J_vc 是所有子模块电容电压偏差的总惩罚,让每个电容电压往参考值 Vdc/N 靠拢。实际中可以只统计当前桥臂候选投入子模块的电压偏差,减少计算量。
- J_sw 是开关切换惩罚,统计候选开关状态与上一时刻状态的差异数量。它用来限制开关频率,防止排序抖动导致器件频繁动作。
由于各项量纲不同,电流误差单位是安培,电容电压单位是伏特,直接相加没有意义。我习惯的做法是先做归一化:电流项除以基准电流 I_base,电压项除以基准电压 V_base,开关项按动作次数直接计数。归一化之后,λ1 通常取 1,其他权重再根据仿真效果调整。
2.4 降维搜索:避免组合爆炸的实用策略
MMC的开关组合数量巨大。假设 N=10,每相上下桥臂各10个子模块,不考虑具体哪个电容投入,只考虑每个桥臂投入的子模块数量,6个桥臂的变化范围都是 0~10,总组合数就是 11^6,约177万种。每个组合都要算一次模型预测,Simulink里根本跑不动。
所以必须降维。最常用的是利用直流母线电压约束:忽略环流影响时,上下桥臂投入数之和应该等于 N,即:
n_pj + n_nj = N
也就是说,只要决定某一相上桥臂投入数量,下桥臂数量就被确定。这样每相只剩一个自由度,三相共有 (N+1)^3 = 11^3 = 1331 种组合,虽然比177万好很多,但对实时仿真来说还是偏大。
实际工程里还常做一步邻域限制:不搜索全范围,只看上一时刻投入数附近的变化。比如设变化范围为 ±1 或 ±2,那么每个桥臂只有3~5个候选值,三相组合数降到 27 或 125 种。这个量级在Matlab Function里做枚举就很轻松了。
这就是我把标题里的“混合”落到实现层面的关键:FCS-MPC负责在上层做有限状态寻优,下层排序算法负责具体子模块分配,两者结合才能在Simulink里跑出满意的速度和效果。
3. Simulink仿真模型总体架构与子模块建模
3.1 顶层信号链路:从三相电源到直流负载
我的Simulink模型顶层结构分三块。前向主电路:三相交流电源 → 交流电感 → MMC三相六桥臂 → 直流负载电阻。反向控制链路:从主电路测到三相电压、三相电流、各子模块电容电压和直流母线电压,进控制器,输出开关信号,再回到主电路。
控制链路的具体顺序是:三相电压先过PLL锁相,得到电网角度;三相电流和电压做Park变换到dq坐标系;直流母线电压给定值与实测值做差,经过PI调节器得到 d 轴电流参考(对应有功),q 轴电流参考设0(对应单位功率因数);dq参考再反变换到abc三相,作为FCS-MPC的电流参考;FCS-MPC求出各相上下桥臂投入数量后,交给电容电压排序模块,产生每一路子模块的开关信号;开关信号驱动主电路的等效受控源,完成闭环。
这一套链路下来,逻辑很清晰:直流电压外环决定交流侧要吸多少有功,FCS-MPC内环保证吸进来的电流波形好、电容电压均衡、环流小。
3.2 子模块两种建模方式:忠实建模与等效建模的取舍
MMC的Simulink建模方式我试过两种,差别很大。
第一种是用Simscape Electrical搭建真实的半桥子模块,每个子模块用两个IGBT、反并联二极管和电容组成。这种方式最能反映开关过程的电磁暂态,但问题也明显:N越大,仿真越慢。比如 N=10 时至少要60个IGBT模块,加上非线性器件和极小步长,仿真速度会慢到令人抓狂,控制算法调试一次要等很久。
第二种是等效受控源模型:桥臂不再需要真实的开关器件,而是通过受控电压源输出桥臂电压;每个子模块电容电压用积分器独立计算,投入信号决定电容是否接入充放电回路。对FCS-MPC这种以控制算法为核心的研究,第二种方式完全够用,而且速度快一个量级。
我最终用的是等效模型:每个桥臂根据投入子模块数量和它们的电容电压,计算桥臂输出电压的瞬时值,用受控电压源替代;同时根据桥臂电流和开关信号,更新每个电容的电压。截图对比时可能没有真实IGBT那么精细,但控制效果、波形趋势和论文实验部分对得上。
3.3 整流工况的级联外环:直流电压闭环生成电流参考
整流器不能像逆变器那样直接把电流参考给成固定值,必须先稳住直流母线电压。我这里用一个经典的单PI外环:
e_v = Vdc_ref − Vdc_meas Id_ref = Kp·e_v + Ki·∫e_v·dt
Id_ref 是有功电流基准,限制在安全范围内。Iq_ref 设0。然后通过反Park变换得到 abc 三相电流参考:
i_abc_ref = T^{-1}(θ) · [Id_ref, Iq_ref]^T
这组参考会进FCS-MPC的代价函数。PI参数可以先按工程经验整定,比如 Kp 取 0.5~2,Ki 取 20~100,再根据动态波形微调。实际复现论文时,注意看论文里的外环结构,有的是直接控功率,有的是两级闭环,但思路一致。
4. 核心控制器实现:Matlab Function代码逐段拆解
4.1 控制器的输入输出设计
控制器我封装成一个单独的Matlab Function模块,输入端口包括:
- Vdc_ref:直流电压参考
- Vdc:直流电压实测
- vs_abc:三相电网电压
- i_abc:三相交流电流实测
- vc_matrix:6×N矩阵,存储6个桥臂所有子模块电容电压
- i_arm:6×1桥臂电流
- n_prev:上一时刻各桥臂投入数(用于邻域搜索)
- theta:PLL输出的电网角度
输出端口是6×N的开关矩阵 Sw_matrix,每位表示对应子模块是否投入。
这个结构有一个好处:所有控制逻辑集中在一个模块里,后续调权重、改预测模型都很方便。
4.2 外环参考电流生成与坐标变换
外环PI可以用Simulink自带PID Controller模块,也可以直接在Matlab Function里写离散PI。我习惯写在同一个函数里,避免模型里拖一堆线和模块。
离散PI实现很简单,每个周期执行:
err = Vdc_ref - Vdc; integral = integral + Ki * err * Ts; id_ref = Kp * err + integral;
id_ref 再限幅,防止过流。然后根据 theta 做dq到abc的反变换:
ia_ref = id_ref * cos(theta) - iq_ref * sin(theta); ib_ref = id_ref * cos(theta - 2pi/3) - iq_ref * sin(theta - 2pi/3); ic_ref = id_ref * cos(theta + 2pi/3) - iq_ref * sin(theta + 2pi/3);
注意Simulink自带的abc_to_dq0模块通常基于cos或sin基准,相位对齐要和PLL一致,否则电流参考相位偏了,整流器会跑成功功率因数为负,白调半天。
4.3 预测与代价函数计算:核心循环
这一部分是整个模型的重头。我按邻域限制实现,伪代码如下:
function [n_opt, J_min] = fcs_mpc_search(prev_n, vs, i_meas, i_ref, ...) np_candidates = max(0, prev_n - d) : min(N, prev_n + d); J_min = inf; for na = np_candidates for nb = np_candidates for nc = np_candidates % 上桥臂投入数:na, nb, nc % 下桥臂投入数 = N - na, N - nb, N - nc nn_a = N - na; nn_b = N - nb; nn_c = N - nc; % 根据当前开关状态计算三相等效输出电压 v_conv_abc v_conv_a = calc_conv_voltage(na, nn_a, vc_matrix, 1); % ... 同理 b、c 相 % 预测下一拍交流电流 i_pred_a = i_meas(1) + (Ts/L) * (vs(1) - v_conv_a - R*i_meas(1)); % ... 预测 b、c 相 % 预测环流 icir_pred_a = i_arm(1) - i_arm(2); % 根据桥臂电流估算 % ... 预测 b、c 相 % 电容电压偏差统计(可简化为候选投入子模块的平均偏差) vc_err_a = mean(vc_matrix(1, 1:na)) - Vdc/N; % ... b、c 相同理 % 开关动作次数 sw_change = sum(abs([na,nb,nc,N-na,N-nb,N-nc] - prev_n)); % 计算代价函数 J = lambda1 * sum((i_ref - i_pred).^2) ... + lambda2 * sum((icir_ref - icir_pred).^2) ... + lambda3 * sum(vc_err.^2) ... + lambda4 * sw_change; % 保留最小代价对应的投入数 if J < J_min J_min = J; n_opt = [na, nb, nc]; end end end end end
这段代码的关键是每次都算完整的预测值,而不是拍脑袋选组合。注意求和里的 i_ref 是三相参考电流,i_pred 是三相预测电流;icir_ref 通常取0;vc_err 是三相桥臂电容电压平均偏差的平方和。
4.4 电容电压排序:让最需要充电的电容先充
FCS-MPC选出了每个桥臂的投入数量,但具体投入哪几个电容,要靠排序模块完成。排序的原则一句话:电容电压低的优先充电,电容电压高的优先放电。
对某个桥臂,如果桥臂电流方向为正(给电容充电),就把当前桥臂的N个电容电压从小到大排序,投入电压最低的那 n 个;如果电流方向为负(电容放电),就投入电压最高的那 n 个。这样每个周期都在充放电方向上做动态轮换,所有电容电压会逐渐收敛到参考值附近。
排序模块在Matlab Function里实现,核心伪代码:
function Sw = cap_balancing(vc_arm, i_arm, n_ref, Sw_old) N = length(vc_arm); [~, idx] = sort(vc_arm); % 升序,idx(1)电压最低 Sw = zeros(1, N); if i_arm > 0 for k = 1:n_ref Sw(idx(k)) = 1; % 充电投入电压最低的k个 end else for k = 1:n_ref Sw(idx(N - k + 1)) = 1; % 放电投入电压最高的k个 end end end
排序之后还可以加一个限频逻辑:如果Si中某一路模块开关状态与上一时刻比变化次数太多,就只保留变化量最小的组合。这个优化能显著降低开关频率,后面避坑部分我会细说。
5. 参数选型与调参经验:权重系数、步长和子模块数的联动
5.1 一套可用的基准参数
复现时不可能上来就仿真,得先有一组合理的基准参数。我以 N=10(11电平)为例列一组能跑的参数:
| 参数 | 数值 | 说明 |
|---|---|---|
| 交流线电压有效值 | 380 V | 三相50Hz |
| 直流母线电压参考 | 700 V | 整流器输出目标 |
| 子模块数/桥臂 | 10 | 每桥臂N=10 |
| 子模块电容参考电压 | 70 V | Vdc/N |
| 子模块电容 | 10 mF | 电容越大电压纹波越小,但充放电惯性大 |
| 桥臂电感 | 5 mH | 抑制环流 |
| 交流侧电感 | 5 mH | 滤波+电流控制 |
| 负载电阻 | 20 Ω | 动态试验时可改为阶跃 |
| 采样周期 Ts | 50 μs | FCS-MPC预测步长 |
这些都是入门级参数,能让模型先跑起来。真正复现论文时,必须换成论文里的参数表,但建模思路不用变。
5.2 权重系数怎么调才不糊
权重系数是调参里最磨人的部分。我的策略是“从单一到多目标”逐步加权重:
- 先把 λ2、λ3、λ4 全部设0,只保留 λ1=1 的电流项,保证系统能稳定跟踪电流参考。
- 加上环流抑制权重 λ2。从0.1开始试,观察桥臂电流里的2倍频分量是否下降。如果出现电流跟踪变差,就减小λ2。
- 加上电容电压均衡权重 λ3。从0.5开始试,观察电压是否收敛到70V附近。太大会让电流波形变差,太小电容电压散开。
- 最后加开关惩罚 λ4,主要目的是限制开关频率。这个值通常很小,比如0.01~0.1,防止过度限制导致控制效果劣化。
调参时一定要录波形对比,别光看最终结果。我一般把交流电流THD、电容电压标准差、桥臂电流峰值三个指标同时看,找一个综合最优值。
5.3 预测步长与计算延迟补偿
Ts选择直接影响系统性能。Ts太大,离散化误差明显,预测模型失真,电流纹波变大;Ts太小,每个周期能用于计算的实时时间极短,仿真时间也变长。对MMC来说,50μs到100μs是比较常见的范围,对应20kHz到10kHz的控制频率,足够体现FCS-MPC的动态优势。
还有一个很容易忽略的细节:控制器计算需要时间,实际系统在k时刻算出来的最优开关状态,只能在k+1时刻生效。如果预测模型不考虑这一拍延迟,会导致控制效果变差甚至震荡。正确做法是做一步延迟补偿:
在k时刻读入当前状态x(k),用模型先预测x(k+1),然后以x(k+1)为起点枚举候选组合,选出的结果作为k+1到k+2时刻的开关状态。
这样相当于把控制器的动作延后一拍,但预测模型与实际系统对齐了。仿真里实现也很简单,在Matlab Function里把预测表达式多推一步即可。
6. 仿真结果怎么看:波形验证与动态响应
6.1 稳态下各关键波形解读
模型跑通后,先看稳态波形。我一般会让仿真跑0.3s以上,等到电容电压、电流都收敛后再截波形。
最关键的是交流侧三相电流。正常稳态下应该是对称正弦,幅值由负载功率决定,相位跟随电压(单位功率因数时电流和电压同相或接近同相)。如果电流畸变明显,先检查是不是权重没配好,再看是不是预测模型里的参数和主电路参数不一致。
第二个看直流母线电压。整流器输出侧电压应稳定在700V附近,纹波控制在很小范围内。纹波大通常说明电容电压均衡没做好,或者外环PI太慢跟不上负载变化。
第三个看子模块电容电压。把所有子模块电压画在同一个Scope里,你会发现它们慢慢从初始值汇聚到70V附近,形成一条“发散的线簇然后收拢”的过程。如果有些子模块明显偏离,说明排序算法有问题或者预测模型里的电容电压更新不对。
第四个看桥臂电流。正常桥臂电流应该同时包含交流基波分量和直流分量,如果环流抑制效果不好,桥臂电流会出现明显的2倍频波动。
6.2 动态响应:直流电压阶跃与负载突加
稳态只是第一步,论文里通常还要展示动态响应。我做的典型试验是在0.4s时把负载电阻从20Ω突降到10Ω,或者直接把直流电压参考从700V阶跃到750V。
观察重点有两个:直流电压的恢复速度和超调量,以及交流电流的调整过程。FCS-MPC的优势体现在这里——几乎一拍就能响应电流参考的变化,不像传统调制策略那样要等调制器“慢慢跟进”。实测下来,直流电压在几步之内就能回到参考值,过渡过程干净利落。
如果你复现的论文里有类似的动态波形,用相同试验条件对比,能很快判断自己的模型是否复现到位。
6.3 FFT谐波分析:用数据说话
Scope里看波形只是定性。论文里要写THD,必须做FFT分析。Simulink里可以把电流信号通过To Workspace导出到MATLAB工作区,再用脚本分析。核心步骤:
- 仿真结束后,在工作区得到电流时间序列 i_a(t) 和时间向量 t。
- 截取稳态段数据,比如 0.3s~0.5s。
- 用 fft() 计算频谱,提取基波幅值和谐波幅值,求THD。
我写过一个简化脚本,核心行如下:
data = i_a(mask); % mask是稳态区间索引 fs = 1/Ts; Nfft = length(data); spectrum = abs(fft(data, Nfft)) / Nfft * 2; freqs = (0:Nfft-1) * fs / Nfft; fund_idx = find(freqs > 45 & freqs < 55); thd = sqrt(sum(spectrum(2:end).^2)) / spectrum(fund_idx) * 100;
N=10的模型,权重调好后THD做到3%以内很正常。如果THD偏高,大概率是权重λ1太小,或者邻域搜索的d值限制太死导致可选组合不足。
7. 复现避坑实录:我反复修改的几个问题
7.1 代数环:仿真报错还是结果诡异
用等效受控源建模时,最容易遇到的问题是代数环。现象是模型仿真报出“Algebraic loop detected”,或者仿真特别慢、结果抖动。
原因是受控电压源的输出信号由控制器决定,而控制器的输入又来源于主电路测量,中间如果有一条没有任何离散延时的直接通路,Simulink就会在同一个仿真步长里来回迭代求解,形成代数环。
我的解决方法是给控制器输出路径加一个Unit Delay模块,或者直接在Matlab Function里把输出信号滞后一拍。这不仅是解决代数环,也是我们在延迟补偿部分说的“控制器固有计算延迟”——两件事天然能合并处理。加了延迟后,模型的物理意义也更接近真实系统。
7.2 电容排序频繁抖动:开关频率高到离谱
第一次跑通排序算法时,我注意到子模块的开关动作极其频繁,几乎每个采样周期都有大量子模块在投切。虽然波形看着还行,但开关频率远超器件承受范围,论文里也没法交代。
问题出在排序算法“太忠诚”:只要投入数变化一个,或者电压排序顺序变化,就会立刻切换一大批子模块。改进方法是在排序模块里加开关次数限制,比如每个采样周期最多允许改变M个子模块状态,超过则保持前一拍状态。实现时可以在Matlab Function里加一个计数器,统计Sw和Sw_old不同的位数:
sw_diff = sum(Sw ~= Sw_old); if sw_diff > M Sw = Sw_old; % 限频:保持原状态 end
这个M一般取1~2,效果立竿见影,开关频率明显下降,波形也不会变差多少。
7.3 启动冲击电流:电容初始电压必须处理
另一个大坑是启动阶段。如果电容初始电压设成0,仿真开始瞬间直流电压参考是700V,交流电源瞬间给电容充电,电流冲击极大,轻则仿真发散,重则让PI输出饱和很久才恢复。
我的处理办法有两个,组合使用效果最好:一是把子模块电容的初始电压直接设成 Vdc_ref/N,也就是70V;二是让交流电源从0幅值斜坡启动,比如前0.05s内电压幅值从0线性升到额定值。这样系统一开始就处于一个接近稳态的工作点,启动过程平稳,后续控制能快速进入正常状态。
7.4 仿真速度慢:等效模型还不够,求解器也要选对
即使用了等效模型,如果还是跑不快,问题多半出在求解器配置上。我遇到的情况是模型里有大量连续积分器,用的是变步长求解器,导致每个开关动作点附近步长缩得非常小,整体仿真时间被拉长。
解决办法是把解算器改成固定步长离散求解器,比如ode3或者离散求解器,步长直接设为Ts(50μs)。因为FCS-MPC本身就是离散控制系统,控制周期固定,主电路的等效模型也不是真正的电磁暂态,连续/离散混合求解反而加慢速度。改成固定步长后,仿真速度能提升好几倍,而且控制波形几乎不受影响。
还有一个小建议:不要挂太多Scope和To Workspace在观测信号上,每个示波器都在拖慢仿真。我一般只保留必要波形,需要分析的数据单独用To Workspace导出,仿真结束在MATLAB里统一画图。
最后再分享一点体会。Simulink里复现FCS-MPC控制MMC,最大的工作量其实不在算法本身,而在“让模型跑起来、跑得快、结果可信”这一连串工程细节上。这个课题特别适合想深入理解预测控制的人去啃,因为我做完这一遍之后,对MMC的建模、代价函数设计、离散化误差、开关频率限制这些东西都有了非常具体的感觉,不只是停留在论文公式层面。