☰
电机控制观测器选型:Luenberger、高增益、滑模与扩张状态观测器对比
2026/10/15 10:56:31 网站建设 项目流程

简介:这份文档面向控制工程、自动化及相关专业的学习者与研究人员,围绕状态观测器设计展开对比研究,帮助读者理解高增益观测器、滑模观测器与扩张状态观测器在动态不确定性、干扰和传感器噪声下的性能差异。资源包内含1个doc文件,约512KB,内容涵盖三种观测器的原理推导、非线性增益函数设计、仿真与实验对比,以及开环与闭环场景下的行为轨迹分析。文档以线性连续时不变系统为切入点,从经典Luenberger观测器出发,逐步引入高增益观测器的非线性增益改进、滑模观测器的切换控制策略,以及扩张状态观测器对状态空间的扩展思路,并给出稳态与瞬态跟踪误差的评估方法。目前已有5902人学习下载,适合需要系统梳理观测器选型依据、补充鲁棒性设计思路或开展相关课题研究的读者参考。

1. 三种状态观测器横向拆解:从 Luenberger 到 ESO 的选型分水岭

做电机控制或者伺服系统调试的人,迟早会撞上一个问题:位置和速度里总有一个测不准,编码器分辨率不够、噪声大、或者干脆装不上传感器。这时候状态观测器就是那个“软测量”的黑匣子——用可测的输出反推不可测的状态。但真到选型的时候,Luenberger、高增益、滑模、扩张状态这几种方案摆在面前,参数怎么定、哪种抗扰更强、哪种对模型误差更宽容,很多人是懵的。这份资料围绕三种先进观测器——高增益观测器(HGO)、滑模观测器(SMO)和非线性扩张状态观测器(NESO)——做了仿真和硬件层面的对照比较,核心结论是 NESO 在动态不确定性、扰动和传感器噪声的综合场景下表现更优。适合正在做伺服控制、运动控制算法选型,或者被观测器参数整定折磨的从业者。

2. 观测器设计的底层逻辑:为什么经典方案不够用

2.1 Luenberger 观测器的阿喀琉斯之踵

经典 Luenberger 观测器的结构很简洁。给定线性时不变系统:

ẋ = Ax + Bu y = Cx

观测器形式为:

x̂̇ = Ax̂ + Bu + L(y - Cx̂)

估计误差 e = x - x̂ 的动力学是:

ė = (A - LC)e

只要把 A - LC 的极点配置在左半平面,误差就会收敛到零。听起来很完美,但这里有一个致命前提:A、B、C 矩阵必须精确已知。实际系统里,摩擦系数会随温度漂移,负载惯量会随工况变化,这些都不在标称模型里。一旦模型和实际对不上,Luenberger 观测器的估计精度就会明显退化,而且它没有任何机制去补偿这种偏差。

这就是为什么后来出现了高增益、滑模和扩张状态这几条技术路线——它们都在试图解决同一个问题:模型不准的时候,观测器还能不能活。

2.2 三种先进观测器的设计哲学差异

高增益观测器(HGO)的思路是“用速度换鲁棒性”。Khalil 和 Esfandiari 提出的方案核心是把观测器增益推到很高,让误差收敛速度远快于系统动态变化,这样即使模型有偏差,误差还没来得及积累就被压下去了。典型形式里引入一个小参数 ε(0 < ε << 1),增益大致按 1/ε 的量级缩放。ε 越小,收敛越快,但对噪声的放大也越严重。这是一个典型的“玄学调参”环节——ε 太小,噪声把估计值淹了;ε 太大,鲁棒性又不够。

滑模观测器(SMO)走的是另一条路。它利用切换项来强制估计误差滑向一个预设的滑模面,在滑模面上误差动力学对模型不确定性完全不敏感。Slotine 和 Utkin 早期的非线性系统故障检测工作就是基于这个原理。SMO 的鲁棒性来自切换控制本身,但代价是抖振——切换频率再高也不可能无限快,实际实现中总会有高频振荡,这在硬件测试里表现得尤其明显。

扩张状态观测器(NESO)是韩京清 1995 年提出的方案,思路和前两者有本质区别。它不去纠结模型准不准,而是把模型不确定性、外部扰动、未建模动态全部打包成一个“扩张状态”变量,然后设计观测器去实时估计这个总扰动。控制律里再把这个估计值补偿掉,系统就近似变成了一个积分器串联的标准型。NESO 不依赖精确的数学模型,鲁棒性是结构自带的,不是靠高增益或切换硬撑出来的。

