☰
齿轮动力学仿真MATLAB源码解析:从建模到短时傅里叶变换故障诊断
2026/10/18 10:43:48 网站建设 项目流程

简介:一份面向机械工程学生、齿轮传动研究人员及设备故障诊断工程师的MATLAB源码资源,聚焦齿轮动力学建模与振动信号分析。资源围绕齿轮的几何参数、啮合特性及负载分布对动态响应的影响,重点演示如何利用短时傅里叶变换(STFT)处理非平稳振动信号,通过窗函数选取与局部频谱分析,识别齿面磨损、裂纹、不对中等常见故障特征。压缩包共包含3个文件,其中2个为.m脚本、1个为.asv自动保存备份,整体大小仅5KB,轻量简洁,便于直接查看核心代码实现。截至目前已有3139人学习下载。借助该源码,读者可快速上手MATLAB的spectrogram函数及相关信号处理流程,理解STFT在齿轮瞬态振动分析中的具体用法,并可根据自身工况修改参数,扩展至其他旋转机械的故障诊断场景。

1. 齿轮动力学仿真,别急着上频谱

很多做齿轮箱状态监测的人,手里拿到的第一份振动数据往往是一堆乱糟糟的时域波形,直接做FFT出来的频谱图看着挺规整,可一旦齿轮出现早期故障,比如齿面点蚀或者裂纹,频谱里那些微弱的边频带很容易被主频淹没,根本看不出问题。这份齿轮动力学MATLAB源码包,解决的正是这个问题——它用一套完整的齿轮动力学模型,把啮合过程中的振动信号先“造”出来,再通过短时傅里叶变换把频率随时间的变化摊开看,让瞬态冲击和调制边频无处可藏。适合正在做齿轮动力学建模、故障诊断算法验证或者课程设计的人,尤其是那些不想从零写动力学方程又想快速看到有效结果的从业者。源码包里不仅包含主程序,还有一份没来得及清理的备份文件,拆开看反而能学到不少建模思路。

2. 齿轮动力学模型:九个参数如何决定一张频谱

2.1 非线性项:啮合刚度为什么不能写成常数

齿轮动力学模型的核心不是一堆公式堆砌,而是怎么处理啮合刚度这个变量。很多初学者自作聪明把啮合刚度设成一个常数,跑出来的频谱干净得像教科书例题,可这种频谱拿到现场根本对不上实测数据——真实齿轮在运转时,啮合齿数随转角周期性变化,单双齿交替啮合让刚度呈周期性波动。这个源码里的模型明确把啮合刚度处理成随转角变化的方波近似,加上齿廓误差和负载波动的影响,本质上是在求解一个带周期性系数的非线性振动方程。

方程中啮合阻尼项也不能随意取,它直接影响共振峰的幅值。如果你把阻尼比调大,振动幅值会明显被压制,频谱上的啮合频率成分变弱,反之则会出现夸张的尖峰。这个模型里阻尼比默认取值在0.02到0.06之间,具体跟材料和对数衰减率相关,跑之前先想清楚自己模拟的齿轮工况是哪一类——是轻载高速还是重载低速,阻尼参数的取值逻辑完全不同。

2.2 参数表与物理意义

源码包里的主程序开头是一段参数定义区域,看起来密密麻麻,实际上每个参数都在下一段积分求解中扮演明确角色。整理成表格会更清晰:

参数名典型取值物理意义对结果的影响
齿数Z20-60决定啮合频率基频齿数越多,啮合频率越高
模数m2-6mm齿轮尺寸与强度影响刚度和固有频率
压力角α20°标准值齿廓形状影响啮合刚度波形
转速n500-3000rpm激励频率来源决定频谱横轴刻度
啮合刚度k(t)1e6-1e8 N/m周期时变参数引起边频带的关键
阻尼比ξ0.02-0.06能量耗散程度控制共振峰尖锐度
负载扭矩T10-200Nm平均载荷提高谐波幅值
误差幅值e1-50μm齿廓偏差激发高频成分
采样频率fs5-20kHz数据密度决定可分析频率上限

这些参数不是孤立的。比如你把转速从1000rpm调到3000rpm,啮合频率成倍增加,但如果采样频率还停留在5kHz,奈奎斯特频率只有2.5kHz,高频谐波全部混叠,跑出来的图就是一堆看不出规律的花纹。我一般先把采样频率设为啮合频率的10倍以上,确保至少能看到前3阶谐波。

2.3 从模型到代码:主循环里每一步在干什么

