2、坐标变换:Clark变换、Park变换原理与实现

好,咱们进入正题。坐标变换这东西,说白了就是换个角度看问题。

你想想看,电机里三相绕组通上交流电,产生的磁场是旋转的。但我们要控制的是转矩,转矩跟电流的直轴和交轴分量有关。直接在三相坐标系下算?太复杂了。我刚开始做电机控制时,就硬着头皮在三相坐标系下解方程,结果把自己绕晕了。

后来老工程师告诉我:把三相坐标系变到两相旋转坐标系下,一切就清晰了。这就是Clark变换和Park变换干的事。

2.1 为什么需要坐标变换?

永磁同步电机的数学模型,在三相静止坐标系下是时变的。电感参数随转子位置变化,方程里一堆三角函数。你想想看,要在这个基础上设计控制器,难度有多大。

我个人的理解是:坐标变换的本质,是把交流量变成直流量。这样我们就可以用经典的PI控制器去控制它,就像控制直流电机一样简单。

核心思想:

  • 三相静止坐标系(ABC)→ 两相静止坐标系(αβ):Clark变换
  • 两相静止坐标系(αβ)→ 两相旋转坐标系(dq):Park变换
  • 最终效果:交流量 → 直流量,时变系统 → 时不变系统

2.2 Clark变换原理

Clark变换,也叫3s/2s变换。就是把三相绕组等效成两相正交绕组。

我记得第一次推导这个公式时,总觉得少了点什么。后来才明白,变换前后要保证磁动势不变,这是基本原则。

假设三相电流为 ia、ib、ic,变换到αβ坐标系下的电流 iα、iβ

iα = ia
iβ = (ia + 2*ib) / √3

嗯,这里要注意。上面这个是等幅值变换,我项目中用得最多的一种。还有一种叫等功率变换,系数会不一样。

变换类型 α轴系数 β轴系数 特点
等幅值变换 1 1/√3 变换后幅值不变,便于调试
等功率变换 √(2/3) √(2/3) 变换前后功率守恒

我的建议:初学者先用等幅值变换。调试时电流波形看起来更直观,幅值不会变。等功率变换在计算功率时更方便,但实际控制中差别不大。

2.3 Park变换原理

Clark变换后,我们得到了两相静止坐标系下的电流。但这两个分量还是交流量,因为转子在转。

Park变换就是解决这个问题的。它把静止的αβ坐标系,旋转到跟转子同步的dq坐标系上

公式很简单:

id = iα * cos(θ) + iβ * sin(θ)
iq = -iα * sin(θ) + iβ * cos(θ)

其中θ是转子电角度,由编码器或霍尔传感器提供。

我曾经在一个项目里踩过坑:角度θ的零点没对准。结果id和iq怎么调都调不好,电机发热严重。后来用示波器抓了角度和电流波形,才发现差了30度电角度。嗯,从那以后我每次都会先校准角度零点。

注意:

  • Park变换需要准确的转子位置信息
  • 角度误差会直接导致id/iq解耦不彻底
  • 建议在调试阶段先用手动给定角度,验证变换是否正确

2.4 代码实现

理论讲完了,咱们看看代码怎么写。我习惯用C语言实现,因为嵌入式系统里C语言最通用。

// Clark变换:三相电流 → 两相静止坐标系
void clark_transform(float ia, float ib, float ic, 
                     float *i_alpha, float *i_beta)
{
    // 等幅值变换
    *i_alpha = ia;
    *i_beta = (ia + 2.0f * ib) / 1.7320508f;  // 1/√3
}

// Park变换:两相静止 → 两相旋转
void park_transform(float i_alpha, float i_beta, float theta,
                    float *i_d, float *i_q)
{
    float sin_theta = sinf(theta);
    float cos_theta = cosf(theta);
    
    *i_d = i_alpha * cos_theta + i_beta * sin_theta;
    *i_q = -i_alpha * sin_theta + i_beta * cos_theta;
}

// 反Park变换:两相旋转 → 两相静止(用于输出)
void inv_park_transform(float i_d, float i_q, float theta,
                        float *i_alpha, float *i_beta)
{
    float sin_theta = sinf(theta);
    float cos_theta = cosf(theta);
    
    *i_alpha = i_d * cos_theta - i_q * sin_theta;
    *i_beta = i_d * sin_theta + i_q * cos_theta;
}

性能优化小技巧:

  • sin/cos计算很耗时,建议用查表法或CORDIC算法
  • 如果使用浮点运算,注意MCU是否带FPU
  • 我习惯把角度归一化到0~2π,避免角度溢出

2.5 实际调试中的坑

说几个我踩过的坑,希望对你有帮助。

第一个坑:三相电流采样顺序

Clark变换要求三相电流之和为零(ia + ib + ic = 0)。但实际采样时,由于ADC触发时刻不同,三路电流可能不是同一时刻的值。我建议用双采样模式,或者只采两相,第三相用公式计算

第二个坑:角度对齐

Park变换的角度,是转子永磁体N极与A相绕组轴线的夹角。如果编码器安装有偏差,需要在软件里做补偿。我曾经因为没做补偿,电机空载电流大了30%。

第三个坑:变换顺序

先Clark再Park,这个顺序不能乱。反变换时先反Park再反Clark。我见过有人把顺序搞反了,结果电流波形完全不对。

2.6 小结

坐标变换是FOC控制的基础。Clark变换把三相变两相,Park变换把静止变旋转。说白了,就是把交流问题变成直流问题

我个人建议,在写代码之前,先在Matlab或Python里把变换验证一遍。给一组三相电流,算一下id和iq,看看是不是你期望的值。这一步做好了,后面调试会省很多时间。

下一章我们讲PI控制器的设计,到时候会用到这里的id和iq。先把基础打牢,后面就顺了。