很多做设备状态监测的朋友第一次接触这套组合拳,多半是被论文里那一串缩写搞懵的:明明就是处理一根振动信号曲线,为什么有人要先用VMD拆一遍,再做FFT看频谱,最后还要拉一个HHT时频图出来?我在现场处理轴承故障数据时也走过不少弯路,一开始直接拿FFT怼原始信号,结果特征频率全被噪声埋掉,换了VMD-FFT-HHT这条流水线之后,故障特征才从一片“草地”里清晰浮出来。这篇内容就把这套组合讲的明明白白,面向正在跟信号数据较劲、做旋转机械故障诊断的同学,也适合想把FFT真正用透的工程师。
1. 为什么组合是VMD加FFT再加HHT:三者各自在解决什么问题
1.1 VMD不是玄学:它本质上是把一团毛线按颜色分股
变分模态分解(Variational Mode Decomposition,VMD)是2014年提出的信号分解方法,核心思想非常直接:把一段多分量、非平稳的信号,拆成若干个中心频率不同、带宽有限的子信号,这些子信号在论文里叫本征模态函数(IMF)。它在数学上构造了一个约束变分问题,通过迭代求极值,一次性把所有模态解出来,而不是像EMD那样一层一层把“剩余信号”剥出来。
我先说个容易踩的坑:第一次见到“VMD”这个词的人很容易把它和电脑BIOS里那个Intel VMD混合存储技术搞混,这俩完全不是一个东西。我们这里说的VMD,是纯信号处理领域里用来做自适应分解的工具,它的价值在于把原始振动信号里混叠在一起的转频、故障冲击、谐波、噪声拉开,让后续分析不再是“一团黑”。
VMD相对EMD最大的优势在于,它从根本上避开了EMD递归筛选带来的模态混叠问题。EMD在信号频率接近或噪声强时,经常出现一个模态里混着两个频率成分的情况,或者同一个频率成分被劈成两个模态,这种“驴唇不对马嘴”的分解结果会让你后面的频谱分析直接走偏。VMD把一个非递归问题变成变分问题来解,每个模态都有明确的中心频率和带宽约束,所以分解结果更稳定、更具物理意义。
不过它也不是万能药,VMD对参数极其敏感,尤其是要提前指定分解模态个数K,还有惩罚因子alpha。K给少了,信号欠分解,一个模态里塞了好几种频率;K给多了,会出现虚假模态,把噪声也当成有用成分拆出来。这块的具体调参经验,我在第2部分和问题排查章节会展开讲。
1.2 FFT是每个做信号的人绕不开的“标配频谱仪”
快速傅里叶变换(Fast Fourier Transform,FFT)大家太熟了。它把时域信号变换到频域,本质是计算信号在各个频率上的幅值和相位,工程上最常用的就是看幅值谱,用来识别信号里存在哪些频率成分。旋转机械故障诊断的物理基础就在这里:轴承、齿轮的局部损伤在运转中会产生周期性冲击,这个冲击频率是可以通过轴承几何尺寸和转速算出来的,比如外圈故障特征频率BPFO、内圈故障特征频率BPFI。只要FFT频谱上对应频率出现了谱峰,基本就能锁定损伤位置。
但FFT有个先天短板:它默认信号是平稳的或者准平稳的,也就是说,它给出的频谱是整个分析时间窗内的“平均”结果。实际采集到的故障信号往往是非平稳的,转速波动、载荷变化、冲击衰减都会导致频率成分随时间变化,这时FFT的谱线会被“糊掉”,看起来峰不高、底噪大、边带杂乱,读不出有效信息。
这就是为什么我在实际故障诊断时,不主张对原始信号直接做FFT。先让VMD把信号拆开,每个IMF至少是窄带且相对平稳的,再对感兴趣的那个模态做FFT,谱线会干净得多,故障特征频率和它的倍频、边带也能分辨清楚。
1.3 HHT补上了FFT丢掉的“时间轴”
希尔伯特-黄变换(Hilbert-Huang Transform,HHT)是黄锷在1998年提出的,它实际上包含两步:第一步对信号做经验模态分解(EMD),把非平稳信号拆成本征模态函数;第二步对每个IMF做希尔伯特变换,得到瞬时频率和瞬时幅值,最终绘制出以时间为横轴、频率为纵轴、颜色表达能量的希尔伯特时频谱。
很多人问:已经有FFT了,为什么还要HHT?我的回答是,FFT回答的是“有哪些频率”,HHT回答的是“这些频率在什么时刻出现、强度怎么变化”。举个例子,一个轴承外圈出现早期点蚀,故障冲击是间歇性出现的,不是每转都打一下。你拿FFT看1秒的平均频谱,能看到BPFO处有一点点凸起,但无法判断这个冲击是连续还是间歇、发生在转轴的哪一圈。HHT时频谱上,这种间歇冲击会表现为一根根等间隔的垂直能量带,冲击间隔、强度变化一目了然。
要注意的是,经典HHT第一步用的是EMD,而EMD有模态混叠的毛病。所以近几年工程界流行用VMD代替EMD做第一步分解,再对分解出的模态做希尔伯特谱分析。严格说,这个流程叫“VMD-HHT”更准确,很多人直接写HHT也只是沿用习惯叫法。我在实际项目里用的就是VMD+HHT这套改良流程。
1.4 三件套的配合逻辑:切分、看频、追时
把三件套串起来的逻辑链条是这样的:原始信号里同时混着转频、高倍频谐波、故障冲击、随机噪声,直接用FFT看是“一锅粥”;先让VMD把这锅粥按频带“分餐”,每个IMF只保留一个或多个窄带成分;然后对每个IMF做FFT,看看各模态里的频率成分是否符合某个故障特征频率;如果想进一步定位冲击出现的时域位置、判断故障严重程度,就对这个IMF做希尔伯特变换,画出时频图。整个过程总结成六个字:切分、看频、追时。
这种组合的现实价值,不只是论文里好看,而是能形成一条完整、可解释、不容易出错的证据链。尤其对故障诊断这种要求“给结论还得有依据”的工种,频谱上的谱峰和时频图上的冲击周期互为印证,比丢给用户一个卷积神经网络的“损坏概率0.87”要让人信服得多。
2. 从数据采集到特征提取:完整流程的每一步细节
2.1 数据怎么来、怎么进MATLAB:CSV和Excel导入的实操细节
好多人卡在第一步:手里是一堆csv或者Excel表格,怎么倒腾到MATLAB里做FFT?这里给一个我常用的模板。如果csv文件第一行是列名,数据从第二行开始,采样率假设已知,用readmatrix读取最简单:
data = readmatrix('vibration_data.csv'); fs = 8192; % 采样率,单位Hz x = data(:, 2); % 假设第二列是振动加速度信号 x = x - mean(x); % 去掉直流分量读取Excel同理,用readmatrix也能直接读xlsx文件,但要注意readmatrix读txt、csv、xlsx都适用,读取后先确认数据的单位。加速度信号一般是m/s²或g,位移信号是μm,不同单位会直接影响到幅值谱的量级,但不影响频率位置判断。读进来以后第一件事就是画时域图看一眼,有没有野值、断点、饱和削顶。数据质量不过关,后面所有分析都是白搭。
预处理方面,我建议至少做两步:去均值和去趋势。去均值是为了消掉直流分量,不然FFT之后0Hz处会顶起一个巨大的谱线,把其他频率细节压得看不清。去趋势是为了消除传感器零点漂移或温漂造成的低频斜坡。/趋势项会污染低频段,让频谱在很低的频率处出现虚假的较大幅值。另外,如果采集的是非等间隔数据,比如某些历史数据时间戳不均匀,必须先用interp1做一次重采样,转成等间隔采样序列,否则FFT的解算是错的。
2.2 采样率和数据长度怎么定:一个能算清楚的工程问题
采样率的选择遵循奈奎斯特采样定理:采样率必须大于信号最高关注频率的两倍,工程上通常取关注频率上限的2.56倍以上,甚至5到10倍。比如你关心轴承外圈故障特征频率BPFO约100Hz,转频20Hz,那采样率取5120Hz已经绰绰有余;但如果还要分析故障冲击引起的结构共振频率,共振峰可能在几千赫兹,采样率就得拉高到20kHz以上。
数据长度决定了频率分辨率,也就是FFT频谱上相邻两根谱线的间隔。频率分辨率Δf = fs / N,N是参与FFT的采样点数。想分辨出BPFO=92.3Hz和BPFI=107Hz这两个只差15Hz左右的频率,频率分辨率至少要优于15Hz,最好能到1Hz。这意味着在fs=4096Hz时,N至少要4096点,也就是1秒数据。我自己做诊断时,谁跟我说“我就采了0.1秒数据”,那基本没法做精细分析,因为0.1秒只有409个点,Δf高达40Hz,特征频率附近全是糊的。
还有一点要提醒:补零能视觉上让谱线更密,但它不提高真实分辨率,只是把FFT结果插值画平滑了。判断频率分辨率是否够,只看实际采样时长T=N/fs够不够长。这是很多新手的误区。
2.3 VMD参数怎么选:K值和penalty alpha的调参思路
VMD调试的核心参数有两个:模态个数K和惩罚因子alpha。官方默认alpha=2000,但实际工程数据千差万别,照抄默认值容易出问题。
关于K值选择,我的做法是“扫描观察法”:固定alpha=2000,把K从2开始递增到8,每次分解后打印各模态的中心频率。如果某两组模态的中心频率越来越接近,或者出现一个中心频率特别低、波形几乎趋于0的模态,说明K已经给多了。反过来,如果K=3时某个模态的中心频率附近还能看到明显的双峰,说明这个模态里混了两种频率,K给少了。我一般在轴承振动数据上选K=4到6,齿轮箱数据由于啮合频率和边带复杂,K会取6到10。
alpha的物理含义是模态带宽约束,alpha越大,每个模态的带宽越窄,对噪声的容忍度越低;alpha越小,带宽越宽,模态里可能裹入无关频率。数据幅值量级不同,alpha的合适取值范围也会漂移。我的习惯是把信号先归一化到[-1, 1],再以alpha=2000为起点试,如果分解出的模态波形毛刺很多,就把alpha提高到5000;如果发现某个模态明显包含多个频率成分,说明带宽太宽了,也往大调;反之,如果模态被拆碎、出现虚假模态,就往小调,比如800到1000。
注意:VMD对初值和迭代次数也有感知,但一般影响不大。MATLAB从R2021a开始自带vmd函数,旧版本需要从作者主页下载官方的vmd.m文件放到路径下,调用方式是一样的。
2.4 对每个IMF做FFT:频谱图和功率谱密度图到底怎么画才算对
对VMD分解出的IMF做FFT,最需要注意的是幅值修正和画单边谱的规则。很多人在这一步画出的频谱幅值差了好几倍,不是因为算法错了,而是没搞清单双边谱和幅值修正。给一个我自己常用的标准模板:
function [f, amp] = single_side_spectrum(x, fs) N = length(x); X = fft(x); amp = abs(X) / N; % 双边幅值谱 freq = (0:N-1) * fs / N; f = freq(1:N/2+1); % 只取正频部分 amp = amp(1:N/2+1); amp(2:end-1) = amp(2:end-1) * 2; % 非直流和非奈奎斯特分量乘2 end直流分量(0Hz处)不乘2,奈奎斯特频率(即fs/2处,只有偶数N才有)也不乘2,其他非直流谱线乘2,这是因为做单边谱时把负频率的能量折回了正频。如果你用的是周期图法算功率谱密度,MATLAB里直接调periodogram即可:
% 加汉宁窗的周期图法功率谱密度估计,等效于频域平滑 [psd, f] = periodogram(x, hann(N), N, fs);至于功率谱密度和幅值谱的区别:幅值谱告诉你某个频率成分的幅值多大,适合找特征频率峰值;功率谱密度告诉你单位频带宽度里有多少功率,适合比较不同频段的能量分布。诊断时我还是习惯两个都看,先幅值谱找峰、对频率,再用PSD看噪声基底和边带能量。
关于加窗,我得特意说一句经验之谈。对原始信号做FFT时,数据截断造成频谱泄露,一般建议加汉宁窗或布莱克曼窗来压低旁瓣。但如果信号已经过了VMD分解,IMF是窄带信号,频谱泄露已经相对小了,加不加窗影响不大。我实际处理时直接对IMF做不加窗FFT,反而能保留更高的频率分辨能力。所以很多人都问“FFT到底要不要加窗”,我的答案是:加窗是缓解频谱泄露的手段,不是规定动作,要看你分析对象是什么。原始信号某一段做FFT,建议加窗;VMD分解后的窄带IMF做FFT,不加窗通常也没问题。
2.5 希尔伯特谱怎么看:瞬时频率编码了故障的“时间指纹”
对VMD分解出的某一个IMF做希尔伯特变换,可以得到它的解析信号,瞬时频率就是解析信号相位的导数,瞬时幅值就是解析信号的模。把所有IMF的瞬时幅值在时频平面叠加绘制,就是希尔伯特谱。
MATLAB里最省事的做法是用hht函数:
% 对第2个IMF绘制时频谱 hht(IMF(:, 2), fs);出来的图,横轴是时间,纵轴是频率,颜色深浅表示瞬时能量。看这种图,我最关注两点:第一,能量带是否随时间产生周期性间断,一段亮一段暗,亮的宽度和间隔能对应到某个故障特征周期;第二,频率是否随时间漂移,如果转速不稳,转频和故障特征频率都会跟着漂,HHT能画出这种漂移轨迹,这是FFT完全做不到的。
还要坦白一个HHT的固有毛病:端点效应。信号两端在做希尔伯特变换时,边界附近瞬时频率经常发散,出现向上或向下的“飞刺”。处理办法是在分析前对信号做镜像延拓,或者干脆把分析段两端的短暂过渡区去掉,只读取中间可信段。这个坑我踩过好几次,后面问题排查里再细说。
3. 一个能直接上手的轴承故障诊断案例
3.1 案例设定与数据说明
为了让大家能完全复现这段流程,我用一个仿真轴承信号来演示。设一个滚动轴承参数:滚动体数量Z=12,节径D=65mm,滚动体直径d=15mm,接触角α=0°,轴转速N=1200rpm,那转频fr=1200/60=20Hz。外圈故障的特征频率BPFO按公式算:
BPFO = (Z/2) × fr × (1 - d/D × cosα) = 6 × 20 × (1 - 15/65) = 120 × (50/65) ≈ 92.31Hz
也就是说,如果外圈上有一个局部损伤,每当滚动体滚过这个损伤点时,会产生一个冲击,理论上这个冲击的重复频率就是92.3Hz。我在MATLAB里模拟这样一段信号:一个20Hz的转频正弦分量,叠加一组按92.3Hz重复的衰减振荡冲击,冲击激起的结构共振频率取3000Hz,再叠加一定量的高斯白噪声。采样率fs=8192Hz,数据长度N=8192点,正好1秒数据。
为什么要造仿真数据?因为真实故障数据里你永远不知道“标准答案”,而仿真数据里每个成分都是我放进去的,跑完流程后拿结果跟标准值对比,才能真正检验这套方法的有效性。这也是我建议所有新手先做的事。
3.2 VMD分解实操代码与调参记录
对生成的仿真信号调用MATLAB自带vmd函数:
[IMF, res] = vmd(x, 'NumIMFs', 4, 'Alpha', 2000, 'InitMethod', 'peaks');我在K值上做了三次试算。K=3时,IMF1的中心频率在19.8Hz附近,代表转频;IMF2中心频率在92Hz附近,是我想找的BPFO频段;但IMF3的中心频率跑到2870Hz附近,里面同时包含了共振冲击和相邻的噪声频带,说明分解不够细。K=4时,IMF2依然稳定在92Hz,IMF3和IMF4把高频段拆成了两个窄带,一个落在1800Hz左右、一个落在2900Hz左右,边界更干净。K=5时,出现了一个中心频率为0.2Hz的模态,波形几乎是一条平线,这就是典型的过分解虚假模态。所以最终选K=4。
alpha方面,我把信号归一化到[-1,1]后,alpha=2000分解出的IMF2包络还比较光滑,不用额外调整。如果你的实测信号噪声更大,可以把alpha调到3000到5000,让模态带宽更窄,减少噪声混入。要注意的是,alpha调大后计算时间会明显上升,这是正常现象。
3.3 各模态FFT频谱:找到故障特征频率及其倍频
分解完成后,我对IMF2做FFT,幅值谱上能看到三根清晰的谱线:92.3Hz、184.6Hz、276.9Hz,分别对应BPFO的基频、二倍频和三倍频。谐波的出现意味着冲击不是纯正弦,而是周期性的瞬态冲击,这种“基频加整数倍频”的组合就是轴承外圈局部损伤的典型频谱特征。
再回头对比一下直接对原始信号做FFT的结果:92.3Hz处的谱峰被噪声抬高了很多,几乎看不出比旁边的谱线高多少;而VMD分解后,噪声被分割到其他模态,IMF2里信噪比大幅提升,BPFO基频的谱峰高度直接突出了近一个数量级。这就是为什么我总是说,FFT不是不中用,而是前面缺了一个好“切片工”。
另外,我还会顺手把IMF1的FFT也画出来,确认它确实是20Hz转频成分,并且没有出现明显的边带。如果在转频两侧看到间隔为BPFO的边带,说明外圈故障对转频产生了幅值调制,这也是故障的另一个佐证。
3.4 HHT时频图:把故障冲击的时刻与强度挖出来
用hht函数画IMF2的时频谱,你会看到一根稳定在92Hz左右、等间隔出现脉冲式亮带的频率轨迹。每个亮带对应一次滚动体滚过外圈损伤点的冲击,相邻亮带的间隔就是1/BPFO≈10.8ms。你再拿时域波形图核对一下冲击的位置,能发现冲击峰值的间隔与亮带间隔完全对应。
这种时间维度的验证,是单纯FFT给不了的。我在实际项目中发生过这样的事:FFT频谱上92Hz处明明有谱峰,但特征频率对应的能量在时间轴上时有时无,后来用HHT才发现故障冲击存在“间歇性”,并不是每圈都打,这直接影响了故障严重程度的判断——连续冲击比间歇冲击通常意味着更严重的损伤扩展。所以遇到这种情况,强烈建议多看一眼时频图。
3.5 特征判据小结:如何从结果给出“轴承坏了”的结论
把整个案例的结论梳理成故障判据,基本分三条。第一条,频域判据:IMF的FFT频谱在BPFO及其倍频处出现明显谱峰,且倍频次数越多、幅值越高,损伤通常越严重。第二条,时域判据:希尔伯特谱上冲击能量带重复间隔等于1/BPFO,说明冲击事件以特征频率周期重复。第三条,调制判据:如果转频两侧存在BPFO间隔的边带,或冲击幅值呈现某种周期性变化,说明损伤位置在承载区变化,常与内圈或滚动体故障相关。三条合起来,就可以比较有把握地给出外圈损伤的结论。
4. 实战中高频踩坑与排查速查表
4.1 VMD不收敛、长时间跑不完怎么办
现象是代码跑了几分钟还在迭代,或者提示达到最大迭代次数但模态仍然失真。常见原因有三个:数据太长、alpha设置过大、K值设置过大。解决办法也直接:把参与VMD的数据截短到0.5到1秒,比如从8192点截到4096点;或者把数据先降采样,但降采样前要保证奈奎斯特频率仍高于关注频率上限;再或者下调alpha到1000左右。VMD计算复杂度不低,几十万点数据跑一次就要好几分钟,不是机器不行,是这种算法天生就吃算力。我在做大批量数据批处理时,都是先写一个自动分段脚本,每段只取1秒数据做VMD,速度能快一大截。
4.2 频谱上全是刺,分不清边带和噪声怎么办
频谱上一堆乱七八糟的谱线时,先别急着怀疑算法,先检查预处理。首要检查是否去均值,其次检查是否存在野值点。野值在FFT里会表现为整个频段上的宽谱噪声抬升,一个削顶脉冲就能毁掉一整段分析。再就是VMD参数问题,如果IMF中心频率附近有明显毛刺,适当提高alpha让模态更窄,或者把数据加窗后再做FFT。还有一个排查技巧:把时域波形用包络谱再验证一次,包络谱对周期性冲击很敏感,故障特征频率会在包络谱上以清晰谱峰出现,这个可以作为旁证。
4.3 端点效应和模态混叠:绕不开的宿命问题
VMD和HHT都存在边界效应,信号两端分解出的模态容易失真。我在工程上常用的数招:第一,截取数据时前后各留一小段“掩护数据”,分析时只读中间段;第二,先做镜像延拓,把数据镜像翻转接到两端再分解,处理完再截掉延拓部分;第三,也是比较实用的一招,直接用分段重叠分析,对每一段取中间的稳定结果拼接。模态混叠则更多是K值没选好或者信噪比太低造成的,先把信号做一次带通滤波预处理,减少远离关注频段的能量干扰,再跑VMD,混叠概率会明显下降。
4.4 算得慢、内存爆:大数据量下如何做工程实用化
VMD和HHT离实时计算还有距离,这一点必须承认。我在做在线监测项目时,通常是这么分工的:嵌入式或PLC侧用FFT加包络谱实时计算特征频率幅值做粗报警;一旦报警触发,把原始波形上传到服务器或PC端,再用VMD-FFT-HHT做精细分析,输出证据链。跟FPGA打交道的朋友可能知道,Vivado里的FFT IP核能把FFT做到微秒级,但VMD是个迭代变分问题,目前想塞进小资源嵌入式芯片里并不现实。所以我的建议是:充分利用FFT做实时快筛,VMD-HHT做离线精判,两头兼顾,不要拿一台服务器死磕实时性,那是跟算法特性过不去。
5. 把这三件套用到更多场景:扩展思路与我的体会
5.1 从轴承到齿轮箱、电机与结构健康监测
这套流程不挑轴承这一个对象。齿轮箱故障里,啮合频率及边带分析同样适合VMD先把啮合频率、转频、故障边带拆开,再做FFT看边带间隔;电机故障里,电流信号的谐波分析也能套用:先把基波工频当作一个模态拆出去,剩余信号里的故障特征频率会暴露得更清楚。还有一些非设备场景,比如一段时间内卫星信号信噪比数据集的趋势分析、风电塔筒振动监测、地震波数据处理,本质上都是“多分量+非平稳+噪声污染”,VMD-FFT-HHT的路子都能走通。我个人的经验是:只要数据里既有周期性又有非平稳性,这套流程大概率有用;如果数据本身就是平稳正弦叠加热噪声,那老老实实一个FFT就够了,不见得每次都要上VMD。
5.2 与机器学习结合:特征工程的新姿势
现在深度学习做故障诊断很火,但工程落地时我反而更喜欢“物理特征+浅层模型”的组合。VMD分解后天然能得到一组特征:各模态的能量占比、中心频率、峰值频率、幅度、包络谱特征、希尔伯特边际谱的特征频率幅值等。把这些整理成特征向量,丢给随机森林或SVM,模型小、可解释、不容易过拟合,而且只要特征物理意义明确,现场工程师也能理解。相比之下,直接把原始波形丢给CNN是精度高,但故障定位和故障机理的解释就成了黑盒,这在很多对严谨性要求高的行业里并不讨喜。如果你想在故障诊断方向做论文或产品,我建议把VMD-FFT-HHT当作特征提取前端,再接一个浅层分类器,效果往往比端到端网络更稳。
5.3 实测下来,这套流程的边界在哪儿
最后说点大实话。VMD-FFT-HHT不是万能的。第一,它对低信噪比数据的容忍度有限,如果故障信号比噪声低20dB以上,VMD也很难把特征频率从噪声里救回来,这时候得靠更定向的带通滤波或包络解调先行处理。第二,VMD参数选择带有一定人工经验色彩,不同人调出的K值可能不同,这会让结果在细节上有差异。第三,分析结果的物理判读仍然依赖人的经验,算法只是把证据摆到桌面上,最终判断还是得靠人对设备机理的理解。我的建议是,初次接触的朋友先在仿真信号上反复打磨流程,等参数手感培养出来,再上实测数据,这样踩坑成本最低。等这套流程用顺手了,你会发现它就像工具箱里的一把好扳手,未必天天用,但遇到难拆的活,它是真能救命。