1. 无感FOC低速困境与HFI的破局逻辑
搞过永磁同步电机(PMSM)无感FOC的人都有一个共识:中高速域用反电动势观测器(比如滑模观测器、隆贝格观测器、龙伯格观测器)基本能打,但一到低速甚至零速,反电动势幅值小到被噪声淹没,转子位置估算直接崩盘。这时候就得换思路——既然反电动势靠不住,那就主动往电机里“打信号”,靠凸极效应(saliency)来提取转子位置。这就是高频注入(HFI, High Frequency Injection)的核心逻辑。
我最早接触HFI是在一个低速大扭矩直驱项目上,电机额定转速才200rpm,启动阶段用反电动势观测器根本锁不住转子,抖得跟筛子一样。后来切到d轴正弦波高频注入方案,才把零速和低速段的位置估算稳下来。这篇文章就把d轴正弦波高频注入的算法原理从头推一遍,把每一步的数学逻辑和工程落地细节都讲清楚。
这篇文章适合谁看?如果你已经做过有感FOC或者无感FOC的中高速方案,想啃低速无感这块硬骨头,那这篇推导对你会有直接帮助。如果你连Clarke/Park变换和SVPWM都还没搞明白,建议先把基础补一补再来看,不然推导过程会比较吃力。
核心关键词先摆出来:无感FOC、HFI、d轴正弦波高频注入、算法原理、PMSM无感FOC控制、转子位置估算。这些词后面会反复出现,因为整个推导就是围绕它们展开的。
先说清楚一个前提:HFI能成立的根本原因是转子凸极效应。对于内置式永磁同步电机(IPMSM),d轴和q轴的电感不相等(Ld ≠ Lq),这个差异就是位置信息的“载体”。表贴式电机(SPMSM)Ld≈Lq,凸极率极低,HFI效果会很差,通常需要人为制造凸极或者改用其他方案。这一点在选型阶段就要确认,不然算法写得再漂亮也白搭。
2. d轴正弦波高频注入的数学推导全流程
2.1 从电机高频模型说起
推导的起点是PMSM在dq坐标系下的电压方程。先写完整版:
ud = Rs·id + Ld·(did/dt) - ωe·Lq·iq uq = Rs·iq + Lq·(diq/dt) + ωe·Ld·id + ωe·ψf其中Rs是定子电阻,ωe是电角速度,ψf是永磁体磁链。当注入频率ωh远高于基波频率ωe时(通常ωh是基波的10倍以上),可以做几个合理简化:
- 电阻压降Rs·i在高频下相对电感压降ωh·L·i可以忽略,因为ωh·L >> Rs
- 反电动势项ωe·ψf在低速时很小,可以忽略
- 交叉耦合项ωe·L·i在低速时也可以忽略
简化后得到高频域下的电压方程:
udh ≈ Ld·(didh/dt) uqh ≈ Lq·(diqh/dt)写成矢量形式,在估计的dq坐标系(带^上标)下:
[ûdh] [Ld 0 ] [dîdh/dt] [ûqh] = [0 Lq] [dîqh/dt]注意这里有个关键点:上面的方程是在真实dq坐标系下成立的。但实际控制中我们用的是估计dq坐标系,两者之间存在角度误差Δθ = θ - θ̂。这个角度误差就是我们要提取的目标。
2.2 坐标变换与角度误差的引入
把真实dq坐标系下的电感矩阵变换到估计dq坐标系,需要用到旋转矩阵。设估计坐标系超前真实坐标系Δθ角度,变换关系为:
[id ] [ cosΔθ sinΔθ] [îd] [iq ] = [-sinΔθ cosΔθ] [îq]把电感矩阵也做同样的旋转变换,得到估计坐标系下的高频电压方程:
[ûdh] [L0 + L1·cos(2Δθ) L1·sin(2Δθ) ] [dîdh/dt] [ûqh] = [L1·sin(2Δθ) L0 - L1·cos(2Δθ)] [dîqh/dt]其中L0 = (Ld + Lq)/2是平均电感,L1 = (Ld - Lq)/2是半差电感。这个矩阵就是整个HFI算法的核心——角度误差Δθ被编码在了电感矩阵的交叉项里。
2.3 d轴正弦波注入的具体形式
现在确定注入信号的形式。所谓“d轴正弦波高频注入”,就是在估计的d轴(即d̂轴)上叠加一个高频正弦电压:
ûdh = Vh·cos(ωh·t) ûqh = 0Vh是注入电压幅值,ωh是注入角频率。为什么选d轴注入而不是q轴?因为d轴注入时,q轴电流响应中会包含sin(2Δθ)项,这个项在Δθ=0附近有良好的线性度,而且d轴注入对转矩的扰动相对可控。q轴注入也能做,但信号处理方式不同,后面会对比。
把注入电压代入上面的矩阵方程,求解电流响应。由于是高频正弦稳态,可以用相量法或者直接解微分方程。先展开:
Vh·cos(ωh·t) = (L0 + L1·cos2Δθ)·(dîdh/dt) + L1·sin2Δθ·(dîqh/dt) 0 = L1·sin2Δθ·(dîdh/dt) + (L0 - L1·cos2Δθ)·(dîqh/dt)这是一个耦合的微分方程组。对于高频正弦稳态,可以假设电流响应也是同频率的正弦形式,用复数阻抗法求解。把d/dt替换为jωh:
[Vh] [jωh(L0 + L1·cos2Δθ) jωh·L1·sin2Δθ ] [Îdh] [0 ] = [jωh·L1·sin2Δθ jωh(L0 - L1·cos2Δθ)] [Îqh]解这个2x2线性方程组,得到电流相量:
Îdh = Vh·(L0 - L1·cos2Δθ) / [jωh·(L0² - L1²)] Îqh = -Vh·L1·sin2Δθ / [jωh·(L0² - L1²)]把分母有理化,注意1/j = -j:
Îdh = -j·Vh·(L0 - L1·cos2Δθ) / [ωh·(L0² - L1²)] Îqh = j·Vh·L1·sin2Δθ / [ωh·(L0² - L1²)]取q轴电流的时域表达式。Îqh是纯虚数乘以j,实际上对应的是正弦还是余弦取决于符号约定。整理后:
îqh(t) = Vh·L1·sin(2Δθ) / [ωh·(L0² - L1²)] · sin(ωh·t)这就是最关键的结论:q轴高频电流的幅值正比于sin(2Δθ),当Δθ→0时,îqh→0。换句话说,q轴高频电流的包络就是角度误差的“指示器”。
2.4 信号解调与位置误差提取
实际采样得到的q轴电流里,除了高频注入响应,还有基波电流、PWM开关噪声、采样噪声等。需要先把高频分量提取出来。常用方法是同步解调(synchronous demodulation):
- 对采样得到的îqh乘以与注入信号同频的参考信号sin(ωh·t)
- 通过低通滤波器(LPF)滤除二倍频分量
- 得到与sin(2Δθ)成正比的直流量
数学上:
îqh(t)·sin(ωh·t) = Vh·L1·sin(2Δθ)/[ωh·(L0²-L1²)] · sin²(ωh·t) = A·sin(2Δθ)·[1 - cos(2ωh·t)]/2经过LPF后,cos(2ωh·t)项被滤除,剩下:
ε = (A/2)·sin(2Δθ) ≈ A·Δθ (当Δθ很小时)这个ε就是位置误差信号。把它送入一个锁相环(PLL)或者龙伯格观测器,就能估算出转子位置和转速。
注意:这里有个容易踩的坑——解调用的参考信号相位必须和注入信号严格对齐。如果注入用的是cos,解调也必须用cos,否则会引入额外的相位偏差,导致估算角度系统性偏移。我在早期调试时就因为这个问题,角度一直差个固定值,查了半天才发现是解调参考相位搞错了。
2.5 为什么是sin(2Δθ)而不是sin(Δθ)
有人会问,为什么误差信号是2倍角度?这是因为凸极效应的周期是π(电角度),而不是2π。d轴和q轴电感差异在转子旋转180度电角度后就重复了,所以位置误差信号天然带有2倍频特性。这意味着:
- 在Δθ=0和Δθ=π处,误差信号都为零,存在伪收敛点
- 需要额外的极性判断逻辑来区分N极和S极
- PLL的线性化范围大约在±π/4以内,超出后可能锁到错误点
解决伪收敛点的常用方法是脉冲注入极性辨识:在d轴正负方向分别注入短时电压脉冲,比较电流响应的饱和程度。由于永磁体的存在,d轴正方向的电感饱和程度与负方向不同,据此可以判断磁极极性。这一步在零速启动时是必须的。
3. 工程落地:从理论到可运行代码的关键环节
3.1 注入参数的选择与计算
理论推导完了,接下来是工程落地。注入参数选不好,要么信噪比不够,要么噪声和损耗太大。核心参数有三个:注入电压幅值Vh、注入频率ωh、以及LPF的截止频率。
注入电压幅值Vh:太小了信噪比不够,太大了会引入可听噪声和额外损耗。经验公式是取额定电压的10%~20%。比如母线电压300V,额定相电压峰值约150V,那Vh取15V~30V比较合适。我一般从15V开始试,逐步加大到能稳定估算为止。
注入频率ωh:需要远高于基波频率,同时远低于PWM开关频率。通常取PWM频率的1/10到1/5。比如PWM频率10kHz,注入频率取1kHz~2kHz。太低会与基波耦合,太高则一个PWM周期内采样点不够,解调精度下降。
LPF截止频率:要低于注入频率,同时高于位置环带宽。一般取注入频率的1/5到1/3。比如注入1kHz,LPF截止取200Hz~300Hz。
下面是一个参数选择的参考表:
| 参数 | 符号 | 典型范围 | 选择依据 |
|---|---|---|---|
| 注入电压幅值 | Vh | 额定电压10%~20% | 信噪比与噪声/损耗的折中 |
| 注入频率 | fh | PWM频率的1/10~1/5 | 高于基波,低于开关频率 |
| LPF截止频率 | fc | fh的1/5~1/3 | 滤除二倍频,保留误差信号 |
| PLL带宽 | ωpll | 50~200 rad/s | 兼顾动态响应与稳态精度 |
3.2 离散化实现与代码框架
实际算法跑在MCU上,需要把连续域推导离散化。假设PWM频率为fpwm,控制周期Ts = 1/fpwm。注入信号在每个控制周期更新:
// 注入信号生成 float theta_h = 2.0f * PI * fh * t; // 注入相位 float Vh_d = Vh * cosf(theta_h); // d轴注入电压 float Vh_q = 0.0f; // q轴不注入 // 叠加到电流环输出 ud_ref += Vh_d; uq_ref += Vh_q;解调部分:
// 采样得到iq_fb后,先提取高频分量 // 方法1:带通滤波(BPF) iq_hp = BPF(iq_fb); // 中心频率fh // 同步解调 float demod = iq_hp * sinf(theta_h); // 与注入同相 // 低通滤波提取直流分量 float error = LPF(demod); // 得到正比于sin(2Δθ)的误差信号 // PLL估算位置和转速 theta_est += (Kp_pll * error + Ki_pll * integral) * Ts;这里有个实现细节:带通滤波器和低通滤波器的设计。我一般用二阶巴特沃斯滤波器,离散化用双线性变换。BPF的中心频率设fh,带宽设fh/2左右;LPF的截止频率设fc。滤波器系数可以离线算好,运行时直接查表或者用差分方程迭代。
3.3 与基波控制的融合策略
HFI不是独立运行的,它要和无感FOC的基波控制融合。典型的融合策略是按速度分段:
- 零速和极低速(<5%额定转速):纯HFI模式,反电动势观测器不工作
- 低速到中速(5%~15%额定转速):HFI和反电动势观测器加权融合,HFI权重逐渐降低
- 中高速(>15%额定转速):纯反电动势观测器模式,HFI关闭
融合时的权重函数可以用sigmoid或者线性过渡。我一般用线性过渡,简单可靠:
float w_hfi = 1.0f - (speed - speed_low) / (speed_high - speed_low); w_hfi = clamp(w_hfi, 0.0f, 1.0f); float w_bemf = 1.0f - w_hfi; theta_final = w_hfi * theta_hfi + w_bemf * theta_bemf;注意:两个观测器的角度不能直接线性加权,因为角度是周期量,直接加权可能在0/2π边界处产生跳变。正确做法是先把角度误差信号加权,再送入同一个PLL。或者用角度误差的sin/cos分量加权后再求角度。这个坑我在项目里踩过,直接加权角度导致切换时电机抖了一下。
3.4 极性辨识的工程实现
前面提到sin(2Δθ)存在伪收敛点,需要极性辨识。工程上常用的方法是d轴正负脉冲注入法:
- 在估计的d轴正方向注入一个短时电压脉冲(比如持续几个PWM周期),记录电流响应幅值I_pos
- 在估计的d轴负方向注入同样幅值和时长的脉冲,记录电流响应幅值I_neg
- 如果I_pos > I_neg,说明估计的d轴正方向对应真实N极;反之则需要将估算角度加π
原理是:d轴正方向对应永磁体N极时,定子电流产生的磁场与永磁体磁场同向,铁芯饱和程度更高,电感更小,同样电压下电流更大。
// 极性辨识伪代码 float I_pos = inject_pulse(+Vpulse, Tpulse); float I_neg = inject_pulse(-Vpulse, Tpulse); if (I_neg > I_pos) { theta_est += PI; // 翻转180度电角度 }这个辨识过程通常在启动前做一次,持续时间几十毫秒。注意脉冲幅值不能太大,否则可能引起转子微小转动或者退磁风险;也不能太小,否则饱和差异不明显。一般取额定电压的30%~50%,持续时间为几个PWM周期。
4. 调试实战:常见问题与排查技巧
4.1 角度估算不准的排查思路
HFI调试最常见的问题就是角度估算不准,表现为电机启动抖动、低速运行不平稳、带载能力差。排查时按以下顺序逐项检查:
第一步:确认凸极率。先测电机的Ld和Lq。如果Ld≈Lq(凸极率<1.1),HFI基本没法用。可以用LCR表在转子不同位置测量,或者用驱动器注入不同方向的电压脉冲测量电流响应来反推电感。
第二步:检查注入信号是否真的加进去了。用示波器看相电流波形,应该有明显的高频纹波。如果看不到,检查注入代码是否被执行、电压是否被限幅。
第三步:检查解调相位。这是最容易出问题的地方。注入用cos,解调也必须用cos;注入用sin,解调也必须用sin。相位差90度会导致误差信号变成cos(2Δθ),在Δθ=0处不是零点,PLL会锁到错误位置。
第四步:检查滤波器参数。BPF中心频率是否等于注入频率?LPF截止频率是否合适?滤波器阶数太高会引入太大相位延迟,导致PLL环路不稳定。
第五步:检查PLL参数。Kp和Ki是否合理?带宽太高会引入噪声,太低则动态响应慢。可以先从低带宽开始调,稳定后再逐步提高。
下面是一个常见问题速查表:
| 现象 | 可能原因 | 排查方法 | 解决措施 |
|---|---|---|---|
| 启动时转子抖动 | 极性辨识错误 | 检查脉冲注入电流响应 | 翻转估算角度或调整脉冲幅值 |
| 低速运行不平稳 | 角度估算有周期性误差 | 示波器看误差信号波形 | 检查解调相位和滤波器参数 |
| 带载能力差 | PLL带宽不足或注入幅值太小 | 加大负载看角度误差 | 提高Vh或PLL带宽 |
| 可听噪声大 | 注入频率在音频范围 | 改变fh | 移到20kHz以上或1kHz以下 |
| 高速切换时抖动 | 融合策略不当 | 检查切换点权重 | 改用误差信号加权而非角度加权 |
4.2 噪声与可听噪声的抑制
HFI的一个副作用是可听噪声。注入频率如果在1kHz~5kHz范围,人耳很敏感,会听到刺耳的啸叫。解决办法有几个:
- 提高注入频率:移到15kHz以上,超出人耳听觉范围。但受限于PWM频率和采样率,不是所有平台都能做到。
- 降低注入幅值:在保证信噪比的前提下尽量减小Vh。
- 随机化注入频率:让注入频率在一定范围内随机跳变,把单频啸叫变成宽带噪声,听感上会好很多。这个技巧在消费类电机驱动里很常用。
- 使用方波注入替代正弦波:方波注入的高频分量更丰富,但解调方式不同,这里不展开。
我个人的经验是,如果PWM频率能到20kHz,注入频率取1.5kHz~2kHz,Vh取额定电压的10%左右,噪声基本可以接受。如果对噪声要求特别高,那就得上随机化或者方波注入方案。
4.3 计算延迟与相位补偿
数字控制系统中,采样、计算、PWM更新都存在延迟。这些延迟会导致解调信号的相位偏差,进而影响角度估算精度。总延迟通常为1.5个PWM周期(采样延迟0.5周期+计算延迟0.5周期+PWM更新延迟0.5周期)。
补偿方法是在解调参考信号中减去延迟对应的相位:
float theta_h_comp = theta_h - omega_h * T_delay; float demod = iq_hp * sinf(theta_h_comp);T_delay = 1.5 * Ts。如果不补偿,在注入频率较高时(比如2kHz),1.5个PWM周期(10kHz PWM下为150us)对应的相位偏差是2π2000150e-6 = 1.88rad,约108度,足以让解调完全失效。这个坑非常隐蔽,因为现象是角度估算“差不多但总差一点”,不仔细看波形很难发现。
4.4 与隆贝格观测器的对比与选择
热词里提到了“无感foc隆贝格观测器”,这里顺便对比一下。隆贝格观测器(Luenberger Observer)本质上是基于反电动势模型的状态观测器,在中高速域表现很好,但低速时反电动势太小,观测器增益需要很大,噪声放大严重。HFI则完全不依赖反电动势,靠凸极效应工作,低速性能好,但高速时注入信号会产生额外损耗和噪声。
所以工程上通常是两者结合:低速用HFI,高速用隆贝格观测器,中间做平滑过渡。这样既保证了全速域的位置估算精度,又避免了单一方法的局限性。选择哪种观测器做高速段,取决于具体应用——隆贝格观测器结构简单、参数好调,滑模观测器鲁棒性强但抖振大,扩展卡尔曼滤波精度高但计算量大。对于大多数工业应用,隆贝格观测器+HFI的组合已经够用了。
5. 从推导到产品的几个关键决策点
5.1 注入方式的选择:旋转注入 vs 脉振注入
HFI的注入方式不止d轴正弦波一种。常见的有:
- 旋转高频注入:在αβ坐标系注入旋转电压矢量,同时在d轴和q轴产生激励。优点是位置信息提取简单,不需要极性辨识(因为旋转注入本身能区分N/S极)。缺点是转矩脉动大,解调复杂。
- 脉振高频注入:在估计的d轴或q轴注入脉振信号。d轴脉振就是本文推导的方案,q轴脉振类似但误差信号形式不同。脉振注入转矩脉动小,但需要极性辨识。
选择哪种取决于应用场景。对转矩脉动敏感的场合(比如直驱、精密控制),选脉振注入;对算法简洁性要求高的场合,选旋转注入。我做的项目大多是脉振d轴注入,因为转矩脉动小,对负载冲击小。
5.2 采样时机与PWM同步
HFI对电流采样时机很敏感。注入信号是高频的,如果采样时刻与PWM不同步,采到的电流相位会随周期变化,解调结果就不稳定。正确做法是在每个PWM周期的固定时刻采样,通常是在PWM计数器过零或者峰值时触发ADC。
对于中心对齐PWM,一般在计数器过零时采样,此时开关噪声最小。如果注入频率是PWM频率的1/2,那每个注入周期有两个采样点,刚好满足奈奎斯特采样定理。如果注入频率更高,就需要更高的采样率或者用欠采样技术。
提示:采样时机不对是HFI调试中最隐蔽的问题之一。现象是角度估算时好时坏,或者随转速变化。用示波器同时看PWM触发信号和电流采样触发信号,确认两者严格同步。
5.3 参数敏感性分析
HFI算法对电机参数的敏感性需要评估。从推导看,误差信号幅值正比于L1/(L0²-L1²),也就是凸极率越高,信号越强。但算法本身不依赖具体的Ld、Lq数值,只依赖凸极的存在。这意味着:
- 电感随电流饱和变化时,误差信号幅值会变,但零点位置不变(仍然是Δθ=0)
- 温度变化导致电感变化,同样只影响幅值不影响零点
- 不同批次的电机凸极率有差异,可能需要调整Vh来保证信噪比
这个特性让HFI的鲁棒性比较好,不需要精确的电感参数。但PLL的增益需要根据误差信号幅值来调整,否则不同电机上环路带宽不一致。工程上可以在启动时做一次自校准,测量误差信号幅值,然后自动调整PLL增益。
5.4 计算资源评估
HFI算法的计算量主要来自:注入信号生成(sin/cos查表或CORDIC)、带通滤波、同步解调、低通滤波、PLL。在100MHz级别的MCU上,这些运算占用大约5%~10%的CPU资源,对于大多数应用是可以接受的。
如果计算资源紧张,可以简化滤波器阶数,或者用查表法替代实时三角函数计算。我一般用256点正弦表+线性插值,精度足够且速度快。BPF和LPF用二阶就够,再高收益不大反而增加延迟。
6. 写在最后:一些踩坑后的真心话
HFI这个算法,理论推导看起来漂亮,但真正落地时魔鬼都在细节里。我印象最深的一次是调试一个低速大扭矩电机,角度估算一直有大约5度的周期性误差,查了滤波器、PLL、采样时机都没问题。最后用示波器逐点对比注入信号和解调参考信号,发现是代码里sin和cos用反了——注入用的是sin,解调却用了cos。改过来之后误差直接降到1度以内。这种低级错误在推导时觉得不可能犯,但实际写代码时因为变量命名混乱、复制粘贴,真的很容易搞错。
另一个体会是不要迷信仿真。Matlab/Simulink里跑得好好的HFI模型,放到实际硬件上可能完全不是那么回事。仿真里没有PWM死区、没有ADC量化噪声、没有计算延迟、没有参数漂移。我现在的习惯是仿真只用来验证算法框架,参数整定和细节调试全部在硬件上做。
最后说一个实用技巧:用误差信号的波形来诊断问题。把解调后的误差信号用DAC输出或者通过串口上传到上位机,观察它的波形。正常情况下,稳态时误差信号应该在零附近小幅波动;如果看到明显的周期性波动,说明角度估算有周期性误差;如果看到直流偏置,说明解调相位有问题;如果看到噪声很大,说明滤波器参数或者注入幅值需要调整。这个信号是HFI调试的“听诊器”,学会看它的波形,大部分问题都能快速定位。
这个方案后续还可以往几个方向扩展:一是结合粒子群算法等优化方法自动整定PLL参数,省去手动调参的麻烦;二是用神经网络做误差信号的智能解调,替代传统滤波器,在低信噪比下获得更好的效果;三是把HFI和隆贝格观测器的融合做得更精细,比如用模糊逻辑动态调整权重。这些方向我还在摸索,有进展再另开一篇聊。