打开chilundonglixue.m,核心是求解方程的时间递推循环。代码骨架如下:

% 定义时间序列 t = 0:1/fs:t_end; N = length(t); % 预分配状态变量,避免循环内动态扩维 y = zeros(2, N); y(:,1) = [0; 0]; % 初始位移和速度 % 周期性啮合刚度:方波近似,每齿啮合周期切换 for k = 1:N-1 zeta = Z * n / 60 * t(k); % 累计转角齿数 k_mesh = k_mean + k_amp * square(2*pi*zeta); % 刚度方波 % 动力学方程:位移、速度、加速度递推 a = (-c_mesh * y(2,k) - k_mesh * y(1,k) + F_load) / m_eq; % 梯形法积分 y(2,k+1) = y(2,k) + h * a; y(1,k+1) = y(1,k) + h * y(2,k+1); end % 计算振动加速度 acc = diff(y(2,:)) / h;

这一段代码里的square函数生成了刚度方波,k_mean和k_amp控制刚度的平均值和波动幅度。m_eq是等效质量,由齿轮副的转动惯量和传动比折算而来。关注点在于:循环内没有使用ODE45这类自适应步长求解器,而是用固定步长的梯形积分,好处是计算速度快,缺点是对步长敏感——如果你把采样频率设得太低,积分步长过大,数值阻尼会吃掉高频细节,跑出来的信号比实际振动“光滑”很多。

3. 把源码跑起来:从.asv残影到第一张振动波形

3.1 文件清单与运行顺序

解压这份源码包后,你会看到三个文件:主程序chilundonglixue.m、一个.asv备份文件,还有一个以428ec93e6a72e45941d3c19a586373e7.m命名的文件。很多人在这一步就慌了,其实不用管名字多怪异——.asv是MATLAB在编辑过程中自动保存的备份,内容往往比主程序还新,你可以把它当成“后悔药”,在主程序跑不通时打开对比,看看是不是改参数时误删了某行。那个哈希命名的文件更像是一个辅助函数或者早期实验版本,打开后如果发现里面封装了一个局部函数,那大概率是主程序调用链中的一环。

运行顺序上的建议:先双击打开chilundonglixue.m,按F9分段执行参数区和主循环,确认各变量维度没有问题,再整体运行。运行完成后工作区会多出t、y、acc几个核心变量,其中acc才是你要的齿轮振动加速度信号。

3.2 采样率和转速的匹配原则

典型的翻车场景是:把转速改成1500rpm,齿数设为25,啮合频率就是251500/60=625Hz。如果你仍然用默认的8192Hz采样率,理论上能看到3次谐波,但如果想提取齿面裂纹特征,需要看到5-8倍啮合频率,采样率至少要6258*2.5=12.5kHz。

这里给一组实际跑通过的参数组合:

% 齿轮基本参数 Z_pinion = 25; % 主动轮齿数 Z_gear = 71; % 从动轮齿数(可改) n_rpm = 1450; % 主动轮转速,rpm fs = 20000; % 采样频率,Hz t_end = 2; % 仿真时长,s % 刚度参数 k_mean = 5e7; % 平均啮合刚度,N/m k_amp = 2e7; % 刚度波动幅值,N/m % 外激励与误差 F_load = 500; % 齿轮啮合力,N e_profile = 20e-6; % 齿形误差幅值,m % 动力学参数 J1 = 0.005; J2 = 0.04; % 主从动轮转动惯量,kg*m^2 r_b = 0.04; % 基圆半径,m m_eq = J1 * J2 / (J1 + J2) / r_b^2; % 等效质量折算

运行完这段后,直接画出时域波形:

figure; plot(t, acc); xlabel('时间 (s)'); ylabel('振动加速度 (m/s^2)'); title('齿轮箱振动加速度时域波形'); xlim([0 0.1]); % 只看前0.1s,避免波形过密看不清

如果画出来的波形振幅在1e-2量级且带有明显的周期性冲击,说明模型工作基本正常。如果振幅小到1e-6或者大到离谱,先去检查m_eq的量级是否折算错误——这是最容易被忽略的问题。

3.3 仿真结果怎么导出和验证

跑出波形只是开始,你还得确认仿真结果确实是“齿轮动力学”而不是凑数的正弦波叠加。验证手段很简单:对加速度信号做FFT,看频谱峰值是否落在啮合频率及其谐波上。

% 频谱计算 L = length(acc); f_axis = (0:L-1) * fs / L; Y = abs(fft(acc)); Y = Y(1:L/2+1); f_axis = f_axis(1:L/2+1); % 找前3个最高峰 [pks, locs] = findpeaks(Y, 'SortStr', 'descend', 'NPeaks', 3); f_peaks = f_axis(locs); disp(['啮合频率理论值: ', num2str(Z_pinion * n_rpm / 60), ' Hz']); disp(['实际峰值频率: ', num2str(f_peaks(1)), ' Hz']);

理论啮合频率等于主动轮齿数乘以转频,即25*1450/60≈604Hz。如果频谱峰出现在604Hz附近,说明模型至少“像”齿轮;如果峰值乱跑,多半是积分步长太大或者刚度方波周期算错了。我在某次调参时遇到过峰值出现在1200多赫兹的情况,后来查出来是方波频率算多了个2倍因子,把zeta变量里的Z * n / 60写成了2 * Z * n / 60,这类手误很难一眼看出来,对照.asv备份文件反而容易发现。

4. 短时傅里叶变换:把非平稳振动拆成二维图谱

4.1 为什么要用STFT而不是直接FFT

齿轮在启动加速或者负载突变的过程中,振动信号是非平稳的,转速每升高一点,啮合频率跟着往上飘。这时候全序列FFT做出来的频谱是一片模糊的“拖尾”——不同时刻的频率混叠在一起,分不清哪个频率是哪个转速阶段的。短时傅里叶变换(STFT)的思路是把长信号切成一小段一小段,对每一段做FFT,再把结果按时间顺序排列成二维图谱,横轴是时间,纵轴是频率,颜色深浅代表能量大小。

齿轮动力学模型里用STFT的另一个理由是可以观察啮合频率随时间漂移。当你在模型里设置转速持续上升时,STFT图谱上会看到一条从低频往高频爬的亮带,这就是啮合频率的时变轨迹——直接FFT永远得不到这种动态信息。

4.2 spectrogram参数设置:窗长、重叠、NFFT

MATLAB里spectrogram函数是把STFT做得最省事的工具,但参数设置不讲究的话,图谱分辨率会很难看。窗长决定时间和频率分辨率的权衡——窗短则时间分辨高但频率分辨差,窗长则反过来。

% 短时傅里叶变换 window_len = 512; % 窗长,点 overlap = 384; % 重叠点数,75% nfft = 1024; % FFT点数,不够自动补零 [spec, freqs, times] = spectrogram(acc, hamming(window_len), overlap, nfft, fs); % 绘制对数谱图 figure; imagesc(times, freqs, 20*log10(abs(spec))); axis xy; xlabel('时间 (s)'); ylabel('频率 (Hz)'); title('齿轮振动信号短时傅里叶变换谱图'); colorbar; ylim([0 5000]); % 只看低频区,高频留白意义不大

窗长512在20000Hz采样率下对应25.6ms的时间窗,频率分辨率约39Hz。如果你的转速变化很快,这个窗长可能太长,瞬态冲击被抹掉了,换成256点窗长会让时间分辨率提升一倍,代价是频率分辨率降到78Hz——对齿轮这类窄带信号来说,78Hz仍然够用,因为边频间隔一般都在几十赫兹以上。

4.3 边频带的判读方法

STFT图谱上除了啮合频率这条主亮带,旁边往往还有等间隔分布的小亮带,这就是边频带。边频带的间隔等于故障特征频率——比如转轴的旋转频率,它的出现说明齿轮存在某种周期性调制,可能是齿面磨损、轮齿裂纹或者装配偏心。

在模型输出中,如果你在刚度参数k_mesh里叠加了一个低频扰动,比如每转一圈刚度波动一次,STFT图谱上就会在主啮合频率两侧显现边带。用MATLAB的findpeaks可以半自动化提取这些边带:

% 提取某个时刻的频谱切片 time_idx = 100; slice = abs(spec(:, time_idx)); [pks, locs] = findpeaks(slice, 'MinPeakDistance', 30); % 计算边带间隔 sideband_interval = diff(freqs(locs(1:min(5, length(locs))))); disp(['边带间隔: ', num2str(mean(sideband_interval)), ' Hz']);

如果算出来的边带间隔等于转轴转频,即1450/60≈24Hz,恭喜你,模型里设置的故障特征成功映射到了频谱上。这个流程就是你在真实设备上做故障诊断的预演——先在仿真模型里把故障信号“调出来”,再拿实际采集的数据去套同样的分析流程,参数调试效率会高很多。

5. 避坑:齿轮动力学模型从建模到出图的血泪经验

5.1 现象:加速度波形振幅比理论值大出几个数量级

