简介:本资源面向机械故障诊断、信号处理方向的初学者与工程实践者,提供轴承典型故障(如内圈、外圈、滚动体缺陷)的仿真信号可视化分析方案,解决教学演示与算法验证中缺乏标准参考波形与频谱的问题。压缩包共3个文件,含2个MATLAB脚本(主运行程序runme.m及核心FFT分析函数)与1段高清操作录屏AVI视频,总大小仅347KB,轻量易部署。已有2944人学习下载,适用于高校实验课辅助、故障诊断入门实训及MATLAB信号分析快速上手。用户可直接运行runme.m一键生成时域波形图与对应频谱图,视频全程演示环境配置、路径设置、代码执行与结果解读全过程,并强调MATLAB 2021a及以上版本兼容性及当前工作路径关键要求,显著降低调试门槛。
1. 项目概述:从振动信号中“听”出轴承的健康状况
在工业设备运维和故障诊断领域,轴承就像旋转机械的“关节”,它的健康状态直接决定了整台设备的运行平稳性与寿命。然而,轴承的早期故障信号往往极其微弱,淹没在巨大的背景噪声和复杂的运行工况中,如何精准、提前地捕捉到这些“求救信号”,是预防性维护的核心挑战。这个项目,就是带你亲手“制造”并“诊断”一次轴承故障。我们不再依赖昂贵的实体实验台和可能损坏的真实设备,而是通过仿真信号的方式,在计算机中模拟出轴承在正常、内圈故障、外圈故障、滚动体故障等不同状态下的振动信号。然后,我们将这些抽象的数学信号,转化为直观的时域波形图和频谱图,就像医生查看心电图和CT扫描片一样,从图形中解读故障的特征与模式。
为什么仿真如此重要?首先,它成本极低、可重复性极高,你可以任意调整故障的严重程度、转速、负载,而无需担心设备损坏。其次,它剥离了现实中的大量干扰,让你能专注于故障信号本身的特征学习,这是入门故障诊断最有效的路径。本项目不仅提供了生成这些信号的核心数学模型(如经典的滚动轴承振动模型),更关键的是,附带了完整的代码操作演示视频。这意味着,即使你之前对信号处理或Python编程了解不深,也能跟着视频一步步操作,从零开始生成数据、绘制图表,并理解每一行代码背后的物理意义和数学原理。最终,你将获得一套可以随时运行、反复修改的“轴承故障仿真与可视化”工具包,为深入学习更复杂的智能诊断算法打下坚实基础。
2. 核心原理:轴承故障振动信号的数学模型与特征
要仿真,必须先理解模型。轴承故障振动信号并非随机噪声,其产生有明确的物理机制和数学模型支撑。这里我们聚焦最经典、最常用的模型,它足够清晰地揭示故障特征。
2.1 滚动轴承的振动激励源
一个健康的轴承在运行时,其振动主要来源于滚动体与滚道之间的弹性接触、制造误差以及装配间隙,这些振动通常幅值较小且频谱成分分散。而当轴承的某一部件出现局部损伤(如点蚀、剥落)时,情况就变了。每当滚动体滚过这个损伤点时,就会产生一个瞬时的冲击力。这个冲击力会激发轴承座及整个机械结构的固有频率,产生衰减振动。由于轴承的旋转是周期性的,这种冲击也会周期性地发生,从而在振动信号中形成一系列周期性的冲击脉冲序列。
这个周期性,就是故障诊断的“钥匙”。对于不同的故障部位,冲击发生的周期(即故障特征频率)是不同的,它们可以通过轴承的几何参数(滚珠直径、节圆直径、接触角等)和旋转速度计算出来。例如:
- 内圈故障特征频率 (BPFI):当损伤在内圈上时,由于损伤点相对于滚动体的位置随内圈旋转而变化,其冲击频率会受转频调制。
- 外圈故障特征频率 (BPFO):当损伤在外圈上时,损伤点位置相对传感器固定,其冲击频率是固定的。
- 滚动体故障特征频率 (BSF):当损伤在滚动体上时,冲击频率与滚动体的公转和自转有关。
- 保持架故障特征频率 (FTF):频率最低,通常与润滑不良或装配问题相关。
2.2 仿真信号的数学模型构建
基于上述物理过程,一个广泛使用的轴承故障仿真信号模型可以表示为:
s(t) = ∑ A_i * exp(-β(t - iT)) * sin(2πf_n (t - iT)) * u(t - iT) + n(t)
我们来拆解这个公式的每一部分:
∑(求和):表示这是一系列脉冲的叠加,i是脉冲的序号。A_i(脉冲幅值):第i个冲击脉冲的幅值。在实际中,由于负载分布、传递路径变化等,幅值会有随机波动,通常用常数加一个小的随机变量来模拟。exp(-β(t - iT))(指数衰减项):模拟冲击激发起的结构共振的衰减过程。β是衰减系数,决定了共振衰减的快慢。这是冲击脉冲呈现“纺锤形”而非方波的关键。sin(2πf_n (t - iT))(谐振项):模拟被冲击激发出的结构固有频率(通常为数千Hz)的振动。f_n是系统的共振频率,这个高频振荡是故障脉冲的“载体”。u(t - iT)(单位阶跃函数):确保每个脉冲只在t >= iT的时刻开始被一个条件判断替代。T(脉冲间隔):这就是前面计算的故障特征周期,等于故障特征频率的倒数。这是区分故障类型的最核心参数。n(t)(背景噪声):模拟现场测量中无法避免的环境噪声、其他部件的振动等。通常用高斯白噪声来模拟,其信噪比(SNR)是一个可调的关键参数,用于控制仿真信号的“干净”程度。
注意:这个模型是一个高度简化的模型,它忽略了调制效应(尤其是内圈故障)、传递函数的影响以及多个故障并存的情况。但对于初学者理解和观察基本的时域波形与频谱特征,它已经足够强大和直观。
2.3 从时域与频域两个视角观察故障
模型产生了信号s(t),我们如何“看”它?
- 时域波形图:横轴是时间,纵轴是振动幅值。在这个视图下,健康的轴承信号看起来像一条幅值很小的、杂乱的“毛线”。而出现故障时,你会清晰地看到周期性的、衰减的脉冲“冒”出来,像一串间隔均匀的“小山丘”。时域图能最直观地展示冲击的周期
T和大致幅值,但对共振频率f_n和微弱的故障频率成分不敏感。 - 频谱图(幅值谱):我们对时域信号做傅里叶变换(FFT),将其从时间维度转换到频率维度。横轴变成频率(Hz),纵轴是各频率成分的幅值。健康的轴承频谱可能在转频及其倍频处有峰值,但整体能量较低且分散。故障轴承的频谱中,除了在共振频率
f_n处有一个高峰外,更关键的是会在故障特征频率(如BPFO、BPFI)及其倍频处出现明显的谱线。频谱图是识别故障特征频率、从而确定故障部位的决定性工具。
一个更高级的工具是包络谱(解调谱),它专门用于提取被高频共振调制的故障特征频率,对于内圈故障等尤为有效。本项目作为入门,我们先掌握时域图和频谱图这两个基本而强大的工具。
3. 仿真环境搭建与代码框架解析
工欲善其事,必先利其器。我们将使用Python来完成全部仿真和可视化工作,因为它拥有极其强大的科学计算和绘图生态。即使你是Python新手,跟着步骤也能顺利搭建环境。
3.1 Python环境与核心库安装
推荐使用Anaconda来管理Python环境,它能很好地处理各种科学计算库的依赖关系。
- 安装Anaconda:从官网下载并安装适合你操作系统的Anaconda版本。
- 创建专属虚拟环境(可选但推荐):打开终端(或Anaconda Prompt),执行
conda create -n bearing_fault python=3.9创建一个名为bearing_fault的Python 3.9环境。然后激活它:conda activate bearing_fault。 - 安装核心库:在激活的环境中,执行以下命令:
pip install numpy scipy matplotlib- NumPy:是进行数组运算和数值计算的基础,我们的信号数据都将用NumPy数组存储和操作。
- SciPy:提供更高级的科学计算功能,如信号处理、特殊函数等,这里我们主要用其FFT工具。
- Matplotlib:Python事实上的标准绘图库,我们将用它绘制时域波形图和频谱图。
3.2 代码框架与核心函数设计
我们的代码将模块化组织,清晰且易于扩展。主要分为以下几个部分:
- 参数定义模块:定义轴承几何参数、运行参数、仿真参数。
- 故障特征频率计算函数:根据几何参数和转速,计算BPFO, BPFI, BSF, FTF。
- 仿真信号生成函数:根据选择的故障类型,利用前述数学模型生成时域信号。
- 绘图函数:绘制时域波形图和频谱图,并进行美观的排版。
- 主程序:串联以上所有步骤,控制仿真哪种故障,并展示结果。
下面是一个核心函数generate_fault_signal的代码框架和解析:
import numpy as np from scipy.fft import fft, fftfreq import matplotlib.pyplot as plt def generate_fault_signal(fault_type, fr, duration, sampling_rate, bearing_params, resonance_freq=3000, damping_ratio=0.1, snr_db=20): """ 生成轴承故障仿真信号。 参数: fault_type : str 故障类型,可选 'normal', 'inner', 'outer', 'ball'。 fr : float 轴旋转频率 (Hz)。 duration : float 信号持续时间 (秒)。 sampling_rate : float 采样频率 (Hz)。 bearing_params : dict 轴承参数字典,需包含滚子数Nb, 节圆直径D_pitch, 滚子直径D_roller, 接触角alpha。 resonance_freq : float, optional 系统共振频率 (Hz),默认 3000。 damping_ratio : float, optional 阻尼比,控制衰减快慢,默认 0.1。 snr_db : float, optional 信噪比 (dB),默认 20。 返回: t : ndarray 时间轴数组。 signal : ndarray 生成的仿真信号数组。 fault_freq : float 计算得到的故障特征频率。 """ # 1. 计算故障特征频率 Nb = bearing_params['Nb'] # 简化计算,忽略接触角,使用近似公式 if fault_type == 'outer': fault_freq = Nb * fr / 2 # BPFO 近似公式 elif fault_type == 'inner': fault_freq = Nb * fr / 2 # BPFI 近似公式,实际需考虑调制,此处简化 elif fault_type == 'ball': # BSF 近似公式 D_pitch = bearing_params['D_pitch'] D_roller = bearing_params['D_roller'] fault_freq = (D_pitch / D_roller) * fr * (1 - (D_roller/D_pitch)**2) / 2 else: # normal fault_freq = 0 # 2. 生成时间轴 num_samples = int(duration * sampling_rate) t = np.linspace(0, duration, num_samples, endpoint=False) signal = np.zeros(num_samples) # 3. 如果是故障状态,生成周期性冲击 if fault_type != 'normal' and fault_freq > 0: fault_period = 1.0 / fault_freq # 故障冲击周期 # 计算在整个持续时间内可能发生的冲击次数 num_impacts = int(duration * fault_freq) impact_times = np.arange(0, num_impacts) * fault_period # 衰减系数 beta 从阻尼比和共振频率计算 beta = damping_ratio * 2 * np.pi * resonance_freq # 对每个冲击时间,生成衰减正弦波并叠加到信号上 for t0 in impact_times: # 找到受该冲击影响的时间段(冲击发生后) idx = np.where(t >= t0)[0] if len(idx) > 0: tau = t[idx] - t0 # 冲击幅值加入轻微随机性,模拟实际情况 impact_amplitude = 1.0 + 0.2 * np.random.randn() # 衰减正弦波模型 signal[idx] += impact_amplitude * np.exp(-beta * tau) * np.sin(2 * np.pi * resonance_freq * tau) # 4. 添加高斯白噪声 signal_power = np.mean(signal**2) if np.any(signal) else 1e-6 desired_noise_power = signal_power / (10**(snr_db / 10)) noise = np.random.randn(num_samples) * np.sqrt(desired_noise_power) signal_with_noise = signal + noise return t, signal_with_noise, fault_freq实操心得:在编写仿真代码时,最容易出错的地方是时间对齐和数组索引。确保你的冲击时间点
t0是精确按照故障周期生成的,并且在将衰减正弦波叠加到signal[idx]时,tau的计算必须准确(t[idx] - t0)。一个常见的调试方法是先仿真一个无噪声、只有少数几个脉冲的信号,单独绘制出来,检查脉冲形状和间隔是否符合预期。
4. 分步实操:生成并可视化四种典型状态信号
现在,我们使用上面搭建好的框架,来具体生成并对比轴承在正常、外圈故障、内圈故障、滚动体故障四种状态下的信号。我们将使用一组典型的深沟球轴承参数。
4.1 参数设置与基准案例(正常状态)
首先,定义一组通用的仿真参数和轴承参数。
# 仿真参数 sampling_rate = 10000 # 采样频率 10 kHz duration = 1.0 # 信号时长 1 秒 fr = 30 # 轴旋转频率 30 Hz (即1800 RPM) # 轴承参数 (以SKF 6205轴承近似参数为例) bearing_params = { 'Nb': 8, # 滚珠数量 'D_pitch': 39.0e-3, # 节圆直径 39 mm 'D_roller': 7.94e-3, # 滚珠直径 7.94 mm 'alpha': 0 # 接触角,深沟球轴承为0 } # 系统参数 resonance_freq = 3200 # 共振频率 3200 Hz damping_ratio = 0.05 # 阻尼比,值越小衰减越慢 snr_db = 15 # 信噪比 15 dB,模拟有一定噪声的环境生成正常状态信号并绘图:
# 生成正常信号 t_normal, signal_normal, _ = generate_fault_signal('normal', fr, duration, sampling_rate, bearing_params, resonance_freq, damping_ratio, snr_db) # 绘制时域图 fig, axs = plt.subplots(2, 1, figsize=(12, 8)) axs[0].plot(t_normal, signal_normal, 'b-', linewidth=0.5) axs[0].set_xlabel('时间 [s]') axs[0].set_ylabel('幅值') axs[0].set_title('正常轴承振动信号 (时域)') axs[0].grid(True, linestyle='--', alpha=0.7) axs[0].set_xlim([0, 0.1]) # 只看前0.1秒,更清晰 # 计算并绘制频谱图 N = len(signal_normal) yf = fft(signal_normal) xf = fftfreq(N, 1/sampling_rate)[:N//2] # 取正频率部分 magnitude = np.abs(yf[:N//2]) * 2 / N # 计算幅值谱 axs[1].plot(xf, magnitude, 'g-') axs[1].set_xlabel('频率 [Hz]') axs[1].set_ylabel('幅值') axs[1].set_title('正常轴承振动信号 (频谱)') axs[1].grid(True, linestyle='--', alpha=0.7) axs[1].set_xlim([0, sampling_rate/2]) # 显示奈奎斯特频率以下 axs[1].set_ylim([0, max(magnitude)*1.1]) plt.tight_layout() plt.show()结果解读:正常轴承的时域信号看起来像杂乱无章的噪声,没有明显的周期性脉冲。频谱图显示,能量主要集中在低频段(可能是转频fr=30Hz处有小峰),并且在共振频率3200Hz附近没有突出的、与故障相关的离散谱线。整体频谱较为平坦,符合随机噪声的特征。
4.2 外圈故障仿真与特征分析
外圈故障通常被认为是“静止”的故障,因为损伤点相对于传感器位置固定,产生的冲击脉冲间隔严格相等。
# 生成外圈故障信号 t_outer, signal_outer, bpfo = generate_fault_signal('outer', fr, duration, sampling_rate, bearing_params, resonance_freq, damping_ratio, snr_db) print(f"计算得到的外圈故障特征频率 (BPFO): {bpfo:.2f} Hz") # 绘图代码结构同上,将signal_normal替换为signal_outer,标题改为‘外圈故障’ # ... (绘图代码省略,与4.1节类似)结果解读:
- 时域图:你会清晰地看到一系列近乎等间隔的冲击脉冲。每个脉冲呈现一个快速的上升和指数衰减,这是衰减正弦模型的典型表现。脉冲的间隔
T_outer = 1/BPFO。 - 频谱图:除了在共振频率
3200Hz处有一个明显的“共振峰”外,频谱的“基座”被抬高了,这是周期性冲击的宽带特性。更关键的是,在低频段(0-1000Hz),你能在BPFO(计算值约120Hz)、2*BPFO、3*BPFO等位置看到清晰的离散谱线。这些就是故障特征频率及其谐波,是诊断外圈故障的铁证。
4.3 内圈故障仿真与调制现象观察
内圈故障的仿真更为有趣,因为损伤点随内圈旋转,冲击的幅值会受到周期性调制(通常以轴旋转频率fr为调制频率)。
# 生成内圈故障信号 (在基础模型上增加幅值调制) t_inner, signal_inner_base, bpfi = generate_fault_signal('inner', fr, duration, sampling_rate, bearing_params, resonance_freq, damping_ratio, snr_db) # 计算调制频率(转频) fm = fr # 创建一个调制函数:1 + 调制深度 * cos(2π * fm * t) modulation_depth = 0.6 modulation = 1 + modulation_depth * np.cos(2 * np.pi * fm * t_inner) # 应用调制 signal_inner = signal_inner_base * modulation print(f"计算得到的内圈故障特征频率 (BPFI): {bpfi:.2f} Hz,调制频率 (转频): {fm} Hz")结果解读:
- 时域图:冲击脉冲仍然是周期性的(周期为
1/BPFI),但脉冲的幅值不再是恒定的,而是呈现“强-弱-强-弱”的周期性变化,其变化周期等于轴的旋转周期1/fr。这是内圈故障的典型时域特征。 - 频谱图:频谱图会变得复杂。在
BPFI两侧,会出现以fr为间隔的边频带。即,你不仅能在BPFI处看到谱线,还能在BPFI ± fr、BPFI ± 2*fr等处看到谱线。这被称为“调制边带”,是诊断内圈故障的关键频谱特征。我们的简化模型通过时域幅值调制实现了这一效果。
4.4 滚动体故障仿真
滚动体故障的冲击周期由滚动体的通过频率决定,其仿真模型与外圈故障类似,但特征频率BSF通常低于BPFO和BPFI。
# 生成滚动体故障信号 t_ball, signal_ball, bsf = generate_fault_signal('ball', fr, duration, sampling_rate, bearing_params, resonance_freq, damping_ratio, snr_db) print(f"计算得到的滚动体故障特征频率 (BSF): {bsf:.2f} Hz")结果解读:
- 时域图:同样能看到周期性冲击,但冲击间隔
T_ball = 1/BSF更大(因为BSF频率更低)。 - 频谱图:在
BSF及其倍频处会出现离散谱线。有时由于滚动体自转和公转的影响,其频谱特征可能不如外圈故障那么纯粹,但特征频率的出现仍是主要判断依据。
4.5 对比分析与综合图表
将四种状态的时域波形(前0.2秒)和频谱图(0-500Hz低频段)放在一起对比,效果非常直观。
fig, axs = plt.subplots(4, 2, figsize=(15, 16)) signals = [signal_normal, signal_outer, signal_inner, signal_ball] titles = ['正常', '外圈故障', '内圈故障', '滚动体故障'] fault_freqs = [0, bpfo, bpfi, bsf] for i, (sig, title, ff) in enumerate(zip(signals, titles, fault_freqs)): # 时域图 axs[i, 0].plot(t_normal[:2000], sig[:2000]) # 取前0.2秒数据 axs[i, 0].set_title(f'{title} - 时域波形') axs[i, 0].set_xlabel('时间 [s]') axs[i, 0].set_ylabel('幅值') axs[i, 0].grid(True, linestyle='--', alpha=0.7) if ff > 0: axs[i, 0].axvline(x=1/ff, color='r', linestyle=':', alpha=0.5, label=f'理论周期={1/ff:.3f}s') axs[i, 0].legend() # 频谱图 (低频段) N = len(sig) yf = fft(sig) xf = fftfreq(N, 1/sampling_rate)[:N//2] magnitude = np.abs(yf[:N//2]) * 2 / N axs[i, 1].plot(xf, magnitude) axs[i, 1].set_title(f'{title} - 频谱') axs[i, 1].set_xlabel('频率 [Hz]') axs[i, 1].set_ylabel('幅值') axs[i, 1].grid(True, linestyle='--', alpha=0.7) axs[i, 1].set_xlim([0, 500]) # 聚焦低频特征频率范围 if ff > 0: # 标记故障特征频率及其前几次谐波 for n in range(1, 5): freq_loc = n * ff if freq_loc < 500: axs[i, 1].axvline(x=freq_loc, color='r', linestyle=':', alpha=0.5) axs[i, 1].text(freq_loc, max(magnitude)*0.9, f'{n}×', fontsize=9, color='red') plt.tight_layout() plt.show()通过这张综合对比图,不同故障模式的时域和频域特征差异一目了然,这正是仿真教学的价值所在。
5. 参数影响分析与仿真进阶技巧
仅仅能运行代码生成图形还不够,理解每个参数如何影响仿真结果,才能让你真正掌握这个模型,并能够调整它来模拟更复杂、更接近现实的场景。
5.1 关键参数灵敏度分析
信噪比 (SNR):
- 作用:控制背景噪声的强弱。
snr_db值越小,噪声越大。 - 影响:高噪声(低SNR)会完全淹没时域中的故障脉冲,使时域图看起来与正常状态无异。在频谱图中,噪声会抬高整个频谱的基底,使得故障特征频率处的谱线变得不明显,甚至无法识别。在实际诊断中,处理低信噪比信号是首要挑战。你可以尝试将
snr_db从20调到0甚至-5,观察图形的变化。
- 作用:控制背景噪声的强弱。
共振频率 (
resonance_freq):- 作用:模拟机械结构(如轴承座)被冲击激发起的主要振动频率。
- 影响:它决定了时域脉冲中高频“振荡”的频率,以及频谱图中那个最高峰的位置。不同的机械系统有不同的共振频率。在包络分析中,我们正是通过带通滤波围绕这个共振频率,来提取干净的故障脉冲包络。
阻尼比 (
damping_ratio):- 作用:控制共振衰减的快慢。阻尼比越小,衰减越慢,单个脉冲的“尾巴”拖得越长。
- 影响:阻尼比过小,时域上相邻脉冲的衰减尾部会相互重叠,干扰对脉冲周期的判断。阻尼比过大,脉冲过于短暂,能量不足,在频谱上特征频率的幅值会降低。通常机械结构的阻尼比在0.01到0.1之间。
故障特征频率 (
fault_freq):- 作用:由轴承几何尺寸和转速决定,是故障类型的“身份证”。
- 影响:它直接决定了时域脉冲的间隔和频谱图中谱线的位置。仿真时务必确保计算出的频率是准确的。可以查阅轴承型号的标准参数,或使用专业计算公式。
5.2 模拟更复杂的真实情况
基础模型是理想的。要让仿真更贴近现实,可以引入以下复杂性:
- 幅值随机性:在
generate_fault_signal函数中,我们让每个脉冲的幅值A_i加入了一点随机扰动(0.2 * np.random.randn())。现实中,由于负载变化、传递路径不确定性,幅值波动可能更大。你可以增大这个随机系数。 - 周期抖动:真实的冲击间隔并非绝对严格相等,会存在微小随机波动。可以在生成
impact_times时,为每个周期T加上一个微小的随机时间偏移。 - 多个故障并存:现实中的轴承可能同时存在多种故障。你可以简单地将不同故障类型的仿真信号线性叠加起来。例如,
signal_mixed = signal_outer + 0.7*signal_inner。然后观察混合信号的频谱,尝试区分出BPFO和BPFI的谱线,这是一个很好的练习。 - 非平稳转速:如果转速
fr是随时间变化的(如启动、停机过程),那么故障特征频率也会变化,在频谱图上会表现为“斜脊”或“扇形”图案,而不是清晰的竖直线。这需要更复杂的阶次跟踪分析技术。
5.3 从仿真到真实数据的桥梁:包络谱分析
当故障特征频率(几十到几百Hz)远低于共振频率(几千Hz)时,直接观察频谱可能因为共振峰太宽而掩盖了旁边的故障频率边带。这时就需要包络谱分析。
- 带通滤波:用带通滤波器(中心频率在
resonance_freq附近)滤出包含故障冲击信息的高频共振频带信号。 - 希尔伯特变换:对滤波后的信号进行希尔伯特变换,求取其解析信号的模,得到信号的包络线。这个包络线就是剔除了高频共振成分、只留下幅值变化规律的信号。
- 对包络线做FFT:对包络线信号进行频谱分析,得到的谱图就是包络谱。在包络谱中,故障特征频率及其谐波会变得异常突出,而共振频率的影响被消除了。
from scipy.signal import hilbert, butter, filtfilt # 假设 signal 是采集到的原始振动信号 # 1. 设计带通滤波器(围绕共振频率) lowcut = resonance_freq - 500 highcut = resonance_freq + 500 nyquist = 0.5 * sampling_rate low = lowcut / nyquist high = highcut / nyquist b, a = butter(N=4, Wn=[low, high], btype='band') # 2. 滤波 filtered_signal = filtfilt(b, a, signal) # 3. 希尔伯特变换求包络 analytic_signal = hilbert(filtered_signal) envelope = np.abs(analytic_signal) # 4. 对包络做FFT得到包络谱 N_env = len(envelope) yf_env = fft(envelope) xf_env = fftfreq(N_env, 1/sampling_rate)[:N_env//2] magnitude_env = np.abs(yf_env[:N_env//2]) * 2 / N_env # 5. 绘制包络谱 (0-500Hz) plt.figure() plt.plot(xf_env, magnitude_env) plt.xlim([0, 500]) # ... 标记故障频率 plt.show()对于内圈故障这种有强烈调制的信号,包络谱分析的效果提升尤为显著。
6. 常见问题、调试技巧与项目扩展
在实际动手编码和调试过程中,你肯定会遇到各种问题。这里我总结了一些常见坑点和解决技巧。
6.1 仿真结果与预期不符的排查清单
| 问题现象 | 可能原因 | 排查与解决方法 |
|---|---|---|
| 时域图看不到脉冲 | 1. 信噪比(snr_db)设置过低,噪声淹没了信号。2. 故障特征频率( fault_freq)计算错误或为0。3. 冲击幅值( A_i)太小。4. 绘图时间范围太短,没包含一个完整的脉冲周期。 | 1. 暂时将snr_db设为一个很大的值(如60),屏蔽噪声。2. 打印 fault_freq的值,检查计算逻辑和输入参数。3. 检查 impact_amplitude的计算,暂时去掉随机性,用固定值(如1)。4. 延长绘图的时间范围,至少显示2-3个 fault_period。 |
| 频谱图中没有离散谱线 | 1. 信号长度(duration)太短,频率分辨率不足。2. FFT计算或幅值归一化有误。 3. 故障特征频率高于显示的频率范围。 4. 冲击模型过于理想,能量分散。 | 1. 增加duration(如到2秒或更长),提高频率分辨率df=1/duration。2. 检查FFT代码,确保取了正频率部分并正确进行了幅值归一化( *2/N)。3. 调整频谱图的x轴显示范围,确保覆盖 fault_freq及其谐波。4. 尝试在模型中增加一点周期抖动,观察谱线是否变宽但仍可识别。 |
| 脉冲形状不对(非衰减振荡) | 1. 阻尼比(damping_ratio)设置不当。2. 共振频率( resonance_freq)设置过低或过高。3. 采样频率( sampling_rate)过低,无法分辨高频振荡。 | 1. 调整damping_ratio(通常在0.01-0.1之间尝试)。2. 确保 resonance_freq在合理范围(如1k-5kHz),且远高于fault_freq。3. 根据奈奎斯特采样定理, sampling_rate必须大于2*resonance_freq,通常取5-10倍。 |
| 内圈故障频谱看不到边频带 | 1. 调制深度(modulation_depth)太小或为0。2. 调制频率(转频 fr)设置错误。3. 频谱分辨率不够,不足以分开 BPFI和BPFI ± fr。 | 1. 增大modulation_depth(如0.5以上)。2. 确认 fr计算正确。3. 大幅增加信号时长 duration,提高频率分辨率,或使用更精细的频谱估计方法(如Zoom-FFT)。 |
6.2 性能优化与代码健壮性建议
- 向量化操作:在
generate_fault_signal函数中,我们使用了for循环来叠加每个脉冲。对于长时长、高频率的仿真,这可能会变慢。一个更高效的向量化方法是预先计算所有脉冲对所有时间点的影响矩阵,但这会消耗大量内存。一个折中的优化是使用np.convolve函数,但需要构造合适的核函数。对于教学和一般仿真,当前的循环方法在可读性和性能之间取得了良好平衡。 - 参数校验:在生产代码中,应该加入对输入参数的校验。例如,确保
sampling_rate > 2 * resonance_freq(满足采样定理),确保duration和sampling_rate的乘积是整数,避免FFT时的频谱泄漏问题(虽然通过endpoint=False的linspace可以缓解)。 - 结果可复现性:在调试时,为了结果可复现,可以固定随机数种子。在代码开头添加
np.random.seed(42),这样每次运行生成的噪声和随机幅值波动都是一样的。
6.3 项目扩展方向
掌握了这个基础仿真平台后,你可以向多个方向深入探索:
- 引入更精确的轴承动力学模型:研究包含非线性刚度、间隙、时变负载的复杂模型,如使用集中参数模型或借助Simulink等工具进行多体动力学仿真。
- 开发完整的故障诊断流程:将本项目作为数据生成器,生成大量带标签的故障数据(正常、外圈、内圈、滚动体、不同损伤程度),用于训练机器学习模型(如SVM、随机森林)或深度学习模型(如1D-CNN、LSTM),实现故障的自动分类。
- 结合真实数据验证:从公开的轴承故障数据集(如美国凯斯西储大学CWRU轴承数据)中下载真实振动信号,用你从仿真中学到的方法(观察时域脉冲、频谱特征频率、包络谱)去分析真实数据,比较与仿真结果的异同,理解理想模型与现实的差距。
- 构建图形用户界面(GUI):使用PyQt或Tkinter为你的仿真程序制作一个界面,允许用户通过滑块动态调整转速、故障尺寸、信噪比等参数,并实时观察图形变化,这将极大地增强教学和演示效果。
这个从仿真信号生成到时频可视化分析的完整流程,构成了旋转机械故障诊断领域最基础、最核心的技能栈。通过亲手实现它,你不仅获得了代码工具,更重要的是建立了对“故障特征”如何从物理现象转化为可观测数字信号的直观理解。下次当你看到一段真实的振动信号时,你就能像侦探一样,从时域波形和频谱图的蛛丝马迹中,寻找轴承健康的真相了。
本文还有配套的精品资源,点击获取