电压空间矢量定义:Clark变换与Park变换

好,咱们进入第三章。前面两章我们把SVPWM的基本概念和三相逆变器的拓扑结构理清了。现在要动真格的了——怎么把实际电机里的三相物理量,变成我们控制算法能用的东西?

说白了,就是坐标变换。你想想看,电机定子上有三相绕组,通入三相正弦电流,产生一个旋转的磁场。但我们在做控制时,直接去控制三相正弦量很麻烦,PID调起来也费劲。能不能换个坐标系,让这些交流量变成直流量?

能。这就是Clark变换和Park变换要做的事。

3.1 为什么要变换坐标系?

我刚开始接触电机控制时,也有个疑问:明明三相正弦波跑得好好的,干嘛非要折腾成两相?

原因其实很简单:控制难度不一样。

  • 在三相静止坐标系(ABC)下,电压、电流都是时变的正弦量。你要设计一个控制器去跟踪正弦波,带宽要求高,稳态误差也不好压。
  • 在两相旋转坐标系(dq)下,基波分量变成了直流量。你只需要用PI控制器去跟踪一个常数,简单得多。

嗯,这里要注意:变换本身不改变物理本质,它只是换了个观察角度。就像你看一个旋转的硬币,从侧面看它在转,从正上方看它就是个圆——信息没丢,但视角变了。

3.2 Clark变换:从ABC到αβ

Clark变换,也叫3s/2s变换。它的任务是把三相静止坐标系(A、B、C)下的量,映射到两相静止坐标系(α、β)下。

数学上,它基于一个假设:三相系统是平衡的,即:

i_A + i_B + i_C = 0

Clark变换的矩阵形式如下:

