☰
Simulink龙伯格观测器实现无传感器电机转速估计
2026/10/24 4:45:57 网站建设 项目流程

提到转速估计,很多人第一反应是装编码器或旋变传感器。但如果是高温、高振动、空间受限的场合,或者纯粹想省掉反馈器件成本,用一个状态观测器在软件里把转速“算”出来,就成了很务实的替代方案。本文要聊的是基于Simulink的龙伯格观测器(Luenberger)转速估计——简单说,就是把电机转速当作一个不可直接测量的状态量,通过系统状态方程和可测的电流、电压等信号,把转速在软件里重建出来。这套思路是状态观测器家族里最经典的一支,适合正在学现代控制理论、想做无传感器控制仿真,或者刚接手电机驱动项目但被“估不准转速”卡住的工程师。

我第一次接触这个观测器时,总觉得它有点玄。后来在Simulink里一步步搭出来才明白,它本质上就一句话:先猜一个状态,再用“实际测量值”和“预测测量值”的差去修正猜测。真正让项目难推进的,往往不是公式推导,而是状态方程怎么列、极点怎么选、增益算出来为什么那么大、模型失配了怎么收敛。下面我把这些环节按照从理论到仿真的顺序一条条拆开讲,文中的参数和模块搭建过程都来自我自己的调试记录,照着操作基本能复现。

1. 无传感器方案为什么绕不开Luenberger观测器

1.1 开环模型估算与闭环观测器的本质区别

做转速估计,最容易想到的办法是“反电动势法”:电机转动时会产生一个和转速成正比的反电动势,测出电压电流,用公式算回去,转速就出来了。这个方法在稳态下挺好用,但一遇到负载突变、加减速,估算值和真实值之间会因为没有反馈校正而越跑越偏。

问题出在“开环”。开环估算就像你凭天气猜明天几点日出,只要初始条件对,未来几个小时内误差不大;但模型有一点误差、系统有一点扰动,估算结果就会像滚雪球一样漂移。Luenberger观测器做的第一件关键事,就是把估算回路闭合:不只看模型预测出来的输出,还要把预测输出和实际输出的差值,乘以一个增益矩阵,再反馈回状态微分方程里。这样一来,只要误差存在,修正项就会持续把估算状态往真实状态方向拉。这就是它比开环计算稳的根本原因。

1.2 为什么转速能成为“可被估计的状态”

观测器能起作用,前提是系统状态本身具备可观测性。很多人听到“可观测性”就头疼,其实放在电机里特别好理解:转速变化会影响反电动势,反电动势会影响电流,电流是能直接测到的。那么从测到的电流波形里,理论上就藏着转速的信息。观测器的工作,就是把这个隐藏在电流里的转速信息一点点“榨”出来。

在状态空间框架下,我们把电机转速作为状态向量的一项,把电流作为输出量的一项。剩下的工作就是设计一个状态方程,让估计状态跟随真实状态。Luenberger观测器给出的校正结构非常直接:

x_hat_dot = A * x_hat + B * u + L * (y - y_hat)

其中x_hat是估计状态,y是实际测量输出,y_hat是估计输出,L就是待设计的观测器增益矩阵。整个公式的意思很简单:先用模型预测状态变化,再拿预测输出和真实测量的差来修正。如果你把L设成0,这个观测器就退化成开环模型估算;L越大,修正力度越强,估计状态收敛越快,但也更容易把测量噪声放大。

配套Simulink环境来学习和调试这套逻辑非常方便,因为矩阵运算、积分器、增益模块都是现成的,不需要自己去写底层的数值积分算法。对比写C代码或者手写Python脚本,Simulink的优势在于能直观看到信号流,尤其是调试L矩阵时,改一个参数就能立刻看到收敛速度变化,这比纯代码环境高效得多。

2. 建模先行:建立包含转速状态的状态方程与可观测性检查

