news 2026/9/7 2:32:23

本质非线性下的描述函数法:自振分析与工程验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
本质非线性下的描述函数法:自振分析与工程验证

自动控制原理——第八章本质非线性(二):描述函数法、负倒描述函数与自振分析

很多人在学自动控制原理时,前几章线性系统分析一路顺畅,到了“非线性”这一章突然卡住。原因并不复杂:前面学的频域分析法、根轨迹法、劳斯判据,几乎都建立在“叠加原理”之上,而本质非线性环节会让叠加原理直接失效。更麻烦的是,这类非线性不是“近似处理一下就能骗过去”的那种,你越是想用小偏差线性化去糊弄它,仿真结果和实际系统就越对不上。

这一篇是“本质非线性”第二篇,重点讲控制工程里最常用也最容易被误用的一类方法:描述函数法。我先把结论放在这里:描述函数法不是一个精确的数学工具,它是一个工程近似方法,只适合回答“系统会不会自振、自振振幅大约是多少、频率大约是多少”这类问题。它不是万能的,但在没有更好工具之前,它依然是分析继电、死区、饱和等典型非线性系统最实用的起点。

读完这篇文章,你能够掌握三件事:第一,理解本质非线性为什么不能用传统线性化工具;第二,学会用描述函数法求解继电非线性系统的自振条件;第三,用 Python 做一次完整的数值验证,把“纸上公式”和“时域波形”真正对应起来。

1. 这篇文章真正要解决的问题

先看一个真实的工程场景。一个控制系统在调试阶段表现正常,但现场运行一段时间后,输出端开始出现持续的等幅振荡,频率固定,振幅也基本不变。你把控制器参数调小,振荡还在;你把执行机构换个新的,振荡仍然出现。最后排查出来,问题出在某个继电器、阀门死区或者齿轮间隙上。

线性系统理论面对这种情况是几乎无解的。因为等幅振荡不是“不稳定”,也不是传统意义上的“临界稳定”,它是非线性系统特有的一种运动形态,学术上叫做自激振荡(自振)。自振与线性系统的临界稳定有一个本质区别:自振的振幅通常由系统自身参数决定,而不是由初始条件决定,干扰过后系统会自动恢复到同一个振荡形态。

所以这篇文章要解决的不是“非线性系统怎么建模”,而是更接近工程本质的问题:如何判断一个包含本质非线性的系统会不会自振;如果会自振,用什么方法估算振幅和频率;估算完之后,怎么用仿真验证结果可信还是不可信。

对于刚学到这里的学生来说,这篇文章可以帮你把第八章最容易混淆的几个概念理清:描述函数、负倒描述函数、极限环稳定性、自振条件。对于做控制工程的人来说,这篇文章的价值在于:当你怀疑系统存在非线性自振时,先用描述函数法做一个快速判断,再用时域仿真确认,这个过程可以节省大量试错时间。

2. 本质非线性概念与典型非线性环节

2.1 什么是本质非线性

自动控制原理里说的“本质非线性”,指的是不能通过在工作点附近做泰勒展开来进行线性化的非线性。这类非线性通常都有一个共同特征:特性曲线存在不可导点、断点或跳变。

举个例子。一个饱和放大器,在输入较小时可以看成线性,但输入增大到限幅值以后输出不再变化,这条特性曲线在拐点处不可导。理想继电特性更极端,输入从正到负变化时,输出在两个定值之间瞬间跳变。死区特性在零点附近有一段完全没有输出,导数等于零。间歇特性则带有回环,输入输出关系甚至不是单值函数。

这三类特性有一个共同后果:小偏差线性化模型无法描述系统在大信号下的行为。你如果把继电器近似成一个高增益放大器,那么在零点附近它是“通的”;但实际系统中,继电器一旦切换,系统结构就发生了变化,这种“变结构”行为是线性模型永远表达不出来的。

2.2 典型非线性特性对比

非线性类型特性描述对系统的主要影响
饱和输入超过限幅值后输出不再增加大信号下等效增益下降,可能引起响应迟缓甚至自振
死区输入在零位附近一定范围内无输出产生稳态误差,低速跟踪时可能出现爬行
间隙输入输出存在回环,换向时有滞后降低定位精度,容易引起极限环振荡
理想继电器输出只有正负两个状态,存在跳变典型开关控制,极易引发自振

这些非线性在物理系统中非常常见。电磁阀、液压伺服阀、齿轮传动机构、运放限幅电路、PWM 功率放大器,或多或少都存在一种或多种这样的特性。这也是为什么非线性系统分析不能跳过,它在工程现场出现的频率远比你想象得高。

3. 描述函数法核心原理

3.1 谐波线性化思想

描述函数法的基本思想非常朴素:给非线性环节输入一个正弦信号,它的输出一般不是正弦,而是包含基波和高次谐波的周期信号。既然高次谐波在线性部分滤波后会被明显衰减,就可以近似认为“起主要作用”的只有基波分量。

于是,非线性环节在正弦输入下被等效成一个随输入振幅变化的复数增益,这个增益就是描述函数。它与传统“增益”最大的不同在于:传统增益是一个常数,而描述函数通常与输入信号的振幅有关,记作 (N(A)),如果非线性还带有储能特性,那么它还与频率有关,记作 (N(A,\omega))。

这就是谐波线性化。它不是把非线性系统变成线性系统,而是用“基波等效”的思路,把一个非线性环节替换成一个随振幅变化的等效线性环节。这样做的好处是,后面可以直接借用线性系统里的频率特性分析方法;代价是,它本质上是一种近似。

3.2 描述函数定义

设非线性环节的输入为:

[ x(t) = A\sin\omega t ]

输出为一个周期信号 (y(t)),将其展开为傅里叶级数,并取基波分量:

[ y_1(t) = Y_1 \sin(\omega t + \varphi_1) ]

那么描述函数定义为:

[ N(A) = \frac{Y_1}{A}e^{j\varphi_1} ]

从定义可以看出,描述函数是一个复数。当非线性特性是单值奇函数时,输出基波与输入同相,(\varphi_1=0),描述函数就是一个实数;当非线性特性存在回环,例如间隙特性时,输出基波会滞后于输入,此时描述函数就是一个复数。

这里需要特别强调:描述函数不只是一个“等效增益”,它把非线性的振幅依赖性和相位滞后都包含进去了。理解这一点,后面看负倒描述函数的时候才不会懵。

3.3 负倒描述函数与奈奎斯特判据

把非线性环节用描述函数等效之后,一个包含非线性环节的单位负反馈系统,可以近似化为一个等效线性系统。系统的闭环特征方程可以写成:

[ 1 + N(A)G(j\omega) = 0 ]

移项得到:

[ G(j\omega) = -\frac{1}{N(A)} ]

这就是描述函数法中最关键的关系式。如果把 (G(j\omega)) 曲线和 (-\frac{1}{N(A)}) 曲线都画在复平面上,两条曲线的交点就对应系统可能存在的周期运动,也就是极限环。

极限环的稳定性怎么判断?教材上有一个比较直观的判据:在交点附近,如果振幅 (A) 增大的方向使 (-\frac{1}{N(A)}) 进入 (G(j\omega)) 曲线非包围的区域,那么这个极限环就是稳定的;反之则不稳定。更口语化地说,稳定极限环的意思是:扰动让它振幅变大,它会衰减回来;扰动让它振幅变小,它又会增长回去,最终始终稳定在同一个振幅和频率上。

当然,描述函数法本身是近似方法,所以判断结果并不保证与真实系统完全一致,但它给工程师提供了一个很有价值的“预判”。

3.4 理想继电特性描述函数推导

理想继电器是最典型的本质非线性,输出只取 (+M) 和 (-M) 两个值。设输入为 (x(t)=A\sin\omega t),当 (x>0) 时输出 (+M),当 (x<0) 时输出 (-M)。

输出的周期方波基波分量幅值为:

[ Y_1 = \frac{4M}{\pi} ]

于是理想继电特性的描述函数为:

[ N(A) = \frac{4M}{\pi A} ]

负倒描述函数为:

[ -\frac{1}{N(A)} = -\frac{\pi A}{4M} ]

这个式子非常重要。它说明理想继电器的负倒描述函数始终位于复平面的负实轴上,并且随着 (A) 增大,从原点附近沿负实轴向左移动。这个特性决定了描述函数法分析继电器系统时,重点关注的是 (G(j\omega)) 曲线与负实轴的交点。

