% 幅值谱计算
Y = fft(signal);
Amplitude = abs(Y) / N; % N是信号长度
% 功率谱密度
PSD = abs(Y).^2 / (fs * N);
% 自功率谱
Auto_Power = abs(Y).^2 / N;
%% 振动分析中不同频谱类型对比
clear; clc; close all;
% 模拟旋转机械振动信号
fs = 2048; % 采样率
t = 0:1/fs:4-1/fs; % 4秒信号
N = length(t);
% 创建复合振动信号
f_rot = 25; % 转频25Hz
f_gear = 8 * f_rot; % 齿轮啮合频率(8齿)
f_bearing = 3.2 * f_rot; % 轴承故障频率
% 信号组成
x = 2.0 * sin(2*pi*f_rot*t) + ... % 转频分量
0.8 * sin(2*pi*2*f_rot*t) + ... % 2倍频
0.5 * sin(2*pi*f_gear*t) + ... % 齿轮啮合
0.3 * sin(2*pi*f_bearing*t) + ... % 轴承故障
0.1 * randn(size(t)); % 噪声
% FFT计算
Y = fft(x);
f = (0:N-1) * fs / N;
% 1. 幅值谱 (Amplitude Spectrum) - 最常用
Amplitude = abs(Y) / N;
Amplitude_single = Amplitude(1:N/2+1);
Amplitude_single(2:end-1) = 2 * Amplitude_single(2:end-1);
f_single = f(1:N/2+1);
% 2. 功率谱密度 (PSD)
PSD = abs(Y).^2 / (fs * N);
PSD_single = PSD(1:N/2+1);
PSD_single(2:end-1) = 2 * PSD_single(2:end-1);
% 3. 自功率谱 (Auto Power Spectrum)
Auto_Power = abs(Y).^2 / N;
Auto_Power_single = Auto_Power(1:N/2+1);
Auto_Power_single(2:end-1) = 2 * Auto_Power_single(2:end-1);
% 4. 对数幅值谱 (dB)
Amplitude_dB = 20 * log10(Amplitude_single);
% 可视化对比
figure('Position', [50, 50, 1400, 900]);
% 时域信号
subplot(3, 3, 1);
plot(t(1:1024), x(1:1024));
xlabel('时间 (s)');
ylabel('加速度 (m/s²)');
title('振动信号(前0.5秒)');
grid on;
% 幅值谱 - 线性坐标
subplot(3, 3, 2);
plot(f_single, Amplitude_single);
xlabel('频率 (Hz)');
ylabel('幅值 (m/s²)');
title('幅值谱(线性)');
xlim([0, 300]);
grid on;
% 幅值谱 - 对数坐标
subplot(3, 3, 3);
semilogy(f_single, Amplitude_single);
xlabel('频率 (Hz)');
ylabel('幅值 (m/s²)');
title('幅值谱(对数)');
xlim([0, 300]);
grid on;
% 功率谱密度
subplot(3, 3, 4);
plot(f_single, PSD_single);
xlabel('频率 (Hz)');
ylabel('PSD ((m/s²)²/Hz)');
title('功率谱密度');
xlim([0, 300]);
grid on;
% 功率谱密度 - dB
subplot(3, 3, 5);
plot(f_single, 10*log10(PSD_single));
xlabel('频率 (Hz)');
ylabel('PSD (dB)');
title('功率谱密度(dB)');
xlim([0, 300]);
grid on;
% 自功率谱
subplot(3, 3, 6);
plot(f_single, Auto_Power_single);
xlabel('频率 (Hz)');
ylabel('功率 ((m/s²)²)');
title('自功率谱');
xlim([0, 300]);
grid on;
% 频率检测对比
subplot(3, 3, 7);
% 使用幅值谱进行峰值检测
[peaks, locs] = findpeaks(Amplitude_single(f_single <= 300), ...
'MinPeakHeight', 0.1, 'MinPeakDistance', 10);
f_peaks = f_single(f_single <= 300);
f_detected = f_peaks(locs);
stem(f_detected, peaks, 'r', 'LineWidth', 2);
xlabel('频率 (Hz)');
ylabel('幅值 (m/s²)');
title('峰值检测结果');
xlim([0, 300]);
grid on;
% 理论vs检测频率对比
subplot(3, 3, 8);
theoretical = [f_rot, 2*f_rot, f_gear, f_bearing];
detected = f_detected(1:min(4, length(f_detected)));
bar_data = [theoretical; detected'];
bar(bar_data');
legend('理论值', '检测值', 'Location', 'best');
xlabel('频率序号');
ylabel('频率 (Hz)');
title('频率检测精度');
grid on;
% 应用场景说明
subplot(3, 3, 9);
text(0.05, 0.9, '振动分析频谱选择指南:', 'FontSize', 12, 'FontWeight', 'bold');
text(0.05, 0.8, '• 幅值谱: 故障诊断, 频率识别', 'FontSize', 10);
text(0.05, 0.7, '• PSD: 随机振动, 噪声分析', 'FontSize', 10);
text(0.05, 0.6, '• 自功率谱: 模态分析', 'FontSize', 10);
text(0.05, 0.5, '• 对数坐标: 宽动态范围', 'FontSize', 10);
text(0.05, 0.3, '检测到的主要频率:', 'FontSize', 11, 'FontWeight', 'bold');
for i = 1:min(length(f_detected), 4)
text(0.05, 0.25-i*0.04, sprintf('%.1f Hz', f_detected(i)), 'FontSize', 10);
end
axis off;
sgtitle('振动分析中的频谱类型对比', 'FontSize', 16, 'FontWeight', 'bold');
% 在命令窗口输出分析结果
fprintf('=== 振动分析结果 ===\n');
fprintf('信号参数:\n');
fprintf(' 采样率: %d Hz\n', fs);
fprintf(' 信号长度: %.1f 秒\n', N/fs);
fprintf(' 转频: %.1f Hz\n', f_rot);
fprintf('\n检测到的主要频率:\n');
for i = 1:min(length(f_detected), 6)
fprintf(' %.1f Hz (幅值: %.3f m/s²)\n', f_detected(i), peaks(i));
end
fprintf('\n频谱类型特点:\n');
fprintf(' 幅值谱: 直接反映振动强度, 单位与原信号相同\n');
fprintf(' 功率谱: 适合随机信号, 能量分析\n');
fprintf(' 对数坐标: 适合宽动态范围的信号\n');
% 典型的振动分析流程
% 1. 预处理
signal = detrend(raw_signal); % 去趋势
signal = signal - mean(signal); % 去直流
% 2. 加窗(减少频谱泄漏)
window = hanning(length(signal));
signal = signal .* window;
% 3. 计算幅值谱
Y = fft(signal);
Amplitude = abs(Y) / length(signal);
Amplitude = Amplitude(1:end/2+1);
Amplitude(2:end-1) = 2 * Amplitude(2:end-1);
% 4. 频率向量
f = (0:length(Amplitude)-1) * fs / (2*(length(Amplitude)-1));
对于你的旋转机械振动分析: