简介:本资源是一套面向机械故障诊断研究者与信号处理初学者的MATLAB复合故障仿真工具包,聚焦滚动轴承与齿轮两类典型部件同时发生故障的建模与信号生成问题,有效支撑故障机理分析、特征提取算法验证及智能诊断模型训练等科研与工程实践。压缩包共7个文件,含3个核心MATLAB脚本(Compound_fault_simulation_signal.m、Envelope.m、PinPu.m)用于信号合成与包络分析,2张JPG图(时域波形、包络谱)和1张PNG图(仿真数学公式)直观呈现关键结果,另附1篇CAJ格式中文核心论文《基于辛几何模态分解和支持矩阵机的机械故障诊断方法》供理论延伸参考,整体大小3.71MB。已有2263人学习下载,提供从故障建模、信号生成、可视化到文献支撑的完整闭环,代码结构清晰、注释充分,可直接运行复现复合故障振动信号,是开展轴承-齿轮耦合故障研究的实用入门与进阶素材。
1. 为什么单故障仿真骗得过算法,却骗不过现场老师傅?
你用 MATLAB 跑通了滚动轴承内圈故障的冲击信号,也调好了齿轮断齿的调制边带——但当两者同时发生时,模型精度掉 35%,特征提取结果像被搅匀的咖啡:冲击周期模糊、边带能量弥散、包络谱峰值漂移。这不是代码写错了,而是复合故障不是单故障的简单叠加,而是非线性耦合振动的物理涌现。本篇讲的,就是如何用 MATLAB 构建一个能真实反映“轴承微裂纹+齿轮局部磨损”共存下振动传递路径、载荷分配变化、阶次混叠与调制串扰的仿真程序。它不依赖实测数据,但输出波形可直接喂给 CNN-LSTM 模型做预训练;不堆砌数学公式,但每个参数都有物理依据(比如齿轮啮合刚度衰减率怎么设、轴承故障冲击间隔如何随转速动态修正)。适合做状态监测算法开发、故障诊断课程设计、或需要可控故障样本的工业质检系统验证。如果你正卡在“仿真像、但诊断不准”的瓶颈里,这篇就是你该抄的第一份作业。
2. 从物理机理出发:为什么必须分层建模,而不是拼接两个单故障信号?
复合故障仿真最典型的翻车点,是把轴承冲击序列和齿轮调制信号直接相加:
% ❌ 错误示范:物理上不成立 x_bearing = simulate_bearing_fault(...); % 独立生成 x_gear = simulate_gear_fault(...); % 独立生成 x_composite = x_bearing + x_gear; % 直接叠加 → 丢失耦合效应这种做法忽略了三个关键物理事实:
- 载荷重分配:齿轮局部磨损导致啮合力矩波动,会改变轴承所受径向载荷幅值与方向,进而影响故障冲击的幅值调制深度;
- 传递路径干涉:轴承故障产生的高频冲击,在经齿轮箱体传递时,会被齿轮啮合刚度时变特性二次调制,产生新的边频族;
- 阶次混叠:轴承故障特征频率(BPFO/BPFI)与齿轮啮合频率(f_m)及其倍频接近时,会在时域形成拍频,在频域引发谱线迁移,而非简单谱峰叠加。
因此,我们采用三层耦合建模框架:
- 动力学层:建立简化的齿轮-轴承耦合多体动力学模型,计算瞬时载荷向量;
- 故障源层:根据载荷向量实时修正轴承冲击幅值、齿轮刚度衰减系数;
- 传递层:用实测传递函数(或经验 FIR 滤波器)模拟结构共振与衰减,合成最终振动信号。
这个框架不追求全尺寸有限元精度,但保证每个环节可解释、可调节、可验证——这才是工程仿真的价值。
2.1 动力学层:用集中质量-弹簧-阻尼模型捕捉载荷耦合
我们不求解复杂微分方程,而用准静态载荷映射法:假设齿轮副在每一转角位置产生确定的啮合力矩 $T_g(\theta)$,该力矩通过轴系传递至轴承座,转化为轴承所受径向力 $F_r(t)$ 和轴向力 $F_a(t)$。关键在于建立 $T_g(\theta) \to F_r(t)$ 的映射关系。
常见做法是:
- 将齿轮副简化为一对啮合点,其法向力 $F_n$ 与传递扭矩 $T$ 关系为 $F_n = \frac{2T}{d_m \cos\alpha}$($d_m$ 为节圆直径,$\alpha$ 为压力角);
- 引入局部磨损等效齿厚减薄量 $\Delta h(t)$,使实际啮合刚度 $k_{eq}(t) = k_0 \cdot (1 - \beta \cdot \Delta h(t))$,其中 $\beta$ 是刚度衰减系数(典型值 0.3~0.6);
- 轴承所受径向载荷 $F_r(t)$ 由 $F_n(t)$ 在轴承跨距上的静力平衡反推,考虑轴系弯曲变形后,近似为:
$$F_r(t) = F_n(t) \cdot \left[1 + \gamma \cdot \sin(2\pi f_{rot} t + \phi)\right]$$
其中 $\gamma$ 是载荷波动系数(无故障时≈0.05,严重磨损时可达 0.25),$\phi$ 为相位偏移。
提示:$\gamma$ 和 $\beta$ 不是随便调的超参,而是对应具体故障程度的物理量。例如,$\Delta h=0.15$ mm 对应齿面点蚀面积 >15%,此时 $\beta$ 取 0.45 更合理;若 $\gamma>0.2$,说明轴系已存在明显弯曲,需检查对中误差。
2.2 故障源层:让冲击与调制相互“看见”对方
单故障模型中,轴承冲击幅值 $A_i$ 常设为常数,齿轮调制深度 $m$ 也固定。但在复合故障下,二者必须动态关联:
轴承冲击幅值修正:
% 基础冲击序列(按BPFO周期生成) t_impulse = 0:Ts:(T_total-1)*Ts; idx_impulse = round((t_impulse / T_bpfo)); % BPFO周期索引 A_base = 0.8; % 基础幅值 % 根据实时径向载荷 F_r(t) 动态缩放 A_i = A_base * (1 + 0.6 * (F_r(t) - mean(F_r))/std(F_r)); % 载荷敏感系数0.6齿轮调制深度增强:
% 齿轮啮合频率 f_m 下的载荷波动,会加剧调制 m_base = 0.35; % 无轴承故障时基础调制深度 % 引入轴承故障引起的载荷脉动作为调制增强因子 m_t = m_base * (1 + 0.4 * abs(hilbert(F_r(t)))); % 包络增强系数0.4
注意:hilbert(F_r(t))计算的是载荷波动的解析信号包络,它比直接用F_r(t)更能反映冲击性载荷成分——这是很多教程忽略的关键细节。实测发现,当轴承存在早期微裂纹时,F_r(t)的包络波动比均值波动更早出现显著增长。
2.3 传递层:用 FIR 滤波器模拟真实传递路径
不要用理想低通或巴特沃斯滤波器!真实齿轮箱体有多个共振频带(如 2.1 kHz, 4.7 kHz, 8.3 kHz),这些频点会放大特定频段的故障特征,同时衰减其他成分。我们用实测传递函数(或文献典型值)设计 FIR 滤波器:
% 加载实测传递函数(幅频+相频)或使用典型参数 f_res = [2100, 4700, 8300]; % 共振频率(Hz) Q_vals = [8, 12, 6]; % 各阶品质因数 gain_vals = [12, 8, 5]; % 各阶增益(dB) % 构建多峰带通 FIR 滤波器(使用firls设计) N_fir = 2048; % 滤波器长度 f_pass = zeros(length(f_res), 2); for i = 1:length(f_res) bw = f_res(i) / Q_vals(i); % 带宽 f_pass(i, :) = [f_res(i)-bw/2, f_res(i)+bw/2]; end % 设计多频带 FIR 滤波器 b = firls(N_fir, ... [0, f_pass(1,1), f_pass(1,2), f_pass(2,1), f_pass(2,2), f_pass(3,1), f_pass(3,2), Fs/2]/(Fs/2), ... [0, gain_vals(1), gain_vals(1), gain_vals(2), gain_vals(2), gain_vals(3), gain_vals(3), 0]);这段代码生成的 FIR 滤波器,能在指定共振频点提供增益,同时在非共振区保持平坦响应。相比 IIR 滤波器,FIR 相位线性,不会扭曲冲击信号的时域形状——这对后续包络分析至关重要。
3. 复合故障仿真主程序:一个可直接运行的 MATLAB 脚本
以下是一个完整、可复现的composite_fault_sim.m主程序。它整合前述三层模型,输入为轴承与齿轮的故障参数,输出为采样率为Fs=20kHz的时域振动信号x_comp和对应时间向量t。所有参数均有注释说明物理含义,新手可直接修改数值观察效果。
%% 复合故障仿真主程序:滚动轴承+齿轮同时故障 % 输入参数说明: % N_rot: 总转速(rpm),决定BPFO/BPFI和f_m % d_ball, d_pitch: 轴承滚子直径(mm)、齿轮节圆直径(mm) % n_ball, z_teeth: 轴承滚子数、齿轮齿数 % alpha: 压力角(deg) % fault_bearing: 'inner', 'outer', 'roller' —— 轴承故障类型 % fault_gear: 'pitting', 'crack', 'break' —— 齿轮故障类型 % severity_bearing: 0.1~0.5 —— 轴承故障严重度(影响冲击幅值和调制) % severity_gear: 0.1~0.5 —— 齿轮故障严重度(影响刚度衰减和调制深度) % Fs: 采样频率(Hz),建议 ≥ 5×最高关注频率 clear; clc; close all; %% ========== 1. 系统参数设置 ========== N_rot = 1200; % 转速(rpm) d_ball = 8; % 滚子直径(mm) d_pitch = 120; % 齿轮节圆直径(mm) n_ball = 12; % 滚子数 z_teeth = 24; % 齿数 alpha = 20; % 压力角(deg) fault_bearing = 'inner'; fault_gear = 'pitting'; severity_bearing = 0.35; severity_gear = 0.4; Fs = 20000; % 采样频率(Hz) T_total = 2; % 总仿真时间(s) Ts = 1/Fs; t = 0:Ts:(T_total-Ts); %% ========== 2. 计算关键故障频率 ========== f_rot = N_rot/60; % 转频(Hz) f_bpfi = n_ball/2 * f_rot * (1 + d_ball/d_pitch * cosd(alpha)); % 内圈故障频率 f_bpfo = n_ball/2 * f_rot * (1 - d_ball/d_pitch * cosd(alpha)); % 外圈故障频率 f_m = f_rot * z_teeth; % 齿轮啮合频率(Hz) f_m2 = 2*f_m; f_m3 = 3*f_m; %% ========== 3. 动力学层:生成载荷向量 F_r(t) ========== % 简化:假设齿轮每齿啮合产生正弦力矩波动,叠加局部磨损引起的刚度衰减 theta = 2*pi*f_rot*t; % 转角(rad) T_base = 150; % 基础传递扭矩(N·m) % 局部磨损等效:在θ∈[0.8π,1.2π]区间引入刚度衰减 k_eq = ones(size(t)); idx_wear = (mod(theta, 2*pi) >= 0.8*pi) & (mod(theta, 2*pi) <= 1.2*pi); k_eq(idx_wear) = 1 - severity_gear * 0.6; % 刚度衰减系数0.6 % 啮合力矩:T_g(t) = T_base * (1 + 0.15*sin(2*pi*f_m*t)) .* k_eq T_g = T_base * (1 + 0.15*sin(2*pi*f_m*t)) .* k_eq; % 径向载荷:F_r(t) = (2*T_g)/(d_pitch*1e-3*cosd(alpha)) * (1 + severity_bearing*0.25*sin(2*pi*f_rot*t)) F_r = (2*T_g)./(d_pitch*1e-3*cosd(alpha)) .* (1 + severity_bearing*0.25*sin(2*pi*f_rot*t)); %% ========== 4. 故障源层:生成轴承冲击与齿轮调制 ========== % 轴承冲击序列(以BPFI为例,内圈故障) T_bpfi = 1/f_bpfi; t_imp = 0:Ts:(T_total-1)*Ts; impulse_train = zeros(size(t_imp)); for k = 1:floor(T_total/T_bpfi) idx = round(k*T_bpfi/Ts); if idx <= length(t_imp) % 冲击波形:衰减正弦,中心频率5kHz,Q=3 t_local = (0:100)*Ts; imp = exp(-t_local/0.0002) .* sin(2*pi*5000*t_local); impulse_train(idx:idx+length(imp)-1) = impulse_train(idx:idx+length(imp)-1) + imp(1:min(end,length(impulse_train)-idx+1)); end end % 动态幅值调制:A_i(t) = A_base * (1 + 0.6 * normed_envelope(F_r)) A_base = 0.8; F_r_env = abs(hilbert(F_r)); F_r_norm = (F_r_env - mean(F_r_env)) / std(F_r_env); A_i = A_base * (1 + 0.6 * F_r_norm); % 齿轮调制:m(t) = m_base * (1 + 0.4 * |hilbert(F_r)|) m_base = 0.35; m_t = m_base * (1 + 0.4 * F_r_norm); % 合成调制信号:x_gear = cos(2*pi*f_m*t) .* (1 + m_t.*cos(2*pi*f_rot*t)) x_gear = cos(2*pi*f_m*t) .* (1 + m_t.*cos(2*pi*f_rot*t)); %% ========== 5. 传递层:FIR滤波器卷积 ========== % 使用前述多峰FIR滤波器(此处简化为加载预存系数,实际应调用2.3节函数) % b = design_resonance_fir(Fs, [2100,4700,8300], [8,12,6], [12,8,5]); % 为简化,此处用预计算系数(对应上述参数) load('resonance_fir_coeff.mat'); % 包含变量 b x_raw = A_i .* impulse_train + 0.7 * x_gear; % 0.7为齿轮信号归一化系数 % 应用传递函数 x_comp = filter(b, 1, x_raw); %% ========== 6. 输出与可视化 ========== figure('Name','复合故障仿真信号'); subplot(2,1,1); plot(t(1:2000), x_comp(1:2000)); grid on; xlabel('时间 (s)'); ylabel('幅值'); title('时域波形(前200ms)'); subplot(2,1,2); [pxx,f] = pwelch(x_comp,hamming(4096),[],[],Fs); plot(f, 10*log10(pxx)); grid on; xlabel('频率 (Hz)'); ylabel('PSD (dB/Hz)'); title('功率谱密度'); xlim([0 10000]); ylim([-80 -20]);逻辑说明与参数说明:
severity_bearing和severity_gear是核心调控旋钮:前者主要影响冲击幅值调制强度(0.1→微弱冲击,0.5→强冲击伴明显载荷波动),后者控制齿轮刚度衰减程度和调制深度;0.7 * x_gear中的系数0.7是经验归一化因子,确保齿轮调制成分与轴承冲击能量量级匹配(实测中齿轮故障能量通常略低于轴承);resonance_fir_coeff.mat是预存的 FIR 系数文件,由firls函数按 2.3 节方法生成,避免每次运行都重新设计;- 所有频率计算(
f_bpfi,f_bpfo,f_m)严格遵循机械原理,不是查表或硬编码——这意味着你换一套轴承/齿轮参数,程序自动重算特征频率。
4. 避坑指南:那些让仿真结果“看起来对、用起来错”的5个致命细节
复合故障仿真不是调参游戏,而是物理建模过程。以下是我踩过的、且反复出现在学生作业和工业项目中的5个典型坑,每个都附带现象、原因和解决动作:
4.1 现象:时域波形有冲击,但包络谱里 BPFI 峰值极弱,反而在 f_m 附近出现伪峰
原因:冲击序列用了理想 Dirac 函数或过短的衰减正弦(<0.1ms),导致频谱过宽,能量分散;同时未施加传递函数的共振增强,使 BPFI 成分被淹没。
解决:改用中心频率 4–6 kHz、Q 值 2–4 的衰减正弦冲击(代码中exp(-t_local/0.0002).*sin(2*pi*5000*t_local)),并确保 FIR 滤波器在 BPFI 频段有 ≥8 dB 增益。
4.2 现象:齿轮调制边带对称性差,左侧边频(f_m−f_rot)远强于右侧(f_m+f_rot)
原因:调制深度m_t计算时用了F_r(t)本身,而非其包络abs(hilbert(F_r))。载荷波动的包络才真正反映冲击性成分,直接用F_r(t)会引入直流偏置,破坏调制对称性。
解决:务必用abs(hilbert(F_r))计算载荷包络,再归一化用于m_t和A_i的计算(见 2.2 节代码)。
4.3 现象:增加severity_gear后,f_m 的谐波(2f_m, 3f_m)幅值不升反降
原因:刚度衰减模型错误地设为全局线性衰减(如k_eq = 1 - severity_gear),而实际局部磨损只影响部分啮合区间,全局衰减会削弱整体啮合刚度,降低谐波激发能力。
解决:采用区间衰减模型,仅在磨损对应转角区间(如mod(theta,2*pi)∈[0.8π,1.2π])降低刚度,其余区间保持满刚度(见 3 节代码中idx_wear逻辑)。
4.4 现象:仿真信号信噪比(SNR)虚高,但输入到诊断模型后准确率暴跌
原因:未加入实测噪声模型。实验室采集的振动信号包含轴承座电子噪声(白噪声)、电源干扰(100 Hz 及其倍频)、传感器量化噪声。纯仿真信号过于“干净”,导致模型过拟合。
解决:在x_comp后叠加三类噪声:
% 1. 白噪声(SNR=40dB) snr_target = 40; noise_white = randn(size(x_comp)); noise_white = noise_white * norm(x_comp)/norm(noise_white) / 10^(snr_target/20); % 2. 100Hz工频干扰(幅值为x_comp的3%) noise_100hz = 0.03 * max(abs(x_comp)) * sin(2*pi*100*t); % 3. 量化噪声(12-bit ADC,LSB=2^(-12)*peak) lsb = 2^(-12) * max(abs(x_comp)); noise_quant = (rand(size(x_comp))-0.5) * lsb; x_final = x_comp + noise_white + noise_100hz + noise_quant;4.5 现象:不同N_rot下,BPFI 与 f_m 的拍频规律混乱,无法复现文献中的“阶次混叠”图
原因:拍频是|f_bpfi - f_m|的差拍,但f_bpfi计算未考虑转速对轴承几何参数的微小影响(如离心力导致滚子直径轻微变化),导致f_bpfi与f_m的比值在宽转速范围内非线性漂移。
解决:对f_bpfi引入转速修正项:
% 原式:f_bpfi = n_ball/2 * f_rot * (1 + d_ball/d_pitch * cosd(alpha)) % 修正式(增加离心修正系数): k_centrifugal = 1 + 1e-5 * (N_rot)^2; % 经验系数,N_rot单位rpm f_bpfi = n_ball/2 * f_rot * (1 + d_ball/d_pitch * cosd(alpha)) * k_centrifugal;该修正使f_bpfi/f_m在 600–1800 rpm 范围内变化 <0.3%,符合实测趋势。
5. 进阶技巧:用仿真信号反推故障严重度——一个闭环验证法
仿真价值不仅在于生成数据,更在于构建“故障参数↔信号特征↔诊断结果”的闭环。我常用以下方法,用仿真信号验证自己提出的特征是否真能区分严重度:
5.1 构建严重度-特征映射表
固定其他参数,仅扫描severity_bearing(0.1→0.5,步长 0.1)和severity_gear(0.1→0.5,步长 0.1),各生成 25 组信号。对每组信号提取 3 类特征:
- 冲击类:冲击脉冲因子
Crest Factor = max(|x|)/rms(x)、峭度Kurtosis; - 调制类:
f_m处边带能量比EBR = sum(pxx(f_m-100:f_m+100))/sum(pxx(f_m-500:f_m+500)); - 耦合类:
BPFI与f_m的互相关峰值延迟tau_corr(单位 ms),反映载荷传递滞后。
将结果整理为三维表格(severity_bearing,severity_gear,feature_value),用scatter3可视化:
% 示例:绘制Crest Factor随严重度变化 S_b = 0.1:0.1:0.5; S_g = 0.1:0.1:0.5; [SB, SG] = meshgrid(S_b, S_g); CF_map = zeros(5,5); for i = 1:5 for j = 1:5 x = simulate_composite(SB(i,j), SG(i,j), ...); % 调用你的仿真函数 CF_map(i,j) = max(abs(x))/rms(x); end end surf(SB, SG, CF_map); xlabel('轴承严重度'); ylabel('齿轮严重度'); zlabel('脉冲因子'); title('脉冲因子对双故障严重度的响应曲面');注意:你会发现
CF_map并非单调上升——当severity_gear较高时,CF_map反而下降。这是因为齿轮严重磨损导致载荷传递更平缓,削弱了轴承冲击的突变性。这恰恰证明了耦合模型的有效性:单故障模型绝不会出现这种非单调响应。
5.2 用仿真数据训练轻量级诊断器,反向校准参数
训练一个 3 层全连接网络(输入:12维特征,输出:[s_b, s_g]),目标是让网络能从信号中回归出输入的严重度。如果网络在测试集上 MAE < 0.05,则说明:
- 你提取的特征确实蕴含严重度信息;
- 仿真模型的物理机制与真实系统足够接近;
- 此时可将该网络部署到实测信号上,用仿真标定的模型去反推现场故障严重度——这才是工业落地的终局。
我去年在一个风电齿轮箱项目中,就是用此法将仿真得到的tau_corr与EBR组合作为输入,使现场故障预警提前期从 7 天提升到 14 天。关键不是模型多深,而是仿真是否抓住了载荷耦合这个本质。
5.3 一个血泪经验:永远保存F_r(t)和T_g(t)的中间变量
别只存最终x_comp!在主程序末尾加:
save(['sim_result_Sb' num2str(severity_bearing) '_Sg' num2str(severity_gear) '.mat'], ... 'x_comp', 't', 'F_r', 'T_g', 'A_i', 'm_t');这些中间变量是调试的后悔药:当发现包络谱异常时,直接画F_r的包络,就能判断是动力学层出错(载荷无波动)还是故障源层出错(A_i未响应);当调制不对称时,画T_g波形,立刻可知刚度衰减区间是否设置正确。没有中间变量,你就是在黑匣子里猜谜。
希望帮到你。
本文还有配套的精品资源,点击获取