系统辨识入门:频率响应分析、扫频测试方法、伯德图解读
做运动控制这么多年,我见过太多工程师一上来就调PID参数,调得满头大汗,结果系统还是抖。为什么?因为你根本不知道你的系统长什么样。说白了,你连对手的底牌都没看清,怎么出牌?
系统辨识,就是帮你摸清系统底牌的那双手。这一章,我们聚焦在频域——用频率响应分析、扫频测试和伯德图,把机械系统的脾气摸透。
为什么要在频域里看系统?
时域里看阶跃响应,你能看到超调、稳态误差、上升时间。但有些东西,时域里看不清楚。比如:
- 系统在哪个频率附近容易共振?
- 高频噪声从哪开始被放大?
- 机械谐振到底在哪个频点?
这些问题,频域一眼就能看出来。我习惯把频域分析比作给系统做“体检”——伯德图就是那张体检报告单。
核心观点:系统辨识不是学术游戏,是工程实战的起点。你花1小时做扫频,可能省下3天盲目调参的时间。
扫频测试方法:怎么给系统“拍X光”?
扫频测试,说白了就是给系统输入一系列不同频率的正弦波,然后看输出怎么变。你想想看,一个弹簧-质量系统,你推它一下,它晃动的幅度和相位跟你的推力频率有关系——这就是频率响应的本质。
具体怎么做?我一般分三步:
- 确定扫频范围:从1 Hz到几百Hz,取决于你的系统带宽。伺服系统通常扫到500 Hz就够用了。
- 选择扫频方式:连续扫频(chirp信号)还是离散点扫频?我个人偏爱离散点——每个频率点停留几个周期,数据更干净。
- 采集并计算:记录输入输出,用FFT算出幅值和相位。
实战技巧:扫频时,信号幅值不要太大。我见过有人用50%的指令幅值去扫,结果机械限位直接撞停。一般用5%~10%的额定幅值就够了,既能激励出系统特性,又不会触发保护。
下面是我常用的扫频测试流程,画成图更直观:
伯德图解读:看懂系统的“心电图”
伯德图有两张子图:幅频特性图和相频特性图。横轴都是频率(对数坐标),纵轴分别是增益(dB)和相位(度)。
怎么看?我教你几个关键点:
- 低频增益:决定了系统的稳态精度。增益越高,静态误差越小。
- 穿越频率(0 dB线):这是系统的带宽。穿越频率越高,响应越快。
- 谐振峰:幅值曲线上凸起的尖峰。这就是机械共振点,必须避开或抑制。
- 相位裕度:在穿越频率处,相位距离-180°还有多少度。一般要求45°以上,否则系统容易振荡。
避坑指南:我曾经遇到一个客户,说系统在500 Hz附近有异响。我让他做扫频,伯德图一出来,500 Hz处有个10 dB的谐振峰。他之前一直调PID,越调越糟。后来加了个陷波滤波器,问题立刻解决。所以记住——不要跟物理规律硬刚,先看伯德图再动手。
频率响应分析的核心参数
下面这张表,是我做整定时经常参考的“健康指标”:
| 参数 | 理想范围 | 说明 |
|---|---|---|
| 穿越频率 | 系统带宽的60%~80% | 太高容易振荡,太低响应慢 |
| 相位裕度 | 45°~70° | 低于30°系统可能振荡 |
| 增益裕度 | ≥6 dB | 低于3 dB有风险 |
| 谐振峰高度 | ≤3 dB | 超过6 dB必须处理 |
实战中的扫频技巧
光说不练假把式。我分享几个在产线上摸爬滚打总结出来的经验:
- 先做粗扫,再做细扫:先用大频率步长(比如每十倍频10个点)快速摸清系统的大致特性,找到谐振区域后,再在那个频段加密扫频点。
- 注意信噪比:低频段(<10 Hz)信号容易被噪声淹没。我习惯在低频段加大幅值,高频段减小幅值——因为机械系统对高频响应本来就弱。
- 多次平均:每个频率点扫3次取平均,能有效剔除随机干扰。嗯,这个习惯帮我避免过很多次误判。
小技巧:如果你用的运动控制卡支持在线扫频,那就直接用。如果不支持,可以用信号发生器+示波器手动扫。虽然慢一点,但效果一样好。我早期做项目时,就是拿函数发生器一个点一个点地扫出来的。
一个完整的扫频代码示例
下面是我在调试时常用的Python脚本片段,用来生成扫频信号并做简单分析:
import numpy as np
import matplotlib.pyplot as plt
# 扫频参数
f_start = 1.0 # 起始频率 (Hz)
f_end = 500.0 # 终止频率 (Hz)
num_points = 50 # 频率点数
amplitude = 0.05 # 幅值 (5% 额定)
# 生成对数分布的频率点
frequencies = np.logspace(np.log10(f_start), np.log10(f_end), num_points)
# 对每个频率点生成正弦信号
for f in frequencies:
t = np.linspace(0, 5/f, int(5/f * 1000)) # 5个周期
u = amplitude * np.sin(2 * np.pi * f * t)
# 这里将 u 发送给运动控制卡,并采集响应 y
# 然后计算幅值比和相位差
# 记录到数组中
# 绘制伯德图
plt.figure()
plt.subplot(2, 1, 1)
plt.semilogx(frequencies, gain_db, 'b-')
plt.grid(True)
plt.ylabel('增益 (dB)')
plt.subplot(2, 1, 2)
plt.semilogx(frequencies, phase_deg, 'r-')
plt.grid(True)
plt.xlabel('频率 (Hz)')
plt.ylabel('相位 (度)')
plt.show()
这段代码虽然简单,但核心逻辑都在了。实际使用时,你需要根据运动控制卡的API做适配。
伯德图解读实战案例
我拿一个真实案例来说。有一次调试一台高速贴片机,Z轴在高速运动时总是有抖动。扫频后伯德图显示:
- 穿越频率在120 Hz,但相位裕度只有28°
- 在280 Hz处有一个8 dB的谐振峰
- 低频增益偏低,只有40 dB
问题很清楚了:相位裕度不足导致系统接近振荡,谐振峰放大了机械振动。解决方案:
- 在280 Hz处加一个陷波滤波器,把谐振峰压下去
- 适当降低速度环增益,把相位裕度提升到50°以上
- 增加一个低通滤波器,抑制高频噪声
调整后重新扫频,伯德图显示谐振峰降到了2 dB以下,相位裕度52°,系统运行平稳。整个过程不到2小时。
记住:伯德图是系统的“指纹”。每台机器都有自己的频率特性,扫一次就记住了。下次再出问题,直接对比新旧伯德图,哪里变了哪里就是问题点。
系统辨识入门就讲到这里。频域分析是运动控制整定的基本功,你花时间把这一步做扎实了,后面的整定工作会轻松很多。说白了,知己知彼,百战不殆——伯德图就是你的侦察兵。