3. 电压前馈解耦:d-q轴电压方程与交叉耦合项补偿

做FOC的人,迟早都会碰到一个问题——d轴和q轴明明是两个独立的控制通道,怎么调来调去总觉得它们在互相拉扯?

这种现象,说白了就是交叉耦合在作怪。我刚开始做电机控制那会儿,也在这上面栽过跟头。当时调一个高速电机,d轴电流一上去,q轴电流就往下掉,PID怎么整都整不好。后来才明白,不是PID不行,是耦合项没处理。

3.1 d-q轴电压方程回顾

先看基础。永磁同步电机在同步旋转坐标系下的电压方程长这样:

Vd = Rs·Id + Ld·(dId/dt) - ωe·Lq·Iq
Vq = Rs·Iq + Lq·(dIq/dt) + ωe·(Ld·Id + ψf)

这里面,-ωe·Lq·Iq 和 +ωe·(Ld·Id + ψf) 就是交叉耦合项。它们把d轴和q轴绑在了一起。

你想想看,当电机转速ωe升高时,耦合项的幅值也跟着变大。低速时还好说,到了高速弱磁区间,耦合项可能比电阻压降还大好几倍。这时候如果不去管它,两个轴的控制就会互相干扰。

核心理解:交叉耦合的本质是反电动势和磁链在d-q轴之间的能量交换。它不是故障,是物理规律。我们要做的不是消除它,而是补偿它。

3.2 耦合项对控制性能的影响

耦合带来的问题,我归纳成三点:

  • 动态响应变慢——调d轴时q轴跟着抖,两个环路互相等待
  • 稳态精度下降——耦合项相当于一个随转速变化的扰动,PI控制器很难完全抑制
  • 参数敏感度增加——电感Ld、Lq不准时,耦合补偿效果打折扣

我在一个项目里遇到过这样的情况:电机转速到3000rpm以上时,q轴电流纹波突然变大,怎么调PI参数都没用。后来用示波器抓了d-q轴电压波形才发现,是耦合项在作祟。补偿加上去之后,纹波直接降了一半。

3.3 前馈解耦原理

前馈解耦的思路其实很直接——既然知道耦合项长什么样,那就主动把它算出来,加到控制输出里抵消掉。

具体做法是:

  1. 从电流环PI控制器输出Vd_pi、Vq_pi
  2. 根据当前转速ωe和电流Iq、Id,算出耦合补偿量
  3. 把补偿量加到PI输出上,得到最终的Vd_ref、Vq_ref

公式表达就是:

Vd_ref = Vd_pi - ωe·Lq·Iq
Vq_ref = Vq_pi + ωe·(Ld·Id + ψf)

嗯,这里要注意——补偿量的符号和电压方程里的耦合项符号是相反的。目的就是让它们互相抵消。

个人习惯:我一般把前馈补偿放在PI控制器之后、SVPWM之前。这样PI控制器只负责处理误差,前馈负责处理已知的耦合扰动,分工明确。

3.4 数字实现中的注意事项

把上面的公式写成代码,看起来很简单。但实际做起来有几个坑:

注意事项 说明 我的建议
时序对齐 补偿用的电流值必须是当前周期的采样值 用上一周期的电流做补偿,会有相位滞后
电感参数误差 Ld、Lq会随电流变化 建议做查表补偿,或者在线辨识
转速信号质量 ωe噪声会直接引入补偿量 对转速做低通滤波,截止频率别太低
饱和处理 补偿后电压可能超过母线限制 先限幅再输出,或者做抗饱和处理

我曾经在一个项目里吃过亏——转速信号没滤波,结果补偿量里全是高频噪声,电流环反而更不稳定了。后来加了个截止频率200Hz的一阶低通,问题就解决了。

3.5 前馈解耦与PI控制器的配合

加上前馈之后,PI控制器的参数可以怎么调?

我的经验是:

  • 比例增益Kp可以适当降低——因为前馈已经处理了大部分扰动,PI不用那么激进
  • 积分增益Ki基本不变——积分还是负责消除稳态误差
  • 带宽可以推高——解耦后两个轴独立了,电流环带宽可以比不解耦时高20%~30%

避坑指南:不要以为加上前馈就万事大吉。如果电感参数偏差超过30%,前馈补偿反而会引入新的扰动。我曾经遇到过标称电感值和实际值差了40%的情况,补偿后电流环直接振荡了。所以,参数不准时,宁可补偿系数打八折,也别硬上。

3.6 弱磁区间的特殊处理

进入弱磁区间后,d轴电流Id变成负值,而且幅值越来越大。这时候耦合项ωe·(Ld·Id + ψf)会变小,甚至变负。

这意味着什么?

在弱磁区,q轴的反电动势被d轴的去磁效应抵消了一部分。如果还用恒定的ψf做前馈,补偿量会偏大。我建议的做法是:

  1. 实时计算ψf + Ld·Id作为等效磁链
  2. 用这个等效磁链做q轴前馈补偿
  3. d轴前馈补偿中的Lq·Iq项不变

这样在弱磁区也能保持解耦效果。

3.7 前馈解耦的整体流程

下面这张图展示了前馈解耦在FOC中的位置和信号流向:

前馈解耦在FOC中的位置与信号流向 Id_ref Iq_ref PI控制器(d) PI控制器(q) Vd_pi Vq_pi 前馈补偿计算 -ωe·Lq·Iq / +ωe·(Ld·Id+ψf) Vd_ref Vq_ref SVPWM → 逆变器 ωe(电角速度) Id, Iq(反馈)

从图上可以看到,前馈补偿计算需要三个输入:转速ωe、反馈电流Id和Iq。补偿结果分别叠加到d轴和q轴的PI输出上,形成最终的电压参考值。

3.8 代码实现示例

下面是一个简化的前馈解耦实现,我用C语言写的,适合嵌入到中断服务函数里:

typedef struct {
    float Ld;       // d轴电感 (H)
    float Lq;       // q轴电感 (H)
    float psi_f;    // 永磁体磁链 (Wb)
    float vd_ff;    // d轴前馈补偿量
    float vq_ff;    // q轴前馈补偿量
} FeedForward_t;

void FeedForward_Calc(FeedForward_t *ff, float Id, float Iq, float omega_e) {
    // d轴前馈:-ωe·Lq·Iq
    ff->vd_ff = -omega_e * ff->Lq * Iq;

    // q轴前馈:+ωe·(Ld·Id + ψf)
    ff->vq_ff =  omega_e * (ff->Ld * Id + ff->psi_f);
}

void CurrentLoop_WithFF(float Id_ref, float Iq_ref, float Id_fb, float Iq_fb, float omega_e) {
    float vd_pi, vq_pi;
    float vd_ref, vq_ref;

    // 1. PI控制器计算(省略内部实现)
    vd_pi = PI_Controller(&pi_d, Id_ref - Id_fb);
    vq_pi = PI_Controller(&pi_q, Iq_ref - Iq_fb);

    // 2. 前馈补偿计算
    FeedForward_Calc(&ff, Id_fb, Iq_fb, omega_e);

    // 3. 叠加补偿量
    vd_ref = vd_pi + ff.vd_ff;
    vq_ref = vq_pi + ff.vq_ff;

    // 4. 限幅处理
    Voltage_Limit(&vd_ref, &vq_ref, Vdc);

    // 5. 输出到SVPWM
    SVPWM_SetVoltage(vd_ref, vq_ref);
}

一个小技巧:如果电感参数不太准,可以在前馈补偿前加一个可调系数Kff。调试时从0.8开始,慢慢往上加,直到电流环响应最好为止。我一般用0.9~1.0之间的值。