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

Clark变换,说白了就是把电机里那三根线的电流,变成两根线的电流。你可能会问:电机本来就是三相的,为什么要多此一举?

我刚开始接触FOC时也有这个疑惑。后来在调试一个伺服驱动器时,发现三相电流直接控制实在太麻烦——三个变量互相耦合,PID调来调去都不对劲。直到我把它们变换到两相坐标系,问题一下子清晰了。

嗯,这就是Clark变换的价值所在。

3.1 为什么要做Clark变换

三相电机有三个绕组,电流分别是ia、ib、ic。这三个电流不是独立的——它们满足ia + ib + ic = 0。所以实际上只有两个自由度。

Clark变换就是把这三个变量映射到两个正交的轴上:

  • α轴:与A相绕组对齐
  • β轴:与α轴垂直

这样一来,原本的三相系统就变成了两相系统。控制起来简单多了。

核心思想:Clark变换不改变电流的频率和幅值,只是换了个坐标系来看它。就像你从不同角度观察同一个物体,物体本身没变,但描述方式变了。

3.2 Clark变换公式推导

推导其实不复杂。我们假设三相电流是正弦波,相位互差120°:

i_a = I·cos(ωt)
i_b = I·cos(ωt - 120°)
i_c = I·cos(ωt - 240°)

现在我们要找到一组基,把这三个量投影到α-β平面上。我习惯用等幅值变换,因为这样变换后的电流幅值跟原来一样,调试时心里有数。

变换矩阵长这样:

[ 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 ]

注意第三行是零序分量i0。对于星形连接且中线不接的电机,i0 = 0,可以忽略。

所以实际用的公式就是:

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

等等,这个简化版怎么来的?

把ic = -ia - ib代入原矩阵,化简一下就得到了。我在项目里一直用这个简化版,省掉一个采样通道,硬件成本也降了。

我的习惯:实际代码里我从来不用完整的3x3矩阵,只用上面那两行。少算一次乘法,少一次加法,在STM32F103这种资源有限的芯片上,能省则省。

3.3 等幅值与等功率变换

这里有个坑,我当年踩过。Clark变换有两种常见形式:

类型 系数 特点
等幅值变换 2/3 变换后电流幅值与原来相同
等功率变换 √(2/3) 变换前后功率守恒

我建议初学者先用等幅值变换。为什么?因为调试时你用示波器看电流波形,幅值没变,心里踏实。等功率变换虽然数学上更优雅,但幅值变了,容易搞混。

注意:如果你从网上抄代码,一定要看清楚它用的是哪种变换。我曾经把一个等功率变换的库跟等幅值变换的Park变换混在一起用,结果电流环怎么调都振荡。查了两天才发现是系数不匹配。

3.4 Clark变换的代码实现

直接上代码。这是我在STM32上跑过的版本,用Q15定点数实现:

/**
 * @brief Clark变换,等幅值形式
 * @param ia, ib, ic: 三相电流,Q15格式
 * @param *pAlpha, *pBeta: 输出αβ轴电流,Q15格式
 */
void clark_transform(q15_t ia, q15_t ib, q15_t ic,
                     q15_t *pAlpha, q15_t *pBeta)
{
    // 利用 ic = -ia - ib 简化计算
    // i_alpha = ia
    *pAlpha = ia;

    // i_beta = (ia + 2*ib) / sqrt(3)
    // 1/sqrt(3) ≈ 0.57735,Q15下为 18919
    q15_t temp = ia + 2 * ib;
    *pBeta = (q15_t)(((q31_t)temp * 18919) >> 15);
}

如果你用浮点运算,更直观:

void clark_transform_f32(float ia, float ib, float ic,
                         float *pAlpha, float *pBeta)
{
    const float ONE_OVER_SQRT3 = 0.577350269f;
    *pAlpha = ia;
    *pBeta  = (ia + 2.0f * ib) * ONE_OVER_SQRT3;
}

注意看,我根本没用到ic。这就是前面说的简化——只要保证ia + ib + ic = 0,ic就是多余的。

避坑指南:实际采样时,三相电流不可能完全满足ia+ib+ic=0。ADC有偏置,运放有温漂。我建议在初始化时做一次偏置校准:电机不转时采100次取平均,把这个值作为零偏减掉。

3.5 知识体系总览

下面这张图把Clark变换在整个FOC中的位置说清楚了:

Clark变换在FOC中的位置 三相电流采样 ia, ib, ic Clark变换 αβ轴电流 iα, iβ Park变换 关键说明 • Clark变换将三相电流映射到两相静止坐标系(αβ) • 变换后电流仍然是交流量,频率不变 • Park变换进一步将αβ交流量变为dq直流量,方便PID控制

从图上你能看到,Clark变换是FOC的第一道关卡。它把ADC采到的三相电流,变成αβ两相电流。然后Park变换再把这些交流量变成直流量,PID就好控制了。

3.6 实际项目中的注意事项

最后分享几个实战经验:

  • 采样时序:三相电流必须在同一时刻采样。我用STM32的定时器触发ADC,三个通道同时采样,误差在1μs以内。
  • 偏置校准:每次上电先做一次偏置校准。电机静止时采100次取平均,存下来做减法。
  • 溢出保护:定点数实现时注意乘法溢出。Q15乘以Q15得到Q31,右移15位再截断,这个顺序不能乱。
  • 调试技巧:先用信号发生器模拟三相正弦波,看Clark变换后的αβ波形是不是正交的正弦波。如果不是,检查系数和符号。

一句话总结:Clark变换就是把三相变两相,公式简单,但系数选择和实现细节决定了你的FOC能不能跑起来。我建议你先把等幅值变换的代码调通,再考虑其他变体。