低速无感控制这个话题,我在台架上熬过的夜比做高速段多得多。去年冬天调一套 48V 风机方案,转速掉到 80 rpm 带轻载就开始抽搐,示波器上相电流一片毛刺,反电动势那点正弦波完全被死区误差和采样噪声埋掉。后来把观测器从常规滑模换成 HSO 高灵敏度观测器这套结构,又花了大概两周把参数一个个钉死,才把 60 rpm 带载启动做到十次十次成功。这篇就把我从原理推导到参数整定的全过程摊开讲,包括那些调试手册上不会写、但会让你在台架前坐到凌晨的坑点。
HSO 全称高灵敏度观测器,在不同团队里具体实现会有差异,有的偏扩张状态观测器,有的偏自适应增益龙伯格,我这边说的是一套以电流观测误差为驱动、把反电动势当作扩张状态来估计、并且增益随工况自适应的降阶观测器结构。它解决的核心问题很明确:无感电机控制在低速段反电动势幅值太小、信噪比太低,常规观测器估不出可用角度,导致带载能力差、启动容易失步。这篇适合已经能把电机转起来、但卡在低速带载和参数整定上的朋友,也适合刚接触无感 FOC、想搞清楚观测器到底在算什么的人。
1. 无感控制低速段为什么老是翻车
1.1 反电动势这道绕不过去的信号墙
先把最基础的事实摆出来。表贴式永磁同步电机在 αβ 坐标系下的电压方程可以写成 uα = Rs·iα + Ls·diα/dt − ωe·ψf·sinθ,uβ = Rs·iβ + Ls·diβ/dt + ωe·ψf·cosθ。后面那两项就是反电动势,幅值等于 ωe·ψf,和电角速度严格成正比。拿一台常见的小功率电机举例,极对数 4、磁链 0.023 Wb、额定 3000 rpm,这时候电角速度约 1257 rad/s,反电动势峰值接近 29V,信噪比相当漂亮。可一旦转速掉到 100 rpm,电角速度只有 42 rad/s,反电动势峰值缩到 0.98V,幅值只剩额定的三十分之一。
要命的地方在于,干扰并不会跟着转速一起缩小。逆变器死区带来的平均电压误差,按 48V 母线、1μs 死区、10kHz 开关频率算,大约是 0.48V,这个数字和 100 rpm 时的反电动势峰值处在同一个量级。再加上相电阻压降,1A 电流、0.35Ω 相电阻就是 0.35V;电流采样零漂折算过来可能又是几十毫伏。真实的反电动势信号就像站在一台轰鸣的机器旁边说悄悄话,你想听清内容,先得把机器关掉,可惜关不掉。
所以低速无感控制的本质矛盾不是算法不够聪明,而是信噪比物理上不够。任何观测器做的事情,本质上都是从一堆噪声里把那个幅值很小、频率很低的正弦分量抠出来。抠得越狠,灵敏度越高,噪声放大也越厉害,这是一条硬性约束,后面调参的所有取舍都围绕它展开。
1.2 传统滑模与锁相环在低速的真实表现
常规滑模观测器的做法是先构造一个电流观测器,用符号函数或者饱和函数去逼迫观测电流跟随实测电流,把切换项低通滤波之后当作反电动势估计。高速段它很稳,鲁棒性强,参数不敏感,这是它的优点。但到了低速,问题成串地冒出来:符号函数带来的抖振在滤波之后残留成角度纹波,滤波截止频率越低纹波越小但同时相位滞后越大,而低速时电角频率本身就低,一点点相位滞后折算成角度误差可能就是十几度。
锁相环这一侧也有麻烦。标准 PLL 的环路增益是固定的,而输入的反电动势幅值随转速线性变化。高速时环路增益大、跟踪快,低速时增益小、跟踪慢,等效带宽随转速漂移。结果就是你按高速调好的 PLL 参数,到了低速响应迟钝得像灌了铅,转速突变时角度跟不上,电流环解耦失效,d 轴和 q 轴电流互相串扰,电机发出明显的低频轰鸣。更糟的是估算角误差会让实际电流矢量偏离最优方向,同样转矩需要更大电流,铜损上升,温升又反过来改变相电阻,形成恶性循环。
我见过不少方案在 300 rpm 以上跑得很漂亮,一下到 100 rpm 带载就失步,现场第一反应往往是怀疑电流环带宽不够,把电流环 PI 一路加大,结果噪声更大、失步更快。方向错了,怎么调都是白费。
1.3 HSO 到底"高灵敏"在哪个环节
HSO 这套结构的核心思路不复杂:把反电动势当作系统的一个扩张状态,用电流观测误差同时驱动电流状态和反电动势状态的收敛,形成一个二阶观测器。数学上它和扩张状态观测器、降阶龙伯格观测器是近亲,区别在于工程实现上做了几件事来提升低速灵敏度。
第一件事是增益不再固定。低速段把观测器带宽提上去,让微弱的反电动势能在几个电周期内被积分出来;高速段再把带宽压回来,避免噪声放大。这个切换可以按估算转速做增益调度,也可以按电流误差的幅值做自适应。
第二件事是引入归一化。反电动势估计出来之后,角度提取环节必须先把幅值除掉再做环路运算,否则环路增益随转速变化的问题依然存在。归一化之后 PLL 的等效带宽就是恒定的,调参一下子变得可预测。
第三件事是接受"低速段需要外部援助"这个现实。再灵敏的观测器也有物理下限,反电动势低于噪声底的时候,硬撑只会得到一个抖动的角度。成熟的方案会在极低速段切到开环强拖或者高频注入,等反电动势长起来再平滑切回闭环。HSO 的价值是把这段"必须开环"的转速区间压到尽可能低,而不是宣称彻底消灭它。
2. HSO 的内部结构:从电流误差到角度输出的每一步
2.1 观测器方程与增益的物理含义
先把式子写清楚,不然后面调参全靠蒙。以 α 轴为例,观测器写成两行:
d(îα)/dt = (uα − Rs·îα − êα)/Ls + k1·(iα − îα) d(êα)/dt = k2·(iα − îα)β 轴完全对称。这里 î 是观测电流,ê 是反电动势估计,k1 的单位是 1/s,k2 的单位是 V/(A·s)。第一行是电流观测器本体,第二行是反电动势的积分通道,电流误差就是它的唯一输入。
把两式相减得到误差动态。令电流误差 ei = i − î,反电动势误差 ee = e − ê,整理后得到 s²·ee + (Rs/Ls + k1)·s·ee + (k2/Ls)·ee = s²·e,对应的特征方程是 s² + (Rs/Ls + k1)s + k2/Ls = 0。把它和标准二阶系统 s² + 2ζωo·s + ωo² 对照,就能直接读出设计公式:
| 参数 | 表达式 | 物理含义 |
|---|---|---|
| ωo | 设计值,一般取 2π×150 到 2π×400 rad/s | 观测器带宽,决定收敛速度 |
| k1 | 2ζωo − Rs/Ls | 电流误差的比例反馈强度 |
| k2 | Ls·ωo² | 反电动势通道的积分增益 |
取临界阻尼 ζ=1,此时 ê 对真实 e 的传递函数是 ωo²/(s+ωo)²,标准的二阶低通。这个结论很有用:观测器带宽 ωo 直接决定了反电动势估计的相位滞后和噪声抑制能力。ωo 越大,收敛越快、低速灵敏度越高,但高频噪声进来的也越多;ωo 越小,估计越干净,但低速时反电动势还没积分出来,角度就已经跟不上了。
还有一个容易被忽略的细节,Rs/Ls 这一项在公式里是存在的。小功率电机 Rs/Ls 数值不小,比如 0.35Ω 配 0.6mH,Rs/Ls 约 583,如果 ωo 取 1257,那 k1 = 2×1257 − 583 = 1931。要是有人图省事直接把 k1 取成 2ωo,实际阻尼会比设计值高,观测器偏慢,低速启动会明显发肉。这个细节我在三份不同的开源代码里都见过踩坑。
2.2 灵敏度上去了,噪声也跟着上来了
把 ωo 从 2π×150 提到 2π×400,反电动势收敛时间缩短到原来的四成不到,低速确实能更快抓到角度。代价体现在两个地方,一个是电流采样噪声,一个是参数误差。
从电流测量的噪声 n 到反电动势估计 ê 的传递函数,在临界阻尼下同样是 ωo²/(s+ωo)²,直流增益等于 1。这意味着电流采样里的直流偏置会一比一地进到反电动势估计里,而且不衰减。假设 ADC 零漂导致 iα 上有 20mA 的直流偏置,折算到 êα 就是固定的 20mA 等效误差项,最终表现为估算角度出现随转子位置变化的二次谐波波动。低速时反电动势真实幅值本来就只有 1V 左右,20mA 的偏置经过增益换算后能占到百分之几,角度误差肉眼可见地抖。
所以 HSO 方案对电流采样的要求比常规方案高一个档次。零点校准必须做,而且不能只在开机时做一次,温升之后运放偏置会漂,我一般会在每次停机状态(上下桥全关、母线有电)重新采一组零点,存到 RAM 里做实时扣除。采样时刻也要卡准,中心对齐 PWM 必须在下桥臂导通的中点触发 ADC,避开开关瞬间的振铃。这两条做不到,后面所有调参都是沙上建塔。
参数误差的影响在低速段被放大得更明显。观测器方程里 Rs 是显式出现的,Rs 偏 30%,等效于在端电压里凭空多算了 0.1V 的压降,而低速反电动势本来就只有 0.5V 到 1V,这个比例足以让角度偏出去十几度。Ls 的误差主要影响动态过程,稳态下没那么致命,但在电流突变时会表现为估算转速的尖峰。ψf 不直接进观测器,但会影响前馈和解耦环节,间接影响低速带载能力。
2.3 角度提取:PLL 不归一化,带宽就随转速乱跑
反电动势估计出来之后是 αβ 两个分量,还需要提取角度和转速。标准做法是锁相环:
ε = −êα·cos(θ̂) − êβ·sin(θ̂) ω̂ = kp·ε + ∫ki·ε dt θ̂ = ∫ω̂ dt代入真实的 êα = −ωe·ψf·sinθ、êβ = ωe·ψf·cosθ,可以算出 ε = ωe·ψf·sin(θ − θ̂)。小角度下 ε ≈ ωe·ψf·Δθ,也就是说环路输入被反电动势幅值缩放了。闭环传递函数是 (kp·s + ki)/(s² + kp·s + ki) 的形式,但实际环路增益被 ωe·ψf 乘了一遍,等效自然频率 ωn = sqrt(ki·ωe·ψf),阻尼比 ζ = kp·sqrt(ωe·ψf)/(2·sqrt(ki))。
问题就在这儿。转速从 3000 rpm 掉到 100 rpm,ωe 缩小 30 倍,环路增益缩小 30 倍,等效带宽缩到原来的 1/5.5。你按高速调出来的 kp、ki,低速时 PLL 相当于被绑住了手脚,角度跟踪滞后严重,动态过程直接失锁。
解决办法是归一化。把 ε 除以反电动势幅值 mag = sqrt(êα² + êβ²),得到 ε_n = sin(Δθ) ≈ Δθ,环路增益就与转速无关了。归一化之后 kp、ki 的物理意义变得干净:ωn = sqrt(ki),ζ = kp/(2·ωn),调参时脑子里想的是带宽和阻尼,不用再惦记当前转速。这个改动只有一行代码,效果是低速动态性能直接上一个台阶,我在多个方案上都验证过。
归一化也有副作用,就是低速时 mag 很小,除法会把噪声放大。工程上的处理是给 mag 设一个下限,低于阈值时不再归一化,直接冻结 PLL 输出,或者切到开环强拖。阈值取多少要看电机,我一般的经验值是额定反电动势峰值的 3% 到 5%,对应大概 3% 到 5% 的额定转速。低于这个点,反电动势确实没法用了,硬撑没有意义。
2.4 离散化落地:10 kHz 下的一份可用 C 代码
理论推完必须落到代码上,我这里给一份实际在用的结构,采样频率 10kHz,Ts = 100μs。参数示例对应 Rs = 0.35Ω、Ls = 0.6mH、ωo = 2π×200 rad/s,算出来 k1 = 1931、k2 = 948,离散后 k1·Ts = 0.193、k2·Ts = 0.0948。
typedef struct { float Rs, Ls; float k1, k2; /* 已含 Ts 的离散增益 */ float ih_a, ih_b; /* 观测电流 */ float eh_a, eh_b; /* 反电动势估计 */ float Ts; float eh_max; /* 反电动势幅值限幅 */ } HSO_t; void HSO_Init(HSO_t *h, float Rs, float Ls, float wo, float Ts) { h->Rs = Rs; h->Ls = Ls; h->Ts = Ts; h->k1 = (2.0f * wo - Rs / Ls) * Ts; h->k2 = Ls * wo * wo * Ts; h->ih_a = h->ih_b = 0.0f; h->eh_a = h->eh_b = 0.0f; h->eh_max = 60.0f; } void HSO_Update(HSO_t *h, float ua, float ub, float ia, float ib) { float err_a = ia - h->ih_a; float err_b = ib - h->ih_b; /* 电流状态更新:欧拉离散 */ h->ih_a += h->Ts / h->Ls * (ua - h->Rs * h->ih_a - h->eh_a) + h->k1 * err_a; h->ih_b += h->Ts / h->Ls * (ub - h->Rs * h->ih_b - h->eh_b) + h->k1 * err_b; /* 反电动势状态更新 */ h->eh_a += h->k2 * err_a; h->eh_b += h->k2 * err_b; /* 幅值限幅,防止启动瞬间积分跑飞 */ float mag = sqrtf(h->eh_a * h->eh_a + h->eh_b * h->eh_b); if (mag > h->eh_max) { float s = h->eh_max / mag; h->eh_a *= s; h->eh_b *= s; } }PLL 部分单独封装,注意归一化和积分限幅:
typedef struct { float kp, ki; float theta, omega; float integ; float mag_min; } PLL_t; void PLL_Update(PLL_t *p, float ea, float eb, float Ts) { float mag = sqrtf(ea * ea + eb * eb); float err = -ea * cosf(p->theta) - eb * sinf(p->theta); if (mag > p->mag_min) { err /= mag; /* 归一化,环路增益与转速解耦 */ p->integ += p->ki * err * Ts; /* 积分限幅,防止过零或失锁时累积 */ if (p->integ > 3000.0f) p->integ = 3000.0f; if (p->integ < -3000.0f) p->integ = -3000.0f; p->omega = p->kp * err + p->integ; } else { p->integ = p->omega; /* 冻结,保持上一时刻转速 */ } p->theta += p->omega * Ts; if (p->theta > 6.2831853f) p->theta -= 6.2831853f; if (p->theta < -6.2831853f) p->theta += 6.2831853f; }欧拉离散在 10kHz 下够用,因为 ωo·Ts 只有 0.126,远小于稳定边界。如果采样率降到 4kHz,Ts 变大,欧拉法会有明显的幅值衰减和相位滞后,这时候建议换双线性变换,或者至少把 ωo 压下来。三角函数的开销在多数控制型 MCU 上是可以接受的,真要省,可以用定点查表或者只算 sin、cos 用一次迭代互推,但那是另一个话题,这里不展开。
3. 调参实战:把 HSO 从"能转"调到"能带载"
3.1 调参之前先把四个参数钉死
所有观测器调参的前提是电机参数可信,这一步省不得。我见过太多人跳过参数测量直接调增益,结果调了三天发现是 Rs 抄错了手册。四个参数里最重要的是 Rs、Ls、ψf,极对数 p 必须绝对准确,写错一个数整套系统都别想正常。
Rs 的测法很简单,用四线法或者高精度电桥测线电阻,除以 2 得到相电阻。注意要在室温下测,并且记录当时的温度,因为铜的电阻温度系数是 0.39%/℃,从 25℃ 到 100℃ 电阻要涨 29%。如果控制器装在小机箱里温升明显,冷态测出来的 Rs 直接烧进代码,热机之后低速角度必然漂。
Ls 测法类似,LCR 表或者电桥在 1kHz 下测线电感除以 2。表贴式电机 Ld 和 Lq 基本相等,可以用一个 Ls 近似;内置式电机两个轴差异明显,观测器里一般用平均值或者分别处理。测电感时转子位置会影响结果,最好转动转子取几个位置的平均值,尤其是内置式电机。
ψf 从反电动势常数反推。如果手册给的是 Ke,单位 V/krpm,并且是线电压有效值,可以用近似公式 ψf ≈ 0.0078 × Ke / p。这个式子我来推一下:线电压峰值 = √3 × 相反电动势峰值 = √3 × ωe × ψf,而 ωe = 2π × (n/60) × p,其中 n 是 rpm。把 Ke 定义成线电压有效值每 1000 rpm,则 √2 × Ke × (n/1000) = √3 × 2π × (n/60) × p × ψf,解出 ψf = √2 × Ke × 60 / (1000 × √3 × 2π × p) ≈ 0.0078 × Ke / p。拿前面那台电机验证,Ke = 12 V/krpm,p = 4,ψf ≈ 0.0234 Wb,3000 rpm 时相反电动势峰值 29.4V,线电压有效值 36V,和 Ke × 3 = 36V 对得上,公式没问题。
没有手册数据的话,可以用外力拖动电机,示波器测线电压波形,读出峰值和对应转速,同样反推。这一步做扎实,后面调参会顺很多。
3.2 观测器增益整定:从频域算到试凑
有了参数就能算增益了。ωo 是唯一需要拍板的设计量,我的取值逻辑是这样:先看电流环带宽,观测器带宽一般取电流环带宽的 1/5 到 1/3。电流环跑 1.2kHz 的话,观测器带宽取 2π×200 到 2π×400 都在合理范围。再考虑最低工作转速,ωo 至少要大于最低转速对应的电角频率的 3 到 5 倍,否则反电动势在观测器里衰减太厉害。
按 2π×200 算,Rs/Ls = 583,k1 = 2×1257 − 583 = 1931,k2 = 0.0006 × 1257² = 948。这两个数直接代入前面代码。试的时候先在台架上让电机空载跑中速,用 DA 输出把 êα、êβ 和实测电流一起打出来,看反电动势估计是不是干净的正弦、幅值是否和理论值一致。幅值对不上先查参数,波形毛刺多先查采样。
增益调大之后的第一个现象往往是估算转速的高频纹波变大,这个可以通过后级滤波缓解,但滤波会带来相位滞后。我的做法是转速输出走一个一阶低通,截止频率取 PLL 带宽的 3 到 5 倍,相位滞后控制在十几度以内,对速度环影响可以接受。角度输出绝对不要滤波,一滤就滞后,低速直接失步。
低速增益调度可以用很朴素的方式实现:按估算转速分三段,低于 10% 额定用大增益(ωo 取 2π×350),10% 到 40% 用中增益(2π×250),40% 以上用小增益(2π×180)。切换点加减速过渡带,避免增益突跳引起角度抖动。这种查表式调度实现简单、行为可预测,比连续自适应好调得多,量产项目里我一般优先选它。
3.3 PLL 带宽和观测器带宽必须拉开档次
PLL 带宽和观测器带宽的关系,我总结成一句话:PLL 要比观测器慢,但慢得不能太多。观测器带宽 2π×200 时,PLL 带宽取 2π×30 到 2π×50 比较合适,比值 4 到 6 倍。PLL 太慢,观测器已经收敛了角度还在爬,动态响应拖沓;PLL 太快,把观测器的噪声和纹波全吃进来,估算转速抖。
按归一化后的公式算,ωn = 2π×30 = 188.5 rad/s,ζ 取 0.8 到 1.0,ki = ωn² = 35530,kp = 2ζωn = 377。这组数对应前面代码里的 kp、ki。注意单位换算是频率 Hz 到角频率 rad/s 那一步,我见过有人把 30Hz 直接当 ωn 用,算出来的 kp 小了 6 倍多,PLL 慢得跟蜗牛一样,还以为是观测器的问题。
带载测试时重点看两件事。一是突加负载时估算转速的跌落深度和恢复时间,跌落太深说明 PLL 带宽不够或者观测器跟随不上;二是稳态时估算转速的峰峰值,空载应该很干净,带载会有一定纹波,但如果超过 5% 额定转速,就要回头看电流采样和死区补偿。我一般的验收标准是:50% 额定转速、满载阶跃,估算转速波动不超过 3%,角度误差(和编码器对比)不超过 5 电角度。这两个指标过了,方案基本可用。
3.4 延时补偿和死区补偿,低速段的两根救命稻草
就算观测器和 PLL 都调好了,低速带载还是会有一段卡在某个转速上不去,这时候大概率是延时和死区在作祟。
延时来自两个地方:一是 ADC 采样到 PWM 更新之间的计算延时,二是 PWM 占空比写入到实际电压输出之间的零阶保持延时。两者合起来,在中心对齐 PWM 下平均延时差不多是 1.5 个 Ts。10kHz 下就是 150μs。转得慢的时候这点延时不算什么,100 rpm、极对数 4 对应电角速度 42 rad/s,150μs 折算角度只有 0.36 电角度,可以忽略。但转速上到 1500 rpm,电角速度 628 rad/s,同样 150μs 折算 5.4 电角度,这个就不能不管了,角度滞后直接导致转矩输出打折、效率下降。
补偿方式很直接,把输出电压用的角度往前推:θ_comp = θ̂ + ω̂ × 1.5 × Ts。这一行代码加在反 Park 变换之前,实测在 2000 rpm 以上能明显看到相电流幅值下降、效率提升。注意补偿角要限幅,ω̂ 在启动或者失锁瞬间可能异常大,不限幅会直接把角度甩出去。
死区补偿在低速段的重要性怎么强调都不过分。前面算过,48V 母线、1μs 死区、10kHz 开关,平均电压误差 0.48V,而 100 rpm 时反电动势峰值才 0.98V,误差占了将近一半。不补偿的话,观测器看到的"反电动势"里混着一大块和电流方向相关的方波成分,角度估计必然偏。
补偿的思路是根据相电流极性在输出电压上加一个反向的补偿量,补偿电压 Vcomp ≈ (Td/Ts) × Vdc,再乘以一个 0.8 到 1.2 的系数做微调。极性判断在电流过零附近会抖,常规做法是设一个电流死区,|i| < 0.1A 时补偿量线性过渡到 0,避免过零抖动。更精细的做法是对相电流做符号函数平滑,用 tanh 或者分段线性替代硬符号。
这里有个容易忽略的点:死区补偿的系数和母线电压有关,母线电压波动时补偿量要跟着变。如果代码里把补偿量写死,电池供电的应用从满电到欠压,补偿不是过头就是不够,低速表现会随电量变化。我一般用实时采样的母线电压参与计算,多一次乘法,省掉一堆现场问题。
3.5 一套可以照着走的上机调试流程
把上面的东西串起来,我给一套实际执行的顺序,按这个走能少绕很多弯。
第一步,不接电机,只跑电流环。给定 d 轴电流阶跃,看实际电流的上升时间和超调,确认电流环带宽达标、采样没有异常。这一步不通过,后面免谈。
第二步,开环强拖,固定电流、逐步升频,用示波器看三相电流是否对称、反电动势波形是否正常。同时把 HSO 跑起来(只观察不参与控制),对比 ê 的幅值和理论值 ωe·ψf,偏差超过 15% 就回头查参数。
第三步,切换到闭环,空载从低速往高速扫,记录每个转速点的估算角度误差(有编码器的话直接对比,没有就看相电流波形是否正弦、电流幅值是否最小)。角度误差超过 10 电角度就要停下来调参数或者补延时。
第四步,加载。从 20% 额定负载开始,逐级加到 100%,每个点稳定运行五分钟,观察估算转速波动、相电流 THD、MOS 管温度。低速满载是最难的点,重点关注 5% 到 15% 额定转速区间。
第五步,动态测试。突加突卸负载、正反转切换、转速阶跃,看恢复时间和是否失步。正反转过零是最容易翻车的地方,因为反电动势过零,观测器输入接近零,归一化失效。我的处理是在 |ω̂| 低于阈值时短暂切到电流闭环、角度由 ω̂ 积分维持,过了零点再切回观测器闭环。
第六步,温升测试。连续跑一小时,记录 Rs 变化带来的角度漂移。如果漂移明显,要么加在线电阻辨识,要么在观测器里加一个随温度修正的 Rs 查表。温度可以用 NTC 或者从 MOS 管内部传感器读,粗糙一点但有效。
4. 踩坑实录:HSO 调参常见问题速查
4.1 现象、根因、排查动作对照表
调了这么多套方案,问题翻来覆去就那么几类。我把最常见的整理成表,现场对着查能省不少时间。
| 现象 | 可能根因 | 排查动作 | 处理方式 |
|---|---|---|---|
| 低速启动反转或抖动 | 初始角度错误、极性判断反了 | 强拖时观察转向与给定是否一致 | 校正初始角,增加启动前预定位 |
| 低速带载失步 | Rs 偏小、死区未补偿、观测器增益不足 | 对比 ê 幅值与理论值,测实际相电阻 | 修正 Rs,加死区补偿,提高低速段 ωo |
| 高速角度滞后、电流偏大 | 计算延时未补偿、PLL 带宽不足 | 高速段对比估算角与编码器角 | 加 1.5Ts 角度超前,适当提 PLL 带宽 |
| 估算转速高频抖动 | 电流采样噪声、观测器增益过大 | 看 ê 波形毛刺,检查 ADC 触发时刻 | 降低 ωo,采样点对齐下桥中点,加零点校准 |
| 角度呈二倍频波动 | 电流采样直流偏置 | 停机采零点,看三相反馈是否偏置 | 实时零点扣除,校准运放 |
| 温升后低速性能变差 | Rs 温漂 | 冷热态对比同一工况的角度误差 | 在线 Rs 辨识或温度查表修正 |
| 正反转过零失步 | 反电动势过零、归一化失效 | 观察过零瞬间的 ω̂ 和 θ̂ | 过零区切电流闭环,角度积分维持 |
| 母线电压变化后低速变差 | 死区补偿量写死 | 不同母线电压下对比同一转速表现 | 补偿量按实时母线电压计算 |
4.2 四个典型翻车现场复盘
第一个现场是低速空载正常、一加负载就抖。当时的电机是一台小功率风机,空载 60 rpm 稳得很,挂上负载叶轮之后 80 rpm 开始周期性抖动,周期大概 200ms。查了半天以为是速度环积分饱和,把积分限幅收紧没用。后来把 êα、êβ 和相电流同时打出来,发现反电动势估计上有明显的方波成分,和电流极性同步。原因就是死区没补偿,负载电流一大,死区误差就显出来了。加上补偿之后抖动消失。这个案例说明空载测试不能作为验收标准,必须带载。
第二个现场是高速效率低、MOS 发热。方案在 2500 rpm 时相电流比理论值大了将近 20%,电机烫得厉害。查电流环、查参数都对,最后对比编码器角度发现估算角滞后了 12 电角度。12 度对应 2500 rpm、极对数 4,反推延时约 330μs,比预期的 150μs 大了一倍多。原因是代码里除了 1.5Ts 的固有延时,还有一层 ADC 采样到中断执行的软件延时没算进去。把补偿系数从 1.5 改成 2.5 之后,电流降下来了,温升也正常了。这件事让我养成了一个习惯:延时补偿系数一定要用实测角度误差反推,不要照抄理论值。
第三个现场是低温启动失败。产品在北方冬天户外启动,室温测试全过,零下十几度就启动不了。低温下永磁体磁性能变强,ψf 上升,同时 Rs 下降,观测器按常温参数算出来的 ê 幅值偏大,PLL 归一化之后的等效增益变化,角度收敛变慢。处理方式是加了一版低温参数表,按 NTC 温度切换 Rs 和 ψf 的修正系数,问题解决。这个坑提醒我,参数标定不能只做一个温度点。
第四个现场是正反转切换炸机。应用需要频繁正反转,正转 500 rpm 直接给 −500 rpm 指令,过零瞬间母线电流冲得很高,几次之后 MOS 就挂了。根因是过零时反电动势接近零,观测器输出角度乱跳,电流环在新旧角度之间来回切,实际输出电压方向错乱。改法是过零前先把转矩电流降到零,等转速自然降到阈值以下,切电流闭环维持角度,过零后再重新切回观测器。切换过程加 50ms 过渡,虽然响应慢了点,但稳定可靠。
4.3 几条手册上不会写的经验
第一条,观测器的 ê 一定要留 DA 输出或者高速数据记录通道。调参阶段我几乎每天都要看这个波形,很多问题看一眼波形就定位了,靠猜能猜一整天。数据记录用串口或者 CAN 上传都行,采样率至少要和 PWM 同步,降采样之后波形失真,看不出问题。
第二条,别迷信仿真。仿真里电流采样是理想的、死区是没有的、参数是准的,跑出来的角度曲线漂亮得像教科书。上机之后你会发现有一半的问题来自硬件,仿真根本模拟不到。我的做法是仿真只用来验证观测器结构对不对、增益量级合不合理,具体的数值一定在台架上定。
第三条,低速段的性能提升,硬件改动往往比算法改动收益大。把电流采样运放从普通型号换成低失调低温漂的,把采样电阻从 1mΩ 换成 5mΩ 提高信噪比,把死区时间从 1.5μs 压到 0.8μs(前提是驱动能力够),这些改动能直接把低速下限拉低一大截,比在算法里堆自适应、堆滤波实在得多。
第四条,每次改参数只改一个,改完必须记录。我吃过同时调三个参数结果不知道是哪个起作用的亏,后来强制自己用表格记录:日期、工况、改动项、现象、结论。看起来很笨,但半年后回头看这份记录,比任何文档都值钱。
5. 从台架到批量:鲁棒性怎么验证
5.1 温漂与参数漂移的补偿思路
台架上调好的参数,到了量产批次一定会遇到离散性。电机参数的批次差异能到 ±10%,控制器采样电路的增益误差能到 ±3%,这些叠加起来,同一套参数不可能覆盖所有个体。
我的处理分三层。第一层是产线标定,每台控制器出厂前自动测一遍相电阻和零点偏置,把修正系数写进 EEPROM。这一步成本很低,产线加个治具,几秒钟的事,但能消掉大部分离散性。第二层是运行时自适应,用观测器本身的电流误差去反推 Rs 的偏差。思路是:稳态时如果 Rs 偏小,观测器算出来的端电压压降不够,ê 会偏大,反映到电流误差上有一个直流量。把这个直流量积分起来修正 Rs,慢速收敛,时间常数取几十秒,避免和动态过程打架。第三层是温度查表,用 NTC 读数直接修正 Rs,简单粗暴但有效,适合对成本敏感、不想做在线辨识的场景。
三层里我最推荐第一层加第三层。在线辨识听起来高级,实际上在低速小电流工况下信噪比很差,容易收敛到错误的值,反而添乱。产线标定加温度补偿的组合,实现简单、行为可预测,量产项目里更稳妥。
5.2 一份可以照着执行的工况遍历清单
最后给一份验证清单,新产品定型前我基本都会跑一遍,缺哪项补哪项。
| 验证项 | 具体条件 | 通过标准 |
|---|---|---|
| 最低速带载 | 5% 额定转速,50% 和 100% 负载各 10 分钟 | 不失步,转速波动小于 5% |
| 最高速带载 | 100% 额定转速,满载 30 分钟 | 相电流 THD 小于 10%,器件温升在限值内 |
| 满载启动 | 冷态和热态各启动 20 次 | 成功率 100%,启动电流不超限 |
| 负载阶跃 | 20% 到 100% 突加突卸各 10 次 | 转速跌落小于 10%,恢复时间小于 300ms |
| 转速阶跃 | 10% 到 80% 来回切换 | 无失步,超调小于 15% |
| 正反转 | 中速正反转连续 50 次 | 过零平稳,母线电流无异常尖峰 |
| 母线波动 | 母线电压 ±20% 变化 | 低速性能无明显退化 |
| 温度循环 | 低温到高温全范围 | 各温度点低速带载正常 |
| 参数离散 | 换 3 台以上不同批次电机 | 不重新调参即可正常运行 |
| 长时间运行 | 满载连续 4 小时 | 角度误差漂移小于 5 电角度 |
跑完这张表,方案基本可以交付。真正量产之后还会遇到各种现场问题,但绝大多数都能在这张表里找到对应的影子,提前暴露总比在客户那里暴露好。
我个人在实际操作中的体会是,HSO 这类观测器的调参,七成时间花在参数测量和硬件确认上,三成时间才花在算法参数上。很多人在算法里反复折腾,其实是 Rs 测错了、零点没校准、死区没补偿。把基础工作做扎实,观测器带宽和 PLL 带宽按前面给的公式算出来,剩下的就是微调。低速无感这件事没有银弹,能做的就是把这个转速下限一点点往下压,每压下去一点,都是靠细节堆出来的。