无感FOC滑模观测器:原理推导、代码实现与调参指南
1. 无感FOC中滑模观测器的定位与反电动势观测动机做电机控制的朋友应该都有这个经历第一次把无感FOC跑起来看着电机在开环I/f驱动下转得挺顺一切到闭环就抖、失步甚至直接过流报警。问题的根源往往不在电流环PI而在于你手里没有一个可靠的转子位置信号。有感FOC可以用编码器、霍尔甚至磁编码器无感方案中我们能拿到的只有相电流和母线电压想要估算出转子位置最直接的办法就是观测反电动势。反电动势的本质是永磁体旋转时在定子绕组里感生出来的电压它的相位就包含转子位置信息。在αβ静止坐标系下表贴式永磁同步电机的反电动势可以写成$$ e_\alpha -\psi_f \omega_e \sin\theta_e,\quad e_\beta \psi_f \omega_e \cos\theta_e $$其中 $\psi_f$ 是永磁体磁链$\omega_e$ 是电角速度$\theta_e$ 是转子电角度。只要把 $e_\alpha$ 和 $e_\beta$ 估计出来角度就能通过反正切得到。问题在于反电动势不是一个可以直接测量的物理量它藏在电压方程里和电流、电阻、电感混在一起必须通过模型把它“剥离”出来。而常规的龙伯格观测器在中高速下表现尚可一旦转速偏低或者参数偏差大观测精度就明显恶化。滑模观测器受欢迎本质上是因为它有两个突出优点一是结构简单不需要复杂的矩阵运算一个开关项加两个积分器就能工作非常适合单片机实时运行二是对电机参数的摄动和外部扰动有很强的鲁棒性尤其是对电阻电感变化不那么敏感。当然它也有一堆自己的毛病比如抖振、低速失效、滤波相位滞后这些后面讲。这篇文章就是把滑模观测器的推导从头到尾走一遍从数学原理到离散代码再到调参尽量让看完的人能自己写出一版能跑的SMO。2. 滑模控制的数学骨架滑模面、到达条件与等效控制2.1 滑模面的构建思路用开关把误差压到一条直线上滑模控制的核心思想听起来甚至有点“粗暴”人为设计一个滑模面再用一个高增益的开关项把系统状态强行“压”到这个面上让它在面上滑动最终收敛到平衡点。以最简单的标量系统为例假设我们要让状态 $x$ 跟踪 $x^$定义误差 $s x - x^$滑模面就是 $s0$。控制律取 $u k,\text{sgn}(s)$$k$ 足够大时误差会被强制拉向 $s0$。在滑模观测器里这个思想被移植到了状态估计上我们用电流的估计值和实测值之差作为滑模面。设当前估计电流为 $\hat{i}$实测电流为 $i$则误差 $\tilde{i} \hat{i} - i$。控制目标就是把 $\tilde{i}$ 驱动到零让观测器的电流轨迹完全“复刻”真实电流。一旦电流估计准确了观测器中那个用来压制误差的等效控制量里就包含了反电动势的全部信息。这里要注意一个关键点滑模观测器不直接估计反电动势它先强制电流误差收敛再反过来从控制量中提取反电动势。这个“让误差为零再反解扰动”的思路正是等效控制法的核心。很多初学者一开始看SMO的框图会懵觉得明明是在估计电流怎么最后输出的是角度其实就是绕了这么一圈。2.2 到达条件开关增益的下限推导要让滑模运动发生必须保证状态轨线在任何初始条件下都向滑模面 $s0$ 靠拢数学上就是李雅普诺夫条件 $s\dot{s} 0$。这个条件会直接给出开关增益 $k$ 的取值下限工程上意义很大。用一个一阶误差系统来说明。设误差动态为$$ \dot{\tilde{\imath}} -\frac{R}{L}\tilde{\imath} \frac{e - k,\text{sgn}(\tilde{\imath})}{L} $$其中 $e$ 是我们要观测的反电动势$k$ 是开关增益。把到达条件展开$$ \tilde{\imath} \cdot \dot{\tilde{\imath}} -\frac{R}{L}\tilde{\imath}^2 \frac{\tilde{\imath}(e - k,\text{sgn}(\tilde{\imath}))}{L} $$第一项 $-\frac{R}{L}\tilde{\imath}^2$ 恒小于等于零是天然的稳定项。要保证整体小于零只需要让第二项也为负。分两种情况$\tilde{\imath} 0$ 时$\text{sgn}(\tilde{\imath})1$要求 $e - k 0$即 $k e$$\tilde{\imath} 0$ 时$\text{sgn}(\tilde{\imath})-1$要求 $e k 0$即 $k -e$。合并起来就是 $k |e|$。也就是说开关增益必须大于反电动势的瞬时绝对值这也是为什么滑模观测器在低速下天生吃亏——反电动势太小信号被噪声淹没而你想靠加大 $k$ 来压误差又会加剧抖振陷入两难。2.3 等效控制滑模面上的“温柔”平衡滑模运动一旦建立系统状态就被“钉”在滑模面上此时 $s0$ 且 $\dot{s}0$。把这个条件代入误差动态方程就能反解出一个连续的控制量这个量叫等效控制 $u_{eq}$。对于上面的例子$$ 0 \frac{e - u_{eq}}{L} \Rightarrow u_{eq} e $$很漂亮的结果开关项虽然自身是高频跳变的不连续量但它在一个控制周期内的平均效果恰好等于反电动势。换句话说反电动势信息被调制进了开关项的低频分量里。实际工程中我们正是通过对开关项做滤波来解调出反电动势的。理解这一点后面看滤波器设计就不会觉得突兀了。等效控制的概念是整个滑模观测器从“控制算法”变成“观测算法”的桥梁。数学上它严谨地解释了为什么一个开关控制能提取出平滑的反电动势波形也告诉我们滤波不是可有可无的而是解调过程的必需环节。3. 永磁同步电机滑模观测器完整推导3.1 αβ坐标系下的电机状态方程先写出表贴式永磁同步电机在αβ静止坐标系下的电压方程。这里假设电机是隐极式即 $L_d L_q L_s$凸极效应忽略不计。实际大多数无感FOC跑的家电、电动工具、水泵风机的电机都满足这个近似凸极电机会用到脉振高频注入等方法不在本文范围。$$ v_\alpha R_s i_\alpha L_s \frac{d i_\alpha}{dt} e_\alpha $$$$ v_\beta R_s i_\beta L_s \frac{d i_\beta}{dt} e_\beta $$这里的 $e_\alpha$ 和 $e_\beta$ 就是上一节写过的反电动势它们包含了转子角度信息。把方程改写成状态方程的形式电流作为状态量$$ \frac{d}{dt}\begin{bmatrix}i_\alpha \ i_\beta\end{bmatrix} -\frac{R_s}{L_s}\begin{bmatrix}i_\alpha \ i_\beta\end{bmatrix}\frac{1}{L_s}\begin{bmatrix}v_\alpha - e_\alpha \ v_\beta - e_\beta\end{bmatrix} $$这个形式的好处是反电动势被明确地建模成了系统的“扰动项”。我们接下来的任务就是利用滑模观测器把这两路扰动从电流动态中分离出来。3.2 观测器结构与误差动态方程按照标准的滑模观测器设计流程构造一个和真实系统同结构的电流估计器唯一的区别是真实系统里是反电动势 $e_\alpha, e_\beta$观测器里用开关控制量 $u_\alpha, u_\beta$ 来替代$$ \frac{d}{dt}\begin{bmatrix}\hat{i}\alpha \ \hat{i}\beta\end{bmatrix} -\frac{R_s}{L_s}\begin{bmatrix}\hat{i}\alpha \ \hat{i}\beta\end{bmatrix}\frac{1}{L_s}\begin{bmatrix}v_\alpha - u_\alpha \ v_\beta - u_\beta\end{bmatrix} $$控制量取为电流误差的符号函数乘以增益$$ u_\alpha k,\text{sgn}(\hat{i}\alpha - i\alpha),\quad u_\beta k,\text{sgn}(\hat{i}\beta - i\beta) $$这里 $k$ 是滑模增益$\text{sgn}(\cdot)$ 是符号函数。将观测器方程减去真实方程得到误差动态$$ \frac{d\tilde{\imath}\alpha}{dt} -\frac{R_s}{L_s}\tilde{\imath}\alpha\frac{e_\alpha - k,\text{sgn}(\tilde{\imath}_\alpha)}{L_s} $$$$\frac{d\tilde{\imath}\beta}{dt} -\frac{R_s}{L_s}\tilde{\imath}\beta\frac{e_\beta - k,\text{sgn}(\tilde{\imath}_\beta)}{L_s} $$这两个轴的误差方程在数学上是解耦的α轴的推导和β轴一模一样所以下面只分析α轴β轴完全对称。误差方程呈现出一个非常清晰的结构第一项是电阻带来的衰减项它把误差往零拉第二项是反电动势和开关项的差分驱动项作用在滑模面上。只要 $k |e_\alpha|$开关项就能把误差牢牢锁在零附近。这就是上一节“到达条件”在具体系统里的落地。3.3 反电动势提取等效控制等于反电动势的直接证明当滑模运动建立之后电流估计误差为零$\tilde{\imath}_\alpha 0$同时它的导数也为零。把这个条件代入误差动态方程$$ 0 \frac{e_\alpha - u_{\alpha,eq}}{L_s} $$于是直接得到$$ u_{\alpha,eq} e_\alpha $$同样β轴有 $u_{\beta,eq} e_\beta$。这里的 $u_{eq}$ 不是那个高频跳变的符号函数本身而是它的等效值工程上讲就是开关控制量经过低通滤波后的连续输出。你可能会有疑问明明 $u_\alpha$ 是正负 $k$ 跳变的方波怎么能说它等于一个正弦反电动势这正是等效控制的精髓——符号函数的高频分量负责维持滑模运动而低频分量恰好就是反电动势只要你把高频分量滤掉剩下的就是 $e_\alpha$。实际代码中很多人直接用饱和函数替换符号函数饱和函数在边界层内本身就是一个连续的比例项输出已经比较平滑。此时输出的 $u_\alpha$ 直接就是近似反电动势低通滤波器从“必须”变成了“加强平滑”。两种方案我都试过饱和函数方案在低噪声环境下表现更干净代码也简单推荐优先采用。3.4 转子角度与转速的最终计算得到 $e_\alpha$ 和 $e_\beta$ 之后转子电角度的计算就简单了。回顾反电动势的表达式$$ e_\alpha -\psi_f \omega_e \sin\theta_e,\quad e_\beta \psi_f \omega_e \cos\theta_e $$做比值$$ \frac{-e_\alpha}{e_\beta} \frac{\psi_f \omega_e \sin\theta_e}{\psi_f \omega_e \cos\theta_e} \tan\theta_e $$所以$$ \hat{\theta}e \arctan\left(-\frac{e\alpha}{e_\beta}\right) $$实际工程里一般用atan2函数实现因为atan在角度接近90度时会因为分母趋零导致数值不稳定$$ \hat{\theta}e \text{atan2}(-e\alpha,\ e_\beta) $$转速可以用反电动势幅值估计$$\hat{\omega}e \frac{1}{\psi_f}\sqrt{e\alpha^2 e_\beta^2} $$但直接开方对噪声很敏感工程上更常见的做法是把角度送进一个PLL锁相环用角度信息去追踪转速这样既能平滑角度又能获得连续的速度估计。PLL的鉴相器误差可以这样构造$$ \varepsilon -e_\alpha \cos\hat{\theta}e - e\beta \sin\hat{\theta}_e $$代入反电动势表达式可以化简为 $\varepsilon E\sin(\theta_e - \hat{\theta}_e)$当估计角度接近真实角度时$\varepsilon \approx E(\theta_e - \hat{\theta}_e)$ 成为一个线性的角度误差信号交给PI调节器就可以闭环锁定角度和转速。标准的三相PMSM无感FOC代码里SMO输出接一个PLL几乎成了标配后面调参部分我会给出一组实用的初始参数。4. 从连续域到离散代码滤波、角度提取与相位补偿4.1 前向欧拉离散化与代码结构在单片机上实现滑模观测器最常用的离散化方法是前向欧拉法。虽然它的精度不如梯形法或龙格库塔法但胜在简单、计算量小、在几十千赫兹的电流环频率下精度足够。以α轴为例把连续微分方程改写成差分方程$$ \hat{i}\alpha[n1] \hat{i}\alpha[n] \frac{T_s}{L_s}\left(v_\alpha[n] - R_s\hat{i}\alpha[n] - u\alpha[n]\right) $$这里 $T_s$ 是电流环控制周期。注意观测器的输入电压 $v_\alpha, v_\beta$ 不是逆变器的给定电压而是实际施加到电机端口的电压最理想是用电压传感器测量但绝大多数低成本驱动器没有电压传感器只能把SVPWM的给定电压近似当作实际电压再补上死区补偿和逆变器管压降补偿。下面是一段简化但完整的SMO离散实现框架我用的是类C语法方便你迁移到自己的代码里// 参数Rs, Ls, Ts, K_slide, delta, wc // 输入v_alpha, v_beta, i_alpha, i_beta // 输出theta_est, omega_est // 1. 计算电流误差 float err_alpha i_alpha_hat - i_alpha; float err_beta i_beta_hat - i_beta; // 2. 饱和函数替代符号函数边界层为 [-delta, delta] float u_alpha sat(err_alpha, K_slide, delta); float u_beta sat(err_beta, K_slide, delta); // 3. 观测器迭代前向欧拉 i_alpha_hat Ts / Ls * (v_alpha - Rs * i_alpha_hat - u_alpha); i_beta_hat Ts / Ls * (v_beta - Rs * i_beta_hat - u_beta); // 4. 一阶低通滤波提取反电动势可选取决于饱和函数边界层厚度 e_alpha_f wc * Ts * (u_alpha - e_alpha_f); e_beta_f wc * Ts * (u_beta - e_beta_f); // 5. 角度提取 theta_est atan2(-e_alpha_f, e_beta_f); // 6. 也可以送PLL继续追踪转速这里的sat函数实现是float sat(float x, float k, float delta) { if (x delta) return k; else if (x -delta) return -k; else return k / delta * x; }4.2 为什么从符号函数换成饱和函数抖振的工程处理理论推导用的是符号函数直接拿到工程上会有一个非常头疼的问题——抖振。由于符号函数输出是离散的 $\pm k$在滑模面附近会以极高的频率来回切换这种切换会通过电流误差一路传导到角度估计里导致控制力矩脉动、噪音变大、甚至激发机械共振。你可以理解为“误差刚越过零点就被一个最大力猛踹回去”如此反复。工程上最常见的处理办法是把符号函数替换为饱和函数即在零点附近设置一个边界层 $[-\delta, \delta]$边界层内输出与误差成比例相当于用一个有限增益的线性环节代替无限增益的开关。边界层外的行为仍然和符号函数一致保证全局收敛性边界层内的行为则是连续的抖振被大大削弱。我实际测试的感受是δ太小效果不明显δ太大会让反电动势波形明显变形。一个比较合理的起点是取额定电流的2%~5%或者观察电流采样噪声幅值噪声多大δ就取多大左右。注意引入饱和函数之后“等效控制等于反电动势”的结论依然成立只不过不是通过滤波从方波里解调而是边界层内的比例控制量本身就近似等于反电动势。这是这类连续化方法的天然优势也是我推荐大家直接用饱和函数而不是“符号函数低通滤波”组合的原因。4.3 低通滤波与相位滞后补偿不管用哪种方案输出端总会残留高频分量。一阶低通滤波器是标配$$ \frac{d e_f}{dt} \omega_c (u - e_f) $$其中 $\omega_c$ 是滤波截止角频率。这个滤波器的相位滞后问题要特别注意一阶低通在频率 $\omega$ 处的相位延迟为$$ \Delta\theta -\arctan\left(\frac{\omega}{\omega_c}\right) $$反电动势的频率就是电频率而电频率正比于转速。转速越高延迟越大最终角度估计会落后于真实位置导致电流环解耦错误、转矩下降。补偿方法是在估计角度上加上一个和转速相关的修正角$$ \hat{\theta}_{comp} \hat{\theta}_f \arctan\left(\frac{\hat{\omega}_e}{\omega_c}\right) $$如果用了PLL追踪角度则可以直接在角度输出端补偿。这个补偿角在低速时很小高转速时非常关键。我有个项目在6000rpm电机上跑没加补偿之前满载转矩掉了10%左右加了补偿之后恢复正常。不过要注意这只是针对线性系统的一阶近似补偿如果滤波器阶数更高或者还在边界层内加速补偿精度会下降。4.4 离散化步长选择与计算量估算电流环周期 $T_s$ 直接决定观测器精度。理论上只要系统稳定离散化步长越短越好但实际受MCU算力和PWM开关频率限制。根据我的经验SMO的离散步长应该和PWM周期保持一致也就是每个PWM中断里算一次通常取10kHz~20kHz。如果算力紧张也尽量不要把SMO放在一个较慢的任务里单独跑因为电流采样不实时整个观测器的收敛性会受到严重影响。SMO本身的运算量非常小两次积分、两次饱和函数、一次atan2再加上一个PLL在Cortex-M0级别的主控上也不过十几微秒的量级。这也是它在低成本电机驱动方案里几乎“垄断”了无感控制的原因——性能不一定是最好的但性价比和可实现性绝对是最高的。5. 工程调参经验与常见问题排障5.1 滑模增益k的整定原则与初始值计算增益 $k$ 的取值是SMO调参的第一步。前面推导已经说明为了满足到达条件必须有 $k |e|$即 $k$ 要大于最大反电动势峰值。反电动势峰值怎么算很简单用永磁体磁链和最大电角速度的乘积$$ E_{max} \psi_f \omega_{e,max} $$有些电机厂商不给 $\psi_f$给的是反电动势常数 $K_e$单位V/krpm。换算要注意$K_e$ 通常指线反电动势有效值要先换算成相反电动势峰值。举个例子一个电机在1000rpm时线反电动势有效值是60V则相反电动势峰值约为 $60 \times \sqrt{2}/\sqrt{3} \approx 49$V电角频率是 $p \times 2\pi \times 1000/60$$p$ 是极对数假设 $p4$则 $\omega_e 418.9$ rad/s于是 $\psi_f 49/418.9 \approx 0.117$ Wb。然后按最大转速估算 $E_{max}$$k$ 取 $E_{max}$ 的1.5~2倍比较合适。太小的 $k$ 在重载或参数变化时会丢失滑模性太大的 $k$ 会让饱和函数的输出噪声变大反电动势波形上能看到明显的毛刺。实际调试的时候我是先把 $k$ 往上调直到观测到的反电动势波形不再随负载变化而畸变然后再往下退10%~20%留一点裕量又不过度激进。5.2 边界层δ与滤波截止频率的配合边界层δ和低通滤波截止频率 $\omega_c$ 是互相影响的两个参数。饱和函数已经提供了一定的平滑效果如果δ选的比较大低通滤波器的截止频率可以相对提高因为不需要承担全部的平滑任务相位滞后也小。反过来如果δ很小、接近符号函数那低通滤波器的截止频率必须足够低才能把抖振压下去相位滞后就大了。我常用的初始组合是δ取额定电流的3%左右$\omega_c$ 取最高电频率的5~10倍。比如最高电频率500Hz那么 $f_c$ 取2500~5000Hz折算出 $\omega_c 2\pi f_c$。这个范围既能把开关噪声压住又不至于让相位补偿太夸张。如果你发现角度波形仍有明显锯齿或跳动先加滤波再看δ不要两个一起乱调否则很难定位问题。5.3 低速启动和切换逻辑SMO的天然短板滑模观测器在低速下失效是物理规律决定的反电动势正比于转速转速低到一定程度反电动势被电流采样噪声淹没信噪比太低再大的 $k$ 也救不回来。所以无感FOC工程方案几乎清一色采用“低速I/f启动中高速切换到SMO”的分段策略。I/f启动阶段电流矢量幅值恒定、角度按照设定的加速度扫频让电机先转起来当转子转速超过额定转速的5%~10%以后再尝试切换到SMO角度闭环。切换的关键是切换瞬间角度不能跳变。我的做法是启动阶段I/f的角度和SMO输出的角度一直在后台比较当两者误差持续小于一个阈值比如5度电角度且持续几百毫秒才允许切换。切换后把SMO输出的角度设为目标值同时把I/f积分器清零避免两套角度打架。这里顺带提醒一个我踩过很多次的坑启动阶段SMO虽然在后台运行但它的输入电压如果没有经过死区补偿低速时反电动势估计会严重失真明明电机已经转了角度的误差却很大导致切换条件迟迟不满足。所以I/f启动时候SMO要先喂可靠的电压值最好加上死区补偿再谈切换。5.4 参数失配与电阻温漂的影响滑模观测器对参数失配的鲁棒性是它的卖点但鲁棒不等于无视。$R_s$ 的温漂影响主要在低速和重载区域。定子电阻随温度升高会增大如果观测器里的 $R_s$ 使用的是常温值实际电阻偏大低速时电流误差中会引入额外的直流偏移最终表现为角度估计有偏。$L_s$ 的影响主要体现在观测器动态响应速度上$L_s$ 偏差过大会导致电流估计相位超前或滞后。一个实用的补偿手段是给 $R_s$ 加上温度系数修正通过检测IGBT或MOSFET的温升估算绕组温度再折算出实时电阻值。如果不想引入温度传感器也可以在运行过程中做简单的电阻在线辨识把定子电流和电压做最小二乘拟合但那个算法调试成本较高。对于大多数应用采取“常温电阻10%~20%的裕量修正”就够了性价比最高。5.5 实测中最常见的五个问题排查表我把做SMO项目过程中遇到的高频问题和解决方向整理成了一张表方便你快速定位现象可能原因排查方向低速能开环转但切闭环就失步SMO角度误差大或切换逻辑不当检查死区补偿、启动切换条件、电流采样噪声角度波形有明显跳动/锯齿k过大、δ过小或电流采样噪声降低k、增大δ、检查ADC同步采样高速满载转矩掉低通滤波相位滞后加角度补偿或提高滤波截止频率噪音大、电流波形毛刺多抖振严重、电压反馈不准确换饱和函数、加大边界层δ、检查逆变器死区空载和带载角度差大电阻参数失配做Rs温度修正、检查电流采样偏置5.6 调参顺序建议与最终验证最后给一个我惯用的调参顺序可以少走弯路。第一步先把电流环调稳这是所有工作的前提电流环抖动的话后面全是假象。第二步开环I/f把电机转到中速用示波器或者上位机同时观察SMO的反电动势波形和估算角度确认波形干净、角度平滑这时先调k和δ。第三步检查估算角度和I/f给定角度是否一致如果不一致优先排查电压反馈和死区补偿。第四步切换闭环小负载跑一下确认稳定后再逐步加大负载和转速范围。第五步在最高转速满载工况下测一下角度滞后如果不满意就调整滤波截止频率和角度补偿。SMO这个东西吧推导看着高大上真正用起来其实就是一个耦合了滑模面的电流观测器加一个锁相环。理解它的原理并不比调好一组PI参数更难但要把它的脾气摸透还是得靠实打实的示波器波形和现场负载跑出来的数据。希望这篇推导加实战的文章能帮你省掉一些我当年瞎调的那几个月时间。