You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Octave的汽车振动FFT分析:代码验证与图表优化请求

嘿,我来帮你梳理下这段FFT代码的问题,顺便搞定图表优化的需求~

代码正确性验证与问题解决

1. 关于0Hz峰值的问题

首先要给你吃个定心丸:你的核心FFT流程是正确的!你已经做了sm = s - mean(s);这步去直流分量的操作,理论上已经消除了0Hz的偏移峰值。如果还是看到0Hz有明显峰值,大概率是这两个原因:

  • 你可能误把图最左端的0Hz点当成了异常峰值,其实去均值后这个点的幅值应该非常小,可以用disp(abs(FTs(1))*2)查看具体数值,确认是否接近0
  • 若0Hz幅值确实很大,建议检查原始数据s的均值mean(s),如果这个值本身就很大,说明采集的振动数据自带明显直流偏移,去均值操作已经在处理它了,你可以对比plot(t,s)plot(t,sm)的时域图,直观看到直流分量被去除的效果

2. 优化图表:仅显示200Hz以下数据

要实现这个需求,我们只需要对频率向量和对应的幅值数据做筛选,保留≤200Hz的部分即可,同时还可以优化图表的可读性。

修正后的完整代码

clc
% 读取振动数据
A = xlsread('50_dirt_road.xlsx');
t = A(:,9);
s = A(:,8);

% 采样参数(你提到采样间隔是0.001s,直接赋值比计算更准确)
Ts = 0.001; 
Fs = 1/Ts; % 采样频率为1000Hz
Fn = Fs/2; % 奈奎斯特频率500Hz
L = numel(t); % 数据总长度3395

% 去除直流分量(解决0Hz峰值的核心步骤)
sm = s - mean(s); 

% FFT计算与正频率提取
FTs = fft(sm)/L; % 归一化FFT结果
Fv = linspace(0, 1, fix(L/2)+1)*Fn; % 生成正频率向量

% 筛选200Hz以下的频率和幅值
target_max_freq = 200;
valid_idx = Fv <= target_max_freq;
filtered_freq = Fv(valid_idx);
filtered_amp = abs(FTs(1:numel(Fv))(valid_idx))*2; % 幅值翻倍还原实际值

% 查找峰值频率和幅值
[peak_amp, peak_idx] = max(filtered_amp);
peak_freq = filtered_freq(peak_idx);

% 绘制优化后的频谱图
figure
plot(filtered_freq, filtered_amp)
grid on
xlim([0, target_max_freq]) % 锁定x轴范围到0-200Hz
text(peak_freq, peak_amp, sprintf('\leftarrow %.4f G, %.0f Hz', peak_amp, peak_freq), 'HorizontalAlignment','left')
xlabel('Frequency (Hz)')
ylabel('Amplitude (G)')
title('Vehicle Vibration Frequency Spectrum (0-200Hz)')

关键改动说明

  • 固定采样间隔:你明确提到采样间隔是0.001s,直接赋值Ts=0.001mean(diff(t))更准确,避免时间数据的微小误差影响后续计算
  • 频率筛选:通过valid_idx = Fv <= target_max_freq精准筛选目标频段的数据,确保只显示200Hz以下的频谱
  • 图表可读性优化:锁定x轴范围、增加标题、给y轴加上单位,让图表信息更清晰
  • 幅值还原:对FFT正半部分的幅值乘以2,还原振动信号的实际幅值(FFT结果的正半部分幅值是实际值的一半,直流和奈奎斯特点除外)

内容的提问来源于stack exchange,提问作者Tomáš

火山引擎 最新活动