2.1 直流电机拖动系统的状态空间方程

Luenberger观测器是模型驱动的,模型越贴近实际,估计越准。为了把推导过程讲清楚,我用一个最常见也最简单的直流电机拖动系统作为说明对象,参数如下表所示。

参数数值说明
电枢电阻 R1.2 Ω电枢回路电阻
电枢电感 L0.01 H电枢回路电感
反电动势系数 Ke0.12 V·s/rad电机反电动势与转速的比例
转矩系数 Kt0.12 N·m/A电流产生的电磁转矩
转动惯量 J0.01 kg·m²电机转子加负载折算惯量
粘滞阻尼 B0.005 N·m·s/rad轴承摩擦和风阻的等效系数

取状态变量x = [电流i, 转速ω]的转置,输入u为电枢电压Va,输出y选择为电流i,状态方程可以写为:

d(i)/dt = -R/L * i - Ke/L * ω + 1/L * Va d(ω)/dt = Kt/J * i - B/J * ω

写成矩阵形式就是:

A = [-R/L, -Ke/L; Kt/J, -B/J] B = [1/L; 0] C = [1, 0] D = 0

代入上面的参数,具体数值如下:

A = [-120, -12; 12, -0.5] B = [100; 0] C = [1, 0]

这里要特别注意C矩阵为什么取[1, 0]。这表示我们只测量电流,不测转速。整个观测器的目标,就是利用这个电流测量值,把第二个状态量ω重建出来。如果C取成[0, 1],那就成了直接测转速,也就没有做观测器的必要了。

2.2 可观测性判据与输出量的选择

列好方程后,先别急着搭Simulink,第一步是检查系统是否可观测。对于这个2乘2系统,可观测性矩阵O的定义是:

O = [C; C*A]

展开计算:

C*A = [1, 0] * [-120, -12; 12, -0.5] = [-120, -12]

所以可观测性矩阵为:

O = [1, 0; -120, -12]

它的行列式是 -12,不为0,满秩,系统可观测。这意味着仅凭电流测量,理论上就能唯一确定转速状态。

这里有一个工程经验值得记住:输出量的选择直接决定了能不能做观测器。如果你手里只有一个电流传感器,而电机参数未知,那至少要先确认C*A这一项不为零。在很多实际驱动器里,电流采样是标配,电压指令也是控制器自己给的,所以用电流作为输出、电压作为输入,是搭建无传感器转速观测器最顺手的一条路。反过来说,如果系统存在不可观模态,比如某些参数恰好让O矩阵降秩,那就必须换一个输出量,或者在模型里增加额外的状态,否则无论L怎么调都救不回来。

3. 观测器增益设计:极点配置计算L矩阵的一种手算方法

3.1 期望极点如何选取

观测器设计问题的核心,是选一个增益矩阵L,让矩阵(A - L*C)的特征值位于期望位置。极点位置决定了估计误差的收敛速度:

  • 极点离虚轴越远,收敛越快,但过远会放大高频噪声。
  • 极点太靠近虚轴,收敛慢,负载突变时转速估计会严重滞后。

工程上比较常见的做法,是把观测器极点的模取为系统开环极点的3到10倍。先算一下系统本身的极点。系统的特征方程为:

det(sI - A) = 0

代入数值计算,得到两个极点约在-1.7和-119。慢极点来自机械惯性,快极点来自电气时间常数。观测器至少要跟上慢极点,否则转速估计会像温水煮青蛙一样慢慢落后;但也不能一味求快,否则电流采样里的开关噪声会被瞬间放大。

在我调试过的几次仿真中,取观测器极点在-100和-150左右,收敛速度和噪声抑制比较平衡。下面就以这两个极点为期望值,演示完整的L矩阵推导。

3.2 基于特征方程解的增益矩阵计算

令L = [L1; L2],C = [1, 0],则(A - L*C)为:

A - L*C = [-120 - L1, -12; 12 - L2, -0.5]

