搞机械故障诊断的兄弟应该都遇到过这个场景:齿轮箱振动频谱里,转频谐波一片一片地立着,齿轮啮合频率的边带在周围张牙舞爪,而你真正想看的轴承外圈故障特征频率BPFO,被压得几乎看不见。更要命的是,设备转速还不稳定,今天25Hz明天23Hz,包络谱上本该在76Hz左右的峰值直接散成一团。今天要说的这个方法——带通滤波后的倒谱预白化,配合平方包络谱,就是专门用来对付这种变速工况下轴承故障检测的。文章末尾给出完整Matlab代码,拿到现场数据改个路径就能跑。
1. 变速工况下,传统包络分析为什么会失效?
1.1 包络分析的基本逻辑
先聊包络分析。滚动轴承的故障机理其实很直白:滚动体滚过缺陷时会产生一个瞬时冲击,激起轴承座、传感器安装处的结构共振——这个共振频率往往在几千赫兹甚至更高,远高于轴的转频。包络分析要做的事,就是把这个高频共振带里的冲击信号提取出来,再做一次频谱分析,看冲击的重复频率是不是落在轴承故障特征频率上。
具体做法是:先把原始振动信号做带通滤波,滤出共振频带;然后用Hilbert变换构造解析信号、取模得到包络;最后对包络做FFT,得到包络谱。包络谱就像一台“放大镜”,把高频冲击中的重复速率翻译成低频谱线。定转速下这套方法极其可靠,BPFO、BPFI这些特征频率上冒出一个尖峰,基本就能断定轴承出问题了。
这里有一个工程习惯要提醒:很多文章直接把包络不加平方就做谱分析,也能看。但在冲击型故障下,平方包络(即包络的平方)会把周期性冲击的基频成分抬得更明显,峰更尖锐。所以现代故障诊断中普遍推荐做平方包络谱(Squared Envelope Spectrum, SES),这也是标题里说的“平方包络谱”的来源。
1.2 定转速下的“黄金法则”
要判断轴承故障,就得先算清故障特征频率。以滚动体个数n、滚动体直径d、节圆直径D、接触角α、轴转频fr为参数,四种典型故障的特征频率如下:
- 外圈故障频率:BPFO = n/2 × fr × (1 - d/D × cosα)
- 内圈故障频率:BPFI = n/2 × fr × (1 + d/D × cosα)
- 滚动体故障频率:BSF = D/(2d) × fr × (1 - (d/D × cosα)^2)
- 保持架故障频率:FTF = fr/2 × (1 - d/D × cosα)
看出来没有?所有特征频率都和转频fr成正比。定转速下fr是个常数,所以故障特征频率是个固定值,在包络谱上表现为一根清晰的谱线。比如某型号轴承,fr=25Hz,BPFO=3.048×fr=76.2Hz,那你在包络谱76.2Hz处看到尖峰,外圈故障就基本实锤了。这就是定转速下的“黄金法则”:特征频率固定,谱峰定位即诊断。
1.3 变速条件带来的三大麻烦
一旦转速开始波动,“黄金法则”就不灵了。第一,特征频率跟着转速漂移。25Hz时BPFO是76.2Hz,23Hz时就降到70.1Hz。整段信号内,这个峰从一个频率“扫”到另一个频率,做FFT包络谱时能量分散在宽频带上,原本清晰的谱峰被抹平成一个“土包”,肉眼很难和随机噪声区分开。
第二,确定性干扰成分太强。齿轮箱里齿轮啮合频率、轴的转频及其谐波,这些确定性信号的能量往往比轴承冲击高出好几个数量级。在包络谱里,它们表现为大量离散谱线和边带,把轴承特征频率的弱小尖峰淹没。第三,现场不一定有转速信号。要做真正严格的阶次跟踪或同步平均,你得有键相或编码器信号,但很多现场设备根本不具备安装条件,这就迫使工程师想一些“不依赖转速”的办法。
倒谱预白化(Cepstrum Pre-whitening, CPW)就是在这个背景下被捡起来的。它不需要转速计,能自动把谐波簇、边带这类周期性干扰从信号里洗掉,让随机冲击成分浮出水面,恰好踩在这些痛点上。
2. 倒谱预白化技术拆解
2.1 先理解倒谱是个什么东西
倒谱(Cepstrum)这个名字本身就是把“频谱(Spectrum)”一词的前四个字母倒过来,中文叫“倒谱”。它的定义很直接:对信号的幅度谱取对数,再做一次逆傅里叶变换,得到的就是倒谱:c(τ) = IFFT( log|X(f)| )。这里自变量τ的单位是时间,但意义已经不是普通时间了,工程上叫倒频率(quefrency)。
理解倒谱最好的方式,是用“频域里的频域”这个说法:如果对数幅度谱里有周期性的波动,比如每隔f_0 Hz出现一个峰,那这种周期性在倒谱里就会形成一个尖峰,对应倒频率1/f_0。打个比方:普通频谱是“时间信号里的周期”,倒谱就是“对数频谱里的周期”。齿轮啮合频率在频谱上立起一排等间距的谐波峰,经过倒谱变换后,会在固定倒频率处凝聚成一个刺眼的尖峰。这就像把一排树(频谱谐波)从侧面看上去,看到的是一个篱笆的影子(倒谱尖峰),篱笆的间距反而成了最显眼的信息。
2.2 预白化到底做了什么
倒谱预白化的操作非常朴素:把倒谱中除零点以外的所有值全部置成0,再用这个“裁剪后的倒谱”重构对数幅度谱,最后恢复成时域信号。严格说,重构后的对数幅度谱会变成一个常数,即原信号对数幅度谱的均值。取指数就得到一条“平谱”——所有频率的幅度都一样,这就是“白化”。再看原来的时域信号,它的确定性谐波成分没了,频谱像白噪声一样平坦,剩下的主要是随机冲击和宽带的非周期成分。
这里面的道理不复杂。确定性信号(转频、齿轮啮合频率及其谐波)在频谱上是一根根窄线,窄线在对数谱里构成周期结构,周期结构集中在少数倒频率点上,所以一剪刀下去就被清零。而轴承故障冲击是瞬态宽带信号,它的能量弥散在整个频带,在对数谱里没有明显的周期结构,倒谱中也没有集中的尖峰,所以白化后基本被完整保留。整个过程不需要任何转速信息,这正是它应对变速工况的核心优势。
2.3 为什么带通滤波要放在倒谱预白化之前
回到标题:带通滤波后的倒谱预白化的平方包络谱。这个顺序是经过实践验证的。如果直接对原始信号做CPW,那么低频强干扰(比如25Hz转频能量巨大)会在对数幅度谱里形成很大的动态范围,白化后这部分能量会被“摊平”到整个频带,反而抬高了噪声底。另外,带通滤波先滤掉共振频带外的噪声和无关能量,让CPW集中精力对付带内干扰,信噪比更高,白化效果更干净。
可以这么理解:带通滤波是“画个框”先把关注区域圈出来,CPW是“擦掉框里的干扰”,平方包络谱是“最后定案”。三者是一条流水线,顺序最好不要打乱。
2.4 变速工况下它依然有效的原因
变速工况最大的麻烦是特征频率时变。但注意,CPW处理的对象是“确定性周期成分”,不管转频是25Hz还是23Hz,只要是等间隔分布的谐波簇,在对数谱里都会形成周期结构,就会在倒谱里留下尖峰。转速漂移只会让这个尖峰稍微变宽,但不会让它消失,所以CPW对变速工况的鲁棒性很好。
相比之下,那些需要等角度采样的阶次跟踪方案,首先要解决转速测量问题,其次要把信号重采样到角域,流程复杂。CPW绕开了所有这些麻烦,直接在时域操作,简单高效。当然它也有局限——如果转速变化非常剧烈,冲击的重复频率已经不是近似周期性的了,那么平方包络谱里的峰同样会发散。这种极端情况通常要先做阶次跟踪,把角域信号做出来,再配合CPW使用。CPW不是银弹,但它是变速诊断链条里非常值钱的一环。
3. 三步流程实操:带通滤波 → 倒谱预白化 → 平方包络谱
3.1 第1步:确定带通滤波频带
这一步的核心是找到轴承冲击激发的共振频带。工程上最常用的自动工具是快速峭度图(Fast Kurtogram),它会把信号在不同中心频率和带宽下分解,计算每段的谱峭度,峭度最大的频带就是冲击最明显的频带。
不过很多现场工程师用得最多的还是经验选带:先看一眼频谱,找能量比较集中、和轴承座结构共振相关的频带,通常选在2000Hz到10000Hz之间。选带太宽会把噪声引进来,太窄又会漏掉共振能量的主体。固定带通滤波时建议用IIR滤波器,但一定要用filtfilt做零相位滤波,否则相位偏移会影响包络谱中谱峰的频率精度。我在示例代码里先用4阶Butterworth带通(2000-6000Hz),如果你的结构共振在不同频段,用Kurtogram自动算一次再替换参数就行。
3.2 第2步:倒谱预白化实现细节
倒谱预白化在Matlab里实现起来不到20行,却有几个细节会让很多人踩坑。一个是对数幅度谱里会有零值,直接log(0)会产生-Inf,所以代码里要加一个极小值eps再取对数,比如写 log_amp = log(abs(X) + eps)。
另一个细节是,重构对数幅度谱后,取指数时得到的可能是一个偏小的幅值,这没关系,因为随后会归一化,不影响频谱中故障特征频率的判读。更重要的是相位信息必须保留原始相位,否则逆FFT回到时域后信号会变成一种“伪随机”信号,包络谱里的周期性又会丢失完整性。这些细节看代码就懂了。
3.3 第3步:平方包络谱的“平方”妙处
得到预白化后的时域信号,紧接着做Hilbert变换,得到解析信号,再对模长取平方,就是平方包络:env = abs(hilbert(x)).^2。对env做FFT,取前半幅值谱,就得到平方包络谱。
为什么取平方?从信号检测的角度看,故障冲击产生的周期性调制在包络信号中表现为周期性波动,对包络取平方相当于平方律检波,能把冲击调制度的动态范围放大,让基频成分在频谱中更突出。相比直接对包络做谱分析,平方包络谱对微弱冲击的灵敏度更高,背景也更干净。需要提醒的是,平方包络里会有一个很大的直流分量(包络的均值),做FFT前最好把均值减掉,不然0Hz附近一大坨会污染低频段的可视化效果。
4. Matlab完整实现
4.1 核心函数:倒谱预白化
先把核心函数贴出来。这是一个独立的m文件,保存为cepstrum_prewhitening.m即可。
function xw = cepstrum_prewhitening(x) % 倒谱预白化:去除确定性谐波与边带成分,保留随机冲击 % 输入:x - 振动信号(行向量或列向量) % 输出:xw - 倒谱预白化后的信号(零均值、单位方差) x = x(:).'; % 统一为行向量 N = length(x); % 1. FFT得到复数谱 X = fft(x); % 2. 对数幅度谱,加eps防止log(0) log_amp = log(abs(X) + eps); % 3. IFFT得到实倒谱 cep = real(ifft(log_amp)); % 4. 将除零倒频外的所有倒谱值置零 cep(2:end) = 0; % 5. 正变换回对数幅度谱 log_amp_new = real(fft(cep)); % 6. 指数还原幅度谱,相位保留原始相位 X_new = exp(log_amp_new) .* exp(1i * angle(X)); % 7. 逆FFT回时域,归一化 xw = real(ifft(X_new)); xw = (xw - mean(xw)) / std(xw); end这里再解释一下为什么对cep做fft就可以重构对数谱:因为第4步把cep变成只在第一个位置有值,fft之后每个频率点的值是那个常数,等价于把所有频率点的对数幅度都设置为同一个值。取指数就是常数幅值,于是频谱被“抹平”了。
4.2 主流程代码
下面是完整主脚本,包含模拟信号生成、带通滤波、倒谱预白化、平方包络谱和对比绘图。模拟信号里我故意放了一个3300Hz的齿轮啮合频率加上转频边带,专门用来模拟“带内确定性干扰淹没轴承冲击”的场景。如果你的数据是现场采集的,把第2节换成load语句就行。
%% 带通滤波 + 倒谱预白化 + 平方包络谱:轴承故障检测流程 clear; close all; clc; %% 1. 系统参数 Fs = 25600; % 采样率 dur = 8; % 信号时长 N = Fs * dur; t = (0:N-1) / Fs; %% 2. 模拟信号 fr = 25; % 轴转频 BPFO = 3.048 * fr; % 外圈故障特征频率 % 2.1 低频转频谐波(带外干扰,可被带通滤除) x_low = zeros(1, N); for k = 1:4 x_low = x_low + 0.5 * sin(2*pi*k*fr*t + 0.5*k); end % 2.2 齿轮啮合频率GMF=3300Hz,带转频边带(带内确定性干扰) GMF = 3300; x_gear = 0.6 * (1 + 0.4*cos(2*pi*fr*t)) .* sin(2*pi*GMF*t + 0.3); % 2.3 轴承外圈故障冲击:共振频率4000Hz,指数衰减 f_res = 4000; alpha = 1500; imp_amp = 0.25; T_imp = 1 / BPFO; x_imp = zeros(1, N); t_cur = 0.02; while t_cur < dur idx = round(t_cur*Fs) + (1:1000); idx(idx < 1 | idx > N) = []; if isempty(idx), break; end t_rel = (idx - round(t_cur*Fs)) / Fs; x_imp(idx) = x_imp(idx) + imp_amp * exp(-alpha*t_rel) .* sin(2*pi*f_res*t_rel); t_cur = t_cur + T_imp; end % 2.4 合成 x = x_low + x_gear + x_imp + 0.05 * randn(1, N); %% 3. 带通滤波 [b, a] = butter(4, [2000 6000]/(Fs/2), 'bandpass'); x_bp = filtfilt(b, a, x); %% 4. 倒谱预白化 x_cpw = cepstrum_prewhitening(x_bp); %% 5. 平方包络谱(分别分析带CPW和不带CPW两种情况) env_bp = abs(hilbert(x_bp)).^2; env_bp = env_bp - mean(env_bp); SES_bp = abs(fft(env_bp, N)) * 2 / N; env_cpw = abs(hilbert(x_cpw)).^2; env_cpw = env_cpw - mean(env_cpw); SES_cpw = abs(fft(env_cpw, N)) * 2 / N; f_axis = (0:N/2-1) * Fs / N; SES_bp = SES_bp(1:N/2); SES_cpw = SES_cpw(1:N/2); %% 6. 画图对比 figure('Position', [100 100 1100 750]); subplot(2,1,1); plot(f_axis, SES_bp, 'Color', [0.6 0.6 0.6], 'LineWidth', 1); hold on; plot(f_axis, SES_cpw, 'b', 'LineWidth', 1.2); xlim([0 300]); xline(BPFO, '--r', 'BPFO'); xlabel('频率 (Hz)'); ylabel('幅值'); title('平方包络谱对比:灰色无CPW / 蓝色带CPW'); legend('带通+包络', '带通+CPW+包络', 'Location', 'northeast'); grid on; subplot(2,1,2); plot(t, x, 'Color', [0.7 0.7 0.7]); hold on; plot(t, x_bp + 2, 'b'); hold on; plot(t, x_cpw + 4, 'r'); xlim([0 0.2]); legend('原始', '带通滤波', 'CPW后'); xlabel('时间 (s)'); ylabel('幅值'); title('时域波形对比(上下平移2/4个单位便于观察)'); grid on;4.3 结果怎么判读
运行这段代码后,重点看第一幅图。没有做CPW的灰色谱线里,BPFO处可能只有一个不起眼的凸起,而做完CPW的蓝色谱线在76.2Hz处会出现一个清晰的尖峰。如果你把鼠标移到峰值附近,能读到频率和BPFO的理论值基本吻合,那么外圈故障的诊断结论就成立了。
实际数据判断时要记住三点:第一,看峰值是否落在特征频率的理论值上,允许有几赫兹的偏差(取决于转速波动量);第二,看是否同时存在特征频率的2倍频、3倍频谐波,这在轴承内圈故障里尤其重要;第三,对比同一数据不做CPW的结果,如果CPW能让目标谱峰明显变清晰,说明这个方法在你的场景下确实有用。另外,如果你的Matlab版本不支持xline函数,用 plot([BPFO BPFO], ylim, '--r') 代替即可。
5. 踩坑记录与排查技巧
5.1 常见问题速查表
处理过的数据多了,翻车场景无非就那么几类,我先用一张表总结,后面再逐个聊细节。
| 现象 | 可能原因 | 处理建议 |
|---|---|---|
| 包络谱目标频率处无峰 | 带通选带未对准共振频带 | 用Kurtogram重新选带 |
| CPW后噪声底抬高 | 选带过宽或带内噪声过大 | 收窄带通,或适当增加平滑 |
| 谱峰频率与理论值偏差大 | 转速波动、轴承参数不准确 | 偏差不大可接受,偏差大则需测转速或核实轴承参数 |
| BPFI处有峰但边带复杂 | 内圈故障的转频调制 | 检查BPFI ± fr边带,综合判断 |
| 短数据下谱峰展宽 | 频率分辨率不足 | 增加信号时长,或降低采样率(保持共振带在内) |
5.2 数据长度与频率分辨率的平衡
包络谱的频率分辨率等于Fs/N。如果信号时长太短,比如只有1秒,25600Hz采样率下分辨率只有1Hz,而故障特征频率本身只有几十赫兹,谱峰会被展宽,判读困难。我在代码里用8秒数据,分辨率0.125Hz,效果就很好。现场如果只能拿到短数据,可以考虑把采样率降下来(前提是保证共振频带在分析带宽内),或者用零填充FFT做插值,但这只是可视化手段,不能真正提高分辨率。
5.3 倒谱预白化后噪声被放大?大概率是选带问题
有一种情况我刚开始用CPW时也遇到过:做完预白化,频谱变得一片白,噪声底抬得一塌糊涂,故障特征反而看不清。回头一查,是带通滤波选带太宽,把大量无关频带的能量也放进来了。CPW对频带内的所有频谱成分一视同仁地“抹平”,于是原来被窄带谐波压制的噪声都冒出来了。
解决办法是先跑Kurtogram或谱峭度,尽量把带通收窄,只保留共振能量集中的子带。记住:CPW是“辣手摧花”,好信号坏信号一起白化,前置滤波的质量直接决定最终信噪比。
5.4 内圈故障为什么比外圈故障难检
外圈故障的冲击路径固定,冲击重复频率稳定,平方包络谱里目标谱峰很直接。内圈故障就不一样了,冲击发生在旋转的内圈上,载荷区不断变化,冲击幅度被转频周期调制,包络谱里除了BPFI外,还有大量以BPFI为中心、间隔为转频的边带。谱线一多,视觉上就乱。
处理内圈故障时,建议同时看BPFI及其一阶边带(BPFI ± fr),不要只盯着BPFI一根线。CPW对这种调制结构也有帮助,因为它会把齿轮等确定性干扰先洗掉,让内圈故障的边带结构更干净地暴露出来。
5.5 大幅快速变速的极端场景怎么做补充
CPW在转速缓变或小幅波动时表现很好,但如果是风电变桨这种大幅快速变速,轴承冲击的重复频率本身就在快速变化,静态FFT包络谱很难避免频散。这种时候我的习惯是把信号与转速信号联动:先用编码器测转速,做阶次跟踪重采样到角域,然后在角域上再做CPW+平方包络谱。CPW在这个链条里并不多余,角域重采样解决了“冲击间隔均匀化”的问题,CPW继续负责清除残余的确定性谐波和边带,两者配合起来比单独用任何一种都稳。
最后说点个人体会吧。我在实际项目里用过不少信号处理方法,倒谱预白化不是那种“换上就出奇迹”的银弹,但它在变速工况下给我的帮助确实超出预期。它最大的价值是省事——不依赖转速,不用装额外传感器,几行Matlab就能把困扰许久的谐波干扰洗掉。如果你手上有现场变速数据一直处理不出满意的包络谱,我建议你先别急着上各种复杂的深度学习模型,花一小时把CPW和平方包络谱这条链跑通,八成会有惊喜。后面有空我再写写CPW和阶次跟踪搭配使用的一些案例,这招在风电传动链上实测下来是真的能打。