电压空间矢量定义: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算法去合成这个αβ矢量。
整个流程是这样的:
- 电流采样 → Clark变换 → Park变换 → 得到dq电流
- dq电流与给定值比较 → PI调节 → 得到dq电压指令
- dq电压指令 → 逆Park变换 → 得到αβ电压指令
- αβ电压指令 → SVPWM调制 → 生成六路PWM波
说白了,Clark和Park就是连接“物理世界”和“控制世界”的桥梁。
3.5 坐标系变换的SVG结构图
下面这张图,我画了三个坐标系的关系,以及变换的流向。你看一眼就能明白整个体系。
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,静止变旋转。