通信算法之266: 无人机信号带宽计算

发布于:2025-04-21 ⋅ 阅读:(31) ⋅ 点赞:(0)

        pwelch 通常返回功率谱密度(PSD)和对应的频率向量。带宽的计算可能涉及到找到 PSD 的有效频率范围,比如半功率点(-3dB)或者根据信号的能量集中区域。

        pwelch 的参数设置,比如窗函数、重叠、FFT 点数,这些会影响频率分辨率。然后,求带宽的方法。半功率带宽是常见的,找到 PSD 下降到最大值一半的两个频率点,差值即为带宽。需要处理可能的多个峰值,所以先找到主峰的最大值,然后确定阈值,再寻找左右截止频率。

以下是通过 pwelch 输出计算信号带宽(以半功率带宽为例)的完整 MATLAB 代码,包含信号生成、功率谱计算和带宽分析:pwelch-bandwidth-calculation基于pwelch的带宽计算V1

生成 bandwidth_calculation.m

% 生成带通信号(中心频率50Hz,带宽20Hz)
Fs = 200;         % 采样率
T = 1/Fs;         % 采样周期
t = 0:T:1-0.005;  % 1秒信号
f0 = 50;          % 中心频率
B = 20;           % 真实带宽(用于验证)
x = cos(2*pi*(f0-B/2)*t) + cos(2*pi*(f0+B/2)*t) + 0.1*randn(size(t)); % 含噪信号

% 计算功率谱(使用pwelch)
window = hann(256);     % 窗函数
noverlap = 128;         % 重叠点数
nfft = 512;             % FFT点数
[Pxx, F] = pwelch(x, window, noverlap, nfft, Fs); % PSD和频率向量

% 计算半功率带宽(-3dB带宽)
[~, idx] = max(Pxx);            % 找到主峰位置
Pmax = Pxx(idx);                % 峰值功率
threshold = Pmax / 2;           % 半功率阈值

% 寻找左截止频率(下降沿)
left_idx = find(Pxx(1:idx) <= threshold, 1, 'last');
if isempty(left_idx), left_idx = 1; end

% 寻找右截止频率(上升沿)
right_idx = find(Pxx(idx:end) <= threshold, 1, 'first') + idx - 1;
if isempty(right_idx), right_idx = length(Pxx); end

% 线性插值优化频率精度
if left_idx > 1
    % 左边界插值
    y1 = Pxx(left_idx);
    y2 = Pxx(left_idx-1);
    f1 = F(left_idx);
    f2 = F(left_idx-1);
    f_left = f2 + (threshold - y2)*(f1 - f2)/(y1 - y2);
else
    f_left = F(1);
end

if right_idx < length(Pxx)
    % 右边界插值
    y1 = Pxx(right_idx);
    y2 = Pxx(right_idx+1);
    f1 = F(right_idx);
    f2 = F(right_idx+1);
    f_right = f1 + (threshold - y1)*(f2 - f1)/(y2 - y1);
else
    f_right = F(end);
end

bandwidth = f_right - f_left; % 计算带宽

% 可视化验证
figure('Color','white','Position',[100 100 800 400])
subplot(1,2,1)
plot(t,x), title('含噪带通信号'), xlabel('时间(s)'), ylabel('幅值')
subplot(1,2,2)
loglog(F, Pxx, 'b-', [f_left f_right], [threshold threshold], 'r--', 'LineWidth',1.5)
hold on
plot(F(idx), Pmax, 'ro', 'MarkerSize',8, 'MarkerFaceColor','r')
xlim([0 Fs/2]), ylim([1e-4 1e2])
title(sprintf('功率谱与带宽(计算值:%.2fHz,真实值:%dHz)', bandwidth, B))
xlabel('频率(Hz)'), ylabel('功率谱密度')
legend('PSD', '-3dB 阈值', '峰值点', 'Location','southeast')
hold off

代码说明:

  1. 信号生成:创建含噪带通信号(中心频率 50Hz,真实带宽 20Hz),用于验证算法
  2. 功率谱计算
    • 使用汉宁窗(256 点)和 50% 重叠
    • 频率分辨率:Fs/nfft = 200/512 ≈ 0.39Hz
  3. 带宽计算
    • 基于半功率点(-3dB)的插值算法
    • 处理边界情况(主峰靠近频域边缘)
    • 线性插值提升频率精度(误差 < 1 个频率点)
  4. 可视化
    • 同时显示时域信号和频域功率谱
    • 红色虚线标记 - 3dB 阈值,红点标记主峰
    • 标题显示计算带宽与真实带宽对比

该方案适用于:
✅ 单峰信号带宽分析
✅ 含噪信号的稳健带宽估计
✅ 需要频率精确定位的场景
(注:多峰信号需先分离主峰,可通过findpeaks函数预处理)

半功率带宽的定义:

        半功率带宽,也称为 - 3dB 带宽,是信号处理和系统分析中一个重要的概念。半功率带宽是指在功率谱密度(PSD)或幅度谱中,信号功率下降到其最大值的一半(即 -3dB)时所对应的频率范围。从频率响应的角度来看,它描述了系统或信号在频域中能够有效通过的频率范围。