4. 描述函数法的适用边界与误差来源

很多人学描述函数法时,只记住了公式,却忽略了它的适用条件,结果一用就出问题。这里必须把使用边界讲清楚。

第一个条件是线性部分的低通滤波特性。描述函数法忽略高次谐波,这个近似成立的前提是线性部分能有效衰减二次、三次等高次谐波。如果线性部分带宽很宽,高次谐波没有被充分抑制,那么描述函数法的误差会很大。

第二个条件是非线性环节的位置。描述函数法通常要求非线性环节可以分离成前向通路中的一个独立环节,并且系统可以画成“非线性环节 + 线性部分”的串联结构。如果非线性环节与线性部分交织在一起,不容易分离,那么描述函数法的使用就会很困难。

第三个条件是多值非线性的相位问题。像间隙这种带滞环的非线性,它的描述函数是复数,负倒描述函数不再落在实轴上,此时不能简单看与负实轴的交点,而要把 (G(j\omega)) 曲线与负倒描述函数轨迹在复平面上的交点整体找出来。

还有一个容易忽略的点:描述函数法只适用于“周期运动是否存在”的分析。它不能用来分析系统的暂态响应、不能给出吸引域大小、也无法处理初始状态显著影响最终平衡点的多平衡点问题。这类问题更适合用相平面法处理,但相平面法又只适合二阶系统。所以两种方法其实是互补的关系。

5. 环境准备与 Python 分析工具

描述函数法的计算量不大,手算可以完成一部分,但绘图和数值仿真最好用 Python。本文涉及的代码只需要三个库:numpy、scipy、matplotlib。如果你本机还没有安装,可以执行下面的命令:

pip install numpy scipy matplotlib

建议使用 Python 3.8 或以上版本。老版本也能跑,但向量化和绘图性能会差一些。如果是在学校机房或者没有安装 Python 的环境,也可以考虑用在线环境,但注意在线环境需要先安装依赖。

6. 完整实例:用描述函数法判断继电系统的自振

6.1 系统模型与解析计算

设一个单位负反馈系统,前向通路中包含一个理想继电器和一个三阶线性部分,结构如下:

[ u = M \cdot \text{sgn}(e) ]

[ G(s) = \frac{6}{s(s+1)(s+2)} ]

其中继电特性参数 (M=1),参考输入 (r=0)。这个系统在画奈奎斯特图时会有一个很典型的特征:线性部分包含一个积分环节,且还有两个惯性环节,频率特性曲线在某个频率下会与负实轴相交。

先求线性部分频率特性:

[ G(j\omega)=\frac{6}{j\omega(1+j\omega)(2+j\omega)} ]

令虚部为零,可以得到曲线与负实轴相交的频率。计算得:

[ \omega=\sqrt{2}\approx 1.414\ \text{rad/s} ]

此时:

[ G(j\sqrt{2})=-1 ]

负倒描述函数为 (-\frac{\pi A}{4M}),令其等于 (-1),得到:

[ A=\frac{4}{\pi}\approx 1.273 ]

所以,描述函数法预测该系统将存在一个自振,振荡频率约为 (1.414) rad/s,振荡基波振幅约为 (1.27)。这个结果可以直接用代码验证。

6.2 代码实现:绘制负倒描述函数与奈奎斯特图

第一个脚本用于绘制 (G(j\omega)) 曲线和负倒描述函数曲线,并计算交点。