它的特征方程为:

s² + (120.5 + L1) * s + (204 + 0.5L1 - 12L2) = 0

期望极点为-100和-150,对应特征方程:

s² + 250 * s + 15000 = 0

对比系数,得到两个方程:

120.5 + L1 = 250 204 + 0.5L1 - 12L2 = 15000

解出来:

L1 = 129.5 L2 = -1227.6

所以:

L = [129.5; -1227.6]

第一次算出这个结果时,我盯着L2发呆,为什么这个反馈增益这么大?这里其实藏着一个很直观的物理原因:电流模型中,转速是通过反电动势系数影响电流的,这个耦合项很小,只有-12。要让转速估计快速收敛,观测器必须把“电流测量误差”以很大的倍率折算成对转速的修正,才能抵消小耦合带来的慢响应。L2很大,不代表观测器设计有误,而是系统本身耦合较弱的一种必然结果。理解这一点,对后面调试噪声抑制非常关键。

3.3 用MATLAB命令快速验证

手算适合理解原理,实际项目中用MATLAB命令能更快验证。可以在命令行里直接调用place函数:

A = [-120, -12; 12, -0.5]; C = [1, 0]; p = [-100, -150]; L = place(A', C', p)'

注意place函数里的转置,是因为我们设计的是对偶系统。执行结果会和手算的L矩阵一致。如果不想记转置,也可以用acker函数,但acker在高阶系统数值稳定性上不如place,两个都试试也行。

验证完后,顺便把闭环观测器极点也check一下:

eig(A - L*C)

输出就是-100和-150,误差收敛行为可以由这个矩阵完全刻画。这一步做对了,再进Simulink心里就有底。

4. 在Simulink中实现Luenberger观测器:模块选择与回路搭建

4.1 搭建目标与总体信号流

在Simulink里实现观测器,目标不是单纯做出一个能跑的模型,而是让模型结构清晰、方便改参数、方便后续接入真实项目。总体信号流分两条路:

  • 真实对象通道:给定电压Va,进入电机模型,输出电流测量值i_meas。
  • 观测器通道:电压Va同时进入观测器,输出转速估计值ω_hat和电流估计值i_hat。i_hat与i_meas做差,经过L矩阵反馈回状态方程。

需要注意的是,观测器必须拿到和真实对象相同的输入电压Va。实际项目中,这个电压一般来自PWM占空比和母线电压的重建值;在仿真阶段,直接取电机模型的输入就行。

4.2 用基础模块搭观测器子系统

我习惯用最基础模块搭,不依赖高级封装,方便看清楚信号流。整个观测器表达式为:

x_hat_dot = Ax_hat + Bu + L*(i_meas - C*x_hat)

在Simulink中,搭建步骤如下:

  1. 新建一个Gain模块,命名为A,参数填[-120, -12; 12, -0.5],用于计算A*x_hat。
  2. 新建一个Gain模块,命名为B,参数填[100; 0],用于计算B*u。
  3. 新建一个Gain模块,命名为C,参数填[1, 0],用于从x_hat中提取电流估计值i_hat。
  4. 新建一个Gain模块,命名为L,参数填[129.5; -1227.6],用于计算反馈修正量。
  5. 用Sum模块把三项加起来,得到x_hat_dot。
  6. 接一个Integrator模块,对x_hat_dot积分,得到x_hat。
  7. 在Integrator模块的Initial condition中设置初值,比如[0; 0],对应初始电流和转速都为0。
  8. 从x_hat向量中引出第二路,用Demux或者Selector模块取出ω_hat,输出到Scope。

如果嫌模块太多,也可以把A、B、C、L灌进State-Space模块里,但那样反馈修正项L*(i_meas - C*x_hat)不好直接接入。个人经验是,首次学习用基础模块搭一次,信号流一目了然;等彻底理解了,再改成State-Space封装提升仿真速度。

