3. Clark变换:三相坐标系到两相静止坐标系

好,咱们正式开始聊FOC的第一个数学变换——Clark变换。很多初学者一上来就被αβ坐标系、矩阵公式给唬住了,觉得这东西高深莫测。其实说白了,Clark变换就是把电机里那三根乱七八糟的线,简化成两根互相垂直的线来管。

我刚开始做电机驱动时,也纳闷过:明明电机就三相,为什么非要多此一举转成两相?后来在调试一个低速抖动问题时我才真正明白——三相直接控制,你根本没法同时盯住三个电流的相位关系。转成αβ之后,一切就清晰多了。

3.1 为什么要做Clark变换?

先想一个问题:永磁同步电机的定子绕组是三相的,A、B、C三相电流相差120°。但你要控制转子磁场,最直观的方式是让定子产生一个旋转的合成磁动势。这个合成磁动势在空间上是一个旋转矢量,而三相电流只是这个矢量在三个轴上的投影。

你想想看,三个轴夹角120°,控制起来多别扭。如果能把这三个投影合并成两个互相垂直的轴(α轴和β轴),那控制就变成了标准的二维矢量控制,简单太多了。

核心思想:Clark变换的本质是坐标投影,把三相120°坐标系映射到两相90°坐标系,保持合成磁动势不变。

3.2 数学推导:从三相到两相

咱们从最基础的公式开始推。假设三相电流为 iA、iB、iC,它们满足基尔霍夫电流定律:

iA + iB + iC = 0

所以实际上只有两个独立变量。Clark变换就是要找到一组正交基,把这三个量投影上去。

设α轴与A相轴线重合,β轴超前α轴90°。那么:

iα = iA

iβ = (iA + 2iB) / √3

等一下,这个公式怎么来的?我习惯从矢量投影的角度理解:把B相和C相的电流分别投影到β轴上,再叠加。推导过程如下:

  1. A相在α轴上的投影就是它自己,在β轴上投影为0
  2. B相在α轴上投影为 iB·cos(120°) = -½ iB,在β轴上投影为 iB·sin(120°) = (√3/2) iB
  3. C相在α轴上投影为 iC·cos(240°) = -½ iC,在β轴上投影为 iC·sin(240°) = -(√3/2) iC
  4. 利用 iC = -iA - iB 代入化简

最终得到完整的Clark变换矩阵形式:

| iα |   | 1      -1/2    -1/2   | | iA |
| iβ | = | 0      √3/2   -√3/2  | | iB |
                        | iC |

嗯,这里要注意:上面这个矩阵是等幅值变换,也就是变换前后电流的幅值不变。还有一种等功率变换,系数会多一个√(2/3),但咱们做FOC控制时,绝大多数都用等幅值变换,因为电流环的PI参数调起来更直观。

我的经验:在实际项目中,我建议统一使用等幅值Clark变换。这样你在调试电流环时,给定1A电流,实际电流就是1A,不用在脑子里来回换算。等功率变换虽然数学上更优雅,但工程上反而容易出错。

3.3 物理意义:到底在干什么?

Clark变换的物理意义,我习惯用一句话概括:把三相绕组的空间分布,等效成两相正交绕组。

你看,原来的三相绕组在空间上相隔120°。经过Clark变换后,我们得到两个虚拟绕组:一个在α轴上,一个在β轴上,两者相差90°。这两个虚拟绕组产生的合成磁动势,和原来三相绕组产生的完全一样。

为什么会这样?因为变换矩阵保证了磁动势不变。换句话说,Clark变换没有改变电机的物理本质,只是换了一套更顺手的坐标系来描述它。

我记得有一次在培训新人时,有个工程师问我:「那我把电机拆了,改成两相绕组行不行?」当然不行。Clark变换只是数学上的等效,物理上电机还是三相的。你最终还是要通过SVPWM把αβ电压还原成三相电压去驱动MOSFET。

避坑指南:我曾经在一个项目里犯过糊涂——直接用Clark变换后的αβ电流去算转矩,结果怎么算都不对。后来才意识到,Clark变换只是坐标变换,转矩计算还需要知道转子位置(也就是后面要讲的Park变换)。千万别跳过Park变换直接算转矩!