# 文件:describing_function_analysis.py import numpy as np import matplotlib.pyplot as plt from scipy.optimize import fsolve def G_jw(w): """线性部分频率特性 G(jw)""" return 6.0 / (1j * w * (1 + 1j * w) * (2 + 1j * w)) def neg_inv_N(A, M=1.0): """理想继电器负倒描述函数 -1/N(A) = -pi*A/(4M)""" return -np.pi * A / (4.0 * M) # 绘制 G(jw) 曲线 w = np.logspace(-1, 2, 800) G = G_jw(w) plt.plot(G.real, G.imag, label=r'$G(j\omega)$') plt.plot(G.real, -G.imag, '--', alpha=0.5, label=r'$G(-j\omega)$') # 绘制负倒描述函数轨迹 A = np.linspace(0.01, 3.0, 500) neg_curve = np.array([neg_inv_N(a) for a in A]) plt.plot(neg_curve, np.zeros_like(neg_curve), 'r-', label=r'$-1/N(A)$') # 求 G(jw) 与负实轴交点 w_sol = fsolve(lambda w: np.imag(G_jw(w)), 1.4) R = np.real(G_jw(w_sol[0])) A_sol = -4.0 * R / np.pi plt.plot(R, 0, 'ko', markersize=8, label='交点') plt.text(R, 0.15, f'({R:.3f}, 0)\nA={A_sol:.3f}', ha='center') plt.xlabel('实部') plt.ylabel('虚部') plt.legend() plt.grid(True, alpha=0.3) plt.axis([-4, 2, -4, 4]) plt.title('Describing Function Analysis') plt.show() print(f'G(jw) 与负实轴交点频率: {w_sol[0]:.4f} rad/s') print(f'交点实部: {R:.4f}') print(f'理论自振振幅 A: {A_sol:.4f}')

这段代码做了三件事。第一,用对数间隔的频率点计算并绘制线性部分的奈奎斯特曲线。第二,绘制理想继电器负倒描述函数,它沿负实轴分布。第三,用fsolve求 (G(j\omega)) 虚部为零的频率,再由实部反推出理论自振振幅。

运行后,你应当会看到一个负数实轴上的黑色交点和对应的振幅数值。

6.3 代码实现:时域仿真验证极限环

解析计算给出的是“预测值”,要验证这个预测,最直接的方法是搭建一个时域仿真模型,把继电器非线性放在反馈回路中,观察系统输出是否能形成等幅振荡。

由于线性部分 (G(s)=\frac{6}{s(s+1)(s+2)}) 是一个三阶系统,可以写出它的可控标准型状态方程。设 (x_1=y),(x_2=\dot y),(x_3=\ddot y),则:

[ \begin{cases} \dot x_1 = x_2\ \dot x_2 = x_3\ \dot x_3 = -2x_2 - 3x_3 + 6u \end{cases} ]

在单位负反馈下,参考输入为零时,误差信号为 (e=-y),继电输出为 (u=\text{sgn}(e))。

# 文件:relay_system_sim.py import numpy as np from scipy.integrate import solve_ivp import matplotlib.pyplot as plt M = 1.0 def relay(e): return M * np.sign(e) def system_rhs(t, x): y = x[0] e = -y u = relay(e) return [x[1], x[2], -2.0 * x[1] - 3.0 * x[2] + 6.0 * u] t_span = (0, 30) t_eval = np.linspace(0, 30, 6000) x0 = [0.6, 0.0, 0.0] sol = solve_ivp(system_rhs, t_span, x0, t_eval=t_eval, method='RK45', max_step=0.01) y = sol.y[0] t = sol.t # 稳态段振幅估计 steady = y[t > 20] A_est = (steady.max() - steady.min()) / 2.0 # 稳态段周期估计:找过零时刻 signs = np.sign(steady) cross = np.where(np.diff(signs) != 0)[0] T_est = None if len(cross) >= 4: period_samples = np.diff(cross)[::2] T_est = np.mean(period_samples) * (t[1] - t[0]) * 2 print(f'仿真稳态振幅估计: {A_est:.4f}') print(f'理论振幅(描述函数法): {4 / np.pi:.4f}') if T_est is not None: print(f'仿真稳态周期估计: {T_est:.4f} s') print(f'理论周期: {2 * np.pi / np.sqrt(2):.4f} s') plt.figure(figsize=(10, 4)) plt.plot(t, y, linewidth=1) plt.xlabel('时间 (s)') plt.ylabel('输出 y(t)') plt.grid(True, alpha=0.3) plt.title('Relay Nonlinear System Time Response') plt.show()

从整体思路上看,这个仿真脚本的核心逻辑是:用solve_ivp求解非线性状态方程,让继电器在每个积分步长内根据误差符号输出 (+1) 或 (-1),然后观察系统的输出波形。

运行这段代码后,如果一切正确,你会在 30 秒的仿真区间中看到输出先出现一段暂态过渡,然后进入稳定的等幅振荡。稳态部分的最大值和最小值关于零对称,所以用“峰值差的一半”可以估算振幅。