Simulink模型运行时,没有特殊的求解器要求,用默认的ode45就可以。但如果你后面打算把观测器代码部署到控制器里,就涉及到离散化问题,这部分我在下一节详细说。

4.3 可选的State-Space封装方式

如果不想每次改参数都去翻好几个Gain模块,可以用State-Space统一封装。做法是把观测器拆成两个矩阵方程:

x_hat_dot = Ax_hat + [B, L] * [u; (i_meas - Cx_hat)]

新建一个State-Space模块,参数设置如下:

  • A矩阵:A
  • B矩阵:拼接[B, L]
  • C矩阵:单位阵[1, 0; 0, 1]
  • D矩阵:零矩阵[0, 0; 0, 0]

这个模块的输出直接就是完整的估计状态向量,后续想输出转速只需要再接一个Selector。这种封装的好处是,A矩阵和L矩阵可以在MATLAB工作区里事先定义好,改模型时只需要重新运行一次参数脚本,不需要进入模块内部改动。缺点是反馈路径隐含在B矩阵里,初次看模型的人理解起来稍微费劲一些。

5. 仿真验证怎么做:收敛曲线、噪声扰动与极点影响的观察

5.1 搭建一个完整可复现的仿真场景

有了观测器模块,还差一个被观测对象。最简单的做法是用另一个State-Space模块搭建真实电机模型,A矩阵和观测器里的A一致,B矩阵一致,C矩阵为[1, 0],输入电压Va,输出电流i_meas。

为了模拟真实场景,可以给输入电压做一个阶跃跳变:0秒开始电压为0,0.5秒时跳到20V,1.5秒时再加一个50%的负载转矩扰动。负载转矩扰动可以建模为输入端的附加项,在状态方程里加到转速微分方程的右侧。真实对象和观测器用同一个电压源,但观测器内部完全不知道负载转矩的存在。这个细节很重要:观测器模型里没有负载项,如果它还能准确估计转速,说明反馈修正项确实在发挥作用。

运行仿真0到3秒,在Scope里同时显示真实转速ω和估计转速ω_hat。你会看到一条很典型的收敛曲线:初始阶段由于观测器初值和真实初值不一致,两个转速有偏差;但在L矩阵作用下,误差迅速缩小到几乎重合。阶跃电压加入后,转速上升过程中估计值会紧跟真实值,不会出现大的滞后。这就是Luenberger观测器应该有的表现。

5.2 该观察哪些关键指标

观察仿真结果时,不要光看“曲线有没有跟上”,需要量化三个指标:

  • 收敛时间:从启动到估计误差降到5%以内的时间。这个时间主要由观测器极点的实部决定,越远离虚轴收敛越快。
  • 稳态精度:转速稳定后,估计值和真实值的差。理想情况下应该为零,但如果模型参数有偏差,会出现大小不一的稳态误差。
  • 动态跟随性:负载突变或电压阶跃瞬间,估计转速的最大偏差。这个指标非常能说明问题,是最考验观测器鲁棒性的场景。

如果收敛太慢,就增大期望极点的绝对值;如果收敛快但噪声大,就适当回调。仿真中你会直观看到这对矛盾:L2那个-1227.6的大增益,会让电流测量中的微小纹波通过修正项传递到转速估计上。最终选择哪个极点组合,完全取决于你的系统对噪声和响应速度的容忍度。

5.3 噪声扰动下的表现

给电流测量信号增加一个幅值为0.01A的高斯白噪声,再跑一遍仿真。观测器输出的转速估计会出现明显的高频抖动,尤其在转速稳定阶段。这个仿真结果能帮我们理解一个现实问题:物理世界里的电流采样噪声逃不掉,观测器极点不能无条件地往远推。

