欢迎光临
我们一直在努力

无感 FOC 算法控制无刷电机:从原理到启动调试讲清楚

目录

1. FOC 到底在控制什么

2. 为什么 FOC 必须知道转子角度

3. 电角度和机械角度不要混

4. Clarke 和 Park 变换到底是干什么的

5. 无感 FOC 的角度从哪里来

6. PLL 锁相环为什么重要

7. 为什么无感 FOC 不能直接零速闭环启动

8. 预定位:先把转子拉到已知位置

9. 开环加速:先让反电动势变得可用

10. 什么时候切入无感闭环

11. 角度融合:比直接切换更稳

12. 电流环:先把底层控制调稳

13. SVPWM:把算法结果变成真正的 PWM

14. 电流采样:很多问题其实不是算法错

15. 电压重构:观测器需要真实电压

16. 高速角度补偿:别忽略控制延迟

17. 推荐调试顺序

17.1 检查硬件和采样

17.2 开环拖动

17.3 观测器旁路运行

17.4 中高速切闭环

17.5 优化启动

18. 常见问题和排查方向

18.1 启动时只是抖,不转

18.2 电机能转,但电流很大

18.3 一切闭环就卡死或过流

18.4 中高速突然失步

18.5 低速闭环不稳定

19. 一组比较实用的初始参数

20. 总结


做无刷电机控制时,很多人都会遇到一个现象:电机开环能转,切到闭环就抖;有霍尔能跑,去掉霍尔以后就不稳定;中高速还能凑合,低速和启动阶段总是翻车。

这些问题看起来很杂,其实都绕不开一个核心点:

FOC 必须知道转子角度,而无感 FOC 的难点,就是在没有位置传感器的情况下,把这个角度估出来。

这篇文章不按论文那套写,也不堆一堆看完就忘的公式。我们按实际调试电机的顺序来讲:

  • FOC 到底在控制什么;

  • 为什么一定要知道转子角度;

  • 无感控制怎么估算角度;

  • 为什么无感 FOC 不能直接零速闭环;

  • 启动、切换、调试时应该重点看哪里。


1. FOC 到底在控制什么

无刷电机里面有三相绕组。控制器给三相绕组通电,定子会产生旋转磁场,转子永磁体跟着这个磁场转起来。

普通六步换相也能让电机转,但它的控制比较粗糙,常见问题是转矩脉动大、噪声大、低速不够平滑。

FOC 的思路更细。它不是简单地判断“现在该给哪两相通电”,而是想办法把电流分解成两个方向:

电流含义主要作用
i_d d 轴电流 影响磁链
i_q q 轴电流 产生转矩

对于常见的表贴式永磁同步电机,一般希望:

i_d = 0

也就是说,尽量不要把电流浪费在 d 轴上,而是把主要电流用在 q 轴上产生转矩。

所以 FOC 的核心,不只是让电机“能转”,而是让电机“转得顺、噪声低、电流利用率高”。


2. 为什么 FOC 必须知道转子角度

FOC 要把电流分成 i_d 和 i_q,就必须知道转子磁场当前指向哪里。

如果不知道转子位置,就不知道哪个方向是 d 轴,哪个方向是 q 轴。

有编码器、旋变或者霍尔传感器时,角度可以直接读出来,这就是有感 FOC。

无感 FOC 没有这些传感器,所以角度只能靠算法估算。

无感 FOC 的基本链路可以理解成这样:

采样相电流
-> 根据电压和电流估算反电动势
-> 从反电动势中估算转子角度
-> 用估算角度做 Park 变换
-> 电流环算出需要的电压
-> 通过 SVPWM 输出三相 PWM
-> 驱动电机继续运行

这里最关键的是第三步:角度估算是否可靠。

角度准,FOC 才能真正发挥作用。角度偏了,电流就会打歪,轻则电流变大、发热增加,重则直接失步或过流。


3. 电角度和机械角度不要混

很多人第一次调 FOC 时,会把机械角度和电角度搞混。

机械角度是转子实际转过的机械角度,通常记作:

theta_m

电角度是控制算法里真正使用的角度,通常记作:

theta_e

两者关系为:

theta_e = p * theta_m

