做电机控制的同学应该都有体会:高速段的无感FOC已经非常成熟,滑模观测器、龙伯格观测器随便抄都能跑。但一旦转速掉到几十转甚至零速,反电动势小到跟噪声一个量级,传统观测器集体失效。这时候想要零速满转矩、想要低速不抖动,高频注入几乎是唯一靠谱的路径。我手头这个项目从需求到样机调试前后花了大约三个月时间,最终落地方案就是基于高频方波电压注入的永磁同步电机无感FOC。这篇文章不打算堆公式,就按我从选型、原理、参数、代码到实机调试这条路,把我踩过的坑和最后能稳跑的方案完整梳理一遍。
1. 为什么是高频方波注入,而不是别的方案
1.1 无感FOC的空白区:低速与零速
先说说需求。我这个项目的对象是一台额定转速3000rpm的低压永磁同步电机,早期带增量式编码器,但实际产品为了减成本、抗震动,必须去掉编码器,只靠控制器和电机三相线工作。应用场景是机器人关节,用户要求很具体:零速必须能顶着负载不丢步,5rpm以下必须平稳无抖动,额定转速以上的弱磁反而没那么重要。
需求一列,方案基本就清楚了:纯反电动势法直接pass,因为零速反电动势为零,信号完全淹没在噪声和逆变器非线性里。低速段也不能指望I/F开环"拖"太久,因为负载波动一大,I/F的功角会漂移,轻则噪声增大,重则直接失步。所以必须有一个真正基于电磁特性的闭环估算方案,能在零速和低速段替代编码器,给出足够准确的转子位置。
这是选型的大背景。无感FOC市面上最常见的几条路我汇总了一下:
| 方案 | 适用速度 | 核心依据 | 优点 | 缺点 |
|---|---|---|---|---|
| 滑模/龙伯格观测器 | 中高速 | 反电动势 | 结构简单、中高速性能好 | 低速/零速失效 |
| 高频正弦旋转注入 | 低速/零速 | 磁凸极 | 实现相对直观 | 带宽低、滤波延迟大 |
| 高频方波注入 | 低速/零速 | 磁凸极 | 带宽高、延迟小 | 对采样时序敏感 |
| I/F强制换相 | 启动/超低速 | 开环角度 | 能兜底 | 带载能力弱、易失步 |
我最终采用的是I/F启动 + 高频方波注入闭环 + 中高速切滑模观测器三段式。其中高频方波注入是真正的核心,因为从零速到大约5%额定转速这一段全靠它顶着。后面切换滑模观测器只是常规操作,反而没花太多精力。
1.2 方波比正弦好在哪里
不少资料一上来就写正弦高频注入,用带通滤波器提取高频电流分量,再经同步解调得到位置误差。这个方案在实验室里跑通不难,但工程化的时候有几个问题特别烦人。
第一,滤波器链导致相位延迟。带通加低通的组合在5kHz以上的注入频率下,相移很容易到几十度。反馈回来的位置误差信号带着相位滞后,观测器带宽一高就发散,只能把带宽压得很低,动态性能就没了。
第二,正余弦注入频率做不高。为了配合滤波器,通常注入频率选1到2kHz,这个频率正好落在转矩环带宽附近,更容易激起机械谐振和电磁噪声。
第三,解调计算复杂。高频电流要经过坐标变换、带通、同步解调、低通,信号链特别长,在一个控制周期内要处理很多浮点运算,MCU负担重。
方波注入的思路完全不同:直接把注入电压设计成与PWM同步的对称方波,在两个相邻PWM周期的中点各采一次相电流,两次电流做差分,高频响应就出来了,不需要任何带通滤波器。它不提取某个频率的正弦分量,而是直接看电流在一个注入半周期内的变化斜率。这个斜率跟电感成反比,而d轴和q轴电感不一样,所以就能从差分电流里解出位置误差。
我最看重的收益有三条:
- 注入频率可以做到PWM频率的一半,比如PWM跑10kHz,注入就是5kHz,远高于电流环带宽,控制环路几乎不受影响;
- 位置误差信号一个注入周期更新一次,观测器带宽可以开到几十赫兹甚至上百赫兹,动态响应明显更好;
- 计算量小,整个注入与解调部分只有几次乘加和差分,DSP或MCU跑毫无压力。
当时看完这几条,我就决定用方波了。后面调试的实践也证明,这个决策帮我省掉了大量的滤波器调参时间,收益非常大。
2. 高频方波注入的原理拆解:从电压到位置,信号是怎么一步步走出来的
2.1 电感不对称是能测位置的根本原因
PMSM转子上有永磁体,磁路在不同方向上饱和程度不一样。d轴方向因为有永磁体,磁路容易饱和,等效电感小;q轴方向磁路相对松,等效电感大。所以对同一台电机,Ld小于Lq,这就是磁凸极效应,也是高频注入能吃这碗饭的根本原因。
对凸极性,有一个绕不开的工程认知:不是所有电机都适合高频注入。表贴式PMSM的凸极率Lq/Ld可能只有1.1到1.3,凸极率太低时信噪比非常差,注入幅值得往大调,噪声和损耗都会上来。内置式PMSM凸极率通常有2到3,效果就明显好。我这个项目用的是内置式,凸极率大概1.8,勉强够用,但也不算特别夸张,所以参数调整上还是要仔细。
你可以把转子理解成一个"形状不规则的透镜",高频信号通过它之后,不同方向上的衰减不一样。我只要测出"哪个方向衰减更厉害",就知道了透镜的朝向,也就是转子位置。这个比喻虽然粗,但方向是对的。
2.2 注入到估算d轴,看q轴的差分电流
在真实转子坐标系d-q下,高频电压方程可以简化成:
udh ≈ Ld * d(idh)/dt
uqh ≈ Lq * d(iqh)/dt
但是如果估算的坐标系跟真实坐标系之间存在角度误差Δθ,那么在估算坐标系里电压和电流关系就不再是对角阵,会出现交叉耦合项。我在估算d轴上注入方波电压,实际的电流响应在估算d轴和q轴都有分量。其中估算q轴上的电流差分分量包含sin(2Δθ)的信息,当Δθ足够小时,它就近似正比于Δθ。
这就是高频注入最经典的处理方式:我不需要直接测准确角度,只需要知道"误差有多大、往哪个方向偏",剩下的交给观测器去收敛。
公式层面,我习惯这样写:
- 施加在估算d轴的方波电压:vdh = ±V_inj
- 在估算q轴的电流差分:Δiq_e ≈ (V_inj * (L_q - L_d) / (2 * L_d * L_q * f_inj)) * sin(2Δθ) ≈ K_err * Δθ
这个K_err就是位置误差增益,直接决定观测器的收敛速度和稳定裕度。量纲上可以理解为每弧度误差对应的电流差分大小。实际标定时,我的办法是:转子锁到已知位置,注入固定方波,测估算q轴差分电流,除以已知的Δθ,就得到K_err的实测值。
很多文档只会告诉你"用PLL解调",但真正做控制器的人知道,K_err必须先实测标定,否则观测器参数无从选起,调的时候就像盲人摸象。
2.3 位置观测器把误差收敛成角度
得到位置误差信号ε之后,我用了龙伯格观测器把它收敛到零。状态量取位置误差、速度、负载扰动,输入就是ε。因为ε本身在小角度下线性化了,就是一个非常干净的误差反馈量。观测器输出的是转子位置角θ_est和转速ω_est,一路供给FOC坐标变换,一路供给速度环。
高频注入段闭环带宽我实测大概能到80到120Hz,对机器人关节的负载波动来说够用。这里有一个特别容易忽略的点:位置误差信号必须在一个注入周期内完成同步采样和解算。如果你的主循环周期拖着两个注入周期甚至更长,位置信息就有明显的相位滞后,动态性能会断崖式下降。我最初用普通控制中断去处理,后来改成在PWM中断里同步处理注入与解调,性能立刻不一样了。
3. 关键参数设计与调试:这张表值得抄作业
3.1 注入频率:跟PWM绑死,别乱选
高频方波注入的频率在工程实现上通常直接设为PWM开关频率的二分之一。原因很简单:方波注入需要在两个相邻PWM周期分别施加正、负电压,一个完整注入周期占两个PWM周期。PWM是10kHz,注入就是5kHz;PWM是20kHz,注入就是10kHz。
选择上下限的依据:
- 下限是电流环带宽的5到10倍,太低会跟电流环动态耦合,控制性能变差;
- 上限要避开电流采样和PWM开关噪声的混叠,一般不超过PWM频率的一半;
- 注入频率太高,电流纹波和铁耗会明显增加,功率管开关损耗也在涨。
我调试的时候最初PWM跑8kHz,注入4kHz,效果能接受但噪声略大。后来把PWM提到16kHz,注入8kHz,噪声明显改善,但MCU负荷和逆变器损耗也上去了。最终选择PWM 10kHz、注入5kHz,这是综合考虑功率管温升和噪声后的取舍。实际产品上这个组合最稳。
3.2 注入幅值:一个需要反复试的值
注入幅值V_inj的选择直接关系到信噪比、噪声、转矩脉动和母线电压利用率。我自己的经验取值是:
V_inj ≈ (5% ~ 15%) * Vdc
具体值靠两个标志性现象来确定:
- 调太小:给定负载下位置误差信号淹没在噪声里,低速电流波形明显"毛",或者启动后位置跳变;
- 调太大:电机静止时能听到明显的电磁噪声,电流THD增大,重载下母线电压可能不够用。
实际操作时,我会先取10%Vdc作为初始值,然后看静止状态下的位置误差信号噪声RMS和1kHz附近的电流谐波。如果噪声RMS超过位置误差有效信号的三分之一,就把注入幅值往上加;如果电流谐波超过基波10%,就往下减。来回几次就能找到可接受的工作点。
还有一个细节:注入幅值不能超过一个PWM周期内电压矢量的可输出范围。如果母线电压低且调制深度高,注入电压可能跟控制电压打架,这时要么提高母线电压,要么降低注入幅值,没有第三种办法。
3.3 电流采样与滤波器:这一步最容易翻车
高频方波注入的命脉是电流采样质量。采样时机必须精确对准注入方波的稳定区,也就是PWM中心采样点。我用的ADC触发方式是这样的:
- 在PWM中心对齐计数模式下,选择三角载波的峰值和谷值两个时刻各触发一次ADC采样;
- 这两个时刻正好对应注入方波正半周期和负半周期的中点;
- 每两次连续采样得到一组差分电流,再经过旋转坐标变换得到估算d/q轴的电流差分。
如果采样时刻偏差超过几微秒,位置误差信号里会混入大量共模分量,观测器怎么调都没用。我踩过的一个坑是ADC采样窗口设在了PWM边沿附近,结果每次开关动作都带出巨大冲击电流,差分信号彻底没法看。
滤波器方面我很诚实:最终几乎没有使用额外低通滤波器,只在位置误差信号上加了一个一阶IIR低通,截止频率约1kHz,用来滤除开关噪声。高频带通、同步解调链统统不要,这才是方波注入的核心优势。如果你发现必须加一堆滤波才能稳定,先检查采样时序,而不是急着加滤波器。
3.4 电流环PI参数对高频注入的影响
高频注入本身是叠加在电流环输出上的电压扰动。如果电流环带宽太高、PI增益太大,电流环会主动"对抗"注入电压,导致位置误差信号被吃掉,严重时整个注入闭环失效。
无感FOC里电流环PI不宜一味求快。我这边电流环带宽设置在800Hz到1kHz,实测在这个范围内,方波注入的差分信号依然清晰。如果你在做传统伺服,电流环带宽普遍喜欢做到2kHz以上,那么切换无感模式时要特别注意重新整定电流环参数。
这个经验是实际调出来的:一开始电流环用的是带编码器调出来的"最快参数",结果高频注入一开,位置误差信号明显变小,甚至出现低频振荡。把电流环带宽降下来后,问题立刻消失。原因就是前面说的,电流环快速调节会抵消注入电压的作用。
4. 代码级实现与启动流程:从I/F到全速段的稳定衔接
4.1 软件架构与任务划分
我的实现框架大致是这样的:
- 主中断:PWM周期中断,10kHz,负责FOC计算、高频注入生成、电流环;
- 子中断:PWM中心点ADC采样完成中断,负责锁存电流采样值;
- 低速任务:位置观测器、速度环、切换逻辑;
- 后台任务:状态监控、参数标定、保护逻辑。
PWM中断里做的事情顺序很关键:先读ADC锁存电流,再根据当前注入极性向估算d轴加或减V_inj,然后计算普通FOC电压,叠加注入电压后写入PWM比较器。这样保证注入电压和采样严格同步,不会差出半个周期。
4.2 注入与采样的同步关系
以10kHz PWM、5kHz注入为例,一个注入周期占两个PWM周期。具体到每一个PWM周期:
- 三角载波峰值:触发ADC采样,读取电流i_a、i_b;
- 根据当前注入极性标志,确定本周期该加还是减V_inj;
- 完成坐标变换和电流环计算后,把控制电压加上注入电压,更新PWM比较寄存器;
- 下一个PWM周期,极性翻转,重复上述流程。
这样两次连续采样得到的就是注入正半周期和负半周期中点处的电流。做差以后,基波电流和反电动势分量被抵消,剩下的是高频注入引起的电流斜率变化。这个差分电流才是后面算位置误差的原料。
伪代码示意如下:
# 伪代码:PWM中断中执行的注入与采样逻辑 if pwm_cycle % 2 == 0: v_inj_polarity = +V_inj else: v_inj_polarity = -V_inj # 从锁存器读取两次采样电流 i1 = adc_sample_prev i2 = adc_sample_current # 做差分,这就是核心信号 di_dq = park_transform(i2 - i1, theta_est) # 位置误差信号取估算q轴分量 epsilon = di_dq.q # 交给观测器更新位置和速度 theta_est, omega_est = observer_update(epsilon) # 计算FOC输出电压 vd = current_loop_pi(id_ref, id_est) vq = current_loop_pi(iq_ref, iq_est) # 叠加注入电压到估算d轴 vd_total = vd + v_inj_polarity vq_total = vq # 写PWM比较器 write_pwm(vd_total, vq_total, theta_est)这里面最容易被忽视的就是极性与PWM周期的同步。如果极性标志更新和PWM比较器更新不是同一拍,注入波形会乱掉,位置误差信号自然不对。我建议在代码里加一个断言或调试口,至少把极性和载波周期打印出来,确认完全对齐后再往下调。
4.3 I/F开环启动段的细节
零速启动我用的是I/F开环强制换相,把转子从静止拖到一个已知角度。速度给定是斜坡上升,比如0到300rpm。I/F段我单独加了一个电流幅值环,限制给电机的电流幅值,防止初始冲击把母线电压打穿。
I/F切换到高频注入的时机是整个项目里最容易翻车的环节。我的切换条件有两个:
- 估算转速超过阈值,比如100rpm;
- 位置误差信号在最近若干周期内保持小角度,观测器已收敛。
不能只看转速,必须等观测器收敛标志有效,否则一切换就失步。切换瞬间,I/F给定的角度和观测器估计的角度可能差几度到十几度,我用了一个斜坡过渡把角度平滑拉过去,电流冲击明显减小。
4.4 观测器实现要点
龙伯格观测器的离散实现,状态量是位置误差、转速、负载扰动。观测器增益K1、K2、K3的选择我用极点配置法:
- 两个闭环主导极点配置在带宽80Hz附近;
- 一个积分极点放远一点,比如20Hz,避免影响动态性能;
- 速度和位置估算直接用观测器内部状态,不额外做一阶滤波,因为观测器自带惯性。
速度估算这里有个经验:如果直接对位置角求导再滤波,会有明显相位滞后,动态性能很差。用观测器内部转速估计就顺滑很多,还能天然滤掉一部分机械噪声。
4.5 与中高速观测器的衔接
高频注入切换到反电动势观测器,我用的是转速切入加缓冲过渡:
- 在500rpm以上关闭高频注入,切到滑模观测器;
- 切换瞬间,用高频注入段的速度和位置做前馈,锁相环重新捕获,避免角度跳变;
- 切换前给速度环一个短时间斜坡过渡。
切换点附近,如果两个观测器的角度差超过10度,直接切换会造成电流冲击。我在切换逻辑里加了角度差校验,差值大时强制回到I/F或高频注入段,等待收敛后再重新尝试切换。这个小逻辑看着不起眼,但救了好几次调试时的"现场事故"。
5. 调试实录:我踩过的坑和排查方法
5.1 电机静止时嗡嗡叫且位置抖动
现象:电机不转,但能听到明显电磁噪声,位置误差信号大幅波动。
我当时的排查路径:
- 关闭高频注入,用编码器确认电流环正常,排除电流环本身的问题;
- 用示波器看ADC采样点附近的电流波形,确认采样时刻落在稳态区;
- 检查注入电压是否在PWM输出中被限幅,剔除母线电压饱和的影响;
- 把注入极性标志与PWM载波同步关系打印出来,确认没有错位。
最终原因是我在PWM更新时用了影子寄存器,但注入极性在中断内更新后没有同步到PWM比较器,导致一个周期内极性错乱。改成在PWM周期更新中断里统一更新后,问题彻底消失。
5.2 启动后低速抖动、时不时顿挫
现象:I/F切换到高频注入后,在10rpm左右电流波形出现周期性尖峰,电机一顿一顿的。
原因是切换太早,观测器还没真正收敛;或者切换瞬间位置角不连续导致转矩波动。处理办法:
- 把切换阈值提高,延长I/F段运行时间;
- 在切换段增加位置角平滑过渡;
- 检查观测器初始化时转速估计是否清零。如果残留旧速度,速度环输出会异常,电机就会顿挫。
我后来在切换逻辑里增加了"观测器位置误差连续50个周期小于3度"才允许切换的条件,这个问题就再没出现过。
5.3 带载后失步
现象:低速带载时,电机突然丢步或剧烈抖动,电流飙升到保护值。
排查思路:
- 确认负载扭矩是否超过启动段最大输出扭矩,如果超过,先提高I/F段的电流限幅;
- 检查凸极率Lq-Ld是否足够。凸极率偏低的电机,注入幅值必须加大,否则信噪比不够;
- 检查观测器速度积分是否发散。我在观测器输出加了一个速度限幅,防止估算转速异常导致速度环失控。
这类问题最隐蔽的是凸极率不足。后来我跟某电机制造方沟通,专门做了台凸极率更高的样机,同一套代码的表现好了一个量级。所以选电机这一步,直接影响无感方案的成败。
5.4 快速正反转时响应迟钝
现象:指令方向突变时,位置观测器收敛慢,电流冲击大,甚至出现短时反转滞后。
处理办法:
- 提高观测器带宽,但注意不要超过机械系统约束,否则会激起机械谐振;
- 增加负载前馈或速度前馈;
- 在方向突变时暂时提高注入幅值,提高信噪比,等转速稳定后再降回正常值。
5.5 常见问题速查表
| 现象 | 可能原因 | 检查/处理 |
|---|---|---|
| 位置抖动、噪声大 | 采样时刻不对、注入幅值不足 | 校准ADC触发时刻,增大V_inj |
| 无法收敛 | 凸极率过低、K_err标定不准 | 实测Ld/Lq,重新标定K_err |
| 低速电流毛刺 | 电流环带宽过高 | 降低电流环PI增益 |
| 切换失步 | 切换条件不完整 | 增加观测器收敛判定 |
| 母线电压利用率低 | 注入幅值占压降太多 | 减小V_inj或提高母线电压 |
| 高速切入后振荡 | 角度跳变、切换缓冲不足 | 增加切换前角度差校验和斜坡过渡 |
这张表基本覆盖了我这三个月遇到的高频问题。如果你也正在调无感FOC,建议直接按这张表对照排查,能省不少时间。
6. 最后:一点个人体会
高频方波注入这个东西,原理并不难,难的是把采样时序、同步关系、参数选型、切换逻辑串成一条完整链路。任何一环出问题,表现都是"位置不对""噪声大""失步",但你根本不知道是哪一个环节的锅。所以调试时一定要有信号链思维:从电压注入、电流采样、差分计算、误差信号到观测器,一级一级加调试口,把每一级信号都打出来看,不要一上来就闷头调PI。
我最建议的做法是:
- 先把观测器收敛过程打点出来,看位置误差信号是否稳定收敛到零附近;
- 再验证切换逻辑是否在正确时机动作;
- 最后才整定快慢参数和滤波深度。
如果让我重新做一遍,我会在做原理验证时就把注入频率和采样频率固定下来,先用示波器确认方波注入下的电流响应波形干净,再去写完整的控制代码。
另外,别迷信高频注入万能。凸极率只有1.1的电机,再怎么调也很难做好。上电之前先用阻抗分析仪或者简单的开环测试把Ld、Lq测出来。如果凸极率太差,趁早换电机或改方案,省得后面浪费几个月。
这个项目跑下来,我最大的体会是:无感FOC的调试时间大部分花在信号处理和同步关系上,真正写代码的时间反而少。把"信号链"这个洞补齐了,这套方案才算是真正掌握。