4. Clark变换与Park变换实现:从三相电流到两相旋转坐标系
好,咱们进入FOC算法里最核心的数学变换部分。说实话,很多初学者一看到矩阵和三角函数就头大。我当年也是,觉得这东西太抽象了。但后来在调试电机时发现,这些变换其实就是把复杂的物理问题,转化成我们能轻松控制的数学问题。
今天咱们就把Clark变换、Park变换,还有反Park变换与SVPWM的衔接,一次性讲透。我会结合我在项目里踩过的坑,帮你少走弯路。
4.1 为什么需要坐标变换?
先想一个问题:三相电机里,电流是正弦波,互相差120度。你直接去控制这三个电流,让它们产生恒定的转矩,难不难?
非常难。因为三个变量互相耦合,而且随时间变化。
但如果我们换个思路——把这三个旋转的电流,映射到一个跟转子一起旋转的坐标系里,会怎样?
你会发现,原本正弦变化的电流,变成了两个直流量:一个产生转矩(q轴),一个产生磁场(d轴)。控制两个直流量,比控制三个正弦量简单太多了。这就是FOC的精髓。
核心思想: Clark变换把三相变两相静止,Park变换把两相静止变两相旋转。最终,我们把交流电机控制问题,变成了直流电机控制问题。
4.2 Clark变换:从三相到两相静止坐标系(αβ)
Clark变换,也叫3s/2s变换。它的任务是把三相电流 ia、ib、ic,投影到两个互相垂直的轴——α轴和β轴上。
公式其实不复杂:
iα = ia
iβ = (ia + 2*ib) / √3
等等,这里有个细节。上面的公式是等幅值变换,我项目里最常用的就是这种。还有一种叫等功率变换,系数不同。我个人习惯用等幅值,因为后续做电流环PI调节时,参数整定更直观。
我的经验: 如果你刚开始做FOC,建议用等幅值变换。等功率变换虽然理论上更严谨,但实际调试时,等幅值变换的PI参数更容易跟仿真结果对应上。
代码实现也很简单:
// 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) * 0.57735f; // 1/√3 ≈ 0.57735
}
嗯,这里要注意一点。实际采样时,我们通常只采样两相电流(比如ia和ib),因为ic = -(ia + ib)。这样可以省一个ADC通道。我曾经在项目里为了省成本,只用了两个采样电阻,效果完全OK。
4.3 Park变换:从静止到旋转坐标系(dq)
Clark变换之后,我们得到了αβ坐标系下的电流。但这两个量还是正弦变化的。怎么办?再转一次,转到跟转子同步旋转的dq坐标系。
Park变换需要知道转子位置角θ(也就是电角度)。这个角度通常来自编码器或霍尔传感器。
公式:
id = iα * cos(θ) + iβ * sin(θ)
iq = -iα * sin(θ) + iβ * cos(θ)
你看,经过这次变换,id和iq就变成了直流量。其中id控制励磁,iq控制转矩。在表贴式PMSM(SPMSM)中,我们通常让id=0,只控制iq来产生转矩。
避坑指南: 我曾经在调试时发现,电机转起来后电流波形不对。查了半天,发现是电角度初始值没校准。如果角度偏差哪怕1度,id和iq就会有耦合,导致转矩波动。所以,上电后一定要先做角度校准。
代码实现:
// Park变换
void park_transform(float i_alpha, float i_beta, float theta, float *id, float *iq) {
float cos_theta = cosf(theta);
float sin_theta = sinf(theta);
*id = i_alpha * cos_theta + i_beta * sin_theta;
*iq = -i_alpha * sin_theta + i_beta * cos_theta;
}
4.4 反Park变换与SVPWM的衔接
好,现在我们在dq坐标系下算出了想要的电压值 Vd_ref 和 Vq_ref(经过PI调节器)。但最终要给电机施加的是三相电压,所以得再变回去。
反Park变换:从dq回到αβ。
Vα = Vd * cos(θ) - Vq * sin(θ)
Vβ = Vd * sin(θ) + Vq * cos(θ)
得到Vα和Vβ之后,下一步就是SVPWM(空间矢量脉宽调制)。SVPWM的任务是:根据Vα和Vβ,计算出三个桥臂的占空比,让逆变器输出等效的电压矢量。
这里有个关键点:SVPWM的输入电压范围。Vα和Vβ的幅值不能超过直流母线电压Vdc的某个比例。如果超过,就会进入过调制区,导致波形失真。
衔接要点: 反Park变换输出的Vα、Vβ,直接作为SVPWM的输入。SVPWM内部会做扇区判断、作用时间计算,最终生成三路PWM波。整个过程是连续的,中间不需要额外处理。
代码示例:
// 反Park变换
void inv_park_transform(float vd, float vq, float theta, float *v_alpha, float *v_beta) {
float cos_theta = cosf(theta);
float sin_theta = sinf(theta);
*v_alpha = vd * cos_theta - vq * sin_theta;
*v_beta = vd * sin_theta + vq * cos_theta;
}
// 然后直接调用SVPWM函数
void svpwm(float v_alpha, float v_beta, float vdc) {
// 扇区判断、占空比计算...
// 这部分我们下一章详细讲
}
4.5 总结与注意事项
咱们把整个流程串起来:
- 采样:采集两相电流 ia、ib
- Clark变换:得到 iα、iβ
- Park变换:得到 id、iq(需要电角度θ)
- PI调节:计算 Vd_ref、Vq_ref
- 反Park变换:得到 Vα、Vβ
- SVPWM:生成PWM波驱动逆变器
每一步都有坑。我列几个常见的:
| 环节 | 常见问题 | 我的建议 |
|---|---|---|
| Clark变换 | 等幅值/等功率混淆 | 统一用等幅值,方便调试 |
| Park变换 | 电角度不准 | 上电做角度校准,运行时用观测器补偿 |
| 反Park→SVPWM | 电压饱和 | 加限幅处理,防止过调制 |
一个小技巧: 在调试时,可以把id和iq的给定值设成固定值(比如id=0,iq=1A),然后观察实际反馈的id、iq是否跟踪。如果跟踪良好,说明变换和PI都没问题。如果偏差大,先检查角度,再检查电流采样。
好了,这一章的内容就到这。Clark和Park变换是FOC的基石,一定要亲手写代码跑一遍。下一章咱们聊SVPWM的具体实现,那才是真正让电机转起来的关键。