其中,p 是电机极对数。

例如:

电机极数极对数 p
2 极 1
4 极 2
14 极 7

也就是说,14 极电机机械上转一圈,电角度会转 7 圈。

所以调试时一定要分清:

  • 机械速度;

  • 电角速度;

  • 机械角度;

  • 电角度。

FOC 里面做 Park 变换用的是电角度,不是机械角度。


4. Clarke 和 Park 变换到底是干什么的

很多人学 FOC,第一个卡住的地方就是 Clarke 变换和 Park 变换。

其实它们的目的很简单:

把不好控制的三相交流量,变成容易控制的直流量。

电机三相电流是:

i_a, i_b, i_c

这三个电流随着电机转动不断变化。如果直接对它们做 PI 控制,并不方便。

FOC 会先做 Clarke 变换,把三相电流变成两相静止坐标下的电流:

i_alpha, i_beta

常用形式是:

i_alpha = i_a

i_beta = (i_a + 2 * i_b) / sqrt(3)

代码里可以写成:

i_alpha = ia;
i_beta = (ia + 2.0f * ib) * 0.57735026919f;

Clarke 变换之后,三相电流就变成了平面上的一个电流矢量。

但这个矢量仍然是在静止坐标系里看的。电机一转,它也在转。

所以还要做 Park 变换,把静止坐标系变成跟着转子一起转的坐标系:

i_d = i_alpha * cos(theta_e) + i_beta * sin(theta_e)

i_q = -i_alpha * sin(theta_e) + i_beta * cos(theta_e)

这里的 theta_e 就是转子电角度。

Park 变换本身不难,难的是你传进去的 theta_e 到底准不准。

如果 theta_e 错了,变换出来的 i_d 和 i_q 就不是真正的 d 轴和 q 轴电流,后面的电流环再怎么调也很难稳定。


5. 无感 FOC 的角度从哪里来

无感 FOC 没有位置传感器,常见做法是利用反电动势估算转子位置。

电机旋转时,转子永磁体会让定子绕组产生感应电压,这个电压就是反电动势。

可以简单理解为:

电机一边被驱动,一边也在“发电”。这个发出来的电压里,包含了转子位置的信息。

在 alpha-beta 坐标系下,电机电压方程可以写成:

u_alpha = R * i_alpha + L * d(i_alpha)/dt + e_alpha

u_beta = R * i_beta + L * d(i_beta)/dt + e_beta

整理一下:

e_alpha = u_alpha – R * i_alpha – L * d(i_alpha)/dt

e_beta = u_beta – R * i_beta – L * d(i_beta)/dt

其中:

  • u_alpha、u_beta 是定子电压;

  • i_alpha、i_beta 是定子电流;

  • R 是相电阻;

  • L 是相电感;

  • e_alpha、e_beta 是反电动势。

理论上,只要知道电压、电流、电阻和电感,就可以估算反电动势,再由反电动势推算角度。

但实际工程里没这么理想。

反电动势会受到很多因素影响:

  • ADC 采样噪声;

  • PWM 开关噪声;

  • MOS 管死区;

  • 母线电压波动;

  • 电机参数误差;

  • 电流采样零偏;

  • 低速时信号太弱。

所以一般不会直接用一次反正切函数就得到最终角度,而是会加观测器和 PLL,让角度估算更平滑、更抗噪。


6. PLL 锁相环为什么重要

反电动势可以提供角度信息,但这个信息并不干净。

如果直接用反电动势算角度,角度会跟着噪声一起抖。角度一抖,Park 变换就抖,电流环也会跟着抖。

PLL 的作用可以理解为:

不直接相信每一次瞬时计算结果,而是平滑地跟踪反电动势方向。

PLL 通常会输出两个量:

theta_hat_e

omega_hat_e

其中:

  • theta_hat_e 是估算电角度;

  • omega_hat_e 是估算电角速度。

实际调试时,不建议一开始就死抠某一个 PLL 公式。因为不同项目里,相序、电角度方向、Park 变换符号、反电动势定义都可能不一样。

