ARTICLE DETAIL

资讯详情

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

无感FOC核心算法:龙伯格观测器原理、离散化与C代码实现

无感FOC核心算法:龙伯格观测器原理、离散化与C代码实现 1. 为什么无感FOC离不开观测器做无感FOCField-Oriented Control磁场定向控制的朋友大概都有过这种体验电机能转但你心里完全没底不知道转子到底在哪尤其从零速往低速爬的那段简直像蒙着眼开车。传统做法是在电机轴上装编码器或旋变位置一清二楚但成本上去了、结构变复杂了、线也多了在很多泵类、风机、压缩机、无人机电调场景里根本不现实。于是行业里普遍的做法是“无感”也就是去掉机械位置传感器转而依靠电压、电流采样通过算法把转子位置和转速估算出来。这个估算位置的算法就是观测器Observer。在FOC里观测器不是可选项而是无感方案的命根子。FOC不同于方波控制它需要实时知道转子磁极的电角度才能把定子电流矢量分解成交轴q轴和直轴d轴实现力矩和磁场的解耦。没有传感器就只能靠电机本身的电气特性反推位置。而龙伯格观测器就是这一类位置估算算法里最经典、也最适合入门的一个。它不仅能用于PMSM永磁同步电机经过改动也可以用在步进电机FOC、异步电机磁场定向等场景。这篇文章我会按我自己的调试习惯来聊先讲清楚龙伯格观测器到底在“观测”什么再写出能直接落地的离散化公式和C代码最后把增益设计、角度补偿、启动切入、噪声处理这些实战中绕不开的问题一次性讲透。内容适合正在做无感FOC的工程师也适合刚入门想弄明白“无感算法为什么这样设计”的学生。看完之后你至少能自己搭一个能跑的龙伯格反电动势观测器而不是停留在PPT公式层面。1.1 装传感器到底难在哪先别急着上算法想明白为什么大家宁可在算法上折腾也不愿意加编码器。一个增量式编码器好一点的光电式要几十块钱磁编码器虽然便宜点但安装精度要求高稍微偏心角度反馈就带纹波电流环跟着抖。而且电机轴端要专门留安装位对体积和重量敏感的产品几乎是致命的。产线装配也多一道工序还容易在运输振动中出问题。这不是说编码器不好而是说在很多场景下它的成本、结构、可靠性和系统复杂度都拼不过无感方案。无感方案等于把原本花在硬件上的钱转移到了算法和调试人力上。而算法一旦稳定量产一致性好边际成本几乎为零。这也是为什么这两年无感FOC在高速吹风机、吸尘器、风机水泵、电动工具里大面积铺开。说到底只有把传感器拿掉产品才有性价比竞争力。1.2 观测器到底在观测什么观测器这个词听着玄乎其实说白了就是“用一个模型去猜测系统的内部状态”。FOC控制里我们能直接测到的物理量就是相电流和母线电压通过坐标变换得到αβ轴的电压Uα、Uβ和电流Iα、Iβ。可是转子角度、转速、反电动势这些关键信息藏在电机内部没法直接测。龙伯格观测器的思路很直接我给电机建一个数学模型输入同样的电压模型里的电流本该跟真实电流一致。如果模型算出来的电流和实际采样电流不一样说明模型里的某个状态猜错了。这个“猜错的部分”主要就来自反电动势。反电动势的方向和转子磁极位置有确定关系所以只要把反电动势估算准转子位置就出来了。这是龙伯格观测器最朴素也最核心的思想用“实际电流 - 观测电流”的误差实时去修正模型里的反电动势状态。后面所有的公式和代码都是围绕这个误差修正展开的。2. 龙伯格观测器的数学底子与建模思路在把代码写出来之前我强烈建议先花半天时间把数学模型捋一遍。龙伯格观测器不像滑模观测器那样有很强的“开关”特性它的估计质量完全依赖模型准确度和增益设计不懂原理的人调参全靠瞎试运气好能转但一换电机就崩。2.1 状态观测器的通用框架一个连续线性系统如果写成状态空间形式$$ \dot{x} A x B u $$ $$ y C x $$其中x是系统状态u是输入y是输出。龙伯格观测器给出的状态估计为$$ \dot{\hat{x}} A \hat{x} B u L (y - C \hat{x}) $$这里的L就是观测器增益矩阵。对比一下就能发现观测器的模型跟原系统一模一样只是多了一项L乘以输出误差。如果估计状态和真实状态有偏差那么真实状态x和估计状态\hat{x}的误差e x - \hat{x}满足$$ \dot{e} (A - LC) e $$也就是说只要设计合适的L让矩阵(A - LC)的特征值都落在左半平面误差e就会以指数速度收敛到零。收敛速度取决于特征值的模值这就是“观测器带宽”的数学来源。用大白话说我照着电机搭了一个数字孪生两个模型吃同样的电压输出电流不一样时我就用这个电流误差去拉我的估计状态拉多久能拉齐由L决定。2.2 PMSM在αβ坐标系下的电压方程FOC里最常用的是表贴式PMSM工程上为了简化常常忽略d、q轴电感的差异把电感统一写成Ls。在静止αβ坐标系下PMSM的电压方程是$$ \begin{bmatrix} v_\alpha \ v_\beta \end{bmatrix} R_s \begin{bmatrix} i_\alpha \ i_\beta \end{bmatrix} L_s \frac{d}{dt} \begin{bmatrix} i_\alpha \ i_\beta \end{bmatrix} \begin{bmatrix} e_\alpha \ e_\beta \end{bmatrix} $$其中eα、eβ就是反电动势在αβ轴上的分量。对于表贴式PMSM反电动势可以写成$$ e_\alpha -\psi_{pm} \omega_e \sin\theta_e $$ $$ e_\beta \psi_{pm} \omega_e \cos\theta_e $$ψpm是永磁体磁链ωe是电角速度θe是转子电角度。看这个关系反电动势里不仅有角度信息还有速度信息所以只要能估出eα和eβ就能同时算角度和转速。把电流项单独挪到一边$$ \frac{d}{dt} i_\alpha -\frac{R_s}{L_s} i_\alpha \frac{1}{L_s} v_\alpha - \frac{1}{L_s} e_\alpha $$ $$ \frac{d}{dt} i_\beta -\frac{R_s}{L_s} i_\beta \frac{1}{L_s} v_\beta - \frac{1}{L_s} e_\beta $$到这里已经很清楚电流的导数受电压、电阻压降和反电动势三部分影响。前两项我都知道只有反电动势是未知的也是我最关心的。2.3 为什么把反电动势扩成“状态”直接在上面的方程里求解eα、eβ当然可以但工程上更喜欢把反电动势作为额外的状态变量放大状态向量里构成一个“扩张观测器”。理由是反电动势变化的速度相比电流变化速度要慢得多在单个PWM周期里近似恒定所以可以假设$$ \frac{d}{dt} e_\alpha \approx 0, \quad \frac{d}{dt} e_\beta \approx 0 $$这样我们就能构建一个四阶系统状态x [iα, iβ, eα, eβ]^T。观测器每周期执行两步第一步用模型预测电流和反电动势第二步用电流误差修正反电动势。整个方案结构统一、推导简洁在STM32这种主控上只需要几十行代码。如果你还想估负载转矩或者扰动同样可以用这个套路把扰动量扩成状态去观测。这是龙伯格观测器最实用的扩展思路很多论文里的“扩张状态观测器”本质都是这一套。2.4 龙伯格观测器的整体设计流程按照我自己的习惯设计龙伯格观测器分四步第一步列写电机模型的状态空间表达式第二步确定要观测的状态本文是反电动势第三步设计增益矩阵L使观测误差收敛第四步离散化并在MCU里实现。这里最需要留意的点是α轴和β轴方程是对称的所以增益矩阵可以解耦成两个独立的通道。也就是说α通道的增益只影响α通道β通道只影响β通道。后面的公式推导我都按这个对称假设来写简化很多。3. 龙伯格观测器在FOC控制环里的具体实现理论部分讲到这儿相信大家已经明白龙伯格观测器在做什么了。现在进入真正能干活的部分——把它写成可以在单片机里跑的实现。3.1 αβ轴电流与反电动势的观测方程把2.2里面的电机模型拿过来加上观测器增益修正写成龙伯格观测器形式$$ \dot{\hat{i}}\alpha -\frac{R_s}{L_s}\hat{i}\alpha \frac{1}{L_s}v_\alpha - \frac{1}{L_s}\hat{e}\alpha l_1(i\alpha - \hat{i}\alpha) $$ $$ \dot{\hat{i}}\beta -\frac{R_s}{L_s}\hat{i}\beta \frac{1}{L_s}v\beta - \frac{1}{L_s}\hat{e}\beta l_1(i\beta - \hat{i}_\beta) $$$$ \dot{\hat{e}}\alpha l_2(i\alpha - \hat{i}\alpha) $$ $$ \dot{\hat{e}}\beta l_2(i_\beta - \hat{i}_\beta) $$这里l1对应电流修正增益l2对应反电动势修正增益。为什么反电动势的微分等于电流误差乘以l2因为电流误差里包含了模型预测不准的部分而最大的模型偏差来源就是反电动势。如果估计的反电动势偏小模型预测的电流就会偏大电流误差就为负l2乘以这个误差就会把反电动势估往下调形成负反馈闭环。3.2 离散化从连续方程到单片机代码MCU里的控制程序是离散的所以要把上面的微分方程离散化。最常用也最简单的是前向欧拉法也就是用第k拍的估计值加上微分项乘以采样周期Ts得到第k1拍的估计值$$ \hat{i}\alpha(k1) \hat{i}\alpha(k) Ts \cdot \dot{\hat{i}}\alpha(k) $$ $$ \hat{e}\alpha(k1) \hat{e}\alpha(k) Ts \cdot \dot{\hat{e}}\alpha(k) $$在FOC电流环采样频率一般在10kHz到20kHzTs在50微秒到100微秒只要观测器极点远离离散化稳定边界欧拉法完全够用。你要是用双线性变换或者更高阶的离散化方法精度提升有限但代码复杂度和占用时间都会增加性价比不高。有一点必须提实际运行时你给观测器的电压vα、vβ不能直接用SVPWM的目标电压指令因为死区、管压降、母线电压波动都会让实际加到电机上的电压跟指令电压有偏差。尤其是低速大电流工况死区影响非常明显。工程上可以做一拍延时补偿条件允许的话测母线电压实时修正再懒一点至少要加死区补偿。否则观测器输入电压不准反电动势估计就会偏最后导致角度偏。3.3 转子角度怎么提取观测器输出的是反电动势eα、eβ。在表贴式PMSM里$$ \hat{\theta}e atan2(-\hat{e}\alpha, \hat{e}_\beta) $$注意是负eα、正eβ不要写反。我用这个公式时也栽过跟头电机要么抖动、要么反转查了半天发现是符号反了。由于观测器本质是一个低通动态系统估计出来的反电动势相比真实值有相位滞后。这个滞后在高转速下尤其明显如果不补偿等效于位置信号滞后会导致实际产生力矩的电流矢量跟d轴对不齐轻则效率下降重则高速掉转矩、过流保护。常见补偿方法是在角度上加上一个与转速相关的补偿值$$ \hat{\theta}_{comp} \hat{\theta}e k{comp} \cdot \hat{\omega}_e $$kcomp需要通过实验标定。更优雅的方法是后级接一个正交锁相环PLL把反电动势当作输入用PLL同时输出平滑的角度和转速。PLL的带宽设得比观测器低还能顺便滤掉高频噪声。这个我在实际产品里用过稳定性比直接atan2加固定补偿要好得多。3.4 一个可以直接抄的龙伯格观测器C代码下面这段代码我按工程风格写读者可以直接移植到自己的工程里。注意这里用float类型采样周期和电机参数需要提前填好。typedef struct { float Rs; // 定子电阻欧姆 float Ls; // 定子电感亨 float Ts; // 采样周期秒 float l1; // 电流误差增益 float l2; // 反电动势误差增益 float ialpha_hat; float ibeta_hat; float ealpha_hat; float ebeta_hat; } LuenbergerObserver_t; void LuenbergerObserver_Init(LuenbergerObserver_t *obs, float Rs, float Ls, float Ts, float l1, float l2) { obs-Rs Rs; obs-Ls Ls; obs-Ts Ts; obs-l1 l1; obs-l2 l2; obs-ialpha_hat 0.0f; obs-ibeta_hat 0.0f; obs-ealpha_hat 0.0f; obs-ebeta_hat 0.0f; } void LuenbergerObserver_Update(LuenbergerObserver_t *obs, float valpha, float vbeta, float ialpha, float ibeta) { float ialpha_dot (-obs-Rs / obs-Ls) * obs-ialpha_hat (1.0f / obs-Ls) * valpha - (1.0f / obs-Ls) * obs-ealpha_hat obs-l1 * (ialpha - obs-ialpha_hat); float ibeta_dot (-obs-Rs / obs-Ls) * obs-ibeta_hat (1.0f / obs-Ls) * vbeta - (1.0f / obs-Ls) * obs-ebeta_hat obs-l1 * (ibeta - obs-ibeta_hat); float ealpha_dot obs-l2 * (ialpha - obs-ialpha_hat); float ebeta_dot obs-l2 * (ibeta - obs-ibeta_hat); obs-ialpha_hat obs-Ts * ialpha_dot; obs-ibeta_hat obs-Ts * ibeta_dot; obs-ealpha_hat obs-Ts * ealpha_dot; obs-ebeta_hat obs-Ts * ebeta_dot; } float LuenbergerObserver_GetAngle(const LuenbergerObserver_t *obs) { return atan2f(-obs-ealpha_hat, obs-ebeta_hat); }实际工程中我会在调用Update之前对输入电压做死区补偿对采样电流做偏置校准否则观测器模型和真实对象之间存在系统性偏差。这个偏差在低速时可能让角度误差放大到几十度非常致命。4. 关键工程细节增益设计、参数整定与仿真验证公式和代码都有了但要让观测器稳定工作增益怎么取、电机参数变了会怎样、仿真怎么验证这些才是真正拉开工程师差距的地方。4.1 观测器增益L怎么设计才不会飘回到前面的α轴子系统。把电流和反电动势写成2x2状态空间A矩阵是$$ A_\alpha \begin{bmatrix} -R_s/L_s -1/L_s \ 0 0 \end{bmatrix}, \quad C_\alpha \begin{bmatrix} 1 0 \end{bmatrix} $$加上增益Lα [l1, l2]^T后误差矩阵为$$ A_\alpha - L_\alpha C_\alpha \begin{bmatrix} -R_s/L_s - l_1 -1/L_s \ -l_2 0 \end{bmatrix} $$这个2x2矩阵的特征多项式是$$ s^2 \left(\frac{R_s}{L_s} l_1\right)s \frac{l_2}{L_s} 0 $$如果我想让观测器的两个极点都落在s -ωo处也就是临界阻尼状态那么对比系数就得到$$ l_1 2\omega_o - \frac{R_s}{L_s} $$ $$ l_2 \omega_o^2 L_s $$这个公式非常实用。你只要根据FOC电流环带宽决定ωo就能算出增益。比如电流环带宽设计在1000 rad/s观测器带宽取5000 rad/s假设Rs0.5ΩLs0.2mH可以算l1 2*5000 - 0.5/0.0002 10000 - 2500 7500 l2 5000^2 * 0.0002 5000注意单位电阻的单位是欧姆电感单位是亨角频率单位是rad/s。观测器带宽不要盲目拉高。带宽容忍的噪声也全进来了电流采样噪声、PWM开关噪声都会通过L增益放大最终造成角度抖动。我在实际项目里通常取5~10倍电流环带宽然后根据示波器上的角度波形再做微调。记住一个原则观测器带宽比电流环高但不是越高越好是“刚刚好能跟上转速变化”最好。4.2 电机参数失配会带来什么后果龙伯格观测器最被人诟病的地方就是它对电机参数敏感尤其是定子电阻Rs。在低速重载时电流很大电阻压降占总电压的比例高如果Rs标定不准反电动势估计会产生明显偏差角度也会跟着歪。而电机发热时Rs变化可能超过20%这就意味着纯开环的Rs补偿不可能完全准确。解决思路有几个在观测器方程里加上在线辨识实时修正Rs。在离线阶段做“锁轴测试”手动旋转电机或堵转把Rs和Ls标得更准。用扩张状态的方法把电阻误差等效成扰动一起观测然后反馈补偿电压指令。我的建议是产品迭代初期先把参数标定做扎实用LCR表测电感、用直流伏安法测电阻然后在仿真模型里扫一遍参数偏差范围看角度误差能不能接受。如果温度范围大最好还是上在线参数辨识或者改用对参数不那么敏感的滑模观测器方案。不过滑模有抖振问题要加低通滤波又会带来相位滞后没有一招鲜的办法。4.3 Simulink仿真怎么搭我平时做FOC验证一定会先在Simulink里把观测器搭出来。原因是MCU上调试问题太多变量看不见不说波形抓取还麻烦。Simulink里可以直接把PMSM模型和控制器离散化代码放一起先用理想模型验证算法逻辑再逐步加入采样延迟、量化噪声、死区非线性等仿真结果满意了再搬代码。搭建要点电机模型用Simulink自带的PMSM模型设置好极对数、定子电阻、电感、磁链。逆变器和SVPWM模块用理想的也行但要保留死区时间参数。电流采样模块加一个零阶保持器模拟真实ADC采样率。观测器用S-Function或者MATLAB Function模块直接填3.4节C代码的逻辑。用Scope同时看真实角度和观测角度、真实反电动势和观测反电动势、电流残差。我习惯先加一个阶跃转速指令看观测角度动态跟踪效果再给负载转矩阶跃看观测器在扰动下是否还能稳住。角度误差要控制在几度以内否则FOC的控制效果会明显劣化。4.4 龙伯格观测器和滑模观测器怎么选很多人在无感FOC方案里会纠结用龙伯格还是滑模。我的判断标准很简单项目对参数鲁棒性要求高、转速范围宽、负载变化大的优先考虑滑模观测器SMO而项目追求角度平滑、噪声低、实现简洁电机参数相对稳定的龙伯格观测器更好。我把两者放在一起对比对比项龙伯格观测器滑模观测器实现难度较低代码量小中等需要设计滑模面参数敏感性较高依赖Rs/Ls准确度较低主要靠开关项把误差“压”住噪声表现平滑增益设计好时很干净有抖振需要额外低通滤波相位延迟有需要补偿或PLL滤波后延迟更明显调试成本中增益和参数校准需要时间中滤波截止频率和滑模增益需要配合实际项目里如果MCU算力紧张、对成本敏感龙伯格观测器是个很合适的起点。如果你想做高速电钻那种负载突变频繁的工具滑模观测器可能更耐造。但无论选哪种我建议先把龙伯格观测器的原理吃透因为滑模观测器本质上也是用一个非线性修正项替代这里的线性增益项思想同源。5. 调试实录无感FOC中我踩过的那些坑光有理论和代码还不够无感FOC调试时遇到的问题才是劝退很多人的真正原因。下面这几个坑是我自己做项目时真实踩过的记录下来供大家参考。5.1 低速段反电动势太小观测器直接“失明”龙伯格观测器依赖反电动势提取角度。反电动势的大小跟转速成正比转速越低信号越小。当转速低到几百转每分钟以下视电机而定反电动势幅值可能只有几十毫伏淹没在电流采样噪声和电压误差里观测器输出角度像一坨噪声电机根本站不住。现实做法是不要指望观测器解决零速和极低速问题。启动阶段要么用I/F强拉注入d轴电流按设定轨迹拖动转子要么用高频注入法利用凸极效应检测位置。转速拉起来之后再平滑切换到观测器闭环。切换时要注意角度不要跳变一般做法是让I/F给定的角度和观测器估计角度在切换前先同步对齐再逐渐把角度来源切到观测器。这个“预同步”过程做好了切换电流波动会小很多。5.2 启动切入时机和角度跳变有一次我调试一个风机启动时总是过流。查了半天发现在切换瞬间观测器角度和拖动角度差了大约30度。虽然程序里做了角度同步但同步速度太慢角度还在追的时候控制器已经切到闭环d轴大电流瞬间激增。后来我把切换策略改成“先同步、后切换、再切速度环”顺序是I/F拖动到设定转速 - 观测器与拖动角度校准对齐 - 继续用拖动角度跑一个固定的时间窗口 - 检查观测器角度误差小于阈值 - 开始多项式过渡比如在200毫秒内把角度从拖动源渐变到观测器源。这样电流波动从几十安降到了几安效果立竿见影。5.3 电流环带宽和观测器带宽要拉开差距这个坑很隐蔽。早期我图省事把观测器带宽设得跟电流环差不多结果系统总是低频振荡电流波形上有明显的等幅波动。后来想明白了观测器要估计的状态变化相对慢带宽如果跟电流环重叠电流环的动态变化会被观测器当成“状态变化死追”两个环之间互相耦合系统就不稳定了。现在我的习惯是拉开至少5倍差距。电流环1kHz观测器5kHz以上如果采样率不高只能把观测器带宽往下压但那也至少要保持3倍差距。另外如果你后级用了PLLPLL的带宽要设置得比观测器低相当于再加一级低通防止转速反馈抖动传导到速度环。5.4 高频噪声和滤波取舍无感FOC的电流采样很容易引入噪声特别是三电阻采样方案开关噪声、地弹、ADC前级RC参数不合适都会导致电流波形毛刺多。观测器增益一高这些毛刺直接变成角度抖动低速甚至能听到电机发出沙沙的声音。我的经验是先测量电流噪声底再决定观测器增益。如果噪声幅值超过电流满量程的1%以上先别急着调观测器而是回头把采样电路捋一遍。电流信号进ADC之前加一个低通RC滤波是常规操作截止频率根据PWM频率设置一般取几十kHz到几百kHz但不能太低否则会引入电流相位延迟需要软件补偿。角度抖动如果不太严重可以在观测器输出之后再套一个低通滤波器控制转速环反馈但要注意滤波带来的相位延迟对速度环稳定性的影响。我一般不用二阶以上滤波一阶就够截止频率跟着速度环带宽走。6. 常见问题速查表与个人体会为了方便大家排查问题我把平时调试过程中的典型现象和原因整理成一张表。这些内容不只在龙伯格观测器里适用很多无感FOC共性问题也能对号入座。6.1 无感FOC龙伯格观测器问题速查问题现象可能原因排查与解决办法电机静止时角度来回跳反电动势信号太弱被噪声主导低速用I/F启动或高频注入不要依赖观测器角度整体偏差大反电动势符号、相位补偿不对检查atan2符号减小Rs误差标定角度补偿系数高速角度滞后导致转矩下降观测器相位延迟未补偿用PLL锁相或加转速相关的角度补偿电流波形有高频率抖振观测器增益过大噪声放大降低ωo增加采样滤波检查电流采样噪声启动切换过流观察角度和拖动角度不同步增加预同步逻辑做渐变切换负载突变后失步观测器带宽不足或参数失配提高观测器带宽重新标定电感电阻电压模型输入不准死区、母线电压波动未补偿增加死区补偿用实测母线电压计算占空比这张表想表达的核心是问题往往不是观测器一个环节造成的。FOC整个链路很长从电流采样、坐标变换、电压重构、SVPWM到观测器、PLL、速度环任何一个环节有问题都会在观测器输出上放大。排查时要沿着信号链路一段一段查不要一上来就调增益。6.2 我的一点实操心得如果只让我说一句话总结龙伯格观测器我会说它就像你在黑屋里用手电筒照着墙上的影子根据影子的变化反推屋子的形状。它的工程价值在于结构简单、运行稳定、调试过程能锻炼你对电机模型的敏感度。我在实际使用中还有一个体会把龙伯格观测器调好之后你会发现对FOC整体的理解都上了一个台阶。因为你会开始主动思考电流环带宽、采样延迟、PWM死区、参数辨识这些底层问题。观测器不是孤立模块它是一个把硬件误差、模型误差、控制带宽全部串起来的枢纽。调试观测器的过程本质上是在调试整个电机控制系统的基本功。最后再分享一个小技巧调好观测器之后别急着拆编码器先用电机轴上的编码器做参考在示波器里同时看真实角度和观测角度的误差。这个误差曲线的均值代表系统偏差波动代表噪声水平。目标是把误差压到电角度几度以内然后你才有底气说这个无感方案能上车。这个验证方法我一直用了很多年每次换新电机、新板子都能省下好几天的无用功。
返回列表