3. FOC核心算法
Clark变换,说白了就是把电机里那三根乱七八糟的电流(Ia、Ib、Ic),映射到一个两相的静止坐标系上。你想想看,三相绕组在空间上差了120°,电流波形也是正弦的,直接去控制三个变量太麻烦了。我们做FOC,第一步就是要把这三个变量变成两个——Iα和Iβ。
我刚开始接触FOC时,总觉得Clark变换就是个数学游戏。后来在调试一个风机项目时,发现Clark变换的系数选错了,整个电流环都在震荡。嗯,从那以后我再也不敢小看这个“简单的变换”了。
3.1 为什么要做Clark变换?
三相电机有三个绕组,电流Ia、Ib、Ic是相互耦合的。直接控制三个正弦波,PID调参能把你逼疯。Clark变换的核心思想就是:把三个耦合的变量,解耦成两个正交的变量。
你可以这样理解:
- 三相坐标系(a,b,c):三个轴互差120°,冗余度高
- 两相静止坐标系(α,β):两个轴互相垂直,正交性好
变换之后,Iα和Iβ仍然是正弦波,但它们是正交的。这就为后面的Park变换(旋转坐标系)铺平了路。没有Clark变换,FOC根本玩不转。
3.2 Clark变换公式推导
我们先从三相电流的表达式开始。假设三相电流是平衡的:
Ia = Im * cos(θ)
Ib = Im * cos(θ - 120°)
Ic = Im * cos(θ + 120°)
其中Im是电流幅值,θ是电角度。注意,Ia + Ib + Ic = 0,这是三相平衡系统的约束条件。
Clark变换的数学本质,就是把三维向量投影到二维平面。变换矩阵长这样:
[ Iα ] [ 1, -1/2, -1/2 ] [ Ia ]
[ ] = [ ] [ ]
[ Iβ ] [ 0, √3/2, -√3/2 ] [ Ib ]
[ Ic ]
这个矩阵是怎么来的?我简单说一下思路:
- α轴与a轴重合,所以Iα = Ia - (1/2)Ib - (1/2)Ic
- β轴与α轴垂直,所以Iβ = (√3/2)Ib - (√3/2)Ic
- 系数2/3是为了保证变换前后幅值不变(等幅值变换)
如果你把Ia、Ib、Ic代入,化简后得到:
Iα = Im * cos(θ)
Iβ = Im * sin(θ)
看到了吗?Iα和Iβ就是一对正交的正弦波。这就是Clark变换的魔力——把三个120°相位差的波形,变成了两个90°相位差的波形。
3.3 等幅值 vs 等功率变换
这里有个坑,我当年踩过。Clark变换有两种主流形式:
| 变换类型 | 变换矩阵系数 | 特点 | 适用场景 |
|---|---|---|---|
| 等幅值变换 | 2/3 | 变换前后电流幅值不变 | 电流环调试、波形观察 |
| 等功率变换 | √(2/3) | 变换前后功率不变 | 功率计算、效率分析 |
等幅值变换的好处是:你用示波器看Iα,波形幅值和Ia一模一样,调试时非常直观。等功率变换的好处是:功率计算不用额外乘系数,适合做效率优化。
我曾经在一个项目中用了等功率变换,结果电流环的PI参数怎么调都不对。后来发现是变换系数没对齐——电流环用的是等幅值,Park变换又用了等功率,两个系数打架了。从那以后,我统一用等幅值变换,省心。
3.4 代码实现
好了,理论讲完了,咱们直接上代码。这是我在STM32上实际跑过的Clark变换实现:
/**
* @brief Clark变换
* @param Ia, Ib, Ic: 三相电流采样值
* @param pIalpha, pIbeta: 变换后的αβ轴电流
* @note 等幅值变换,系数2/3
*/
void Clark_Transform(float Ia, float Ib, float Ic,
float *pIalpha, float *pIbeta)
{
// 系数1/3,避免重复计算
float one_third = 1.0f / 3.0f;
// α轴:与a轴重合
*pIalpha = Ia - 0.5f * Ib - 0.5f * Ic;
// β轴:与α轴垂直
*pIbeta = 0.8660254f * (Ib - Ic); // √3/2 ≈ 0.8660254
// 等幅值变换,乘2/3
*pIalpha *= 0.6666667f; // 2/3
*pIbeta *= 0.6666667f;
}
这段代码有几个细节要注意:
- 系数预计算:0.5、0.8660254、0.6666667都是常量,不要每次调用都算一遍
- 浮点精度:STM32F4有FPU,直接用float没问题。如果是F1系列,建议用Q15定点数
- 输入校验:实际项目中,ADC采样可能有噪声,建议加个简单的限幅滤波
3.5 验证方法
代码写完了,怎么验证对不对?我一般用两种方法:
方法一:数学验证
给一组已知的输入,手动算一遍,再和代码输出对比。比如:
输入:Ia = 1.0, Ib = -0.5, Ic = -0.5
预期输出:Iα = 1.0, Iβ = 0.0
输入:Ia = 0.0, Ib = 0.866, Ic = -0.866
预期输出:Iα = 0.0, Iβ = 1.0
方法二:波形验证
用DAC输出Iα和Iβ,接示波器看波形。给电机通三相正弦电流,Iα和Iβ应该是两个相位差90°的正弦波。如果波形有畸变或者幅值不对,说明变换系数有问题。
3.6 Clark变换的SVG流程图
下面这张图展示了Clark变换的完整流程,从三相电流采样到αβ轴输出:
3.7 常见问题与避坑
最后,我总结几个Clark变换的常见坑:
- 系数选错:等幅值和等功率混用,导致电流环震荡。统一用一种,我推荐等幅值。
- ADC采样顺序:三相电流不是同时采的,会有时间差。如果转速高,这个时间差会导致变换误差。我一般用双ADC同步采样,或者做软件补偿。
- 浮点运算速度:Clark变换本身计算量不大,但如果放在高频中断里(比如20kHz),每次调用都算一遍系数会浪费CPU。建议把常量预计算好,用宏定义或者const变量。
- 零序电流:如果电机是Y型接法且中性点不接地,理论上Ia+Ib+Ic=0。但实际中ADC采样有误差,建议在变换前做一次零序补偿:Izero = (Ia+Ib+Ic)/3,然后Ia -= Izero,以此类推。
Clark变换是FOC的基石,看似简单,但细节决定成败。把这一步做扎实了,后面的Park变换和SVPWM才能顺利推进。