1. FOC控制基础:永磁同步电机数学模型与坐标变换
各位同学,咱们今天正式开讲FOC控制的第一章。说实话,FOC这名字听起来挺唬人,什么磁场定向控制、矢量控制……但说白了,它就是让电机转得又稳又准的一套方法论。我当年刚接触时也被一堆公式吓到过,后来发现,只要把几个核心概念吃透,剩下的都是套路。
这一章咱们要搞定三件事:PMSM的数学模型、Clark变换与Park变换、SVPWM调制技术。这三块是FOC的基石,缺一不可。
本章核心脉络:物理模型 → 数学抽象 → 坐标变换 → 电压调制。每一步都是为了把复杂的交流电机控制,简化成类似直流电机的控制方式。
1.1 永磁同步电机(PMSM)的数学模型
先聊聊PMSM本身。永磁同步电机,转子是永磁体,定子是三相绕组。你给它通三相交流电,就会产生旋转磁场,拖着转子一起转。听起来简单,但真要控制好,得先建个数学模型。
我习惯从电压方程和磁链方程入手。在ABC三相静止坐标系下,电压方程长这样:
u_a = R_s * i_a + dψ_a/dt
u_b = R_s * i_b + dψ_b/dt
u_c = R_s * i_c + dψ_c/dt
其中ψ_a、ψ_b、ψ_c是各相磁链,包含自感和互感,还有转子永磁体贡献的部分。这方程本身不复杂,但麻烦在于——电感是随转子位置变化的。你想想看,转子转到一个位置,A相绕组和永磁体的相对位置变了,电感值也跟着变。这就导致方程是时变的,直接求解非常痛苦。
我的经验:千万别在ABC坐标系下硬算PID,那是在给自己挖坑。我早期一个项目就这么干过,结果参数调了两个月,效果还是一塌糊涂。后来老老实实做坐标变换,一周就搞定了。
好在有磁链方程帮我们理清关系:
ψ_a = L_aa * i_a + M_ab * i_b + M_ac * i_c + ψ_f * cos(θ)
ψ_b = M_ba * i_a + L_bb * i_b + M_bc * i_c + ψ_f * cos(θ - 120°)
ψ_c = M_ca * i_a + M_cb * i_b + L_cc * i_c + ψ_f * cos(θ + 120°)
ψ_f是永磁体磁链,θ是转子电角度。看到没?电感矩阵里全是位置相关的项。这就是为什么我们要做坐标变换——把时变系统变成时不变系统。
1.2 Clark变换:从ABC到αβ
Clark变换是第一步。它的任务是把三相静止坐标系(ABC)下的量,映射到两相静止坐标系(αβ)下。说白了,就是用两个正交的轴来代替三个互差120°的轴。
变换公式很简单:
[i_α] [1, -1/2, -1/2 ] [i_a]
[i_β] = [0, √3/2, -√3/2] [i_b]
[i_c]
这是等幅值变换,我项目中一直用这种。还有一种等功率变换,系数不同,但原理一样。
为什么要做Clark变换?因为三个变量不好处理,两个变量就舒服多了。而且αβ轴是正交的,后续做旋转变换更方便。
注意:Clark变换本身不改变信号的频率特性。它只是把三相的交流量,映射成两相的交流量。α轴和β轴上的分量仍然是正弦波,频率和原来一样。
我记得第一次在STM32上实现Clark变换时,踩过一个坑——电流采样时序。三相电流必须同时采样,或者至少在一个PWM周期内完成。如果分时采样,相位差会导致变换结果失真。后来我改用双ADC同步采样,问题才解决。
1.3 Park变换:从αβ到dq
Clark变换之后,我们有了αβ坐标系下的交流量。但交流量控制起来还是麻烦,PI调节器对交流信号的跟踪效果并不好。这时候就需要Park变换出场了。
Park变换的核心思想是:把旋转的坐标系,对准转子磁场方向。这样,原来在αβ坐标系下旋转的矢量,在dq坐标系下就变成了直流量。
变换公式:
[i_d] [cos(θ), sin(θ)] [i_α]
[i_q] = [-sin(θ), cos(θ)] [i_β]
其中θ是转子电角度,由编码器或霍尔传感器提供。
变换之后,d轴对应励磁分量,q轴对应转矩分量。对于表贴式PMSM(SPMSM),我们通常让i_d=0,只控制i_q来产生转矩。对于内置式PMSM(IPMSM),还会用到最大转矩电流比(MTPA)控制,让i_d为负值。
| 坐标系 | 变量性质 | 控制难度 | 典型应用 |
|---|---|---|---|
| ABC(三相静止) | 时变交流 | 高 | 直接六步换向 |
| αβ(两相静止) | 时变交流 | 中 | 滞环电流控制 |
| dq(两相旋转) | 时不变直流 | 低 | FOC矢量控制 |
你看这个表格就明白了。从ABC到αβ再到dq,变量从交流变成了直流,控制难度直线下降。这就是FOC的精髓——通过坐标变换,把交流电机控制问题,转化成直流电机控制问题。
关键点:Park变换需要准确的转子位置信息。角度误差会直接导致dq轴耦合,影响控制性能。我建议使用高分辨率编码器(至少1024线),并在软件中做角度补偿。
1.4 SVPWM调制技术详解
好了,现在我们已经通过PI调节器算出了想要的d轴和q轴电压。但问题是——怎么让三相逆变器输出这个电压矢量?
这就是SVPWM(空间矢量脉宽调制)要做的事。相比传统的SPWM(正弦脉宽调制),SVPWM的电压利用率更高(高约15%),谐波更小。
SVPWM的基本原理是:用八个基本电压矢量(六个非零矢量+两个零矢量),来合成任意目标电压矢量。
六个非零矢量把平面分成六个扇区,每个扇区60°。目标矢量落在哪个扇区,就用相邻的两个非零矢量和零矢量来合成。合成原则是伏秒平衡:
U_ref * T_s = U_x * T_x + U_y * T_y + U_0 * T_0
其中T_s是PWM周期,T_x和T_y是两个相邻非零矢量的作用时间,T_0是零矢量作用时间。
具体实现步骤:
- 判断扇区:根据U_α和U_β的符号和比值,确定目标矢量在哪个扇区
- 计算作用时间:根据扇区查表,计算T_x、T_y、T_0
- 计算占空比:将作用时间映射到三相PWM比较值
- 生成PWM:更新STM32定时器的CCR寄存器
实现技巧:STM32的定时器支持中心对齐模式,非常适合SVPWM。我一般用TIM1或TIM8的高级定时器,配置成中央对齐PWM,死区时间设为1-2μs(根据功率管型号调整)。
代码实现片段(基于STM32 HAL库):
// 扇区判断
uint8_t svpwm_sector_calc(float U_alpha, float U_beta) {
uint8_t sector = 0;
if (U_beta > 0) sector |= 0x01;
if (sqrtf(3)*U_alpha - U_beta > 0) sector |= 0x02;
if (-sqrtf(3)*U_alpha - U_beta > 0) sector |= 0x04;
return sector;
}
// 计算作用时间
void svpwm_calc_times(float U_alpha, float U_beta, float *T1, float *T2) {
// 根据扇区查表计算
// 具体实现略,参考TI或ST的电机库
}
避坑指南:我曾经在SVPWM的过调制区吃过亏。当目标电压矢量幅值超过六边形内切圆时,需要做过调制处理。如果不处理,输出波形会畸变,电机噪音大、发热严重。建议在调制比超过0.906时,采用最小幅值误差过调制策略。
最后说一句,SVPWM的载波频率选择也很关键。频率太高,开关损耗大;频率太低,电流谐波大。我一般选10kHz-20kHz,兼顾损耗和性能。对于大功率应用,可以降到5kHz-8kHz。
好了,这一章的内容就到这里。数学公式虽然多,但核心逻辑很清晰:建模 → 变换 → 调制。把这套流程走通,FOC的大门就为你敞开了。