滚动轴承故障特征频率计算与Python包络谱分析实验指南

滚动轴承故障特征频率计算与Python包络谱分析实验指南 简介一份面向机械工程专业学生的滚动轴承实验报告模板适用于机械设计、液压与气压传动等课程的实验环节可协助学习者掌握滚动轴承的工作原理、载荷分布规律和摩擦特性测量方法。文档基于ZQGZ滚动轴承实验台系统覆盖实验目的、原理、设备清单、操作步骤、数据记录与安全注意事项内容包括滚动轴承径向载荷分布及变化实验、轴向与径向载荷传感器标定、油膜压力曲线绘制、摩擦系数测量及摩擦特性曲线绘制等并附有静态与动态数据记录表格、当量动载荷计算示例以及理论值对比可帮助读者快速复现实验流程并规范完成实验报告。文件为单个docx格式大小约210KB排版清晰、内容可直接编辑便于补充个人测量数据后提交。目前已有96人学习下载适合正在准备实验报告或想深入理解轴承性能测试细节的学生与教师参考。1. 滚动轴承实验跑通的第一步把故障特征频率这件事先想清楚在滚动轴承实验里最容易出现的误判是把频谱图中能量最高的峰当成故障特征草草写进报告。实际拿回一段现场振动数据能量最高的峰往往来自转频的低次谐波、齿轮啮合频率或装配不对中引入的 2 倍频真正的内圈、外圈故障特征藏在高频共振区里幅度反而很低。所以滚动轴承实验这份文档的成败不在于录了多少数据而在于一开始就把轴承的几何参数、实测转频和采样频段想明白让报告里出现的每个谱峰都能对应到具体物理含义。下面按“特征频率 → 采集参数 → 特征提取 → 自动成稿”的顺序把滚动轴承实验从加速度计原始信号到 .docx 成品的完整链路拆开讲。它适合做设备状态监测的工程师、搭自动化测试台的人以及需要批量产出轴承实验报告的场景。读完能照着参数表算出 FTF、BPFO、BPFI、BSF用 Python 处理时域和包络谱并把图表与结果表自动写进一份格式可控的 Word 实验报告。2. 滚动轴承特征频率公式与采集参数设定2.1 滚动轴承四个故障特征频率的物理含义滚动轴承振动分析普遍采用单点缺陷模型作为起点。假设外圈固定在轴承座上、内圈随轴旋转滚动体在滚道里既公转又自转当某个滚道表面出现点蚀或剥落时滚动体滚过缺陷会产生周期性冲击。这个冲击的重复频率就是缺陷对应的特征频率。它由滚动体数量 Z、节圆直径 Dp、滚动体直径 Db、接触角 α 和转频 fr 共同决定和缺陷的实际尺寸没有直接关系只要测出特征频率就能初步判断是哪一类元件出了问题。实验报告里通常把四个特征频率同时算出来列成一张表故障类别特征频率公式物理含义保持架 FTFfr/2 ×1 − Db/Dp·cos α保持架公转一周的频率通常最低外圈故障 BPFOZ/2 × fr ×1 − Db/Dp·cos α滚动体相对外圈固定缺陷的通过频率内圈故障 BPFIZ/2 × fr ×1 Db/Dp·cos α滚动体相对内圈旋转缺陷的通过频率滚动体故障 BSFDp/(2·Db) × fr ×1 −Db/Dp·cos α²滚动体表面缺陷的自旋频率打滑时漂移明显有一点物理直觉值得记住外圈固定滚动体走过的是静止滚道BPFO 的频率系数接近 Z/2内圈跟着轴转滚动体与内圈缺陷的相对速度更高所以 BPFI 的系数普遍大于 Z/2。以 6205 深沟球轴承为例Z9 时 BPFO 系数约 3.57BPFI 系数约 5.43两者相差接近 2 倍转频。因此谱图上 BPFI 很容易被误认为 BPFO 的谐波写报告时必须以公式按几何参数计算不能靠肉眼猜。所有公式都建立在纯滚动、无滑动、接触角恒定的理想前提上。实际运行中滚动体会轻微打滑实测频率与理论值之间通常有 1%–2% 偏差BSF 受保持架游隙影响更大偏差更明显。所以报告里不应该写“实测频率与理论频率完全相等”而是看相对偏差是否落在容差带内。分布式磨损故障还不一定出现独立特征频率峰而是噪声本底抬高这时候 RMS 和峭度趋势比单纯找峰更有用这一层在下一章会展开。2.2 采样率、采集时长与转速测量怎么设采集参数比传感器灵敏度更值得先定因为后处理阶段的频率分辨率完全由采集时长决定。工程上的常见配置是如果分析上限要到 10 kHz采样率取 25600 Hz。抗混叠滤波器不是理想低通必须留出过渡带频谱有分析意义的区间通常只用 0.4 × fs 以内。单次采集时长至少 1 秒建议 10 秒以上FFT 窗长 T 对应的频率分辨率是 Δf 1/T要分出 BPFI 峰两侧相隔一个转频的边带1 秒是最低条件。离线实验报告直接录 10 秒数据量也就几 MB处理时间可以忽略。转频 fr 不能只靠电机铭牌。异步电机带载后存在转差满载时转差率常在 1%–3%铭牌转速除以 60 得到的转频可能与实测值差 0.5 Hz 以上。实验时应把光电转速计或编码器信号作为同步通道录入同一份数据文件。参数整理成表如下参数推荐值备注采样率 fs25600 Hz有效分析范围约到 10 kHz采集时长10 s/工况Δf≈0.1 Hz边带可分窗函数Hanning频谱泄漏小工程上最常用转速信号编码器/光电测速铭牌转速仅作初值提示增量式编码器在转速很低时脉冲间隔很长测速波动大。这时优先用包络谱 0–100 Hz 内的峰值间距反推转频不直接采信仪表读数。2.3 一个覆盖四种故障频率的最小计算函数特征频率计算建议放在整个分析项目的最前面后面导入数据、做包络谱和匹配都调用同一份几何参数避免报告里把外圈公式是否写对都难检查。常见做法是把轴承参数集中到一个字典而不是散落在各个函数里import numpy as np BEARING { 型号: 6205, Z: 9, # 滚动体数量 Dp: 39.04, # 节圆直径单位 mm Db: 7.94, # 滚动体直径单位 mm alpha_deg: 0, # 接触角深沟球近似为 0 } def bearing_fault_freq(Z, Dp, Db, alpha_deg, fr_hz): alpha np.deg2rad(alpha_deg) cos_a np.cos(alpha) q Db / Dp ftf fr_hz / 2.0 * (1.0 - q * cos_a) bpfo Z / 2.0 * fr_hz * (1.0 - q * cos_a) bpfi Z / 2.0 * fr_hz * (1.0 q * cos_a) bsf Dp / (2.0 * Db) * fr_hz * (1.0 - q * q * cos_a * cos_a) return {FTF: ftf, BPFO: bpfo, BPFI: bpfi, BSF: bsf} fault bearing_fault_freq( BEARING[Z], BEARING[Dp], BEARING[Db], BEARING[alpha_deg], 29.8 ) print(fault)bearing_fault_freq先把接触角从角度转成弧度再取余弦值最后一次性返回四个特征频率。用字典而不是元组返回后续在匹配代码中按名称取值比解包四个值更不容易写反。参数里最需要注意的是 Dp 是节圆直径指滚动体中心所在圆不是轴承外径Db 是滚动体直径。这两个值查轴承手册最准不要拿游标卡尺直接量外圈和保持架缝隙代替。先用铭牌转速算出初值等实测转速到位后再重跑一次报告中转速字段以第二次结果为准。3. 用 Python 从振动数据中提取滚动轴承故障特征3.1 实验数据导入与统一格式实验数据通常来自采集仪导出的 .mat、CSV 或二进制文件。我一般会统一成最小格式振动数组vib、采样率fs、实测转速rpm三个字段。用scipy.io.loadmat读 .mat用numpy.genfromtxt或pandas.read_csv读 CSV之后统一变成np.ndarray。导入函数要处理两个常见问题一维矩阵方向不统一文件里采样率字段可能缺失import numpy as np from scipy.io import loadmat def load_bearing_signal(path, sec10, keyvib): mat loadmat(path, squeeze_meTrue) raw np.asarray(mat[key], dtypefloat) # 压成一维数组 fs int(mat.get(fs, 25600)) # 文件里带 fs 就用否则回退默认值 n int(fs * sec) if n raw.size: raise ValueError(请求的采集时长超出文件长度) x raw[:n].copy() x - x.mean() # 去掉直流分量 return x, fssqueeze_meTrue会把 1×N 和 N×1 矩阵都压成一维np.asarray再兜一层避免得到对象数组。mat.get(fs, 25600)优先读文件自带的采样率而不是把采样率作为参数写死在函数里。截取用raw[:n]拿连续时间段x - x.mean()去除直流否则后续做 FFT 和 Hilbert 变换时直流分量会占据 0 Hz 附近的能量导致谱图纵轴比例失衡。如果信号存在温度漂移引起的趋势项只减均值不够还需要用scipy.signal.detrend做一次趋势消除。3.2 时域指标RMS、峭度、峰值因子一起算频域匹配之前用一组时域指标对数据做质量检查很有必要。轴承早期点蚀会产生稀疏冲击峭度和峰值因子对这类短时冲击敏感RMS 反映整体能量适合判断故障后期是否出现明显劣化。分布型磨损不会形成清晰的特征频率峰但会让 RMS 抬升、峭度回落到接近 3。所以报告里时域表格至少要有 RMS、峭度、峰值因子三列指标定义判断倾向RMSsqrt(mean(x²))总体振动能量故障后期明显上升峭度E[(x−μ)⁴]/σ⁴接近 3 为正常冲击越强数值越高峰值因子peak / RMS对单次冲击敏感与 RMS 配合判断计算时先做一次高通滤波再统计指标否则轴颈处的低频摆动会把 RMS 抬高掩盖轴承自身的冲击成分from scipy.signal import butter, filtfilt def time_metrics(x, fs, high1000): b, a butter(4, high, btypehighpass, fsfs) xf filtfilt(b, a, x) # 零相位滤波不改变冲击时间位置 rms float(np.sqrt(np.mean(xf ** 2))) peak float(np.max(np.abs(xf))) kurt float(np.mean((xf - xf.mean()) ** 4) / (xf.std() ** 4)) return {RMS_g: rms, Peak_g: peak, Kurtosis: kurt, Crest: peak / rms}高通下界取 1000 Hz 能滤掉转频和 2 倍频等低频干扰如果实验台转速很低比如转频 5 Hz 以下特征频率与边带也靠近低频这时高通下界要降到 200 Hz否则轴承特征本身也被滤掉了。filtfilt做正反两次滤波没有相位延迟冲击在时间轴上保持在原始位置为后面包络分析做准备。3.3 包络谱把共振区里的冲击重复率解调出来普通 FFT 频谱对早期轴承故障不友好因为故障冲击激起的是轴承座或传感器的谐振频带而冲击间隔对应的特征频率以调制边带形式出现在共振峰两侧。直接对整段信号做 FFT特征频率能量被摊开噪声一大就找不到峰值。包络谱的思路是先带通滤波抓出共振频带再用 Hilbert 变换求瞬时幅值最后对瞬时幅值做 FFT。结果里高频载波被解掉剩下的是故障冲击的重复频率也就是 BPFO、BPFI 这类特征import numpy as np from scipy.signal import butter, filtfilt, hilbert from numpy.fft import rfft, rfftfreq def envelope_spectrum(x, fs, band(1000, 10000), n_fft25600): b, a butter(4, band, btypebandpass, fsfs) xb filtfilt(b, a, x) # 只保留共振频带 analytic hilbert(xb) env np.abs(analytic) # 瞬时幅值包络 seg env[:n_fft] win np.hanning(len(seg)) # 抑制频谱泄漏 spec np.abs(rfft(seg * win)) / np.sum(win) * 2 freq rfftfreq(len(seg), d1.0 / fs) return freq, specband(1000, 10000)不是对所有轴承和高装状态都成立。第一次处理一个新测试台时先用平均功率谱找共振峰再把共振频带回填到这里。n_fft25600对应 1 秒数据、约 1 Hz 频率分辨率足以分开 BPFI 峰两侧相隔一个转频的边带。np.sum(win)对窗函数面积归一化把幅值折算成实际幅值*2是因为 rfft 只返回单边谱需要补偿负频率部分能量。窗口短时频率分辨率粗边带容易糊成一团报告中的谱图宁可用 1 秒窗也不要为了省计算量降到 0.1 秒。3.4 特征频率匹配按峰值排序再算相对偏差得到包络谱后不要让程序直接挑全谱最高峰那大概率是转频或工频谐波。正确顺序是先用低频段确认实测转频再更新特征频率候选表最后在包络谱中按显著峰做匹配from scipy.signal import find_peaks def match_candidates(freq, spec, candidates, tol0.02): peaks, props find_peaks(spec, heightnp.median(spec) * 5) order np.argsort(props[peak_heights])[-15:][::-1] matched [] for pos in order: p peaks[pos] for name, fc in candidates.items(): dev abs(freq[p] - fc) / fc if dev tol: matched.append({ 故障部位: name, 理论频率: fc, 实测频率: freq[p], 相对偏差: dev, }) return matchedheight取包络谱中位数的 5 倍只保留显著性较高的峰减少低频噪声干扰。order按峰值高度从大到小取前 15 个限制匹配数量避免一组数据里出现几十条“命中”。tol0.02指相对偏差 2%对应滚动体轻微打滑下的正常偏移BSF 通常单独放宽到 3%因为它受保持架游隙影响更明显。匹配结果不理想时先回头检查bearing_fault_freq的几何参数和实测转频不要盲目调宽容差。把匹配结果和谱图落盘是下一章写报告的输入。谱图保存可以这样import matplotlib.pyplot as plt fig, ax plt.subplots(figsize(9, 3.5)) ax.plot(freq, spec) ax.set_xlim(0, 400) ax.set_xlabel(频率 (Hz)) ax.set_ylabel(包络幅值) ax.grid(alpha0.3) fig.savefig(spectrum.png, dpi150)dpi150保证 Word 插入图片后仍然清晰x 轴限制在 400 Hz 以内能看清特征频率和边带不会因为高频段的大片噪声把纵轴压垮。4. 把滚动轴承实验数据和谱图自动写入 docx 报告4.1 用 python-docx 组织报告取代手动粘贴每组数据都从 matplotlib 窗口手动复制图片再粘进 Word实验一多就会出问题图片大小不统一、表格列数对不上、某组数据漏粘。python-docx 直接操作 Office Open XML原理上是在本地把标题、段落、表格、图片组织成文档对象树执行后保存为 .docx 文件全程不需要打开 Word。一个滚动轴承实验报告可统一为固定结构标题、实验条件、时域指标表、包络谱图、特征频率匹配表。评审拿到的每份报告扫同一位置就能对比不同工况差异。安装依赖只需要pip install python-docx numpy scipy matplotlib4.2 最小报告生成函数表格和图片都走同一入口下面这个函数把时域指标和匹配结果写进报告内置 “Light Grid Accent 1” 表格样式避免每次手动调边框from pathlib import Path from docx import Document from docx.shared import Cm from docx.enum.table import WD_TABLE_ALIGNMENT def write_bearing_report(meta, metrics, matched, images, out_path): doc Document() doc.add_heading(滚动轴承实验, level0) doc.add_paragraph( f轴承型号{meta[型号]}实测转速{meta[转速_rpm]:.1f} rpm f采样率{meta[采样率_Hz]} Hz测点{meta[测点]} ) doc.add_heading(1. 时域指标, level1) table doc.add_table(rows1, colslen(metrics)) table.style Light Grid Accent 1 table.alignment WD_TABLE_ALIGNMENT.CENTER for j, name in enumerate(metrics): table.rows[0].cells[j].text name cells table.add_row().cells for j, val in enumerate(metrics.values()): cells[j].text f{val:.3f} doc.add_heading(2. 包络频谱图, level1) for caption, fig_path in images: doc.add_paragraph(caption) doc.add_picture(str(fig_path), widthCm(12)) doc.add_heading(3. 特征频率匹配, level1) t2 doc.add_table(rows1, cols4) t2.style Light Grid Accent 1 for j, col in enumerate([故障部位, 理论频率, 实测频率, 相对偏差]): t2.rows[0].cells[j].text col for row in matched: c t2.add_row().cells c[0].text row[故障部位] c[1].text f{row[理论频率]:.2f} c[2].text f{row[实测频率]:.2f} c[3].text f{row[相对偏差] * 100:.2f}% doc.save(out_path) return out_pathmetrics是上一章time_metrics返回的字典matched是match_candidates返回的列表images是(说明文字, 图片路径)元组列表。表格先写表头再通过add_row()追加数据行列数由运行时数据自动决定不会出现写死列名导致指标增加后漏列。图片宽度统一Cm(12)A4 页面去掉页边距后可用宽度约 16 cm12 cm 保证谱图不拥挤且有足够余量放注释。4.3 批量处理实验工况自动生成多份 docx一个完整工况列表循环执行分析链路是最终落地形态。下面把每个工况的元信息放在case_list里逐一生成上下文文件并把文档名按“日期_轴承型号_转速_编号”组织import re from datetime import datetime from pathlib import Path OUTPUT_DIR Path(reports) OUTPUT_DIR.mkdir(exist_okTrue) def timestamped_name(meta, tag): stamp datetime.now().strftime(%Y%m%d_%H%M%S) safe re.sub(r[^\w\-], _, f{meta[型号]}_{meta[转速_rpm]:.0f}rpm_{tag}) return OUTPUT_DIR / f{stamp}_{safe}.docx case_list [ {型号: 6205, 转速_rpm: 1788.0, 测点: 驱动端轴承座, 采样率_Hz: 25600}, {型号: 6205, 转速_rpm: 1788.0, 测点: 自由端轴承座, 采样率_Hz: 25600}, ] for i, meta in enumerate(case_list): x, fs load_bearing_signal(Path(fcase_{i}.mat)) metrics time_metrics(x, fs) candidates bearing_fault_freq( BEARING[Z], BEARING[Dp], BEARING[Db], BEARING[alpha_deg], meta[转速_rpm] / 60 ) freq, spec envelope_spectrum(x, fs) matched match_candidates(freq, spec, candidates) images [(驱动端包络谱, spectrum.png)] write_bearing_report( meta, metrics, matched, images, timestamped_name(meta, fcase_{i}) )timestamped_name用正则把不适合做文件名的字符全部替换为下划线避免轴承型号中带斜杠或空格时保存失败。case_list可以改成从 Excel 或采集仪导出清单读入每个工况执行一次“导入 → 时域指标 → 包络谱 → 匹配 → 写文档”按顺序执行即可。当工况数量达到几百组并行化优先放在envelope_spectrum计算段因为loadmat本身是单线程docx 保存也受文件 IO 限制整个链路并行收益不大。5. 滚动轴承实验报告成稿前的 4 个验证技巧5.1 没有测速通道时用低频谱峰间隔反推转频实验台没装编码器或光电探头时先从包络谱的 0–100 Hz 段入手。稳定转速下谱峰之间的最小间隔往往就是实测转频。取前几个显著峰两两作差后找最小差值再回填到bearing_fault_freq重算候选频率差值之间偏差超过 0.5% 时说明转速不稳这次数据不适合做精确匹配。很多“特征频率怎么都对不上”的报告根因不是公式错而是把铭牌额定转速当成了实测转频。sel (freq 0.5) (freq 100) peak_hz freq[sel][find_peaks(spec[sel], heightnp.median(spec[sel]) * 8)[0]] top np.sort(peak_hz)[-5:] fr_est np.diff(top).min()fr_est是转频初值代入匹配流程后还要看 BPFI 边带位置是否和它对齐对齐才可采信。5.2 先扫共振带再定带通不固定 2k–10k固定band(1000, 10000)只适合常见测试台。更换轴承型号、测点或传感器安装方式后共振区会明显移动。拿到新数据后先用scipy.signal.welch看平均功率谱的隆起频带把凸起区间填入envelope_spectrum的band。共振带不明显时按传感器安装谐振附近取值并在报告里注明“带通范围为经验值”。固定带通最容易把非故障工况误判成故障因为包络谱只放大所选频段内的调制成分。5.3 匹配表必须保留相对偏差列报告表格如果只写“理论频率”和“实测频率”两列评审很难判断偏差在不在合理范围内。相对偏差列应固定为百分比保留两位小数算法侧将 BPFO/BPFI/FTF 容差设为 2%BSF 单独放到 3%。批量生成前先打印一份未命中列表未命中的原因通常排在三个方向转速反推错误、带通未对准共振区、轴承参数填错。先处理未命中项再生成所有 docx能省去文档生成后再返工一轮。5.4 批量归档用结构化文件名与控制清单报告落盘不要用“实验1.docx”“报告_final.docx”。常见做法是20250612_6205_1788rpm_驱动端.docx日期前缀保证同批多次覆盖不冲突型号和测点让文件自身具备检索性。对齐原则是原始 .mat、谱图 png、docx 放同一目录文件名保持相同前缀用 4.3 的timestamped_name生成。跑完批量后把print(\n.join(map(str, generated)))的输出转成一份 txt 清单存档人工核对缺失项后再归档实验数据链路才算闭环。本文还有配套的精品资源点击获取