平面波下阵列信号模拟及波束形成

0 阅读1分钟

平面波阵列信号模拟与波束形成

1. 问题背景

阵列信号处理的核心任务:多个传感器按一定几何位置摆放,通过时延对齐实现信号同相叠加,从而增强特定方向的信号、抑制其他方向的干扰。

平面波假设:当信号源距离阵列足够远时,波前可视为平面,各阵元接收的信号仅存在时延差异,波形本身不变。


2. 阵列模型

2.1 几何关系

        来波方向 θ
           ↘
            ↘    平面波前
    ─────────────⊥────────────→
    │      │      │      │
   [0]    [d]   [2d]   [3d]    ← 阵元位置
    x1     x2     x3     x4
  • 阵元间距:dd
  • 来波方向:θ\theta(相对于阵列法线,0°为垂直入射)
  • nn 个阵元相对于参考阵元的波程差ΔLn=(n1)dsinθ\Delta L_n = (n-1)d \cdot \sin\theta

2.2 时延计算

波程差转换为时间延迟: τn=(n1)dsinθc\tau_n = \frac{(n-1)d \cdot \sin\theta}{c}

其中 cc 为波速(空气中约343 m/s,水中约1500 m/s)。


3. 时延实现:整数 + 小数分离

实际处理的是离散采样信号,时延需要分解为整数部分小数部分分别处理。

3.1 整数时延:循环移位

将信号向量整体平移整数个采样点:

x_delayed = circshift(x, delay_integer);
  • delay_integer > 0:向后移位(延迟)
  • delay_integer < 0:向前移位(超前)

3.2 小数时延:一阶线性插值

小数时延无法直接移位,采用相邻两采样点加权近似:

x(tα)(1α)x(t)+αx(t1),0<α<1x(t - \alpha) \approx (1-\alpha) \cdot x(t) + \alpha \cdot x(t-1), \quad 0 < \alpha < 1

权重分配逻辑

  • α\alpha 越接近0:当前采样点权重越大 (1α)(1-\alpha)
  • α\alpha 越接近1:前一个采样点权重越大 (α)(\alpha)

4. 波束形成流程

原始阵列信号 → 估计来波方向 → 计算各阵元时延 
                                    ↓
                              整数时延(circshift)
                                    ↓
                              小数时延(线性插值)
                                    ↓
                              各阵元信号时延对齐
                                    ↓
                              同相叠加(求和)
                                    ↓
                              输出增强信号

5. 关键代码结构

5.1 时延计算模块

% 时延转换为采样点数
delay_samples = ((0:N-1)*d * sin(theta)/c) * fs;

% 分离整数和小数
delay_int = round(delay_samples);
delay_frac = delay_samples - delay_int;  % 范围: [-0.5, 0.5]

5.2 整数时延处理

x_int = circshift(x, delay_int(n));

5.3 小数时延处理(一阶权重)

if delay_frac(n) > 0
    % 向后插值:混合当前点与前一点
    x_shifted = circshift(x_int, 1);
    x_out = (1-frac)*x_int + frac*x_shifted;
else
    % 向前插值:混合当前点与后一点  
    x_shifted = circshift(x_int, -1);
    x_out = (1-abs(frac))*x_int + abs(frac)*x_shifted;
end

6. 验证思路

6.1 信号对齐验证

  • 输入:各阵元存在明显相位差的正弦信号
  • 输出:经正确方向时延对齐后,各通道波形应完全重合

6.2 方向扫描验证

  • 固定信号来波方向(如30°)
  • 遍历-90°~90°扫描,对每个方向做时延对齐+求和
  • 结果应在真实方向出现峰值,其他方向衰减

7. 代码与结果

7.1 完整代码

function delayed_signal = array_delay_beamforming(received_signal, doa, d, fs, c)

% ARRAY_DELAY_BEAMFORMING 对阵列接收信号进行时延波束形成

%

% 输入:

% received_signal - 阵列接收信号矩阵 [N_samples x N_elements]

% doa - 来波方向 (角度,单位度,相对于阵列法线方向)

% d - 阵元间距 (米)

% fs - 采样率 (Hz)

% c - 波速 (m/s,空气中约343m/s,水中约1500m/s)

%

% 输出:

% delayed_signal - 时延对齐后的信号 [N_samples x N_elements]

[N_samples, N_elements] = size(received_signal);

% 计算各阵元相对于参考阵元(第一个阵元)的时延

% 阵元位置: x = [0, d, 2d, ..., (N-1)d]

element_positions = -(0:N_elements-1) * d;

% 来波方向转换为弧度,并计算波程差引起的时延

% doa=0表示垂直入射(法线方向),doa=90表示端射方向

theta = doa * pi / 180;

% 时延: tau = (x * sin(theta)) / c

% 正值表示相对于参考阵元的延迟时间

delays = (element_positions * sin(theta)) / c;

% 转换为采样点数

delay_samples = delays * fs;

% 分离整数时延和小数时延

delay_integer = floor(delay_samples); % 整数时延

delay_fraction = delay_samples - delay_integer; % 小数时延 (-0.5 ~ 0.5)

% 初始化输出

delayed_signal = zeros(N_samples, N_elements);

for n = 1:N_elements

% 获取当前阵元信号

x = received_signal(:, n);

% ========== 步骤1: 整数时延 (直接循环偏移) ==========