计算方法

  • 基于功率谱密度(PSD)计算
    1. 首先,通过相关方法(如 Welch 方法等)计算信号的功率谱密度 P(f),得到功率谱密度随频率 f 的变化关系。
    2. 找到功率谱密度的最大值 Pmax​。
    3. 确定功率谱密度下降到 Pmax​/2 时所对应的两个频率点 f1​ 和 f2​,通常 f1​ 为较低频率点,f2​ 为较高频率点。这两个频率点之间的差值就是半功率带宽,即 B=f2​−f1​。
  • 基于频率响应函数计算
    • 对于线性时不变系统,若已知其频率响应函数 H(f),则先计算出幅度响应 ∣H(f)∣。
    • 找到幅度响应的最大值 ∣Hmax​∣。
    • 确定幅度响应下降到 ∣Hmax​∣/2​(因为功率与幅度的平方成正比,功率下降到一半时,幅度下降到原来的 1/2​)时所对应的两个频率点 f1​ 和 f2​,半功率带宽同样为 B=f2​−f1​。

        在实际计算中,可能需要通过插值等方法来更精确地确定 f1​ 和 f2​ 的值,特别是当离散的频率点不能恰好对应到半功率点时。

1. 基于半功率带宽(-3dB 带宽)的计算

该方法适用于已知信号功率谱的情况,通过找到功率谱下降到最大值一半的频率范围来确定带宽。

signal-bandwidth-calculation基于半功率带宽的信号带宽计算 MATLAB 代码

V1

生成 half_power_bandwidth.m

% 生成示例信号
fs = 1000; % 采样频率
t = 0:1/fs:1; % 时间向量
f1 = 50; % 信号频率
f2 = 150; % 信号频率
x = sin(2*pi*f1*t) + sin(2*pi*f2*t); % 信号

% 计算功率谱
nfft = 1024;
[Pxx, f] = pwelch(x, hamming(nfft), nfft/2, nfft, fs);

% 找到功率谱最大值
Pmax = max(Pxx);

% 计算半功率阈值
threshold = Pmax / 2;

% 找到半功率点对应的频率
idx = find(Pxx >= threshold);
f_low = f(idx(1));
f_high = f(idx(end));

% 计算带宽
bandwidth = f_high - f_low;

% 显示结果
disp(['半功率带宽: ', num2str(bandwidth), ' Hz']);

% 绘制功率谱
figure;
plot(f, 10*log10(Pxx));
hold on;
plot([f_low f_high], [10*log10(threshold) 10*log10(threshold)], 'r--');
hold off;
xlabel('频率 (Hz)');
ylabel('功率谱密度 (dB/Hz)');
title('信号功率谱及半功率带宽');
grid on;    

2. 基于能量百分比的带宽计算

该方法根据信号能量的一定百分比来确定带宽,例如包含 90% 能量的频率范围。

signal-bandwidth-calculation基于半功率带宽的信号带宽计算 MATLAB 代码

V2

生成 energy_percentage_bandwidth.m

% 生成示例信号
fs = 1000; % 采样频率
t = 0:1/fs:1; % 时间向量
f1 = 50; % 信号频率
f2 = 150; % 信号频率
x = sin(2*pi*f1*t) + sin(2*pi*f2*t); % 信号

% 计算频谱
nfft = 1024;
X = fft(x, nfft);
P = abs(X).^2 / length(x);
f = (0:nfft-1)*(fs/nfft);

% 计算总能量
total_energy = sum(P);

% 设定能量百分比
energy_percentage = 0.9;

% 按能量累积排序
[~, idx] = sort(P, 'descend');
cumulative_energy = cumsum(P(idx));
idx_90 = find(cumulative_energy >= energy_percentage * total_energy, 1);

% 找到对应的频率范围
f_range = f(idx(1:idx_90));
f_low = min(f_range);
f_high = max(f_range);

% 计算带宽
bandwidth = f_high - f_low;

% 显示结果
disp(['包含 ', num2str(energy_percentage*100), '% 能量的带宽: ', num2str(bandwidth), ' Hz']);

% 绘制频谱
figure;
plot(f, 10*log10(P));
hold on;
plot([f_low f_high], [min(10*log10(P)) min(10*log10(P))], 'r--');
hold off;
xlabel('频率 (Hz)');
ylabel('功率谱密度 (dB/Hz)');
title('信号频谱及能量百分比带宽');
grid on;    

代码解释

  • 半功率带宽计算:先产生示例信号,再用 pwelch 函数算出功率谱,找出功率谱最大值,设定半功率阈值,进而确定半功率点对应的频率,最终计算带宽并绘图展示。
  • 能量百分比带宽计算:先产生示例信号,通过 fft 算出频谱,计算总能量,设定能量百分比,按能量累积排序后找出包含指定能量百分比的频率范围,计算带宽并绘图展示。

网站公告

今日签到

点亮在社区的每一天
去签到