2. 电机控制模型概述:永磁同步电机(PMSM)数学模型、Clark变换与Park变换

做电机控制这些年,我最大的感触就是:数学模型是控制算法的灵魂。你想想看,电机本身是个非线性、强耦合的玩意儿,如果没有数学模型把它“翻译”成我们能理解的语言,那控制根本无从谈起。

这一节,我们就来聊聊永磁同步电机(PMSM)的数学模型,以及两个非常重要的坐标变换——Clark变换和Park变换。嗯,这些是后续做软件在环仿真的基础,绕不开的。

2.1 永磁同步电机(PMSM)的数学模型

PMSM的数学模型,说白了就是描述电机内部电磁关系的方程组。我习惯从电压方程和磁链方程入手。

2.1.1 三相静止坐标系下的模型

在三相静止坐标系(ABC坐标系)下,PMSM的电压方程长这样:

u_a = R_s * i_a + d(ψ_a)/dt
u_b = R_s * i_b + d(ψ_b)/dt
u_c = R_s * i_c + d(ψ_c)/dt

其中,u_a、u_b、u_c是三相电压,i_a、i_b、i_c是三相电流,R_s是定子电阻,ψ_a、ψ_b、ψ_c是三相磁链。

磁链方程呢?

ψ_a = L_aa * i_a + M_ab * i_b + M_ac * i_c + ψ_f * cos(θ_e)
ψ_b = M_ba * i_a + L_bb * i_b + M_bc * i_c + ψ_f * cos(θ_e - 2π/3)
ψ_c = M_ca * i_a + M_cb * i_b + L_cc * i_c + ψ_f * cos(θ_e + 2π/3)

这里L_aa、L_bb、L_cc是自感,M_ab等是互感,ψ_f是永磁体磁链,θ_e是电角度。

注意: 这个模型里,电感和互感都是随转子位置变化的!也就是说,它们是θ_e的函数。这就导致方程非常复杂,直接用来做控制,计算量巨大。我曾经在早期项目里试图直接用这个模型做实时控制,结果发现CPU根本跑不动。

2.1.2 为什么需要坐标变换?

你想想看,三相静止坐标系下的模型,电感参数时变,耦合严重。这就像在一个乱糟糟的房间里找东西,效率极低。

所以,我们需要坐标变换。目的只有一个:把时变的参数变成常数,把耦合的变量解耦。Clark变换和Park变换就是干这个的。

2.2 Clark变换

Clark变换,也叫3/2变换。它把三相静止坐标系(ABC)变换到两相静止坐标系(αβ)。

为什么要这么做?因为三相系统本质上只有两个自由度(三相电流之和为零),用两相就能完整描述。

2.2.1 变换公式

Clark变换的公式如下(等幅值变换):

i_α = i_a
i_β = (i_a + 2*i_b) / √3

或者写成矩阵形式:

[i_α]   [ 1       -1/2      -1/2   ] [i_a]
[i_β] = [ 0       √3/2     -√3/2  ] [i_b]
[i_0]   [ 1/2      1/2       1/2   ] [i_c]

注意,这里有个i_0分量,它是零序分量。在电机控制中,如果三相平衡,i_0 = 0,我们通常只关心i_α和i_β。

我的习惯: 在实际代码中,我通常只计算i_α和i_β,忽略i_0。因为PMSM是三相三线制,没有中线,零序电流不存在。这样可以省掉一次乘法和一次加法,积少成多嘛。

2.2.2 代码实现

下面是一个简单的C语言实现:

typedef struct {
    float i_alpha;
    float i_beta;
} Clark_Output;

Clark_Output clark_transform(float i_a, float i_b, float i_c) {
    Clark_Output out;
    out.i_alpha = i_a;
    out.i_beta  = (i_a + 2.0f * i_b) * 0.577350269f; // 1/√3
    return out;
}

嗯,这里要注意,1/√3 ≈ 0.57735,我建议直接写成常量,避免每次计算除法。