这里要特别提醒一个仿真细节:sign函数是不连续的,如果积分步长过大,仿真结果可能出现明显的“过冲”或“非真实振荡”,导致振幅估计严重偏大。因此,max_step要设置得足够小,这里取0.01是为了保证积分精度。

7. 运行结果与效果验证

7.1 预期输出结果

按照 6.1 节的理论计算,系统应当出现以下特征:

指标理论值仿真预期
振荡频率1.414 rad/s约 1.41 rad/s
振荡周期4.44 s约 4.44 s
基波振幅1.273约 1.27

仿真的振幅估计基于稳态输出波形的最大值和最小值。需要注意的是,理想继电器的输出是一个方波,线性部分对高次谐波有滤波作用,所以系统输出并不是标准正弦波,而是接近正弦的周期信号。用峰值差的一半估算振幅,得到的结果接近基波振幅,这符合描述函数法的假设。

7.2 如何判断分析与仿真是否一致

判断结果是否一致,不要仅仅比较“振幅数值是否一样”,还要看两个特征:第一,系统是否进入持续的等幅振荡,而不是衰减到零或者发散;第二,振荡的周期是否与分析值接近。如果振幅接近但周期明显不同,通常说明线性部分的模型状态方程写错了,或者频率计算有误。

如果仿真波形出现振幅持续增大、最终数值溢出,第一件事不是怀疑描述函数法错了,而是检查三阶线性部分的状态方程是不是写对了。很多人把可控标准型的状态矩阵写错,导致线性部分变成不稳定系统,仿真自然发散。

7.3 参数变化对自振的影响

描述函数法不仅能判断当前参数下是否自振,还能用于指导参数调整。以本例为例,如果把线性部分的增益从 (6) 降低到 (4),(G(j\omega)) 曲线与负实轴的交点就会从 (-1) 变为约 (-0.67),交点位于负倒描述函数更右侧的位置。此时交点是否还存在,需要重新判断。

更一般地说,减小线性部分增益会使奈奎斯特曲线内缩,从而使系统从“存在自振”变为“无自振”,这也是继电器系统中常用的一种自振抑制思路。类似的,在线性部分增加校正环节、改善相角裕度,也可以改变 (G(j\omega)) 曲线与负实轴的交点位置,从而消除或改变自振状态。

8. 常见问题与排查思路

描述函数法虽然简单,但在使用过程中很容易踩坑。这里把最常见的几种现象整理成一张排查表。

问题现象可能原因排查方式解决方案
(G(j\omega)) 与负倒描述函数无交点系统在当前参数下不存在周期运动,或交点位于曲线未覆盖区域检查参数是否与模型一致,扩大绘图范围根据奈奎斯特判据判断稳定性;改变增益或校正参数
仿真振幅与理论值偏差较大线性部分低通滤波效果不足,高次谐波未被充分衰减查看输出波形是否明显偏离正弦增加线性部分阶数或滤波器;接受近似误差,以时域仿真为准
仿真结果发散状态方程写错,或积分步长过大检查可控标准型矩阵和max_step重新推导状态方程,减小步长,降低初始扰动幅值
曲线存在多个交点系统存在多个可能的极限环,部分稳定部分不稳定逐点判断稳定性结合稳定性判据和仿真确定实际极限环
含间隙等回环特性时无法用实轴交点多值非线性的描述函数是复数在复平面上画完整的负倒描述函数轨迹使用复平面轨迹整体判断交点
不同初值得到不同稳态结果系统存在多个平衡点或吸引子用不同初值多次仿真结合相平面法分析吸引域,不能只看一次仿真

其中,多个交点的现象在工程中值得特别关注。一个闭环系统可能存在不止一个极限环:一个是稳定的,一个是不稳定的。简单说,稳定极限环是“可以观察到的振荡”,不稳定极限环是“理论上存在但扰动后不会保持”的状态。调试现场如果出现时有时无的振荡,往往就是系统处于这两类极限环之间的复杂状态,此时要非常谨慎。

9. 最佳实践与工程建议

9.1 先定性,再定量

