3. 基于频谱分析的电机轴承故障检测

基于频谱分析的电机轴承故障检测 学习卡片

任务说明

本案例针对电机滚动轴承的振动加速度信号,通过快速傅里叶变换(FFT)将时域波形转换至频域,提取轴承故障特征频率(BPFO、BPFI、BSF、FTF)处的幅值,并与健康状态基线对比,从而判断轴承是否存在内圈、外圈或滚动体故障。输入为一段模拟的轴承振动信号(含噪声及故障特征频率成分),输出为频谱图与故障判定结论。

轴承故障特征频率计算

滚动轴承故障特征频率由几何参数与转频决定。设轴转速为 \( f_r \)(Hz),滚动体个数为 \( Z \),节径为 \( D \),滚动体直径为 \( d \),接触角为 \( \alpha \),则各故障特征频率为:

  • 外圈故障频率:\( BPFO = \frac{Z f_r}{2} \left(1 - \frac{d}{D} \cos\alpha\right) \)
  • 内圈故障频率:\( BPFI = \frac{Z f_r}{2} \left(1 + \frac{d}{D} \cos\alpha\right) \)
  • 滚动体故障频率:\( BSF = \frac{D f_r}{2d} \left(1 - \left(\frac{d}{D} \cos\alpha\right)^2\right) \)
  • 保持架故障频率:\( FTF = \frac{f_r}{2} \left(1 - \frac{d}{D} \cos\alpha\right) \)

本案例采用典型深沟球轴承6205-2RS的参数:\( Z=9 \),\( d=7.94 \) mm,\( D=39.04 \) mm,\( \alpha=0 \),转频 \( f_r=29.5 \) Hz(约1770 RPM)。代入计算得:BPFO≈106.4 Hz,BPFI≈159.1 Hz,BSF≈69.8 Hz,FTF≈11.8 Hz。

Python实现代码

import numpy as np
import matplotlib.pyplot as plt

# 轴承参数与特征频率
Z = 9
d = 7.94e-3      # 滚动体直径 (m)
D = 39.04e-3     # 节径 (m)
alpha = 0.0      # 接触角 (rad)
fr = 29.5        # 转频 (Hz)

BPFO = Z * fr / 2 * (1 - d / D * np.cos(alpha))
BPFI = Z * fr / 2 * (1 + d / D * np.cos(alpha))
BSF  = D * fr / (2 * d) * (1 - (d / D * np.cos(alpha))**2)
FTF  = fr / 2 * (1 - d / D * np.cos(alpha))

print(f"BPFO={BPFO:.1f} Hz, BPFI={BPFI:.1f} Hz, BSF={BSF:.1f} Hz, FTF={FTF:.1f} Hz")

# 生成模拟振动信号(含外圈故障特征)
fs = 12000       # 采样率 12 kHz
T = 2.0          # 采样时长 2 秒
N = int(fs * T)
t = np.linspace(0, T, N, endpoint=False)

# 外圈故障:BPFO 及其 2、3 次谐波,叠加转频调制与噪声
signal = (0.8 * np.sin(2 * np.pi * BPFO * t) +
          0.5 * np.sin(2 * np.pi * 2 * BPFO * t) +
          0.3 * np.sin(2 * np.pi * 3 * BPFO * t) +
          0.2 * np.sin(2 * np.pi * fr * t) * (1 + 0.5 * np.sin(2 * np.pi * BPFO * t)))
rng = np.random.default_rng(42)
signal += 0.15 * rng.standard_normal(N)

# FFT 频谱分析
win = np.hanning(N)
S = np.fft.rfft(signal * win, n=N)
freqs = np.fft.rfftfreq(N, 1 / fs)
mag = 2.0 * np.abs(S) / np.sum(win)

# 在特征频率附近搜索峰值幅值(±1.5 Hz 带宽)
def peak_amplitude(freq_target, freqs, mag, bandwidth=1.5):
    mask = (freqs >= freq_target - bandwidth) & (freqs <= freq_target + bandwidth)
    if np.any(mask):
        return np.max(mag[mask])
    return 0.0

amp_bpfo = peak_amplitude(BPFO, freqs, mag)
amp_bpfi = peak_amplitude(BPFI, freqs, mag)
amp_bsf  = peak_amplitude(BSF, freqs, mag)
amp_ftf  = peak_amplitude(FTF, freqs, mag)

print(f"BPFO幅值={amp_bpfo:.3f}, BPFI幅值={amp_bpfi:.3f}, BSF幅值={amp_bsf:.3f}, FTF幅值={amp_ftf:.3f}")

# 故障判定:阈值设为健康基线幅值的 3 倍(基线由纯噪声信号估计)
noise_floor = 0.15 * np.sqrt(2) / np.sqrt(N) * 2  # 噪声底限近似
threshold = 3 * noise_floor
print(f"判定阈值={threshold:.4f}")

faults = []
if amp_bpfo > threshold:
    faults.append("外圈故障")
if amp_bpfi > threshold:
    faults.append("内圈故障")
if amp_bsf > threshold:
    faults.append("滚动体故障")
if amp_ftf > threshold:
    faults.append("保持架故障")

if faults:
    print("判定结果:检测到 " + "、".join(faults))
else:
    print("判定结果:轴承状态正常")

# 绘制频谱图
plt.figure(figsize=(10, 4))
plt.plot(freqs, mag, linewidth=0.8)
for f, name in [(BPFO, "BPFO"), (BPFI, "BPFI"), (BSF, "BSF"), (FTF, "FTF")]:
    plt.axvline(f, color="red", linestyle="--", alpha=0.7)
    plt.text(f, plt.ylim()[1]*0.9, name, color="red", fontsize=8, ha="center")
plt.xlim(0, 500)
plt.xlabel("频率 (Hz)")
plt.ylabel("幅值")
plt.title("电机轴承振动信号频谱")
plt.grid(alpha=0.3)
plt.tight_layout()
plt.savefig("bearing_spectrum.png", dpi=150)
plt.show()

运行与验证

运行方式:将上述代码保存为 bearing_fault_detection.py,在已安装 numpy 和 matplotlib 的 Python 3.8+ 环境中执行 python bearing_fault_detection.py。

预期输出:控制台打印特征频率计算值(BPFO≈106.4 Hz,BPFI≈159.1 Hz,BSF≈69.8 Hz,FTF≈11.8 Hz),随后打印各特征频率处的频谱幅值。由于模拟信号中注入了 BPFO 基频及谐波成分,BPFO 幅值应显著高于阈值(约0.003),而 BPFI、BSF、FTF 处幅值接近噪声底限,因此判定结果为“检测到外圈故障”。同时生成 bearing_spectrum.png 频谱图,图中在 BPFO 及其 2、3 次谐波处可见明显峰值。

判定标准:若代码运行后控制台输出“检测到外圈故障”,且频谱图中 BPFO 频率处出现明显尖峰(幅值超过图中噪声底限的3倍以上),则验证通过。如需测试内圈或滚动体故障,可将信号生成部分中的 BPFO 替换为 BPFI 或 BSF 后重新运行。

轴承故障检测流程与频谱特征定位 振动信号采集 fs=12kHz, T=2s 加窗 + FFT Hanning窗, rfft 特征频率计算 BPFO/BPFI/BSF/FTF 幅值提取与阈值比较 ±1.5Hz带宽峰值 频谱幅值示意(外圈故障) 频率 (Hz) 幅值 噪声底限 判定阈值 BPFO 106Hz 2×BPFO 213Hz 3×BPFO 319Hz fr FTF BPFI BSF 判定:外圈故障