2.3 Park变换

Clark变换之后,我们得到了αβ坐标系下的两相交流量。但交流量控制起来还是麻烦,我们希望它变成直流量。Park变换就是干这个的。

Park变换把两相静止坐标系(αβ)变换到两相旋转坐标系(dq)。这个旋转坐标系以电角速度ω_e同步旋转,并且d轴通常与转子永磁体磁链方向对齐。

2.3.1 变换公式

i_d =  i_α * cos(θ_e) + i_β * sin(θ_e)
i_q = -i_α * sin(θ_e) + i_β * cos(θ_e)

其中,θ_e是电角度,由转子位置传感器(如编码器)提供。

反过来,逆Park变换(从dq到αβ)也很常用:

i_α = i_d * cos(θ_e) - i_q * sin(θ_e)
i_β = i_d * sin(θ_e) + i_q * cos(θ_e)
核心思想: 经过Park变换后,i_d和i_q变成了直流量。i_d控制励磁分量,i_q控制转矩分量。这就是大名鼎鼎的矢量控制(FOC)的基础。说白了,就是通过控制这两个直流量,来独立控制电机的磁通和转矩。

2.3.2 代码实现

typedef struct {
    float i_d;
    float i_q;
} Park_Output;

Park_Output park_transform(float i_alpha, float i_beta, float theta) {
    Park_Output out;
    float sin_theta = sinf(theta);
    float cos_theta = cosf(theta);
    
    out.i_d =  i_alpha * cos_theta + i_beta * sin_theta;
    out.i_q = -i_alpha * sin_theta + i_beta * cos_theta;
    return out;
}

这里我用了sinf和cosf,是单精度浮点版本。在嵌入式平台上,如果CPU没有硬件浮点单元(FPU),可以考虑查表法或者用CORDIC算法来加速。我曾经在一个低成本MCU上做过,用查表法把三角函数计算时间从200μs降到了5μs。

2.4 完整的变换流程

在实际的FOC控制中,完整的电流采样与变换流程是这样的:

  1. ADC采样得到三相电流i_a、i_b、i_c(通常只采样两相,第三相通过i_c = -i_a - i_b计算)
  2. Clark变换:ABC → αβ,得到i_α、i_β
  3. Park变换:αβ → dq,得到i_d、i_q
  4. PI控制器对i_d、i_q进行调节,输出v_d、v_q
  5. 逆Park变换:dq → αβ,得到v_α、v_β
  6. SVPWM(空间矢量脉宽调制)生成三相占空比

这个流程,在软件在环仿真中,我们会用C代码或者Simulink模型完整地实现一遍。

2.5 避坑指南

我曾经踩过的坑:
  • 角度对齐问题: Park变换用的θ_e必须与转子实际位置严格对齐。如果编码器安装有偏差,或者初始角没找对,那i_d、i_q就解耦不彻底,电机要么抖,要么转不起来。我建议上电后先做一次转子初始位置检测。
  • 变换系数问题: Clark变换有等幅值和等功率两种形式。等幅值变换下,变换后的αβ电流幅值与三相电流幅值相同;等功率变换下,功率守恒。两种都可以用,但后续的PI参数整定会不一样。我个人习惯用等幅值变换,因为调试时看电流波形更直观。
  • 浮点精度问题: 在定点DSP上做变换时,要注意三角函数和乘法的精度。我曾经因为角度量化误差太大,导致电流环出现低频振荡。后来把角度用Q24格式表示,问题就解决了。

2.6 小结

这一节我们聊了PMSM的数学模型,以及Clark和Park两个坐标变换。说白了,这些变换就是给电机“换个坐标系”,让复杂的交流耦合问题变成简单的直流解耦问题。这是矢量控制的基石,也是后续软件在环仿真中必须实现的核心模块。

下一节,我们会把这些数学模型搬到仿真环境中,看看它们在实际代码中是怎么跑的。到时候,我会带着大家一步步搭建一个完整的PMSM仿真模型。