2.3 非线性增益函数的设计细节

NESO 的一个关键设计点是非线性增益函数的选择。原始方案里用的是类似 fal 函数的修正指数增益:

fal(e, α, δ) = |e|^α · sign(e), |e| > δ = e / δ^(1-α), |e| ≤ δ

其中 α 在 0 到 1 之间取值,δ 是小量。这个函数的特性是:误差大的时候增益自动降低,误差小的时候增益提高,从而在“快速收敛”和“避免超调”之间取得平衡。

但这份资料指出,当系统初始条件未知时,NESO 会产生明显的瞬态估计误差。为此提出了新的非线性增益函数形式,核心改进是引入负指数项来抑制初始阶段的误差峰值。仿真中对比了三种增益函数(对应不同的 α 和 δ 组合),结果显示选择合适的参数后,瞬态误差可以显著缩小。具体参数在仿真部分给出:k1 = 12.5,k2 = 15,α 取 {1, 0.5, 0.25} 三档,δ = 10⁻³。

3. 仿真平台搭建与三种观测器的参数整定

3.1 被控对象模型与仿真环境配置

仿真用的是一套工业控制测试平台的线性模型:

ẏ = v v̇ = a(t) + b·u

其中 y 是输出位置,u 是送到驱动马达功率放大器的控制电压,a(t) 代表已知动力学加未知扰动,b 是控制增益。这个模型虽然简单,但包含了观测器设计中最核心的挑战:a(t) 里既有模型已知部分,也有未知的摩擦和扰动。

三种观测器的采样频率统一设为 1 kHz,输出叠加白噪声以模拟真实传感器环境。为了公平比较,三种观测器的参数被调整到对噪声的敏感度大致相当。这一点很重要——如果只调一种观测器的参数让它表现好,那比较就没意义了。

3.2 高增益观测器的参数配置

HGO 的实现代码如下:

import numpy as np class HighGainObserver: def __init__(self, epsilon=0.01, poles=None): """ epsilon: 小参数,控制增益大小,越小增益越高 poles: 期望的观测器极点位置 """ self.eps = epsilon # 二阶系统,两个观测器极点 if poles is None: poles = [-1.0, -1.0] self.poles = poles # 计算观测器增益 L # 对于二阶系统,A - LC 的特征多项式 # s^2 + (l1)*s + (l2) = 0 self.l1 = -poles[0] - poles[1] self.l2 = poles[0] * poles[1] # 高增益缩放 self.L = np.array([self.l1 / epsilon, self.l2 / epsilon**2]) self.x_hat = np.zeros(2) # [位置估计, 速度估计] def update(self, y_meas, u, dt): """ y_meas: 测量输出(位置) u: 控制输入 dt: 采样周期 """ y_hat = self.x_hat[0] error = y_meas - y_hat # 观测器动力学 # x̂̇1 = x̂2 + L1 * error # x̂̇2 = a_known + b*u + L2 * error # 这里 a_known 假设为 0(标称模型) dx1 = self.x_hat[1] + self.L[0] * error dx2 = self.L[1] * error # 标称模型下 a_known = 0 self.x_hat[0] += dx1 * dt self.x_hat[1] += dx2 * dt return self.x_hat.copy()

这里 ε = 0.2 被用在仿真中。注意 L 的计算方式:l1 和 l2 来自期望的 Hurwitz 多项式,然后分别除以 ε 和 ε²。这意味着 ε 减半,增益翻两番。实际调参时,ε 的选取需要在收敛速度和噪声抑制之间折中。我一般会从 0.1 开始试,观察估计误差的噪声水平,如果噪声太大就往上调。

3.3 滑模观测器的切换项设计

SMO 的实现核心是切换项:

class SlidingModeObserver: def __init__(self, k1=12.5, k2=15, switching_gain=50): """ k1, k2: 线性反馈增益 switching_gain: 切换项增益,需大于模型误差上界 """ self.k1 = k1 self.k2 = k2 self.eta = switching_gain self.x_hat = np.zeros(2) def update(self, y_meas, u, dt): y_hat = self.x_hat[0] error = y_meas - y_hat # 滑模面:s = error # 切换项用饱和函数代替 sign 以减小抖振 def sat(s, boundary=0.01): if abs(s) < boundary: return s / boundary return np.sign(s) switching = self.eta * sat(error) dx1 = self.x_hat[1] + self.k1 * error dx2 = self.k2 * error + switching self.x_hat[0] += dx1 * dt self.x_hat[1] += dx2 * dt return self.x_hat.copy()

