4. 矢量控制(FOC)原理:电流环、速度环、位置环的PI调节器设计,SVPWM调制技术

矢量控制,圈里人常叫它FOC。说白了,就是让电机像直流电机一样听话。我刚开始接触这个技术时,觉得它挺玄乎的,后来亲手调过几套系统才明白——它就是把交流电机的电流分解成“励磁”和“转矩”两个分量,然后分别控制。

嗯,咱们今天就把FOC的核心拆开揉碎了讲。重点放在三个闭环的PI调节器怎么设计,还有SVPWM到底是怎么把电压“变”出来的。

核心思路:FOC的本质是坐标变换。把静止的三相电流,通过Clark变换转到两相静止坐标系,再通过Park变换转到旋转坐标系。在旋转坐标系下,电流变成了直流量,用PI控制就顺理成章了。

4.1 电流环:FOC的“内功心法”

电流环是三个环里最快的一个。我习惯把它的带宽设到速度环的5~10倍。为什么?因为电流响应慢了,速度环和位置环的控制精度都会受影响。

电流环的PI调节器设计,我一般用“零极点对消法”。先测出电机的电气时间常数τ = L/R,然后把PI调节器的积分时间常数Ti设成跟τ一样。这样,被控对象的极点就被PI的零点抵消了。

// 电流环PI参数计算示例
// 电机参数:Rs = 0.5Ω, Ls = 5mH
// 电气时间常数 τ = Ls / Rs = 0.01s

// 设定电流环带宽 fc = 1000Hz
// 比例增益 Kp = Ls * 2π * fc = 0.005 * 6283 ≈ 31.4
// 积分增益 Ki = Kp / τ = 31.4 / 0.01 = 3140

float Kp_iq = 31.4f;   // q轴电流环比例增益
float Ki_iq = 3140.0f; // q轴电流环积分增益
float Kp_id = 31.4f;   // d轴电流环比例增益
float Ki_id = 3140.0f; // d轴电流环积分增益

我的经验:实际调试时,Kp可以先给计算值的一半,然后慢慢往上加。加到电流波形开始出现振荡时,回调20%左右。积分项Ki我习惯先给Kp的1/τ,再根据稳态误差微调。

d轴和q轴的电流环参数可以设成一样,前提是电机的Ld和Lq差别不大。对于内置式永磁同步电机(IPMSM),Ld和Lq可能差好几倍,这时候就得分别整定了。

4.2 速度环:承上启下的“中坚力量”

速度环在电流环外面。它的输出就是电流环的给定值(通常是iq*)。速度环的带宽一般设到电流环的1/5~1/10。

速度环的PI设计,我推荐用“对称最优法”。为什么?因为速度环的被控对象是积分环节加惯性环节,对称最优法能给出比较好的相位裕度。

参数 计算公式 说明
Kp_speed J * ωc / (1.5 * p * ψf) J:转动惯量,ωc:速度环带宽,p:极对数,ψf:永磁体磁链
Ki_speed Kp_speed / (4 * h * Ts) h:中频宽(一般取5~10),Ts:速度环采样周期

我曾经在一个项目中遇到过速度环振荡的问题。当时怎么调Kp和Ki都没用,后来发现是速度反馈的滤波时间常数太大了。把滤波从10ms降到2ms,问题就解决了。你想想看,反馈信号滞后太多,PI调节器就会“乱猜”当前状态。

注意:速度环的积分限幅一定要做。我见过有人忘了限幅,结果积分项越积越大,电机突然加速到飞车。嗯,这个教训挺深刻的。

4.3 位置环:最外层的“指挥官”

位置环是最外层的环。它的输出是速度环的给定值。位置环的带宽通常设到速度环的1/5左右。

位置环的PI设计,我习惯只用P控制,不加I。为什么?因为位置环的稳态误差可以通过前馈补偿来消除,加积分反而容易引起超调和振荡。

// 位置环P控制示例
// 位置环比例增益 Kp_pos = 20
// 位置误差限幅:防止积分饱和(虽然没用积分,但输出要限幅)

float pos_error = target_position - current_position;
float speed_ref = Kp_pos * pos_error;

// 限幅
if(speed_ref > MAX_SPEED) speed_ref = MAX_SPEED;
if(speed_ref < -MAX_SPEED) speed_ref = -MAX_SPEED;

如果要求位置精度特别高,比如伺服系统,我会加一个速度前馈。前馈量直接从位置指令的微分得到。这样,位置环的P增益可以设小一点,系统更稳定。

4.4 SVPWM调制技术:把电压“算”出来