[ 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₀。在平衡系统中,i₀ = 0,可以忽略。实际工程中,我们通常用等幅值变换(系数为2/3)或等功率变换(系数为√(2/3))。我个人习惯用等幅值变换,因为这样变换后的αβ幅值和原三相幅值一致,调试时直观一些。

关键点: Clark变换后,α轴与A轴重合,β轴超前α轴90°。两个正弦量,相位差90°,幅值不变——这就是空间矢量的雏形。

3.3 Park变换:从αβ到dq

Clark变换只是把三相变两相,但信号仍然是交流的。要把它变成直流,还得再转一次——这就是Park变换(2s/2r变换)。

Park变换的核心思想:让坐标系跟着转子磁场一起转。旋转角速度是 ωₑ,角度是 θₑ。

[ i_d ]   [ cosθₑ   sinθₑ ] [ i_α ]
[ i_q ] = [ -sinθₑ  cosθₑ ] [ i_β ]

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

[ i_α ]   [ cosθₑ  -sinθₑ ] [ i_d ]
[ i_β ] = [ sinθₑ   cosθₑ ] [ i_q ]

你看,只要 θₑ 跟踪得准,d轴和q轴上的量就是直流量。d轴对应励磁分量,q轴对应转矩分量——这就是矢量控制(FOC)的数学基础。

一个小技巧: 我在项目中调试Park变换时,经常先给一个直流偏置看dq输出是否稳定。如果d轴和q轴有纹波,多半是角度 θₑ 没对准,或者Clark变换的符号反了。别问我怎么知道的……

3.4 变换的物理意义与SVPWM的关系

你可能会问:这些变换跟SVPWM生成有什么关系?

关系大了。SVPWM本质上是在αβ坐标系下合成电压矢量的。我们通过Park逆变换,把dq轴上的电压指令(直流量)变回αβ坐标系下的交流量,然后用SVPWM算法去合成这个αβ矢量。

整个流程是这样的:

  1. 电流采样 → Clark变换 → Park变换 → 得到dq电流
  2. dq电流与给定值比较 → PI调节 → 得到dq电压指令
  3. dq电压指令 → 逆Park变换 → 得到αβ电压指令
  4. αβ电压指令 → SVPWM调制 → 生成六路PWM波

说白了,Clark和Park就是连接“物理世界”和“控制世界”的桥梁。

3.5 坐标系变换的SVG结构图

下面这张图,我画了三个坐标系的关系,以及变换的流向。你看一眼就能明白整个体系。

坐标系变换关系图 坐标系变换与SVPWM关系图 三相静止 ABC坐标系 两相静止 αβ坐标系 两相旋转 dq坐标系 Clark变换 Park变换 逆Park变换 SVPWM 调制算法 说明: • Clark变换:ABC → αβ,将三相交流量变为两相交流量,幅值不变(等幅值变换)。 • Park变换:αβ → dq,将两相交流量变为两相直流量,需要转子角度 θₑ。 • 逆Park变换:dq → αβ,将控制输出的直流量变回交流量,供SVPWM使用。

3.6 工程实现中的几个坑

理论说完了,聊聊实际中容易踩的坑。我曾经在调试一个伺服驱动器时,电机一上电就啸叫,电流波形乱七八糟。查了两天,最后发现是Park变换的角度符号搞反了。

避坑指南:

  • 角度方向: 确认你的电机是正转还是反转,Park变换的 θₑ 方向必须与转子实际旋转方向一致。反了就是正反馈,电流直接飞起来。
  • 变换系数: 等幅值变换用 2/3,等功率变换用 √(2/3)。混用会导致电流环增益不对,PI参数怎么调都调不好。
  • 零序分量: 如果系统不平衡(比如三相电流采样有偏置),i₀ 不为零。这时候Clark变换的第三行不能丢,否则会引入误差。
  • 角度精度: Park变换对角度精度敏感。我建议用浮点运算或Q格式定点数,角度分辨率至少到0.1°电角度。

3.7 代码示例:C语言实现Clark与Park变换

下面是我在实际项目中用的一段代码,做了简单的注释。你可以直接拿去用,但记得根据你的MCU调整数据类型。

// ============================================
// Clark变换:三相电流 → αβ电流
// 输入:iA, iB, iC (float)
// 输出:*iAlpha, *iBeta (float)
// 等幅值变换,系数 2/3
// ============================================
void Clark_Transform(float iA, float iB, float iC,
                     float *iAlpha, float *iBeta)
{
    *iAlpha = (2.0f / 3.0f) * (iA - 0.5f * iB - 0.5f * iC);
    *iBeta  = (2.0f / 3.0f) * (0.8660254f * iB - 0.8660254f * iC);
    // 0.8660254 = sqrt(3)/2
}

// ============================================
// Park变换:αβ电流 → dq电流
// 输入:iAlpha, iBeta, theta (float)
// 输出:*id, *iq (float)
// theta = 转子电角度 (rad)
// ============================================
void Park_Transform(float iAlpha, float iBeta, float theta,
                    float *id, float *iq)
{
    float cosT = cosf(theta);
    float sinT = sinf(theta);
    
    *id =  iAlpha * cosT + iBeta * sinT;
    *iq = -iAlpha * sinT + iBeta * cosT;
}

// ============================================
// 逆Park变换:dq电压 → αβ电压
// 输入:vd, vq, theta (float)
// 输出:*vAlpha, *vBeta (float)
// ============================================
void InvPark_Transform(float vd, float vq, float theta,
                       float *vAlpha, float *vBeta)
{
    float cosT = cosf(theta);
    float sinT = sinf(theta);
    
    *vAlpha = vd * cosT - vq * sinT;
    *vBeta  = vd * sinT + vq * cosT;
}

个人建议: 在MCU上跑这些变换时,三角函数用查表法或者Cordic算法,别直接调math.h的cosf/sinf,太慢了。我一般用256点或512点的正弦表,精度够用,速度能快一个数量级。

3.8 小结

这一章我们干了三件事:

  • 理解了为什么要做坐标变换——把交流变直流,降低控制难度。
  • 掌握了Clark变换的数学形式——从ABC到αβ,三相变两相。
  • 掌握了Park变换的数学形式——从αβ到dq,静止变旋转。