切换增益 η 必须大于模型误差的上界,否则滑模面无法到达。但 η 越大,抖振越严重。仿真中用了饱和函数 sat 代替理想 sign 函数来缓解这个问题,边界层厚度取 0.01。实际硬件上,这个边界层还得再放大,因为采样频率有限,切换不可能无限快。

3.4 扩张状态观测器的三阶结构

NESO 的结构和前两者不同,它是三阶的:

class NonlinearESO: def __init__(self, k1=12.5, k2=15, alpha=0.5, delta=1e-3, b0=1.0): """ k1, k2: 观测器增益 alpha: 非线性增益指数 delta: 线性区间宽度 b0: 控制增益估计值 """ self.k1 = k1 self.k2 = k2 self.alpha = alpha self.delta = delta self.b0 = b0 self.z = np.zeros(3) # [z1: 位置估计, z2: 速度估计, z3: 总扰动估计] def fal(self, e): """非线性增益函数""" if abs(e) > self.delta: return (abs(e) ** self.alpha) * np.sign(e) else: return e / (self.delta ** (1 - self.alpha)) def update(self, y_meas, u, dt): e = self.z[0] - y_meas fe = self.fal(e) # 三阶 ESO 离散更新 dz1 = self.z[1] - self.k1 * e dz2 = self.z[2] - self.k2 * fe + self.b0 * u dz3 = -self.k2 * self.fal(e) * 0.5 # 扩张状态变化率 self.z[0] += dz1 * dt self.z[1] += dz2 * dt self.z[2] += dz3 * dt return self.z.copy()

z3 就是扩张状态,它实时估计系统总扰动。控制律里把 u = (u0 - z3) / b0 代入,系统就近似变成了双积分器。NESO 的调参比前两者直观:k1、k2 按带宽配置,α 和 δ 决定非线性增益的形状。仿真中 α 取 0.5、δ 取 10⁻³ 时综合表现最好。

4. 开环与闭环对比:仿真和硬件测试中的真实表现

4.1 开环测试:标称、摩擦、惯量三种工况

开环测试分三种环境:纯标称模型、标称加库伦摩擦、标称加 100% 惯量变化。输入是阶跃信号,观测器参数在所有仿真中保持不变。

标称工况下,三种观测器的稳态精度和噪声敏感度大致相当。NESO 收敛稍慢,因为它不依赖模型知识,需要额外时间估计总扰动。但 z3 确实收敛到了真实的 a(t) 值,说明扩张状态的设计是有效的。

加入 0.5 N·m 库伦摩擦后,差异立刻显现。HGO 和 SMO 的估计误差明显增大,而 NESO 的误差曲线几乎和标称工况重合。z3 快速收敛到了摩擦加已知动力学的联合值。这就是扩张状态的威力——它不需要知道摩擦模型是什么形式,直接把它当成一个未知量估出来。

100% 惯量变化工况下,NESO 仍然表现最好,SMO 次之,HGO 最差。惯量变化相当于模型参数 b 发生了大幅偏移,HGO 的高增益策略在这种情况下反而放大了模型失配的影响。

4.2 未知初始条件下的增益函数对比

这部分是这份资料的一个亮点。初始条件设为 y(0) = 10 rev,速度初始为 0,观测器极点统一放在 8 rad/s。三种非线性增益函数(对应 α = 1、0.5、0.25)的瞬态误差曲线差异明显。

α = 1 时退化为线性增益,初始误差峰值最大。α = 0.25 时初始误差最小,但收敛速度稍慢。α = 0.5 是一个折中。资料还建议在初始阶段引入负的激励项来进一步压制瞬态误差,这个技巧在实际调试中很实用——如果你的系统每次启动时观测器都会产生一个大跳变,可以试试在启动后前几百毫秒内临时增大 δ 或降低 α。

4.3 闭环控制中的抖振与鲁棒性差异

闭环测试基于状态反馈加观测器的结构。控制器用 PD 形式,NESO 和 SMO 分别提供状态估计。

标称环境下两个控制系统输出几乎一样。但加入库伦摩擦后,SMO 的抖振问题在闭环中暴露得很明显——控制输出里能看到持续的高频振荡,而 NESO 的控制信号平滑得多。正弦扰动工况下,NESO 的跟踪误差明显小于 SMO。

