ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

高频注入无感FOC控制:低速位置估计链路与代码实现全解析

高频注入无感FOC控制:低速位置估计链路与代码实现全解析 做无感FOC的同行应该都有体会中高速段用滑模观测器或者龙伯格观测器效果挺理想但转速一掉到低速甚至零速反电动势信号弱得可怜位置估计就开始飘电机抖着抖着就飞了。这种工况下业内主流的做法基本收敛到了同一个答案——高频注入也就是HFI。这篇文章就是把高频注入无感FOC这条链路彻底拆开讲从高频电压怎么叠进去IIR滤波器怎么提信号位置误差怎么解出来到最后磁极极性怎么不搞反全部落到代码层面一句一行捋清楚。适合正在做PMSM低速无感控制的工程师也适合刚接触无感FOC、想直接看代码理解原理的研究生。1. 先说清楚为什么低速无感控制要换高频注入这条路线1.1 反电动势在低速段失效的根本原因永磁同步电机的反电动势大小跟转速成正比公式写出来就是 E Ke·ω。转速掉到额定值的5%以下时反电动势的幅值可能只有毫伏到几十毫伏级别被电流采样噪声、PWM开关纹波、死区畸变这些因素一盖基本就看不见了。滑模观测器这类基于反电动势模型的方案本质上都是在解一个包含反电动势项的方程。信号弱到一定程度观测器里那个“滑模面”就很难维持稳定表现出来的就是估计角度剧烈抖动、启动失败、甚至带载时反转。这不是参数没调好而是原理上就决定了这类方法在低速段必然失效。而高频注入走的是另一条路它不依赖反电动势而是利用电机本身的凸极性——也就是d轴和q轴的电感差异。只要转子在某个位置哪怕转速为零高频激励下的电流响应也会带着位置信息。所以高频注入天然适合零速和极低速区间。1.2 高频注入与滑模观测器的分工默契现在的无感FOC工程里很少只用一种观测器。最常见的架构是低速和零速用高频注入中高速切换到滑模观测器或龙伯格观测器中间设一段过渡区做加权切换。为什么不在全速域都用高频注入原因有两个。第一高频注入在高速段会和电机的旋转反电动势耦合产生较大的角度误差第二注入的高频电流会带来额外损耗和噪声在高速段得不偿失。所以在实际项目里高频注入主要负责解决“从零到大概5%~10%额定转速”这一段滑模观测器负责“5%到100%”这一段。中间过渡区间常见做法是做一个速度相关的加权系数让两个估计器的输出按照转速比例平滑融合避免切换瞬间角度跳变。1.3 两种高频注入方案怎么选高频注入按信号叠加的位置分成旋转高频注入和脉振高频注入两种。旋转高频注入是在静止αβ坐标系里注入一个旋转的高频电压矢量然后通过解调高频电流的负序分量来提取转子位置。它的好处是不依赖初始角度对准但结构上要处理正序和负序分量的分离滤波器设计和信号解调都更复杂对采样同步要求也高。脉振高频注入是在估计的d轴方向注入高频余弦电压高频电流响应经过解调后直接给出位置误差信号再送到锁相环收敛。它的逻辑更直观实现代码量也更小配合磁场定向控制天然就是同一个坐标系。我在实际项目里基本都是用脉振注入调试链路短出的问题也容易定位。有一点需要提醒脉振高频注入对凸极率有要求内置式永磁电机IPMSM的d/q轴电感差异明显效果很好表贴式永磁电机SPMSM的凸极性主要来自磁饱和相对较弱信号信噪比会差一些需要更精细的滤波器设计。2. 高频电流提取IIR滤波器设计与信号解调全解析2.1 高频信号提取链路是怎么串起来的脉振高频注入的信号链路我习惯画成一条明确的数据流电流采样 → Clark变换 → Park变换 → d/q轴电流 → 高通滤波提取高频分量 → 解调乘以同频余弦 → 低通滤波 → 位置误差信号 → PLL位置估计器一步步看。三相电流采样先做Clark变换得到αβ轴电流再用手头估计出来的角度做Park变换得到d/q轴电流。这里用到的角度就是还在不断修正的“估计角度”。因为注入电压是叠加在估计d轴上的所以高频电流响应也主要在d轴分量上体现我们重点处理d轴电流就行。实际调试时把示波器探头接在ADC输出后的d轴电流变量上能看到一个明显的高频正弦叠加在低频电流之上。这就是我们后续要处理的核心信号——高频电流包络它里面藏着转子位置误差。2.2 IIR滤波器为什么是MCU上的最优解提取高频分量教科书上会推荐带通滤波器。但工程上我更推荐一个组合“高通滤波器 解调 低通滤波器”效果等同带通但每一级的截止频率都直观可控。为什么用IIR而不是FIR因为FIR要用很多阶才能在10kHz采样率下把几百赫兹的窄带信号干净地抽出来几十上百阶的卷积运算对MCU来说太重了而且代码写起来也不好看。IIR滤波器用二阶结构就能达到工程上够用的衰减特性每个滤波器只要5个乘法实时性好得很。代价是IIR的相位是非线性的会带来群延迟这个后面single说怎么补偿。具体到代码我常用的是直接I型二阶IIR结构差分方程长这样y[n] b0·x[n] b1·x[n-1] b2·x[n-2] - a1·y[n-1] - a2·y[n-2]写成C语言就是标准的结构体加处理函数typedef struct { float b0, b1, b2; float a1, a2; float x1, x2; float y1, y2; } iir_biquad_t; float iir_biquad_process(iir_biquad_t *f, float x) { float y f-b0 * x f-b1 * f-x1 f-b2 * f-x2 - f-a1 * f-y1 - f-a2 * f-y2; f-x2 f-x1; f-x1 x; f-y2 f-y1; f-y1 y; return y; }2.3 滤波器的代码实现与参数标定高通那一级我直接用一阶高通目的是把低频基波电流和直流偏置踢掉。截止频率一般放在注入频率的1/10到1/5左右。比如注入频率是1kHz高通截止就取100~200Hz。这样基波和直流被基本干掉了而1kHz的高频分量衰减很小。一阶高通的系数设计很简单给定采样周期Ts和截止频率fcfloat alpha 1.0f / (1.0f 2.0f * 3.14159265f * fc * Ts); // 高通y[n] alpha * (y[n-1] x[n] - x[n-1])解调那一步是把高通滤波后的d轴高频电流乘上一个与注入信号同频同相的余弦序列。这里有一个很容易踩的坑必须保证参与解调的余弦序列和实际注入信号同步不能直接用固定的三角函数查表就完事因为电流环计算延时和逆变器PWM延时都会让实际加到电机上的电压相位产生偏移。如果解调参考相位对不准误差信号里会出现一个固定偏差位置估计就会偏。稳妥的做法是拿一个“注入相位计数器”从注入信号生成的同一个地方取相位通过查表或库函数生成cos/sin一路跟着采样时刻走。解调后的信号包含一个直流分量我们想要的误差信号和一个二倍注入频率的分量需要滤除。这时候用一个一阶低通滤波器就够了截止频率一般取50~200Hz。低通系数同样简单float beta 2.0f * 3.14159265f * fc_lp * Ts; float b_lp beta / (1.0f beta); // 低通y[n] b_lp * x[n] (1 - b_lp) * y[n-1]如果手头有稍微高端的MCU也可以直接上二阶带通滤波器用Python先算出系数再填进去import numpy as np from scipy import signal fs 10000.0 f0 1000.0 q 2.0 w0 2.0 * np.pi * f0 / fs b, a signal.butter(2, w0 / np.pi, btypelow)但我在实际调试中还是推荐高通低通的组合因为调试时可以分开观察哪一级出了问题而不是对着一个二阶带通biquad系数发呆。3. 位置估计与磁极极性判断从误差信号到转子角度3.1 锁相环估计位置的完整代码解调并低通滤波之后我们得到的是一个与位置误差成近似正弦关系的信号ε。理论上它是sin(2Δθ)的形式在误差不大时近似等于2Δθ。这个信号就是锁相环的输入。锁相环不需要知道电机模型结构就是标准的PI积分器。PI把误差信号稳到零积分器的输出就是估计的电角速度再积分就是估计角度。typedef struct { float kp; float ki; float integral; float omega_est; float theta_est; float ts; } hfi_pll_t; void hfi_pll_update(hfi_pll_t *pll, float error_signal) { float p_out pll-kp * error_signal; pll-integral pll-ki * error_signal * pll-ts; pll-omega_est p_out pll-integral; pll-theta_est pll-omega_est * pll-ts; // 角度归一化长时间运行防止浮点溢出 if (pll-theta_est 6.2831853f) { pll-theta_est - 6.2831853f; } else if (pll-theta_est 0.0f) { pll-theta_est 6.2831853f; } }PLL带宽的整定要注意和电流环拉开距离。电流环带宽通常200~500HzPLL带宽如果设太高会把高频噪声直接放进速度环电机表现出顿挫。我一般先按期望位置估计带宽20~50Hz来整定PI参数。如果知道阻尼比ζ和期望带宽ω_pll可以这样算Kp和KiKp 2·ζ·ω_pllKi ω_pll²比如取ζ0.707带宽ω_pll2π·30≈188.5rad/s那么Kp≈266Ki≈35530。实际再乘以误差信号的归一化增益做一次标定。3.2 为什么锁相环会带来180度模糊这是一个特别容易忽略、但实际非常致命的问题锁相环只能把角度收敛到两个可能值之一这两个值相差180度。原因是误差信号ε正比于sin(2Δθ)而sin(2θ)和sin(2θ2π)是同一个值。锁相环把sin(2Δθ)拉到零但Δθ0和Δθπ都满足条件。所以在没有额外手段时电机可能“正着转”也可能“反着转”完全取决于初始状态和扰动方向。这也是为什么高频注入不能只靠锁相环就完成初始定位。必须额外做一次磁极极性判断把180度歧义消掉。3.3 磁极极性判断的两种代码实现磁极极性判断的核心物理基础转子磁路在N极方向更容易饱和导致d轴正方向N极方向的高频电流响应幅值大于反方向。换句话说同样是加一个正向电压脉冲和反向电压脉冲两个方向的电流峰值不一样大的那个就是N极方向。工程上最直接的方法我称为“正反脉冲法”。流程是锁相环先收敛到某个角度θ₀然后分两次注入脉冲电压比较电流响应幅值。代码框架大致如下float measure_pulse_current(float angle, float v_pulse, float t_pulse) { float current_peak 0.0f; // 1. 将估计角度强制设为 angle // 2. 施加 v_pulse * cos(angle) 到 d轴参考电压 // 3. 持续 t_pulse 时间期间采样 d轴电流记录峰值 // 4. 关断电压等待电流衰减到零 return current_peak; } void polarity_detect() { float i_pos, i_neg; // 第一次在锁相环收敛角度方向注入 i_pos measure_pulse_current(theta_est, V_PULSE, T_PULSE); // 等待电流完全衰减 // 第二次在反方向注入 i_neg measure_pulse_current(theta_est 3.14159265f, V_PULSE, T_PULSE); if (i_neg i_pos) { // 说明收敛方向反了补180度 theta_est 3.14159265f; if (theta_est 6.2831853f) theta_est - 6.2831853f; } }写代码容易调好需要注意几个细节。第一个细节是“等待电流衰减到零”不能省否则第二次注入时磁路初始状态和第一次不一样比较结果就失真了。衰减时间取决于电机的电气时间常数L/R一般给2到5毫秒足够。第二个细节是脉冲电压幅值的选择。太小电流响应差异被噪声淹没太大可能把电流推到过流保护阈值。我习惯从额定电流对应的电压开始观察ADC采到的峰值再往回调整到大概额定电流的30%~50%左右。第三种极性判断方法是分析高频电流包络的谐波成分。因为磁饱和不仅产生2Δθ项还会产生与极性相关的Δθ项通过在解调后提取一次谐波的符号来判断N/S。这个方法代码量不算大但滤波器和FFT的配合比较麻烦我用过一次之后就改回了脉冲法。4. 高频注入系统的启动流程与调参实战4.1 从零速到闭环的完整时序实际项目里高频注入系统不是“上电就直接跑HFI”这么简单需要一套完整的启动流程。我常用的时序是第一步初始位置粗估计。用高频注入让锁相环先收敛得到一个可能的转子角度可能是正的也可能是反的。这一步一般几百毫秒内完成。第二步磁极极性判断。按前面说的正反脉冲法把收敛角度修正到真正的N极方向。做完这一步转子初始位置就确定了。第三步强制建立电流环闭环。用估计角度做Park变换d轴给定一个小幅励磁电流q轴给定0让电流环先接管d/q轴电流。第四步速度环投入进入低速闭环运行。此时如果目标就是零速堵转保持系统就已经进入运行状态如果还要提速那么当转速进入中高速区间后开始切换到滑模观测器。每一步之间要留出足够的稳定时间不要刚做完极性判断马上切到满速给定否则电流冲击和角度跳变会让系统直接失控。4.2 关键参数怎么选频率、幅值、带宽高频注入的参数选型是整个系统能不能稳定工作的关键放在一张表里看参数典型范围选择原则注入频率0.5~2kHz远低于PWM采样频率的1/5同时高于电流环带宽3倍以上注入幅值5%~15%母线电压信噪比与噪声、损耗的折中高通滤波截止100~300Hz滤除基波和直流保留注入频率信号解调低通截止50~200Hz滤除二倍频同时保住位置动态响应PLL带宽20~50Hz远低于电流环带宽避免干涉极性判断脉宽0.5~2ms足够建立电流峰值又不过流注入频率的选取我习惯先用PWM开关频率的1/8到1/10作为一个粗略起点。比如PWM是10kHz注入频率取1kHz左右。接着检查一下电流环带宽假设300Hz注入频率1kHz是它的3倍多基本不会让电流环误响应。还要保证采样频率对注入频率有足够的过采样倍数10kHz采样对1kHz注入有10个采样点解调出来的波形足够顺畅。注入幅值这块我个人的经验是从10%母线电压起步然后看电流响应。如果高频电流峰峰值低于额定电流10%就提高幅度如果电机噪声明显刺耳就降低幅度。调试到最后多数项目落在6%~12%区间。4.3 系统联调的调参顺序参数之间是耦合的乱调会是灾难。我推荐的顺序是先定频再定幅再调滤波最后整定PLL。第一步把注入频率和幅值先固定下来。第二步只加高频注入不给转速给定观察d轴高频电流波形是否干净对称。如果波形上有明显毛刺或不规则畸变先查采样时序和滤波系数不要急着调PLL。第三步给一个小角度的阶跃扰动看解调输出误差信号能不能跟着变方向对不对。第四步投入PLL看估计角度是否平顺收敛。第五步再做极性判断并验证初始定位方向。第六步切闭环给负载观察零速保持能力。我见过太多人一开始就猛调PLL参数结果角度一会儿震荡一会儿发飘折腾几天都不知道问题出在滤波器上。实际上百分之八十的高频注入调试问题都出在信号链路上而不是环路参数上。5. 实战中的常见问题与排查技巧5.1 问题速查表调试中反复出现的问题其实很集中我整理成了一张速查表现象可能原因排查与解决估计角度持续抖动解调后噪声大PLL带宽过高降低PLL带宽检查低通滤波截止频率启动时反转磁极极性判断失败增大脉冲电压延长电流衰减等待时间位置总有固定偏差滤波器群延迟产生相位滞后做相位补偿或实测标定高频啸叫明显注入频率落在人耳听觉范围提高注入频率至18kHz以上或降低幅值切换到中高速时角度跳变过渡区加权切换处理不当提前让两个观测器角度对齐再切换电流环发热严重电流环P反馈响应了高频分量电流反馈通道加陷波或低通剥离注入频率那个“抖动”的问题我多说一句。如果你发现角度在某个位置来回摆而电流波形又正常先不要动任何参数把解调低通的输出打出来看一眼。很多时候是低通的带宽给得太高二倍频分量没有滤干净。把低通截止频率从200Hz降到80Hz波形会立刻平滑很多。5.2 几个值得警惕的隐蔽坑滤波器群延迟这个坑不是看理论就能发现的。我最早调的板子上估计角度与实际角度存在十几度的固定偏差一开始以为是电流采样偏置查了很久后来把滤波前后的高频信号用示波器对比才发现是IIR滤波器在中心频率附近的群延迟把误差信号整体平移了。补偿的方法是在角度估计结果上加上一个与运行状态有关的固定补偿角实测标定一遍就行。还有一个坑是极性判断时的负载干扰。如果电机带着负载做极性判断负载转矩会在电流响应上叠加一个方向性的偏差容易导致正反脉冲比较结果误判。工程上的做法是把极性判断安排在零速、零负载或轻载状态下进行分两步走先空载判断极性再带载运行。高频噪声问题也值得单独讲讲。全桥逆变器本身是电压源PWM开关会产生电流纹波如果注入幅值太小高频电流响应很容易被开关纹波淹没。有些方案喜欢把注入频率提到超声段来避免噪声但对采样率和电流环延时要求更高。低成本MCU上折中的做法是把注入频率设在1kHz附近接受可闻噪声同时做好占空比限制。最后提醒一下浮点处理的问题。如果MCU没有FPU纯软件浮点跑解调和滤波会很吃力。我一般会把滤波器系数和PLL参数全部转成Q15格式状态变量也用定点更新性能能快好几倍。代码结构整体不变只是把乘法替换成定点宏。我个人在实际操作中体会到高频注入无感FOC这套系统原理书上几页纸但真正让它稳定可靠地跑起来功夫全在信号链路的每一个环节。滤波器群延迟、极性判断时序、注入参数和电流环的配合每一个细节都值得反复验证。做完一个完整的调试流程之后你对整个电机控制系统的理解会和只写滑模观测器时完全不在一个层次上。这套思路不仅适用于低速无感后续做中高速切换、带载启动、甚至某些特殊电机参数的适配都会顺手很多。
返回列表