x_int_delayed = circshift(x, delay_integer(n));

% ========== 步骤2: 小数时延 (一阶权重/线性插值) ==========

% 一阶近似: x(t - tau_frac) ≈ (1-tau_frac)*x(t) + tau_frac*x(t-1)

% 或者使用前后两个采样点加权

frac = delay_fraction(n);

if frac == 0

% 无小数时延

delayed_signal(:, n) = x_int_delayed;

else

% 一阶线性插值: 加权相邻两个采样点

% x_delayed[n] = (1-frac) * x_int[n] + frac * x_int[n-1]

% 注意: frac>0表示需要向后插值(延迟),frac<0表示向前插值(超前)

% 创建偏移一个采样的版本

x_shifted = circshift(x_int_delayed, sign(frac));

% 一阶权重相加

% |frac| 越接近0,当前采样点权重越大

% |frac| 越接近1,相邻采样点权重越大

weight_current = 1 - abs(frac);

weight_adjacent = abs(frac);

% 正小数时延: 向"过去"插值 (延迟)

% x(t-frac) ≈ (1-frac)*x(t) + frac*x(t-1)

delayed_signal(:, n) = weight_current * x_int_delayed + ...

weight_adjacent * x_shifted;

end

end

fprintf('来波方向: %.1f°\n', doa);

fprintf('阵元时延(采样点): ');

fprintf('%.3f ', delay_samples);

fprintf('\n');

end

%% ============ 使用示例 ============

clear; clc; close all;

% 参数设置

fs = 10000; % 采样率 10kHz

c = 343; % 声速 (空气中)

d = 0.05; % 阵元间距 5cm (半波长条件: d <= c/(2*f_max))

N_elements = 8; % 阵元数

N_samples = 512; % 采样点数

% 信号参数

f0 = 1000; % 信号频率 1kHz

doa_true = 30; % 真实来波方向 30度

SNR = 20; % 信噪比 dB

% 生成阵列信号

t = (0:N_samples-1)' / fs;

s = sin(2*pi*f0*t); % 原始信号

% 生成各阵元接收信号 (加入方向时延和噪声)

received_signal = zeros(N_samples, N_elements);

for n = 1:N_elements

% 计算该阵元的真实时延

tau_n = ((n-1)*d * sin(doa_true*pi/180)) / c;

delay_sample = tau_n * fs;

delay_int = round(delay_sample);

delay_frac = delay_sample - delay_int;

% 整数时延

s_delayed = circshift(s, delay_int);

% 小数时延 (一阶近似)

if delay_frac ~= 0

s_shifted = circshift(s_delayed, sign(delay_frac));

s_delayed = (1-abs(delay_frac))*s_delayed + abs(delay_frac)*s_shifted;

end

% 加噪声

noise = randn(N_samples, 1) / sqrt(10^(SNR/10));

received_signal(:, n) = s_delayed + noise;

end

% 测试不同来波方向的波束形成

doa_scan = -90:1:90; % 扫描角度

beam_output = zeros(length(doa_scan), 1);

for i = 1:length(doa_scan)

% 时延对齐

aligned_signal = array_delay_beamforming(received_signal, doa_scan(i), d, fs, c);

% 简单求和波束形成

beam_output(i) = mean(abs(sum(aligned_signal, 2)));

end

aligned_true = array_delay_beamforming(received_signal, doa_true, d, fs, c);

received_signal_plot = received_signal./max(received_signal, [], "all")/2 + (1:N_elements);

aligned_true_plot = aligned_true./max(aligned_true, [], "all")/2 + (1:N_elements);

% 绘图

figure('Position', [100 100 1200 400]);

% 原始阵列信号

subplot(1,3,1);

plot(received_signal_plot);

title('原始阵列信号 (未对齐)');

xlabel('阵元编号');

ylabel('时间采样');

% 时延对齐后的信号 (真实方向)

subplot(1,3,2);

plot(aligned_true_plot);

title(sprintf('时延对齐后 (DOA=%d°)', doa_true));

xlabel('阵元编号');

ylabel('时间采样');

% 波束形成方向图

subplot(1,3,3);

plot(doa_scan, 20*log10(beam_output/max(beam_output)), 'LineWidth', 2);

hold on;

xline(doa_true, 'r--', 'LineWidth', 1.5, 'Label', '真实方向');

xlabel('来波方向 (度)');

ylabel('归一化功率 (dB)');

title('波束形成方向图');

grid on;

xlim([-90 90]);

fprintf('\n真实来波方向: %d°\n', doa_true);

[~, max_idx] = max(beam_output);

fprintf('估计来波方向: %d°\n', doa_scan(max_idx));

7.2 运行结果

波束形成方向图

波束形成结果.png

8. 常见问题

问题原因解决
对齐后仍有残余相位差小数时延精度不足改用更高阶插值(sinc/FIR)
方向图旁瓣过高阵元数太少或间距过大增加阵元数,控制 dλ/2d \leq \lambda/2
峰值方向偏移时延计算误差累积检查角度转弧度、采样率单位

9. 扩展方向

  1. 高阶小数时延:使用sinc插值或FIR分数延迟滤波器,提高精度
  2. 自适应波束形成:根据干扰环境自动调整权重(MVDR/LCMV)
  3. 宽带信号:不同频率时延不同,需频域处理或抽头延迟线