原因:等效质量m_eq折算错误。把转动惯量除以基圆半径的平方时少除了一个传动比系数,导致等效质量偏小,加速度自然暴涨。某次我把J2看成了输入轴惯性,完全忘了从动轮要乘以传动比的平方才能折算到主动轴。

解决:回来先核对m_eq的量级。一个模数2、齿数25的钢制齿轮,等效质量通常在几千克量级,如果算出0.01或者1000,一定是折算公式没写对。老老实实把传动比i=Z_gear/Z_pinion带进去,用J1 + J2 * i^2折算到主动轴。

5.2 现象:FFT频谱峰值频率对不上理论啮合频率

原因:数字角频率和物理频率混用。方波函数里如果直接用2*pi*t而没有乘转频,周期性激励的周期会变成1秒一次,FFT峰值自然落在1Hz附近而非几百赫兹。

解决:把激励写成2*pi*(Z*n/60)*t,让方波的每一个周期对应一个齿的啮合。我在这个坑里至少花了两小时,后来对着.asv文件对比才发现改转速时把公式里的n/60误删了。

5.3 现象:STFT图谱上部一片模糊,看不出边频带

原因:窗函数太短或者FFT点数不足。窗长256点加上nfft=512时,频率分辨率约78Hz,边频带间隔才24Hz,根本分不开。

解决:窗长加大到1024,NFFT设为2048,重叠率保持85%以上。牺牲时间分辨率换来频率分辨率,对齿轮这类转速稳定的信号完全值得。

5.4 现象:仿真时长越长,结果越“飘”,振幅逐渐发散或者衰减到零

原因:固定步长梯形积分在非线性刚度激励下会产生数值不稳定,尤其是刚度方波切换瞬间导数不连续,梯形法的局部误差会积累。如果阻尼比设得太小,系统本身接近临界稳定,数值误差更容易放大。

解决:把步长h缩小一半,或者换成ode45做一次对比。我一般先跑1秒数据校验稳定性,确认没问题再拉长仿真时长。阻尼比低于0.01时表现得更明显,建议至少在阻尼项加上均值刚度对应的临界阻尼比。

5.5 现象:生成的频谱图在低频段有异常大峰值

原因:积分过程漂移造成的趋势项。梯形法累加过程中,如果初始速度不为零,位移信号会包含一个线性趋势,差分后对应到加速度的直流偏移。FFT对直流分量非常敏感,低频段会因此出现一个冒尖的峰值。

解决:先对加速度信号做去趋势处理:

acc_detrend = detrend(acc, 'linear');

再做FFT和STFT。这一行代码不需要任何额外工具箱,却能省掉你大半天排查低频噪声的功夫。

6. 进阶:用残差信号验证故障特征频率

基础跑通后,下一个实用技巧是基于残差分析验证特征频率。操作方法是先从原始信号中剔除啮合频率及其整数倍谐波,剩下的残差信号主要包含随机冲击和调制成分,更容易暴露早期故障。

% 构造啮合频率及谐波的正弦拟合 f_mesh = Z_pinion * n_rpm / 60; t_col = t(:); X = [sin(2*pi*f_mesh*t_col), cos(2*pi*f_mesh*t_col), ... sin(4*pi*f_mesh*t_col), cos(4*pi*f_mesh*t_col), ... ones(size(t_col))]; % 最小二乘拟合后求残差 beta = X \ acc(:); fit_signal = X * beta; residual = acc(:) - fit_signal; % 对残差做STFT figure; spectrogram(residual, hamming(256), 192, 1024, fs, 'yaxis'); title('残差信号STFT谱图');

这里用最小二乘把啮合频率基波和前2次谐波拟合并剔除,残差信号里的周期成分会被大幅削弱。对残差做STFT后,如果仍然可以看到每隔转频出现的冲击亮斑,说明模型内部包含了额外的调制源——在真实设备上这往往指向轴承故障或轴弯曲。这个手段让我在分析实测数据时多了一个验证维度,不再对着一堆重叠峰值猜故障原因。

从那以后我每次做载荷数据和实测波形对比,都强制走一遍先验齿频率再剔除加残差分析的流程,哪怕仿真结果看着已经很“理想”。这个习惯帮我抓住过好几次模型参数虚设的问题,比如误差激励幅值设得太小导致残差里看不到任何特征。如果你是刚拿到这份源码,建议也按这个流程把振动波形从头到尾拆一遍,齿频、边带、残余冲击逐条核对,比直接套别人调好的参数更能摸清模型的脾气。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询