我实际调到极点取-200和-250时,转速估计抖动幅度比-100和-150时大了将近一倍。所以如果项目里电流采样滤波已经做得很好,可以用快极点;要是采样噪声本身就大,宁可接受少慢一点的收敛速度,也要把极点往回调。这类权衡,书上不会写,只能靠仿真和实测迭代出来。

6. 调参经验:仿真和实物联调中常见的三个坑

6.1 极点频率太高导致估计噪声放大

这是新手最容易踩的坑。看到观测器收敛太慢,第一反应就是把极点往远处拖,结果转速估计曲线抖动剧烈,甚至出现明显毛刺。原因在第三节已经提到:L矩阵的增益和极点位置强相关,极点越远,L2值越大,电流测量噪声被放大的倍数就越高。

处理办法是先看电流采样噪声水平,再定观测器极点。一个可供参考的经验是:先把极点设置为系统开环慢极点绝对值的5倍左右,跑通仿真,再逐步增大,每步观察转速估计噪声。如果噪声增幅明显高于收敛速度改善,就说明极点已经推到这台系统能接受的极限了。

6.2 模型参数失配会让稳态转速估计偏航

这是从仿真走向实物时最头疼的问题。仿真里A矩阵和真实对象完全一致,所以稳态误差为零;拿到实物上,电阻R会随温度变化,转动惯量J可能因为负载变化而改变,反电动势系数Ke也有一定分散性。这些参数一旦和观测器模型不一致,稳态转速估计就会出现系统偏差。

直观理解就是:观测器内部坚持用错误的模型预测电流,而修正项L只能把估计状态往真实测量上拉,但无法完全抵消模型错误带来的偏离。实践中规避这个问题的办法有三层:

  • 优先确保B矩阵和输入电压通道准确,这决定了观测器的基础驱动能力。
  • 对电阻和转动惯量做在线辨识,或者采用自适应观测器,这是进阶方案。
  • 在Luenberger观测器后面再加一个慢速的转速修正环,利用电机方程里的稳态关系校准估计值。

第一层和第三层实现成本较低,可以优先做。第二层虽然效果好,但工作量明显增加,适合在项目中期再推进。

6.3 仿真求解器、初值和执行器饱和的细节问题

Simulink仿真中还有一个容易忽略的细节:如果全模型既有电机模型又有观测器,而且你用了比较大的L增益,仿真步长太大会产生数值振荡。现象是转速估计曲线在启动瞬间出现高频锯齿,但真实转速曲线正常。这时要把最大步长调小,或者切换到变步长求解器,把相对误差上限设得严格一些。

初值问题也不能轻视。观测器积分器初值如果和真实初始状态差得远,启动瞬间的修正量会非常大,可能让估计转速出现一个很大的尖峰。解决办法是把真实对象的初值设置成和观测器初值保持一致,或者给观测器设置一个启动软化逻辑,限制最大修正量。

最后一个坑是执行器饱和。实际电机控制中,电压指令通常会受母线电压限制而饱和;如果观测器里用的B*u没有同步考虑饱和,模型预测的电流变化速率就会偏大,估计转速在饱和期间会明显超前。仿真中如果只在理论上跑线性范围,这个问题不会出现,但实物联调时几乎必现。建议在Simulink里就给电压通道加上饱和模块,并让观测器复用同一个饱和后的电压值,这样仿真结论才更贴近真实运行条件。

说了这么多,归根结底,Luenberger观测器是一个“框架正确、参数敏感”的方案。框架正确,意味着只要模型结构和可观测性条件满足,它一定能把转速状态重建出来;参数敏感,意味着从极点选择到电压馈入,每个细节都会影响最终估计质量。如果你也在调无传感器转速估计,我建议先把这套基础模型在Simulink里完整跑通,包括负载阶跃、测量噪声、参数失配三种场景都试一遍。等这几类问题你都亲手处理过,后续再接触滑模观测器、扩展卡尔曼滤波这些更复杂的方法时,理解起来会顺畅很多。

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

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

立即咨询