硬件测试用的是无刷直流伺服系统,采样频率 1 kHz,控制器输出限幅。结果和仿真一致:基于 NESO 的控制器在摩擦工况下更稳定、更精确,SMO 的抖振在硬件上比仿真更严重,因为实际采样频率和开关频率都有限制。

5. 避坑与排查:观测器调试中最容易翻车的五个地方

5.1 高增益观测器的噪声放大

现象:ε 调小后,估计值噪声急剧增大,速度估计几乎不可用。

原因:HGO 的增益按 1/ε 和 1/ε² 缩放,ε 减半意味着速度通道增益翻四倍。传感器噪声也被同样放大。

解决:在观测器输出后加低通滤波,但会引入相位滞后。更好的做法是找到 ε 的下限——从 0.5 开始逐步减小,观察噪声水平,在噪声可接受的前提下取最小值。我一般会在 0.1 到 0.3 之间选。

5.2 滑模观测器的抖振在硬件上失控

现象:仿真里用 sat 函数还好,烧到板子上电机发出明显啸叫,电流波形全是毛刺。

原因:仿真步长可以很小,实际采样周期受限于处理器和 ADC 速度。切换频率不够高时,滑模面附近的抖振会激发机械谐振。

解决:增大饱和函数的边界层厚度,或者改用连续近似函数(如 sigmoid)。另外切换增益 η 不要盲目取大,刚好大于模型误差上界即可。如果还是抖,考虑降采样或加输出滤波。

5.3 NESO 的 b0 估计偏差导致稳态误差

现象:系统稳态时总有一个固定偏差,z3 收敛了但控制效果不对。

原因:NESO 的控制律里 u = (u0 - z3) / b0,b0 是控制增益的估计值。如果 b0 和真实值偏差太大,补偿就不准确。

解决:b0 可以通过开环阶跃响应实验测出来——给一个已知电压,看加速度响应,b0 ≈ Δa/Δu。如果 b0 不确定,可以把它也当成扩张状态的一部分,但会牺牲一些收敛速度。

5.4 初始条件未知时 NESO 的瞬态大误差

现象:每次启动时观测器输出有一个大跳变,要好几秒才收敛。

原因:NESO 的积分器初始值为零,但实际系统初始状态不是零。误差大时 fal 函数增益低,收敛慢。

解决:用资料里提到的非线性增益函数改进方案,在初始阶段增大增益。或者简单粗暴一点——启动时先用测量值初始化 z1,z2 和 z3 置零,能省掉大半瞬态时间。

5.5 采样频率和观测器带宽不匹配

现象:观测器带宽设得很高,但实际估计效果反而变差,甚至发散。

原因:离散化后的观测器带宽受采样频率限制,一般不应超过采样频率的 1/10 到 1/5。带宽设太高,离散化误差和计算延迟会导致相位裕度不足。

解决:先确定采样频率,然后反推观测器带宽上限。1 kHz 采样对应观测器带宽不超过 100-200 rad/s。如果确实需要更高带宽,先提采样频率。

6. 从仿真到硬件的迁移技巧:我的参数整定习惯

把观测器从仿真搬到硬件,最大的坑是仿真里忽略的东西——计算延迟、ADC 量化噪声、PWM 更新时机——在硬件上全冒出来了。我自己的习惯是分三步走。

第一步,在仿真里把观测器带宽设到理论值的 60%,留出余量。比如理论上可以做到 200 rad/s,仿真里先用 120 rad/s。第二步,硬件上先用这个保守参数跑通,确认没有发散和明显振荡后,再逐步提高带宽,每次加 10%,观察电流波形和估计误差。第三步,在最终带宽确定后,再回头微调非线性增益函数的 α 和 δ,优化瞬态响应。

这套流程看起来慢,但比直接拿仿真参数烧进去然后炸机要快得多。有一次我跳过第二步,直接把仿真里调好的 NESO 参数写到伺服驱动器里,上电瞬间电机就猛转了一下——后来发现是 z3 初始值为零但实际负载转矩不为零,启动时补偿量突变导致的。从那以后我每次从仿真迁移到硬件,都强制走一遍“保守参数→逐步加带宽→微调非线性增益”的流程,再也没翻过车。

另外一个小技巧:如果系统对成本敏感,NESO 的计算量其实比 SMO 大不了多少。三阶 ESO 每个周期就是几次乘加和一次 fal 函数查表,在主流 DSP 上跑 1 kHz 绰绰有余。SMO 虽然结构简单,但抖振问题带来的滤波和补偿开销反而可能更大。选型的时候别只看算法复杂度,把调试成本和硬件风险也算进去。

希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询