SVPWM,全称是空间矢量脉宽调制。它跟传统的SPWM比,电压利用率更高,谐波更小。我刚开始做FOC时,用的就是SPWM,后来换成SVPWM,同样的母线电压,电机转速能提15%左右。

SVPWM的核心思想:把三相逆变器的8种开关状态映射到复平面上,形成6个非零矢量和2个零矢量。然后通过合成这些矢量,得到任意方向和大小的电压矢量。

SVPWM空间矢量与扇区划分 扇区I 扇区II 扇区III 扇区IV 扇区V 扇区VI U₄(100) U₁(001) U₆(110) U₂(010) U₃(011) U₅(101) U₀(000)/U₇(111) Uref θ 图例: 基本电压矢量 参考电压矢量Uref 零矢量

SVPWM的实现步骤,我总结为三步:

  1. 判断扇区:根据Uα和Uβ的符号和大小关系,确定参考电压矢量在哪个扇区。
  2. 计算作用时间:用相邻两个非零矢量和零矢量来合成参考矢量,算出每个矢量的作用时间T1、T2、T0。
  3. 生成PWM波:根据作用时间,计算出三相的比较值,写入定时器比较寄存器。
// SVPWM扇区判断与时间计算(简化版)
// 输入:Ualpha, Ubeta(归一化到0~1之间)
// 输出:Ta, Tb, Tc(三相PWM比较值)

// 第一步:判断扇区
float U1 = Ubeta;
float U2 = 0.866f * Ualpha - 0.5f * Ubeta;
float U3 = -0.866f * Ualpha - 0.5f * Ubeta;

int sector = 0;
if(U1 > 0) sector |= 1;
if(U2 > 0) sector |= 2;
if(U3 > 0) sector |= 4;

// 第二步:计算X, Y, Z
float X = Ubeta;
float Y = 0.866f * Ualpha + 0.5f * Ubeta;
float Z = -0.866f * Ualpha + 0.5f * Ubeta;

// 第三步:根据扇区计算T1, T2
float T1, T2;
switch(sector) {
    case 1: T1 = Z; T2 = Y; break;
    case 2: T1 = Y; T2 = -X; break;
    case 3: T1 = -Z; T2 = X; break;
    case 4: T1 = -X; T2 = Z; break;
    case 5: T1 = X; T2 = -Y; break;
    case 6: T1 = -Y; T2 = -Z; break;
}

// 第四步:计算三相占空比
float T0 = 1.0f - T1 - T2;
float Ta = (1.0f - T1 - T2) * 0.5f;
float Tb = Ta + T1;
float Tc = Tb + T2;

我的调试技巧:SVPWM最容易出问题的地方是扇区判断的边界条件。我建议在扇区切换点附近加一个滞回区,比如±0.01的死区,避免频繁切换导致PWM波形抖动。

还有一个细节:SVPWM的调制比最高可以达到1.1547,比SPWM的1.0高了15.47%。这意味着同样的母线电压,SVPWM能让电机跑得更快。我在做无人机电调时,就靠这个多榨出了几百转的转速。

4.5 三个环的协同调试

三个环的调试顺序,我建议从内到外:先调电流环,再调速度环,最后调位置环。千万别反过来调,否则你都不知道问题出在哪一层。

调试电流环时,把电机堵转(或者用负载模拟器),给一个阶跃电流指令,看电流的响应速度。我一般要求电流环的上升时间在1ms以内。

速度环调试时,让电机空载运行,给一个速度阶跃,观察速度的超调和稳态误差。我习惯把超调控制在5%以内。

位置环调试时,给一个位置阶跃,看定位精度和响应时间。对于大多数应用,位置精度达到0.1度就够用了。

避坑指南:我曾经在一个项目中,三个环单独调都没问题,联调时却振荡了。查了两天才发现,是电流环的采样频率和速度环的更新频率不匹配。电流环跑20kHz,速度环跑2kHz,中间差了10倍,导致速度环看到的电流是“跳变”的。后来把速度环的更新频率降到1kHz,问题就解决了。

好了,FOC的核心内容就这些。电流环、速度环、位置环的PI设计,加上SVPWM调制,构成了矢量控制的完整闭环。你把这些吃透了,大部分电机控制项目都能拿得下来。

本章要点回顾:

  • 电流环PI用零极点对消法,带宽设到速度环的5~10倍
  • 速度环PI用对称最优法,注意反馈滤波时间常数
  • 位置环建议只用P控制,必要时加前馈
  • SVPWM比SPWM电压利用率高15%,实现分三步:判扇区、算时间、生成PWM
  • 调试顺序:电流环→速度环→位置环,从内到外

专注资料整理