资讯动态

EEMD与MATLAB滚动轴承故障诊断:从IMF筛选到包络谱

发布时间:2026/10/26 5:08:56 来源:尧图企业网站定制
简介面向机械振动信号分析与轴承故障诊断学习者这套MATLAB代码实现了集成经验模态分解EEMD算法通过向原始信号叠加小幅白噪声并多次执行EMD再取平均抑制模式混叠与噪声放大把非平稳振动序列拆解为若干内在模态函数便于提取轴承内圈裂纹、滚珠磨损等异常特征频率。压缩包共11个文件约761KB以9个.m函数脚本为主体涵盖主程序入口、极值点与包络计算、IMF分量筛选、显著性检验及频谱变换等环节另附1个.mat实测振动数据与1个.asv备份文件可直接载入自有信号运行并做可视化对比。目前已有2034人学习下载适合具备一定MATLAB基础、希望从理论走到工程实现的高年级学生与设备监测工程师用作算法复现、参数调试与故障特征提取的参考范例。1. 从一坨糊谱里把故障冲击捞出来滚动轴承的早期损伤在振动信号里只表现为一串很弱的周期冲击被转频、结构共振和背景噪声压住直接做 FFT 看到的是一片糊谱故障特征频率根本浮不出来。EEMD集合经验模态分解在这个环节被大量使用它把原始振动自适应地拆成若干本征模态函数 IMF让冲击集中的那几层单独拿出来做包络解调包络谱上 BPFO、BPFI 这类特征频率才会露头。这份 MATLAB 程序包把 EEMD 分解、IMF 筛选、包络谱出图串成一条链路适合做设备状态监测的工程师直接套自己的数据也适合刚接触模态分解、想看清每一步中间结果的人。2. EEMD 的算法骨架与 MATLAB 落地噪声幅值、集合次数到底怎么定EEMD 被讲烂的一句话是「加白噪声再平均」但真到调参的时候九成的翻车都发生在这两个参数上噪声幅值系数 Nstd 和集合次数 NE。程序包里的主函数只是把这套流程封装好了参数还是得自己给。这一章先把 EMD 到 EEMD 的那两步改动说清楚再落到具体调用和返回值的形状上——后者是新手最容易卡住的地方因为不同实现的返回矩阵方向不一样。2.1 EMD 的筛分过程与模态混叠是怎么来的EMD 的核心动作叫筛分sifting对信号找全部极大值点和极小值点分别用三次样条拟合出上包络和下包络取两者均值 m1用原信号减掉 m1 得到一个候选分量 h1如果 h1 还不满足 IMF 的两个条件极值点与过零点数目相差不超过一个、上下包络局部均值为零就继续对 h1 重复这个过程直到满足为止这时得到 IMF1。剩下的残差再走一遍同样的流程依次拿到 IMF2、IMF3……直到残差变成单调函数或者只剩几个极值点。问题出在极值点的分布上。实测振动信号里如果存在间断性的冲击、短时突变或者脉冲噪声极值点的间隔会忽宽忽窄三次样条在稀疏区间会拟合出剧烈摆动的包络这个摆动会被当成信号本身的成分塞进 IMF导致同一个 IMF 里混进了两个数量级不同的时间尺度——这就是模态混叠。表现出来就是 IMF1 里既有高频共振又有转频成分后面拿它做包络谱谱线被搅得没法判读。2.2 EEMD 只做两件事加噪集合与平均抵消EEMD 的处理思路很朴素既然极值点分布不均匀是混叠的根源那就人为把分布打匀。每次分解前给原信号叠加一组幅值很小的正态白噪声白噪声在整个频带上均匀铺开能把稀疏区的极值点补齐对叠加后的信号做一次完整 EMD得到一组 IMF重复 NE 次每次用不同的噪声样本最后把所有次同层的 IMF 逐点取平均。平均这一步是关键。白噪声的均值是零NE 足够大时各次噪声在平均中相互抵消剩下的就是信号本身的成分。噪声幅值和集合次数之间有个经典的经验关系这两个量的乘积大致落在 0.2 这个量级附近时分解结果的相对误差比较小。也就是说 Nstd 取 0.2、NE 取 100 是一组常见起点Nstd 取 0.1 时 NE 就得往 400 走反过来 Nstd 拉到 0.4NE 给 30 次也能收敛个大概。工程上没人愿意等几百次分解所以 Nstd 一般往 0.2 到 0.3 靠。参数含义常用取值调大的后果Nstd辅助白噪声标准差 ÷ 原信号标准差0.1 ~ 0.3混叠改善但残余噪声抬高底噪IMF 之间开始串NE集合平均次数50 ~ 200噪声抵消更干净耗时线性增长maxIMF最大分解层数6 ~ 10层数过多后几层退化成残差碎片maxSift单层最大筛分次数5 ~ 10过大易把 IMF 筛成纯正弦丢失冲击调制信息提示Nstd 是相对量不能按绝对值给。同一台设备换了量程或者换了传感器灵敏度绝对噪声幅值变了但 Nstd 该取多少基本不变因为它除的是信号自己的标准差。2.3 第一段能跑通的代码分解、IMF 矩阵与残差解压后的文件夹里一般有主函数和几个辅助函数先把路径挂上再拿一段自己的数据跑通。下面这段是最小调用骨架注意输入必须是列向量。% 挂载解压目录下所有子函数 addpath(genpath(pwd)); fs 20000; % 采样频率 Hz按实际采集设置改 S load(vib.mat); % 自己的振动数据文件 x S.vib(:); % 强制转成列向量行向量会让返回矩阵转置 x detrend(x); % 去线性趋势否则 IMF 末尾会被趋势项污染 x x - mean(x); % 去直流包络谱上 0 Hz 附近会干净很多 Nstd 0.2; % 噪声幅值系数 NE 100; % 集合次数 imf eemd(x, Nstd, NE); % 返回 N×K 矩阵每列一个 IMF从高频到低频 res x - sum(imf, 2); % 残差 原信号 - 全部 IMF 之和 fprintf(分解得到 %d 层 IMF残差能量占比 %.2f%%\n, ... size(imf,2), 100*norm(res)/norm(x));这段代码有三个地方值得说明。x(:)那一行不是洁癖是血泪经验多数第三方 EEMD 实现内部用size(x,1)判断长度传进行向量时它会当成一个 1×N 的信号分解结果的维度全乱后面sum(imf,2)直接报错新手往往在这里排查半天以为是算法问题。detrend也一样重要实测信号里常有传感器温漂造成的缓慢基线漂移不处理的话 EMD 会把这条趋势当成最低频的 IMF 提出来占掉一层分解名额。eemd的返回矩阵形状是整个链路的地基。列数 K 由信号本身的极值点分布决定同一台设备不同时间段采的数据K 可能差一两层所以后面所有按层取 IMF 的代码都不能写死列号得用判据自动选。残差单独算出来是有用的如果残差能量占比超过 10%通常意味着分解层数给少了故障冲击那部分还压在残差里没提出来。如果你的环境下这个包跑不起来换机器后缺函数、MATLAB 版本差异导致语法报错一份自包含的最小实现能顶上去不依赖任何工具箱function [imf, res] eemd_simple(x, NE, Nstd, maxIMF, maxSift) % EEMD 最小实现白噪声集合 EMD 筛分 同层平均 x x(:); N numel(x); sd std(x); pool cell(NE,1); for e 1:NE xe x Nstd*sd*randn(N,1); % 每次叠一组独立白噪声 pool{e} emd_core(xe, maxIMF, maxSift); end L min(cellfun((c) size(c,2), pool)); % 各次层数可能不同取最小对齐 imf zeros(N, L); for e 1:NE imf imf pool{e}(:,1:L); end imf imf / NE; % 平均抵消噪声 res x - sum(imf, 2); end function imf emd_core(x, maxIMF, maxSift) x x(:); N numel(x); imf zeros(N, maxIMF); r x; for k 1:maxIMF h r; for s 1:maxSift [lo, hi] env_spline(h); % 上下包络 m (lo hi)/2; if norm(m)/norm(h) 1e-3, break; end h h - m; % 筛分一步 end imf(:,k) h; r r - h; if sum(abs(diff(sign(diff(r))))) 4, break; end % 残差已单调 end end function [lo, hi] env_spline(h) N numel(h); t (1:N); imax find(h(2:end-1) h(1:end-2) h(2:end-1) h(3:end)) 1; imin find(h(2:end-1) h(1:end-2) h(2:end-1) h(3:end)) 1; hi spline_extra(t, h, imax, N); % 端点做镜像延拓压端点效应 lo spline_extra(t, h, imin, N); end function y spline_extra(t, h, idx, N) ti [2-t(idx(1)); t(idx); 2*N-t(idx(end))]; % 两端镜像点 hi [h(idx(1)); h(idx); h(idx(end))]; [ti, u] unique(ti); hi hi(u); y interp1(ti, hi, t, spline); end这份实现的重点不在性能在可读性。eemd_simple的四个参数含义和前面表格一一对应maxIMF默认给 8 层足够覆盖轴承信号的主要频带。env_spline里那段镜像延拓是端点效应的低成本对策在首尾各补一个对称的虚拟极值点样条就不会在边界处向外飞IMF 两端的发散幅度能压掉一大半。真要彻底解决端点问题得上极值点延拓或者神经网络延拓那是另一个话题。3. 轴承故障诊断的特征频率链路从转频到包络谱的四步EEMD 只是前端后面还得把 IMF 变成能判读的谱线。这条链路是算特征频率 → 选 IMF → 做 Hilbert 包络 → 看谱峰。四步里最容易出错的是第二步因为选错 IMF 之后包络谱仍然会出图只是图上那个峰跟故障没关系你会拿着噪声当结论上报。3.1 四类故障特征频率的算式与参数来源滚动轴承的四类典型故障对应四个特征频率外圈 BPFO、内圈 BPFI、滚动体 BSF、保持架 FTF。它们都由几何参数和转频决定公式里的 n 是滚珠数、d 是滚珠直径、D 是节径、α 是接触角。function f bearing_freq(fr, n, d, D, alpha) % fr 转频 Hzn 滚珠数d 滚珠直径 mmD 节径 mmalpha 接触角度 c cosd(alpha); f.BPFO n/2 * fr * (1 - d/D*c); % 外圈冲击重复频率 f.BPFI n/2 * fr * (1 d/D*c); % 内圈常伴随转频调制边带 f.BSF D/(2*d) * fr * (1 - (d/D*c)^2); % 滚动体自转频率 f.FTF fr/2 * (1 - d/D*c); % 保持架能量弱最难测 end四个式子里 BPFO 和 BPFI 用得最多因为外圈故障的冲击传递路径固定、幅值稳定包络谱上是一根干净的谱线内圈故障的冲击源随轴旋转会被转频调制谱线上表现为 BPFI 两侧各出现一根间隔为转频的边带这个边带特征反而是内圈故障的确认依据。参数来源必须准转频不能只看电机铭牌要用转速计实测或者从振动信号的转频谱峰反推滚动体打滑会让实际冲击频率比理论值低 1% 到 2%所以判读时要在理论值附近留一个 ±2% 的容差窗口别拿一根谱线去死磕小数点。3.2 IMF 筛选的三种判据与优先级分解出来的 IMF 少则五六层多则十几层不可能每层都做包络。常用的判据有三个可靠性从高到低排判据计算方式适用场景局限包络谱峰值比对每层做包络谱算特征频率处幅值 ÷ 谱线中位数已知轴承几何参数需要先算理论频率峭度kurtosis(imf(:,k))冲击成分强的早期故障对单个野点敏感纯噪声也可能峭度高相关系数与原信号的皮尔逊相关系数判断哪层保留了原始信息高频 IMF 天然相关低会误杀实操里我一般先用峭度粗筛出前两三层再对这几层分别做包络谱看谁在理论特征频率处的峰值比最高两个判据结果一致就用它。只有峭度没有包络谱验证是危险的因为一段纯噪声的峭度也可能很高。K size(imf,2); ku zeros(K,1); cc zeros(K,1); for k 1:K ku(k) kurtosis(imf(:,k)); % 峭度冲击性 cc(k) abs(corr(imf(:,k), x)); % 相关系数保真度 end [~, idxKu] sort(ku, descend); cand idxKu(1:min(3,K)); % 取峭度前三层做包络验证 fprintf(候选 IMF 层号%s\n, mat2str(cand(:)));这段代码的作用是把候选层压到三层以内避免后面无差别地对所有层做 Hilbert 变换。sort拿到的idxKu是层号索引cand直接拿去遍历。之所以取前三而不是取最大是因为峭度最大的那层有时恰好是一段局部干扰多留两层做交叉验证成本很低。3.3 Hilbert 包络解调与谱线判读包络解调的目的是把被高频共振载波携带的低频冲击重复频率解出来。轴承故障冲击激发的是结构的高频共振通常几千赫兹故障特征频率本身只有几十到几百赫兹直接看原始频谱只能看到共振峰看不到特征频率。取绝对值再低通、或者用 Hilbert 变换取解析信号的模就能把包络线提出来对包络线做 FFT 就是包络谱。fs 20000; for k cand env abs(hilbert(imf(:,k))); % 解析信号取模 包络 env env - mean(env); % 去直流否则 0 Hz 压倒一切 L 2^nextpow2(numel(env)); % 补零到 2 的幂加速 FFT E abs(fft(env, L)) / numel(env); f (0:L-1) * fs / L; band f 5 f 500; % 只看 5~500 Hz 的判读区间 [pk, ip] max(E .* band); fprintf(IMF%d 包络谱主峰 %.2f Hz峰值 %.4f\n, k, f(ip), pk); end几个参数值得掰开讲。2^nextpow2补零不改变频率分辨率真正的分辨率由信号时长决定采样 1 秒分辨率就是 1 Hz要区分 105 Hz 的 BPFO 和旁边 100 Hz 的干扰信号时长至少得 1 秒以上短于这个长度时补零只是把谱线画得更平滑两个峰还是糊在一起。band那个逻辑索引把 5 Hz 以下的直流泄漏和 500 Hz 以上的高频噪声都排除了判读区间按你的转频和特征频率范围调转频 25 Hz、BPFO 105 Hz 这种量级5 到 500 Hz 是合适的。归一化除numel(env)是为了让不同长度信号的峰值可比否则长信号算出来的幅值天然更大。判读的核心是「对表」把包络谱主峰频率和 3.1 算出来的理论值逐一对落进 ±2% 窗口且峰值比周围谱线高出一个数量级才敢下结论。只出一根不知道对应什么的峰说明选的 IMF 不对或者信号本身没有明显故障别硬解释。4. 拿仿真轴承信号做闭环验证一次可复现的端到端跑通手上的实测数据往往没有确定的故障标签跑完不知道对错。用一段已知参数的仿真信号把整条链路走一遍是最省时间的验证方式你清楚信号里埋的是 105 Hz 的外圈冲击就看代码能不能把它捞出来。捞不出来说明参数或流程有问题跟数据无关。4.1 构造带外圈冲击的仿真信号轴承故障信号的物理模型可以拆成三部分周期冲击序列、冲击激发的结构共振衰减振荡、以及背景噪声加转频分量。冲击重复频率就是 BPFO共振频率取几千赫兹衰减系数控制冲击的持续时间。fs 20000; T 2; N fs*T; t (0:N-1)/fs; fr 25; % 转频 25 Hz1500 rpm fo 105; % 外圈故障特征频率 Hz fn 3000; % 结构共振频率 Hz beta 800; % 衰减系数越大冲击越短促 imp zeros(N,1); for k 0:floor(T*fo)-1 idx round(k*fs/fo) 1; if idx N, imp(idx) 1; end % 每个故障周期打一个脉冲 end h exp(-beta*t) .* sin(2*pi*fn*t); % 单次冲击的共振响应 y conv(imp, h, same); % 冲击序列激励共振 y y 0.6*sin(2*pi*fr*t); % 转频分量制造干扰 y y 0.4*randn(N,1); % 背景噪声 y y / max(abs(y));这段仿真的关键在conv(..., same)。same 保证输出和输入等长脉冲位置不会因为卷积整体平移否则后面算出来的特征频率会有一个固定偏移你还以为是算法把频率算错了。beta控制冲击的衰减速度取 800 时冲击在 1~2 ms 内衰减完对应共振带宽大约几百赫兹这个带宽刚好落在 EEMD 第一二层的通带里是最理想的验证条件。转频分量故意加到 0.6 的幅值比冲击还强用来模拟真实工况里转频压过故障冲击的情况。4.2 从分解到包络谱的完整脚本把 2.3 和 3.3 串起来中间加上 IMF 筛选就是一条完整链路。下面的脚本可以直接存成 .m 文件跑输出会打印每一层的峭度和主峰频率。imf eemd(y, 0.2, 100); K size(imf,2); fprintf(分解层数 K %d\n, K); ku zeros(K,1); for k 1:K, ku(k) kurtosis(imf(:,k)); end [~, order] sort(ku, descend); for k order(1:min(3,K)) env abs(hilbert(imf(:,k))); env env - mean(env); L 2^nextpow2(numel(env)); E abs(fft(env, L)) / numel(env); f (0:L-1) * fs / L; band f 5 f 400; Eb E .* band; [pk, ip] max(Eb); % 峰值比主峰 / 判读区间中位数衡量谱线突出程度 ratio pk / (median(E(band)) eps); fprintf(IMF%d 峭度%5.2f 主峰%6.2f Hz 峰值比%6.1f\n, ... k, ku(k), f(ip), ratio); end跑通之后你应该看到峭度最大的那层通常是 IMF1 或者 IMF2在 105 Hz 附近有一根主峰峰值比在 10 以上。如果主峰跑到 25 Hz 去了说明选中的 IMF 主要装的是转频分量得往后一层找如果主峰在 3000 Hz 附近那是共振载波本身没解调干净检查hilbert之前有没有做去均值。4.3 参数敏感性改哪几个量结论会翻车仿真最大的价值是可以随便改参数看结果怎么变。下面这几个量是我反复试过的敏感点改完之后结论会明显不同改动结果变化结论beta 从 800 改到 200冲击拖长IMF 层数减少一到两层衰减慢的信号分解层数天然少别硬套层数经验Nstd 从 0.2 改到 0.02模态混叠回潮IMF1 里混进转频噪声太小等于没做 EEMD和 EMD 无异Nstd 从 0.2 改到 0.8IMF 层数虚增出现纯噪声层噪声过大把信号自身结构冲散了信号时长 T 从 2 改到 0.3105 Hz 主峰宽度超过 ±3 Hz分辨率不足理论值和干扰分不开NE 从 100 改到 10每次跑结果都不一样主峰位置漂平均次数不够噪声没抵消干净这张表里最值得记住的是 Nstd 的双向失效太小不起作用太大反而引入虚假分量。很多人以为噪声越大越「集合」实际上噪声幅值超过信号本身的 0.5 倍之后EMD 分解的主导成分变成了噪声信号被拆散在多个层里峭度最大的那层往往是噪声层。我一般把 Nstd 锁在 0.2需要提升稳定性就加 NE不去动 Nstd。另外提醒一句复现性问题如果没设随机种子同样的输入跑两次结果会有细微差别主峰频率可能差零点几赫兹。做对比实验前先rng(42)固定种子否则你会被自己上一轮的结论误导。5. 避坑与排查EEMD 在 MATLAB 里最常见的五个翻车现场这一章全是踩过的坑每条按现象、原因、解决办法写。有些坑看起来是算法问题实际是数据格式或者参数单位的问题排查顺序建议从数据开始往算法走。坑一IMF 两端剧烈发散画出来像喇叭口。现象是分解结果的 IMF1 首尾几十个点幅值暴涨比中间段大好几倍做包络谱时这两段会拖出一片低频噪声。原因在三次样条的端点信号两端没有极值点约束包络线会向外自由外推误差随筛分次数累积。解决办法有三个层次最省事的是分解后直接裁掉两端各 5% 的点再做后续分析中等成本是给样条加镜像延拓也就是 2.3 那份实现里spline_extra的做法彻底一点用极值点延拓或者支持向量回归延拓但代码量上去了。工程上裁点最常用只要信号长度够丢 5% 不影响频率分辨率。坑二每次运行结果都不一样主峰位置左右漂。现象是同一份数据跑两遍包络谱主峰从 105.2 Hz 跳到 104.6 Hz峭度排序也变了。原因有两个一是没固定随机种子每次叠加的白噪声样本不同二是 NE 给得太小噪声平均不充分。快速验证时 NE 给 20 也能出图但要下结论至少给到 100。解决办法是先rng(42)或者在循环里用固定种子的随机流再把 NE 提到 100 以上重新跑两遍确认结果稳定。如果提了 NE 还是漂检查 Nstd 是不是给得太小噪声幅值低于信号标准差的 5% 时集合平均基本没有改善混叠的效果。坑三分解层数给少了故障信息藏在残差里。现象是 IMF 全部做完包络谱上什么峰都没有但看残差波形能看到明显的周期冲击。原因是 maxIMF 设得太保守故障冲击所在的低频段还没被单独提取出来就停止了。判断依据是残差能量占比超过 10% 就说明还有结构没提干净。解决办法是把 maxIMF 从 6 提到 8 或 10重跑后看残差能量是否降到 5% 以下。反过来层数给太多也不行后几层会退化成几乎纯直流的碎片白白消耗计算时间还干扰 IMF 筛选的排序。坑四直接对原始信号做包络谱也能看到峰那还要 EEMD 干嘛。这是被问得最多的问题。原始信号直接做 Hilbert 包络确实有时也能看到特征频率因为共振频带本身就在信号里。但全带包络会把多个共振频带的调制结果混在一起谱线周围糊成一团弱故障的峰值被淹没。EEMD 的价值在于把不同频带的成分分开你能针对冲击集中的那一层单独解调信噪比提升是实打实的。解决办法不是抛弃 EEMD 改用全带而是先做带通滤波圈定共振频带常用快速谱峭度或者包络谱峭度图定中心频率再对滤波后的信号做 EEMD两步结合比单用任一步都稳。坑五输入是行向量返回矩阵维度全乱。现象是imf的大小变成 K×N后面按列取 IMF 拿到的是时间点的切片包络谱画出来是一条直线。原因是多数实现的长度判断写的是size(x,1)行向量会被当成 N 个通道的单点信号。这个问题排查起来最费时间因为不报错只是结果荒谬。解决办法是养成在入口处x x(:)的习惯同时用assert(iscolumn(x))在函数开头做一次断言。我现在的脚本模板里所有信号入口都强制转列向量宁可多写一行。注意eemd系列函数在不同实现下的参数顺序不统一有的签名是eemd(x, Nstd, NE)有的是eemd(x, NE, Nstd)。换包之后先看函数头注释确认顺序参数搞反时 Nstd 会被当成 100噪声幅值是信号的 100 倍分解结果全是噪声但程序不会报任何错。6. 把 EEMD 封装成可批处理函数一份自检清单与两个提速技巧单次分析跑通之后真正的活是批处理——一台设备一天几十个测点一个月上千条数据逐条手工跑不现实。封装成函数时要注意的点和单次分析完全不同核心是让每条数据的处理结果可比、可追溯。function out eemd_batch(files, opt) % files: 文件路径 cell 数组opt: 参数结构体 % 返回 table文件名、层数、选中层、主峰频率、峰值比、判定结论 if isfield(opt,seed), rng(opt.seed); end % 批处理内固定种子 rows cell(numel(files),1); for i 1:numel(files) S load(files{i}); x S.vib(:); x detrend(x); x x - mean(x); if numel(x) opt.minLen, continue; end % 太短的样本跳过 imf eemd(x, opt.Nstd, opt.NE); ku arrayfun((k) kurtosis(imf(:,k)), 1:size(imf,2)); [~, order] sort(ku, descend); best struct(ratio, 0, f, nan, k, 0); for k order(1:min(3,size(imf,2))) env abs(hilbert(imf(:,k))); env env - mean(env); L 2^nextpow2(numel(env)); E abs(fft(env, L)) / numel(env); f (0:L-1) * opt.fs / L; band f opt.fLo f opt.fHi; [pk, ip] max(E .* band); r pk / (median(E(band)) eps); if r best.ratio best struct(ratio, r, f, f(ip), k, k); end end hit abs(best.f - opt.fTarget) / opt.fTarget 0.02; % ±2% 容差 rows{i} {files{i}, size(imf,2), best.k, best.f, best.ratio, hit}; end out cell2table(vertcat(rows{:}), VariableNames, ... {file,nIMF,bestIMF,peakHz,peakRatio,isFault}); end参数结构体里fTarget是 3.1 算出来的理论特征频率fLo/fHi是判读区间minLen用来卡掉采集不完整的样本seed保证同批数据每次跑结果一致。arrayfun那行替代了显式 for 循环算峭度层数多的时候能省一点开销。输出的 table 直接能导 CSV方便和台账对上。两个提速技巧。第一fft之前用2^nextpow2补零长度是质数时 FFT 会退化到接近 O(N²)补零到 2 的幂这一行能让单次 FFT 快三到五倍批量跑的时候累积效果明显。第二EEMD 的 NE 次分解完全可以并行把for e 1:NE换成parfor四核机器上大致能压到三分之一耗时前提是循环体内不共享可变状态——我见过有人在 parfor 里往同一个全局变量累加结果每次跑出来的平均值都不一样排查了大半天。验证自己结果是否可信我习惯用下面这份对照表过一遍再出报告检查项通过标准不通过时的动作残差能量占比 5%提高 maxIMF 重跑峭度排序稳定性两次运行前三层一致提高 NE固定种子主峰峰值比 8换候选层或先带通滤波主峰与理论值偏差 2%核对几何参数与实测转频内圈故障的边带两侧间隔约等于转频检查谱分辨率是否够这套流程走过几十台设备之后我现在拿到任何一份振动数据都强制先跑一遍仿真闭环——用同一套脚本处理已知参数的仿真信号确认链路没坏再去碰实测数据。有一次换电脑后第三方包的路径没挂全emd内部调用了一个缺失的辅助函数MATLAB 用的是另一份同名旧版本分解结果看起来正常但包络谱主峰始终对不上理论值整整查了两天才发现是函数版本冲突。从那以后仿真验证这一步我再忙也不会跳。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