第二节 PMSM矢量控制建模:Clark变换与Park变换、电流环PI控制器、SVPWM调制
好,咱们直接进入正题。这一节要干的事,说白了就是把电机控制里最核心的三个模块给搭出来。Clark变换、Park变换、电流环PI、还有SVPWM。这几个东西你要是能在Simulink里玩明白,那离自动代码生成就不远了。
我个人习惯,建模之前先想清楚物理意义。别一上来就拖模块,那样容易翻车。
2.1 Clark变换与Park变换建模
先说说坐标变换。为什么要变?因为三相交流电那玩意儿控制起来太麻烦。你想想看,三个电流互相耦合,你调一个另外两个也跟着动。所以我们要把它转到两相旋转坐标系下,让控制变得像调直流电机一样简单。
2.1.1 Clark变换(3s/2s)
Clark变换就是把三相静止坐标系(ABC)转到两相静止坐标系(αβ)。公式很简单:
Iα = Ia
Iβ = (Ia + 2*Ib) / √3
嗯,这里要注意,我用的等幅值变换。有些教材用等功率变换,系数不一样。我个人习惯用等幅值,因为后面算SVPWM时方便。
在Simulink里建模,我建议直接用Fcn模块或者MATLAB Function。别用一堆加减乘除搭,看着乱。
核心要点:
- 输入:三相电流Ia, Ib, Ic(Ic = -Ia - Ib,可以省一路)
- 输出:Iα, Iβ
- 系数:等幅值变换,α轴与A轴对齐
我的小技巧: 我在项目中遇到过,有些工程师把Ic也算进去,其实没必要。三相平衡系统下,Ic = -(Ia+Ib),省一个传感器还能省钱。
2.1.2 Park变换(2s/2r)
Park变换是把αβ转到dq旋转坐标系。这里需要电角度θ。公式:
Id = Iα*cosθ + Iβ*sinθ
Iq = -Iα*sinθ + Iβ*cosθ
为什么要有这个变换?因为转到dq坐标系后,Id控制励磁,Iq控制转矩,两者解耦了。你想想看,这不就跟直流电机一样了吗?
建模时,θ从哪里来?通常来自编码器或者观测器。我这里先假设θ已经给出来了,后面章节会讲怎么获取。
避坑指南: 我曾经在项目里吃过亏——Park变换的θ和反Park变换的θ必须严格同步。差一个采样周期,电流环就抖得不行。所以建议用同一个信号源,别复制一份。
2.2 电流环PI控制器设计
电流环是矢量控制的内环,响应速度要快。说白了,就是让实际电流快速跟上给定值。
2.2.1 PI参数整定
PI控制器的传递函数:
G(s) = Kp + Ki/s
参数怎么定?我一般用工程整定法。先算电机电气时间常数τ = L/R,然后:
| 参数 | 计算公式 | 说明 |
|---|---|---|
| Kp | L * ωc | ωc是电流环带宽,一般取1000-3000 rad/s |
| Ki | R * ωc | 保证零极点对消 |
嗯,这里要注意,实际项目中还要考虑数字实现的离散化。我习惯用后向差分法,简单稳定。
离散化后的PI算法:
// 位置式PI
error = ref - feedback;
integral += Ki * error * Ts;
output = Kp * error + integral;
// 限幅处理
if(output > max) output = max;
if(output < min) output = min;
2.2.2 Simulink建模要点
在Simulink里搭PI控制器,我建议用离散模块。别用连续模块,因为最终代码生成出来是离散的。
- 使用Discrete PI Controller模块(Simulink自带)
- 或者自己搭:Gain + Discrete Integrator + Sum
- 别忘了输出限幅!我见过有人没加限幅,积分饱和导致系统发散
我的经验: 电流环的采样频率建议设到10kHz以上。太低的话,电流纹波大,电机噪音也大。我之前有个项目,采样频率从5kHz提到12kHz,噪音直接降了8dB。
2.3 SVPWM调制模块搭建
SVPWM,空间矢量脉宽调制。这玩意儿比SPWM好,电压利用率高,谐波小。说白了,就是让逆变器输出一个旋转的电压矢量。
2.3.1 基本原理
SVPWM的核心思想:用八个基本电压矢量(六个非零矢量+两个零矢量)来合成任意方向的电压矢量。
步骤其实就三步:
- 扇区判断: 根据Uα, Uβ判断当前电压矢量在哪个扇区
- 作用时间计算: 计算相邻两个基本矢量的作用时间T1, T2
- 占空比分配: 根据扇区计算三相占空比Ta, Tb, Tc
2.3.2 Simulink实现
我建议用MATLAB Function来实现SVPWM,代码清晰,调试方便。下面给个核心代码片段:
function [Ta, Tb, Tc] = svpwm(Ualpha, Ubeta, Vdc, Ts)
% 扇区判断
Vref1 = Ubeta;
Vref2 = (sqrt(3)/2)*Ualpha - 0.5*Ubeta;
Vref3 = -(sqrt(3)/2)*Ualpha - 0.5*Ubeta;
if Vref1 > 0, sector = 1; else sector = 4; end
if Vref2 > 0, sector = bitxor(sector, 2); end
if Vref3 > 0, sector = bitxor(sector, 1); end
% 计算X, Y, Z
X = sqrt(3)*Ubeta*Ts/Vdc;
Y = (sqrt(3)/2*Ubeta + 3/2*Ualpha)*Ts/Vdc;
Z = (sqrt(3)/2*Ubeta - 3/2*Ualpha)*Ts/Vdc;
% 根据扇区计算T1, T2
switch sector
case 1, T1 = Z; T2 = Y;
case 2, T1 = Y; T2 = -X;
case 3, T1 = -Z; T2 = X;
case 4, T1 = -X; T2 = Z;
case 5, T1 = X; T2 = -Y;
case 6, T1 = -Y; T2 = -Z;
end
% 过调制处理
if(T1 + T2 > Ts)
T1 = T1/(T1+T2)*Ts;
T2 = T2/(T1+T2)*Ts;
end
% 计算占空比
T0 = Ts - T1 - T2;
Ta = (T0/2 + T1 + T2)/Ts;
Tb = (T0/2 + T2)/Ts;
Tc = (T0/2)/Ts;
end
重要提醒: 过调制处理一定要做!我曾经在测试时忘了加,结果T1+T2超过Ts,占空比算出来大于1,逆变器直接炸了。嗯,那次教训挺深刻的。
2.3.3 模块封装建议
我建议把SVPWM封装成一个子系统,输入是Uα, Uβ, Vdc, Ts,输出是三相占空比。这样上层调用时特别清爽。
封装好后,记得把采样时间设成Ts。不然代码生成时会有警告。
最终效果: 把Clark、Park、PI、SVPWM串起来,你就得到了一个完整的电流环。输入是Id_ref, Iq_ref和电角度θ,输出是六路PWM波。这就是矢量控制的内核。
好了,这一节的内容就到这。下一节我们讲速度环和位置环的建模,还有怎么把整个系统跑起来。到时候我会分享一些调试技巧,保证让你少走弯路。