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^$,滑模面就是 $s=0$。控制律取 $u = k,\text{sgn}(s)$,$k$ 足够大时,误差会被强制拉向 $s=0$。
在滑模观测器里,这个思想被移植到了状态估计上:我们用电流的估计值和实测值之差作为滑模面。设当前估计电流为 $\hat{i}$,实测电流为 $i$,则误差 $\tilde{i} = \hat{i} - i$。控制目标就是把 $\tilde{i}$ 驱动到零,让观测器的电流轨迹完全“复刻”真实电流。一旦电流估计准确了,观测器中那个用来压制误差的等效控制量里就包含了反电动势的全部信息。
这里要注意一个关键点:滑模观测器不直接估计反电动势,它先强制电流误差收敛,再反过来从控制量中提取反电动势。这个“让误差为零,再反解扰动”的思路,正是等效控制法的核心。很多初学者一开始看SMO的框图会懵,觉得明明是在估计电流,怎么最后输出的是角度,其实就是绕了这么一圈。
2.2 到达条件:开关增益的下限推导
要让滑模运动发生,必须保证状态轨线在任何初始条件下都向滑模面 $s=0$ 靠拢,数学上就是李雅普诺夫条件 $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 等效控制:滑模面上的“温柔”平衡
滑模运动一旦建立,系统状态就被“钉”在滑模面上,此时 $s=0$ 且 $\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[n+1] = \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$ 是极对数,假设 $p=4$,则 $\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参数更难,但要把它的脾气摸透,还是得靠实打实的示波器波形和现场负载跑出来的数据。希望这篇推导加实战的文章,能帮你省掉一些我当年瞎调的那几个月时间。