3.4 代码实现:从公式到C语言

好了,理论说完了,咱们直接上代码。下面是一个标准的Clark变换实现,我用的是Q15定点数格式,适合在低成本MCU上跑:

/**
 * @brief Clark变换:三相电流 → 两相静止坐标系电流
 * @param ia A相电流 (Q15)
 * @param ib B相电流 (Q15)
 * @param ic C相电流 (Q15)
 * @param i_alpha 输出α轴电流 (Q15)
 * @param i_beta  输出β轴电流 (Q15)
 */
void clark_transform(q15_t ia, q15_t ib, q15_t ic,
                     q15_t *i_alpha, q15_t *i_beta)
{
    /* 1/√3 的Q15近似值:0.57735 * 32768 = 18919 */
    const q15_t ONE_OVER_SQRT3 = 18919;

    /* α轴电流 = ia */
    *i_alpha = ia;

    /* β轴电流 = (ia + 2*ib) / √3 */
    q31_t temp = (q31_t)ia + ((q31_t)ib << 1);  /* ia + 2*ib */
    *i_beta = (q15_t)((temp * ONE_OVER_SQRT3) >> 15);
}

这段代码有几个关键点:

  • 输入是三相电流:实际采样时,你只需要采两相(比如A和B),第三相通过 iC = -iA - iB 算出来。省一个ADC通道,省一分钱。
  • Q15定点运算:MCU没有FPU时,定点数比浮点快10倍以上。1/√3用18919表示,乘完后右移15位还原。
  • 注意溢出:ia + 2*ib 可能超过16位,所以用q31_t做中间变量。我见过有人直接写 int16_t,结果电流大时直接溢出,电流环瞬间崩掉。

如果你用的是带FPU的MCU(比如STM32F4系列),浮点版本更简洁:

void clark_transform_f32(float ia, float ib, float ic,
                          float *i_alpha, float *i_beta)
{
    const float ONE_OVER_SQRT3 = 0.577350269f;

    *i_alpha = ia;
    *i_beta  = (ia + 2.0f * ib) * ONE_OVER_SQRT3;
}

嗯,就这么几行。但你别小看它,整个FOC的精度都建立在这个变换上。我建议你在实际项目中,先用浮点版本验证算法,确认无误后再转定点优化。

3.5 知识体系总览

下面这张图把Clark变换在整个FOC中的位置和作用画清楚了。你可以看到,Clark变换是电流采样的第一站,后面紧跟着Park变换进入旋转坐标系:

Clark变换在FOC中的位置与作用 三相电流采样 iA, iB, iC Clark变换 3相 → 2相静止 αβ轴电流 iα, iβ Park变换 静止 → 旋转坐标系 dq轴电流 id, iq 关键作用 • 降维:3→2 • 正交化:120°→90° • 磁动势不变 • 为Park变换 提供输入 • 简化电流控制 • 便于SVPWM 电压重构 图:Clark变换是FOC电流采样后的第一个处理环节,将三相电流映射到两相静止坐标系

3.6 常见问题与避坑

问题 原因 解决方案
αβ电流波形畸变 ADC采样时序不对,三相电流不是同一时刻采的 使用PWM中心对齐触发ADC,确保三相同时采样
β轴电流始终为0 代码里用了 iC = -iA - iB,但ADC只采了两相,第三相计算有误 检查ADC通道配置,确认两相采样值正确
变换后幅值不对 用了等功率变换的系数,但PI参数是按等幅值调的 统一使用等幅值变换,或者重新标定PI参数
定点数溢出 中间变量用了16位,ia + 2*ib 超出范围 用32位中间变量,或者先缩放到Q14再计算

调试小技巧:我习惯在代码里加一个调试模式,把Clark变换前后的电流值通过DAC输出到示波器。如果看到αβ电流是标准正弦波且相位差90°,说明变换正确。如果波形有毛刺,先查ADC采样,再查代码逻辑。

Clark变换是整个FOC的基石。它不复杂,但必须理解透彻。你想想看,后面所有的控制——电流环、速度环、位置环——都建立在αβ坐标系的基础上。这一步走稳了,后面的路就好走了。