面对一个可疑的非线性系统,不要直接上仿真,也不要直接写描述函数。先做定性判断:非线性环节属于单值还是多值?输出是否存在回环?线性部分是否具有低通滤波特性?系统是否可能自振?这些判断决定了后面应该用什么工具、能信任多少精度。

9.2 描述函数法当作“快速估算器”

在实际工程项目中,我更推荐把描述函数法定位成一个“快速估算器”,而不是最终结论的来源。先用描述函数法估算自振频率和振幅,再用 Simulink 或 Python 做时域仿真验证,两者一致就可以作为设计依据。如果两者不一致,优先以时域仿真和现场实验为准,同时回头检查描述函数法的适用条件是否被破坏。

9.3 抑制自振的常见工程手段

如果系统存在有害的自振,常用的措施包括:

  • 降低线性部分增益,使奈奎斯特曲线内缩,让交点消失。
  • 引入校正环节,改善相角裕度,避免频率特性包围临界点。
  • 在继电器或开关控制前增加死区,减小频繁切换。
  • 对系统内部存在的间隙、摩擦非线性,使用高频抖动信号或更平滑的控制律。
  • 使用滞环比较器或 PWM 调制,用更高频的周期性动作替代低频大幅自振。

这里特别注意:死区可以抑制小幅自振,但也会引入稳态误差。间隙会加剧振荡。每种措施都有代价,不能看到自振就盲目加死区。

9.4 学习建议

对于正在学习《自动控制原理》的读者,建议把描述函数法和相平面法放在一起学。描述函数法适合高阶系统的自振估算,相平面法适合二阶系统的精确分析。两者的结论相互印证,才能真正理解“极限环”这一非线性系统独有的现象。

考研复习时,重点掌握理想继电器、死区、饱和这三类典型非线性的描述函数推导,以及“负倒描述函数与奈奎斯特曲线相交”的分析流程。这个考点在教材和真题中出现的频率都很高。

9.5 代码与仿真建议

做非线性系统仿真时,有几个习惯值得养成:第一,所有积分参数要在代码里写成常量,方便复现;第二,仿真时间要足够长,确保暂态结束后再提取稳态信息;第三,不要把“一次仿真的输出”当作最终结论,尤其是遇到不连续环节时,要改变步长和初始条件做对比,确认结果没有明显依赖步长。

从工程角度看,描述函数法解释了一个很重要的事实:非线性系统的自振不是“故障”,而是系统自身的数学性质。理解了这一点,调试非线性系统时你就不会盲目地反复调参数,而是会先判断这个振荡是怎么产生的,再决定是消除它,还是利用它。

如果这篇文章对你有帮助,建议收藏备用。接下来可以继续学习相平面法,或者结合具体的控制系统仿真工具,把描述函数法的判断流程真正跑通到你自己的项目里。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 2:28:20

双引擎解耦架构如何实现工业设备5分钟接入?JVS实践解析

1. 项目概述&#xff1a;JVS双引擎解耦到底在解什么 工业设备接入这件事&#xff0c;真做过的朋友都懂。明明协议就那几类&#xff0c;Modbus、OPC UA、三菱PLC、西门子S7&#xff0c;翻来覆去就那些寄存器地址和字节序&#xff0c;但每次新接一台设备&#xff0c;还是得让开发…

作者头像 李华
网站建设 2026/9/7 2:26:57

专业教材编写必备:AI写教材,快速搭建框架并生成完整内容!

刚完成高校教材编写的初稿后&#xff0c;接下来的修改和优化过程简直让人头疼。要一遍又一遍地通读全文&#xff0c;找出逻辑上的漏洞和知识点的错误&#xff0c;光是这个环节就得花费不少时间。更麻烦的是&#xff0c;稍微调整一个章节的结构&#xff0c;后面的内容就会连带被…

作者头像 李华
网站建设 2026/9/7 2:25:18

PIC18指令系统实战解析:从51汇编到16位指令字的进阶之路

简介&#xff1a;PIC18系列单片机指令中文讲解是一份面向单片机初学者和嵌入式开发者的指令集学习资料&#xff0c;聚焦PIC18家族指令的快速入门与日常查阅。文档对算术运算、位元运算、程式流程控制、数据传输、逻辑运算及移位等常用指令进行了分类整理&#xff0c;并给出助记…

作者头像 李华