更靠谱的做法是:

  • 先开环拖动电机;

  • 让观测器和 PLL 在后台运行;

  • 先不要把估算角度用于控制;

  • 观察开环角度和估算角度是否方向一致、变化连续;

  • 再决定符号和参数是否正确。

  • 很多无感 FOC 跑不起来,不是整个算法错了,而是某个符号反了。


    7. 为什么无感 FOC 不能直接零速闭环启动

    这是无感 FOC 最容易踩坑的地方。

    基于反电动势的无感控制有一个物理限制:

    反电动势大小和转速有关。

    转速高,反电动势明显。 转速低,反电动势很弱。 电机静止时,反电动势基本为零。

    所以在零速时,观测器几乎没有有效信号,PLL 也没有可靠目标可以跟踪。

    这就导致一个很现实的问题:

    基于反电动势的无感 FOC,通常不能从静止状态直接闭环启动。

    它必须先通过某种办法把电机拖起来,等转速达到一定程度、反电动势足够明显后,再切入无感闭环。

    典型启动流程是:

    IDLE -> ALIGN -> OPEN_LOOP -> SENSORLESS_CLOSED_LOOP

    也就是:

  • 待机;

  • 预定位;

  • 开环加速;

  • 无感闭环。


  • 8. 预定位:先把转子拉到已知位置

    上电时,控制器不知道转子停在哪里。

    既然不知道,就先用一个固定方向的磁场,把转子吸到一个已知位置。

    这一步叫预定位。

    代码上可能是这样:

    theta_e = 0.0f;
    id_ref = align_current;
    iq_ref = 0.0f;

    预定位阶段的目标不是让电机转,而是让转子对齐。

    调预定位时要注意:

    • 电流太小,转子吸不过来;

    • 电流太大,电机发热、抖动明显;

    • 时间太短,转子还没稳定;

    • 带负载启动时,时间通常要更长。

    常见起始范围可以设为:

    t_align = 300 ms ~ 800 ms

    这个范围不是标准答案,只是调试起点。不同电机、不同负载需要重新调整。


    9. 开环加速:先让反电动势变得可用

    预定位结束后,控制器有了一个已知初始角度。

    接下来进入开环加速阶段。

    这个阶段暂时不用观测器角度,而是人为生成一个逐渐增加的电角度:

    theta_open(k + 1) = theta_open(k) + omega_open(k) * Ts

    同时让开环速度逐渐增加:

    omega_open(k + 1) = omega_open(k) + accel_open * Ts

    代码上可以写成:

    theta_open += omega_open * Ts;
    omega_open += accel_open * Ts;

    这个阶段的目的很明确:

    先把电机拖到一定速度,让反电动势变得明显。

    开环加速最常见的问题有两个。

    第一个是加速度太大。 如果定子磁场跑得太快,转子跟不上,就会失步。表现是电机抖一下、电流上去,但转不起来。

    第二个是启动电流太小。 如果启动电流不够,磁场拉不动转子,尤其是带负载时,电机会嗡嗡响但速度上不去。

    所以开环启动阶段一般要一起调:

    • 预定位电流;

    • 预定位时间;

    • 开环启动电流;

    • 开环加速度;

    • 开环目标速度;

    • 切闭环速度。


    10. 什么时候切入无感闭环

    很多程序会用一个速度阈值切闭环:

    if (omega_open > omega_switch)
    {
    use_observer_angle = true;
    }

    这种方法简单,但不一定稳。

    因为“速度到了”不等于“观测器已经可靠”。

    更稳妥的判断应该同时看这些条件:

    • 反电动势幅值是否足够;

    • PLL 误差是否已经收敛;

    • 估算速度是否连续;

    • 电流是否没有明显震荡;

    • 开环角度和观测器角度是否差距不大。

    如果只看速度阈值,可能出现这种情况:

    开环速度到了
    但观测器角度还没稳定
    一切闭环,角度突然跳变
    电流环瞬间输出异常
    电机抖动、失步或过流

    所以无感启动真正难的地方,不只是把电机拖起来,而是把控制权从开环角度平稳交给观测器角度。


    11. 角度融合:比直接切换更稳

    最简单的切换方式是:

    theta_final = theta_observer;

    但如果切换瞬间角度差比较大,电机会明显冲一下。

    更稳的方法是角度融合:

    theta_final = k * theta_open + (1 – k) * theta_hat_e

    其中:

    • theta_open 是开环角度;

    • theta_hat_e 是观测器估算电角度;

    • k 是融合系数,范围是 0 到 1。

    刚启动时:

    k = 1

    完全使用开环角度。

    随着观测器逐渐稳定,让:

    k -> 0

    最后完全使用观测器角度。

    这样切换过程会柔和很多,电流冲击也会小很多。

    进一步优化时,k 不一定只按时间变化,也可以根据观测器可信度变化。例如:

    • 反电动势幅值越大,观测器越可信;

    • PLL 误差越小,观测器越可信;

    • 估算速度越平稳,观测器越可信;

    • 电流波形越正常,观测器越可信。

    实际项目里,这种融合比硬切换更容易调出稳定启动。


    12. 电流环:先把底层控制调稳

    FOC 里面最重要的闭环是电流环。

    电流环的目标是:

    i_d -> id_ref

    i_q -> iq_ref

    常见控制中:

    id_ref = 0

    iq_ref = 转矩需求

    电流环 PI 的输出是电压指令:

    v_d, v_q

    不过逆变器能输出的电压是有限的,所以 PI 一定要做限幅,否则很容易积分饱和。

    一个简化的 PI 可以这样写:

    typedef struct
    {
    float kp;
    float ki;
    float integral;
    float out_min;
    float out_max;
    } PI_Controller;

    float PI_Update(PI_Controller *pi, float ref, float feedback, float dt)
    {
    float error = ref – feedback;

    pi->integral += pi->ki * error * dt;

    if (pi->integral > pi->out_max)
    {
    pi->integral = pi->out_max;
    }
    else if (pi->integral < pi->out_min)
    {
    pi->integral = pi->out_min;
    }

    float output = pi->kp * error + pi->integral;

    if (output > pi->out_max)
    {
    output = pi->out_max;
    }
    else if (output < pi->out_min)
    {
    output = pi->out_min;
    }

    return output;
    }

    调试顺序建议是:

  • 先调电流环;

  • 再调观测器;

  • 然后调切闭环;

  • 最后再调速度环。

  • 不要一上来就电流环、速度环、观测器全部闭上。那样一旦出问题,很难定位。


    13. SVPWM:把算法结果变成真正的 PWM

    电流环输出的是 v_d 和 v_q。

    接下来要通过反 Park 变换得到:

    v_alpha, v_beta

    公式为:

    v_alpha = v_d * cos(theta_e) – v_q * sin(theta_e)

    v_beta = v_d * sin(theta_e) + v_q * cos(theta_e)

    但硬件上,控制器真正能输出的是三相桥的 PWM 占空比。

    所以还需要 SVPWM。

    SVPWM 的作用是:

    把期望的空间电压矢量转换成三相 PWM 占空比。

    整体流程是:

    电流环输出 vd / vq
    |
    v
    反 Park 得到 valpha / vbeta
    |
    v
    SVPWM 计算 duty_a / duty_b / duty_c
    |
    v
    更新 PWM
    |
    v
    驱动三相逆变桥

    初学阶段不一定要马上把 SVPWM 每个扇区公式都背下来。先搞清楚它的位置:

    SVPWM 是 FOC 算法和三相逆变桥之间的接口。


    14. 电流采样:很多问题其实不是算法错

    无感 FOC 对电流采样非常敏感。

    因为观测器、电流环、坐标变换都依赖电流采样。电流采样一旦不准,后面全都会受影响。

    需要重点检查:

    • ADC 零偏是否校准;

    • 三相电流方向是否正确;

    • 采样点是否避开开关噪声;

    • 采样是否和 PWM 同步;

    • 低边采样是否有足够采样窗口;

    • 母线电流采样是否存在盲区;

    • PCB 上强电和弱电是否互相干扰。

    很多电机跑不稳,不是因为 FOC 理论错了,而是电流采样质量太差。

    典型表现包括:

    • 电流波形畸变;

    • 观测器角度抖动;

    • PLL 锁不住;

    • 切闭环时电流突然冲击;

    • 低速运行不稳定。

    所以调无感 FOC 时,不要只盯代码,也要看波形。


    15. 电压重构:观测器需要真实电压

    反电动势观测器需要知道定子电压:

    u_alpha, u_beta

    但实际控制器通常不会直接测三相相电压,而是根据 PWM 占空比和母线电压估算。

    例如:

    u_a = (duty_a – 0.5f) * vbus;
    u_b = (duty_b – 0.5f) * vbus;
    u_c = (duty_c – 0.5f) * vbus;

    然后再变换到 alpha-beta 坐标系。

    这里有个很常见的坑:

    母线电压不能随便写死。

    如果代码里写:

    #define VBUS 24.0f

    但实际电机加速或带载时,母线电压掉到了 20 V,那么观测器输入的电压就是错的。

    电压错了,反电动势会错。 反电动势错了,角度会错。 角度错了,FOC 就会变差。

    所以实际工程中,建议实时采样母线电压,把真实的 Vbus 用到电压重构里。


    16. 高速角度补偿:别忽略控制延迟

    控制器从采样到输出不是瞬间完成的。

    中间会有:

    • ADC 采样延迟;

    • 滤波延迟;

    • 坐标变换计算延迟;

    • 观测器计算延迟;

    • PLL 输出延迟;

    • PWM 更新延迟;

    • 驱动芯片传播延迟。

    低速时,这些延迟对应的电角度很小,影响不明显。

    高速时,同样的延迟会变成明显的角度误差。

    常见表现是:

    • 高速电流变大;

    • 电机声音变尖;

    • 效率下降;

    • 高速突然失步;

    • 电流环容易饱和。

    可以加一个简单的角度补偿:

    theta_comp = theta_hat_e + omega_hat_e * Tdelay

    其中:

    • theta_comp 是补偿后的电角度;

    • theta_hat_e 是估算电角度;

    • omega_hat_e 是估算电角速度;

    • Tdelay 是估计的系统延迟。

    初始调试时可以先取:

    Tdelay = 1 * Ts ~ 1.5 * Ts

    然后根据高速电流和运行声音微调。


    17. 推荐调试顺序

    无感 FOC 不建议一上来就闭环启动。

    更稳的顺序是下面这样。

    17.1 检查硬件和采样

    先确认:

    • PWM 是否正常;

    • 驱动芯片是否正常;

    • 三相桥臂是否能正确导通;

    • 电流采样零偏是否合理;

    • 母线电压采样是否正确;

    • 过流保护是否可靠;

    • 电机相序是否接对。

    硬件不对,算法再好也没用。

    17.2 开环拖动

    先不用观测器。

    人为生成一个开环角度,让电机低速平滑转起来。

    如果开环都不顺,先不要看无感算法。应该先检查:

    • 相序;

    • 电流方向;

    • SVPWM;

    • Park 变换符号;

    • 电流环参数;

    • 硬件驱动。

    17.3 观测器旁路运行

    保持电机开环运行。

    让反电动势观测器和 PLL 在后台跑,但先不要把估算角度用于控制。

    观察:

    • 估算角度是否连续;

    • 估算速度是否稳定;

    • 估算方向是否正确;

    • PLL 误差是否收敛;

    • 反电动势波形是否合理;

    • 开环角度和估算角度是否保持稳定关系。

    这一步能帮你判断观测器是否可靠。

    17.4 中高速切闭环

    不要一开始就挑战低速闭环。

    先让电机开环跑到中高速,再切入无感闭环。

    如果切换后电流没有明显冲击,速度没有剧烈波动,电机声音也比较平稳,说明无感闭环基本跑通了。

    17.5 优化启动

    闭环能跑以后,再逐步优化启动:

    • 调预定位电流;

    • 调预定位时间;

    • 调开环启动电流;

    • 调开环加速度;

    • 调切换速度;

    • 调角度融合时间;

    • 调 PLL 参数;

    • 补保护逻辑。

    调试时尽量一次只改一个参数。否则电机表现变了,你也不知道是哪一个参数起作用。


    18. 常见问题和排查方向

    18.1 启动时只是抖,不转

    可能原因:

    • 相序接错;

    • 电流采样方向反了;

    • 预定位电流太小;

    • 开环加速度太大;

    • i_q 方向反了;

    • Park 变换符号错误;

    • SVPWM 输出顺序错误。

    建议先确认开环能不能稳定转动。

    18.2 电机能转,但电流很大

    可能原因:

    • 估算角度偏差大;

    • PLL 参数不合适;

    • 电机 R、L 参数误差太大;

    • 母线电压重构不准;

    • 死区补偿不足;

    • 电流环 PI 参数过激。

    重点看三个东西:

    估算角度是否稳定
    电流波形是否接近正弦
    d 轴电流是否明显偏离 0

    18.3 一切闭环就卡死或过流

    可能原因:

    • 开环角度和观测器角度相差太大;

    • 切换速度太低;

    • PLL 尚未锁定;

    • 切换方式太硬;

    • 观测器角度方向反了。

    建议先用角度融合,不要直接硬切换。

    18.4 中高速突然失步

    可能原因:

    • 电压饱和;

    • 角度补偿不足;

    • PLL 带宽太低;

    • 速度环加速太猛;

    • 电流环输出限幅不合理;

    • 母线电压跌落明显。

    可以尝试:

    • 增加角度前馈补偿;

    • 限制速度环加速度;

    • 检查电流环是否饱和;

    • 动态采样母线电压;

    • 优化 PLL 参数。

    18.5 低速闭环不稳定

    这是反电动势无感控制的典型难点。

    低速时反电动势太弱,信噪比差。

    可以尝试:

    • 提高切闭环速度;

    • 优化电流采样;

    • 减小 ADC 噪声;

    • 调整观测器滤波;

    • 使用角度融合;

    • 避免低速大负载闭环运行。

    如果应用必须零速或极低速大转矩控制,仅靠反电动势无感方案通常不够,需要考虑高频注入等方法。


    19. 一组比较实用的初始参数

    下面这些不是标准答案,只适合作为调试起点。

    参数建议初始值
    PWM 频率 20 kHz
    电流环频率 20 kHz
    速度环频率 1 kHz
    预定位时间 300 ms ~ 800 ms
    开环启动时间 500 ms ~ 2000 ms
    切闭环速度 额定速度的 10% 左右
    id_ref 0 A
    iq 限幅 按电机额定电流设置
    角度补偿时间 1 * Ts ~ 1.5 * Ts
    PLL 参数 先保守,再逐步提高带宽

    调参顺序建议:

    硬件采样
    |
    v
    开环拖动
    |
    v
    电流环
    |
    v
    观测器
    |
    v
    PLL
    |
    v
    切闭环
    |
    v
    速度环
    |
    v
    启动优化

    不要一上来就调速度环。

    速度环只是最外层,底层电流环和角度估算不稳,速度环调得再漂亮也没用。


    20. 总结

    无感 FOC 的难点不在某一个公式,而在整条链路必须都对。

    它涉及:

    • 电流采样;

    • 电压重构;

    • 坐标变换;

    • 电流环;

    • SVPWM;

    • 反电动势观测器;

    • PLL;

    • 开环启动;

    • 闭环切换;

    • 保护策略;

    • 高速角度补偿。

    对刚入门的人来说,可以先记住这条主线:

    FOC 要控制 id 和 iq
    |
    v
    控制 id 和 iq 必须知道转子角度
    |
    v
    无感系统没有位置传感器
    |
    v
    只能通过反电动势估算角度
    |
    v
    低速反电动势太弱
    |
    v
    所以必须先预定位,再开环拖动
    |
    v
    观测器可靠后,再切入无感闭环

    调试时也要记住:

    不要一上来就闭环。

    先确认开环能转,再确认电流采样正确,再看观测器角度是否稳定,最后再切闭环。

    无感 FOC 最终追求的不是简单地“转起来”,而是:

    • 启动平顺;

    • 电流稳定;

    • 噪声低;

    • 切换无冲击;

    • 带负载不失步;

    • 高速运行不发散。

    做到这些,才算真正把无感 FOC 跑稳。

    赞(0)
    未经允许不得转载:171主机测评 » 无感 FOC 算法控制无刷电机:从原理到启动调试讲清楚
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址