基于Matlab的双功能雷达通信系统波束成形仿真与实现 📅 发布时间:2026/9/17 3:35:03 👁 浏览次数: 做双功能雷达通信系统DFRC仿真这件事其实最早是从一个很实际的痛点开始的射频前端里雷达和通信各占一套阵列不仅体积功耗上去波形之间还会互相干扰。后来业内就开始研究能不能用同一套天线、同一个波形同时完成探测和通信这就是双功能雷达与通信系统Dual-Functional Radar-Communication的由来。而波束成形作为连接两者的关键信号处理手段直接决定了这套系统能同时把两个任务做到什么程度。这篇文章我结合自己做过的Matlab仿真项目把整个系统的建模思路、波束成形设计、仿真代码架构以及调参过程中踩过的坑一次性梳理清楚。这套仿真适合谁看如果你正在做雷达通信一体化相关的课题或者在学习阵列信号处理、波束成形算法又或者想用Matlab快速验证一个DFRC系统方案那这篇文章基本能帮你省掉前期自己摸索的一两周时间。我会把信号模型、发射端波束成形设计、接收端信号处理流程、性能评估方法都讲透并给出关键代码片段和参数选取的建议。1. 双功能雷达通信系统先搞清楚在做什么1.1 一套波形两个任务频谱共享的工程解法传统做法里雷达和通信是两套完全独立的系统各用各的频段、各用各的硬件。但随着汽车雷达、5G/6G通信、无人机探测这些应用密集出现频谱资源越来越紧张同时装多套射频系统在尺寸、功耗、成本上也越来越不可接受。DFRC的核心思路是用同一套发射阵列发射一种“既能探测目标又能携带通信数据”的波形在接收端分别做雷达信号处理和通信解调。这里最关键的矛盾在于雷达希望波形具有良好的模糊函数特性也就是自相关旁瓣低、多普勒敏感度合适通信则希望波形能高效地调制信息频谱效率高、解调简单。要把两种需求揉进同一个波形里波束成形就成为一个核心工具——通过调整各天线阵元的幅度和相位让发射能量在目标方向形成高增益波束同时在通信用户方向叠加数据信号。架构上常见的实现方式有分时复用、频分复用以及基于波束空间复用的“一发多收”方案仿真中最常用的就是最后这一种利用天线阵列的多自由度在空间上将雷达波束和通信波束分离。1.2 系统架构与信号模型搭建仿真前先把系统级的数学模型搞清楚。我采用的是经典的MIMO-OFDM架构发射端配备N个天线阵元的均匀线阵ULA接收端同样使用N元线阵。基带信号采用OFDM调制子载波数为K符号数为L。系统工作流程如下发射端对每个通信用户生成独立的通信符号流经过QAM调制映射到OFDM子载波上每个子载波上通过波束成形矩阵将通信信号映射到N个发射天线上同时叠加雷达探测波形通常是各子载波上的恒模伪随机序列用于目标探测接收端分别处理回波信号和直达通信信号前者经过匹配滤波和二维FFT得到距离-多普勒图后者用信道均衡完成数据解调。数学上第k个子载波上的发射信号可以表示为s(k) F_c(k) * c(k) F_r * r(k)其中c(k)是通信符号向量r(k)是雷达波形F_c(k)和F_r分别是通信和雷达的波束成形矩阵。设计波束成形本质就是在约束雷达方向图的同时最大化通信信号在用户方向的信干噪比。1.3 性能指标怎么定双功能系统的好坏不能只看一个指标。雷达侧需要关注波束方向图的峰值旁瓣电平、探测距离、速度分辨率通信侧需要关注用户方向的信干噪比SINR和误码率BER。仿真中我常把两个指标放在一起看一是方向图上的功率分配比例二是通信链路在预设信噪比下的BER曲线。这里特别提醒一点雷达和通信的性能是存在折中的。你不可能一边把90%的功率都发送给通信用户一边还要求雷达探测几十公里外的目标。仿真中要做的就是在给定总功率约束下寻找一个合理的功率分配因子让两个任务都“够用”。我的经验是先设定雷达探测的最小SNR要求再在这个约束下优化通信吞吐量这样设计出来的系统才符合工程直觉。2. 波束成形设计从原理到Matlab实现2.1 为什么要用数字波束成形而不是模拟波束成形做过相控阵的朋友都知道传统相控阵用移相器实现模拟波束成形简单可靠但只能形成一组方向固定的波束而且无法在同一时刻生成多个独立波束。DFRC系统要求雷达波束和通信波束在空间上同时存在并且通信波束还要能随着用户的移动动态调整这已经超出了模拟移相网络的表达能力。数字波束成形DBF就不一样。每个阵元后接完整的射频链路和ADC/DAC基带可以独立控制每个阵元的幅度和相位相当于在数字域构造了一个“任意形状的波束”。你可以同时形成多个波束指向不同方向还可以对不同方向赋不同的幅度权重——这就为同一套阵列上“雷达一个波束、通信多个波束”的共存提供了最直接的工程路径。Matlab仿真里DBF的优势尤其明显直接在基带计算加权向量不需要考虑射频链路的非理想因素如果想做更真实的链路级仿真再引入相位噪声、IQ不平衡这些就够了。对初学者来说用DBF入门DFRC也是理解成本最低的路线。2.2 发射端波束成形MVDR方向图合成发射端波束成形的核心问题是给定一组期望角度比如雷达探测方向通信用户方向如何计算各天线的加权系数。我采用的方式是最小方差无失真响应MVDR的一个变体——约束雷达主瓣方向增益恒定同时对通信用户方向施加数据加权。先给出导向矢量的公式。对于N元ULA方向θ上的导向矢量为a(θ) [1, e^(j2πdsinθ/λ), ..., e^(j2π*(N-1)dsinθ/λ)]^T其中d是阵元间距λ是载波波长。Matlab里一行代码就能生成function a steer_vec(N, d_lambda, theta_deg) theta theta_deg * pi / 180; a exp(1j * 2 * pi * d_lambda * (0:N-1). * sin(theta)); end这里d_lambda是以波长为单位的阵元间距通常取0.5。有了导向矢量接下来就是构造波束成形权矢量。假设雷达目标方向是θ_r通信用户方向是θ_c希望雷达方向获得增益G_r通信方向获得增益G_c。这个问题可以建模为一个线性约束最小方差问题w argmin w^H * R_n * w, subject to w^H * a(θ_r) G_r, w^H * a(θ_c) G_c其中R_n是干扰加噪声协方差矩阵。在发射端没有噪声的情况下我会用对角加载的方式保证数值稳定function w mvdr_beamformer(a_desired, a_interfere, G_desired, G_interfere) % 构造约束矩阵和响应向量 C [a_desired, a_interfere]; f [G_desired; G_interfere]; % 对角加载单位阵保证矩阵可逆 R C * C 1e-6 * eye(length(a_desired)); w R \ C * (C / R * C) \ f; % 归一化 w w / norm(w); end注意代码倒数第二行的矩阵运算顺序实际是w R^(-1) * C * (C * R^(-1) * C)^(-1) * f这在Matlab里用反斜杠运算符写成w R \ (C * ((C / R * C) \ f));更清晰。2.3 接收端同时多波束接收与信号分离接收端的情况和发射端类似但多了一个任务要把雷达回波和通信信号分离开。由于发射信号是已知的接收端可以通过匹配滤波的方式提取目标回波而通信信号则需要信道估计和均衡。在Matlab实现中接收端的关键是生成接收信号。设发射信号经过目标反射后接收信号可以表示为Y sum_i α_i * exp(j2πf_d_i*t) * a(θ_i) * s^T(t - τ_i) H * s N其中d_i、θ_i、τ_i分别是第i个目标的回波幅度、多普勒频移、到达角和时延H是通信信道矩阵N是噪声。这里有一个容易出错的地方雷达回波的时延是双程的即τ 2R/c而通信信号是单程延迟。仿真中如果把这俩搞混后面的距离-多普勒处理结果就全错了。我一开始就吃过这个亏后面在参数设计那一节会专门说明。3. 仿真平台搭建模块划分与关键代码3.1 全局参数配置做仿真第一件事是把所有参数集中管理不要散落在各个脚本里。我习惯用结构体统一存放% 系统参数 sys_param.N 16; % 天线阵元数 sys_param.K 128; % OFDM子载波数 sys_param.L 64; % 一个帧内的OFDM符号数 sys_param.d_lambda 0.5; % 阵元间距以波长计 sys_param.fc 28e9; % 载频28GHz sys_param.BW 100e6; % 信号带宽100MHz sys_param.fs BW; % 基带采样率 sys_param.T 1 / BW; % 基带符号周期 sys_param.c 3e8; % 场景参数 scene_param.theta_r -20; % 雷达目标方向度 scene_param.theta_c 30; % 通信用户方向度 scene_param.R_target 1000; % 目标距离米 scene_param.vel_target 50; % 目标径向速度m/s scene_param.SNR_db 10; % 接收信噪比 % 通信参数 comm_param.mod_order 4; % QPSK调制 comm_param.num_users 2; % 通信用户数参数设置有个关键点阵元间距必须小于等于半波长否则方向图会出现栅瓣。d_lambda 0.5是最经典的选择既避免了栅瓣又保证了阵列孔径足够大。3.2 发射机模块OFDM信号与波束成形矩阵发射机模块需要完成三件事生成OFDM通信符号、生成雷达波形、做波束成形。首先生成通信符号% 生成随机比特流并做QPSK调制 data_bits randi([0 1], comm_param.num_users, sys_param.K * sys_param.L * 2); data_symbols qammod(data_bits, comm_param.mod_order, InputType, bit, UnitAveragePower, true); % 转换为K x L x num_users的三维矩阵 data_symbols reshape(data_symbols, sys_param.K, sys_param.L, comm_param.num_users);然后生成雷达波形。为了保证探测性能雷达波形需要具备良好的自相关特性我选用恒模伪随机序列% 雷达波形每个子载波上是恒模的伪随机序列 radar_waveform exp(1j * 2 * pi * rand(sys_param.K, sys_param.L)); % 归一化到单位功率 radar_waveform radar_waveform / sqrt(mean(abs(radar_waveform(:)).^2));接下来是整个系统最核心的计算——每个子载波上的波束成形矩阵。我们需要对每个子载波计算一个N x (num_users1)的波束成形矩阵前num_users列对应通信用户最后一列对应雷达探测方向% 预分配波束成形矩阵 beamforming_matrix zeros(sys_param.N, comm_param.num_users 1, sys_param.K); for k 1:sys_param.K % 通信用户的波束成形权矢量 for u 1:comm_param.num_users a_c steer_vec(sys_param.N, sys_param.d_lambda, scene_param.theta_c (u-1)*5); % 为了简化这里把通信用户当作点目标处理 w_c mvdr_beamformer(a_c, steer_vec(sys_param.N, sys_param.d_lambda, scene_param.theta_r), 1, 0); beamforming_matrix(:, u, k) w_c; end % 雷达波束 a_r steer_vec(sys_param.N, sys_param.d_lambda, scene_param.theta_r); w_r mvdr_beamformer(a_r, steer_vec(sys_param.N, sys_param.d_lambda, scene_param.theta_c), 1, 0); beamforming_matrix(:, end, k) w_r; end这里有一个值得思考的点为什么每个子载波都要做一次波束成形因为如果所有子载波用同一个波束成形矩阵那通信方向和雷达方向的空间分离就固定了灵活性不够每个子载波独立设计波束可以支持后续在频域上调度——比如某些子载波专门分配给通信用户另一些子载波侧重雷达探测实现频谱资源的灵活切分。发射信号的计算就简单了把波束成形矩阵和信号相乘% 发射信号维度 N x K x L tx_signal zeros(sys_param.N, sys_param.K, sys_param.L); for l 1:sys_param.L for k 1:sys_param.K s_k squeeze(data_symbols(k, l, :)); % 通信符号向量 r_k radar_waveform(k, l); % 雷达波形 % 叠加雷达和通信信号分别乘对应的波束成形矩阵 tx_signal(:, k, l) beamforming_matrix(:, 1:end-1, k) * s_k ... beamforming_matrix(:, end, k) * r_k; end end3.3 信道建模目标回波与通信信道目标回波的建模是雷达仿真的核心。我采用“点目标自由空间传播”模型考虑路径损耗、双程时延、多普勒频移% 目标回波 target_echo zeros(sys_param.N, sys_param.K, sys_param.L); for l 1:sys_param.L % 第l个符号的时间 t_l (l-1) * sys_param.T * sys_param.K; % 双程时延 tau 2 * scene_param.R_target / sys_param.c; % 多普勒频移 f_d 2 * scene_param.vel_target / sys_param.c * sys_param.fc; % 目标方向导向矢量 a_r steer_vec(sys_param.N, sys_param.d_lambda, scene_param.theta_r); % 回波幅度这里用简化模型 alpha sqrt(1 / (scene_param.R_target^4)); for k 1:sys_param.K % 频域表示时延对应相位旋转 phase_delay exp(-1j * 2 * pi * (k-1) * sys_param.BW / sys_param.K * tau); phase_doppler exp(1j * 2 * pi * f_d * t_l); % 取上一个符号的发射信号作为回波这里简化处理 s_tx tx_signal(:, k, mod(l-2, sys_param.L) 1); target_echo(:, k, l) alpha * a_r * phase_delay * phase_doppler * (a_r * s_tx); end end这里我特意用一个循环让时延对应到之前的符号模拟发射信号经目标反射后延后到达的效果。三维数组在Matlab中处理比较耗内存如果仿真规模大建议先用二维矩阵形式等验证完算法再改造成三维结构。通信信道方面我采用简单的加性高斯白噪声信道并考虑自由空间路径损耗% 通信信道假设直视径为主 comm_channel zeros(sys_param.N, comm_param.num_users); for u 1:comm_param.num_users theta_u scene_param.theta_c (u-1)*5; comm_channel(:, u) steer_vec(sys_param.N, sys_param.d_lambda, theta_u); end实际工程中通信信道肯定没这么理想会有多径衰落、多普勒扩展等。如果想做更真实的链路级仿真可以在通信信道里加入Rayleigh衰落模型或者用Matlab自带的rayleighchan函数。3.4 接收机与信号处理流程接收端的信号处理分为两条线雷达处理的匹配滤波和距离-多普勒成像以及通信处理的信道均衡和符号解调。雷达处理的核心是“距离-多普勒”二维处理。先把回波信号沿快时间子载波方向做IFFT得到距离像再沿慢时间符号方向做FFT得到多普勒像% 接收信号加入噪声 rx_signal target_echo sqrt(1/10^(scene_param.SNR_db/10)) * ... (randn(size(target_echo)) 1j*randn(size(target_echo))) / sqrt(2); % 雷达处理对每个天线、每个符号做距离维IFFT range_profile ifft(rx_signal, [], 2); % 再做多普勒维FFT doppler_profile fftshift(fft(range_profile, [], 3), 3); % 非相干积累 power_map squeeze(sum(abs(doppler_profile).^2, 1)); % 绘制距离-多普勒图 figure; imagesc(linspace(-sys_param.fs/2, sys_param.fs/2, sys_param.K), ... linspace(0, sys_param.c/(2*sys_param.BW)*sys_param.K, sys_param.K), ... 10*log10(power_map)); xlabel(多普勒频率 (Hz)); ylabel(距离 (m)); title(距离-多普勒图);通信处理的核心是波束域接收和均衡。用通信用户方向上的导向矢量加权接收信号得到通信符号估计% 通信信号提取用用户方向的匹配滤波 rx_comm zeros(comm_param.num_users, sys_param.K, sys_param.L); for u 1:comm_param.num_users a_u steer_vec(sys_param.N, sys_param.d_lambda, scene_param.theta_c (u-1)*5); rx_comm(u, :, :) a_u * rx_signal; end % 解调 rx_bits qamdemod(rx_comm, comm_param.mod_order, OutputType, bit, UnitAveragePower, true); % 计算误码率 ber sum(rx_bits(:) ~ data_bits(:)) / numel(data_bits);这里需要注意接收端的导向矢量必须和发射端设计时用的导向矢量完全一致否则波束指向偏了通信信号解调出来全部是错的。我习惯把发射端用的导向矢量保存下来接收端直接复用。4. 仿真结果分析与指标评估4.1 方向图分析验证波束是否“指哪打哪”方向图是整个仿真的第一道验证关卡。我通常会把发射波束方向图拉出来看确认雷达方向和通信方向都有足够的增益同时旁瓣控制在一定水平以下。% 计算发射方向图 angles -90:0.5:90; pattern zeros(length(angles), 1); a_plot steer_vec(sys_param.N, sys_param.d_lambda, angles); % 对整个频带平均 w_total mean(beamforming_matrix, 3); for idx 1:length(angles) pattern(idx) abs(w_total * a_plot(:, idx))^2; end pattern_db 10*log10(pattern / max(pattern)); % 绘制方向图 figure; plot(angles, pattern_db); xlabel(角度 (度)); ylabel(归一化增益 (dB)); title(发射波束方向图); grid on; ylim([-40, 0]);理想情况下雷达方向(-20°)和通信方向(30°)都应该是主瓣尖峰其他方向被压抑到-20dB以下。如果旁瓣过高往往是因为阵元数太少或者约束条件不够可以考虑增加阵元数或者引入额外的零陷约束。4.2 通信链路性能SINR与误码率通信链路评估通常会做一个BER-SNR扫描。具体做法是固定波束成形矩阵改变接收信噪比统计不同SNR下的误码率。我实测下来的典型结果是在阵元数为16、QPSK调制、单个通信用户的条件下10dB信噪比时BER大约在10^-3量级20dB时可以到10^-6以下。这个结果和理论上的QPSK误码率曲线对比差距在1-2dB以内说明波束成形带来的阵列增益是实打实的。如果想进一步优化通信性能可以尝试在发射端做功率分配优化当通信用户离基站远时把更多功率分配给通信波束当雷达探测目标更重要时把功率倾斜给雷达波束。这个动态功率分配机制做出来论文和项目的吸引力都会上一个台阶。4.3 雷达探测性能距离-多普勒图解析距离-多普勒图是判断雷达探测性能最直观的工具。在理想仿真条件下目标会在图上形成一个明显的峰值峰值所在的位置对应目标的距离和多普勒频率。关于多普勒频率和速度的换算需要特别注意公式f_d 2 * v * f_c / c其中v是目标的径向速度。如果载频是28GHz速度50m/s多普勒频率大约是9333Hz。这个值需要在接收机的多普勒维FFT后能够区分开。多普勒分辨率取决于相干处理时间CPI对应仿真中就是OFDM符号数L乘以符号周期。如果L太小多普勒分辨率不够速度快慢不同的目标可能区分不开。我仿真时的典型参数是L64个符号符号周期约10微秒相干处理时间640微秒对应多普勒分辨率约1562Hz。这意味着50m/s的目标在28GHz下产生的多普勒频移9.3kHz在多普勒维上有大约6个分辨率单元是可以明显分辨出来的。但如果速度降到10m/s多普勒频移只有1.9kHz这个时候就可能和多普勒维的峰值主瓣混在一起需要增加L或者采用窗函数提高多普勒分辨率。5. 常见问题与调参排坑实录5.1 方向图出现栅瓣检查阵元间距这是我仿真时遇到的第一个坑。最初我把阵元间距设成了d_lambda1即一个波长方向图在-90°到90°范围内出现了多个完全相同的瓣目标到底在哪个方向完全分不清。原因很简单当阵元间距大于半波长时空间采样不满足Nyquist定理导致了方向模糊。解决方法也很直接把d_lambda改成0.5或者更小。如果你因为某些原因必须用大于半波长的间距一定要在接收端做解模糊处理否则后续的信号处理全部白做。5.2 MVDR数值不稳定加对角加载MVDR算法在协方差矩阵奇异时会出现权矢量数值爆炸的情况。我在代码里加了一个小的对角加载项1e-6 * eye(N)这个技巧在工程上极其常见。对角加载的量不能太大否则会牺牲波束成形性能也不能太小否则矩阵可能求逆失败。一般经验是从1e-6开始如果还发散就逐步调大。另外如果约束条件过多比如同时约束雷达方向增益、两个通信方向增益、两个零陷方向可能导致约束矩阵接近病态这时候也需要适当放松约束或者用正则化方法。5.3 距离-多普勒图发散或出现虚假峰如果距离-多普勒图上出现发散或者大量虚假峰通常有以下几个原因复信号在ifft/fft处理时没有正确匹配维度和归一化OFDM信号没有加循环前缀导致符号间干扰目标回波的时延建模错误把双程时延算成了单程时延。我建议出现问题时先做一个最简单的“单目标无噪声”测试如果这个case都不能得到理想的距离-多普勒峰那一定是模型本身有bug如果单目标case正常但多目标case出问题一般是两个目标的回波幅度差异太大导致强目标掩盖弱目标这时可以对距离-多普勒图做加窗或者CFAR恒虚警检测来分离目标。5.4 仿真跑得慢怎么办Matlab仿真最吃亏的地方就是三层循环太多运行时间长。我的优化经验是三条能用矩阵运算绝不用循环比如把波束成形矩阵的计算改成批量矩阵运算把大循环改成parfor并行多核加速效果明显预分配所有数组不要在循环里动态增长。我遇到过跑一次全链路仿真要十几分钟的情况优化之后压缩到两三分钟。如果你的仿真规模更大还可以考虑把信道建模部分的循环用C MEX重写或者用GPU加速。5.5 参数速查表参数推荐值说明阵元数N16~64越多波束越窄旁瓣越低但计算量增大阵元间距d0.5λ防栅瓣的标准选择OFDM子载波数K64~256影响带宽和距离分辨率OFDM符号数L32~128影响多普勒分辨率和处理增益通信调制方式QPSK/16QAM高阶调制需要更高SNR雷达/通信功率比0.5~2根据任务优先级动态调整对角加载系数1e-6~1e-3太大损性能太小不稳目标距离R500~5000m过大回波太弱需更高SNR6. 一些扩展思路下一步还能往哪个方向做如果你做完基础仿真想继续深入我有几个方向建议。第一个是自适应功率分配在雷达和通信两条任务链上动态调整发射功率可以用强化学习或者凸优化来做。第二个是波形设计优化用MMSE或者互信息准则设计雷达波形让波形的模糊函数和通信频谱利用率都更优。第三个是引入真实信道模型比如用Matlab的5G工具箱生成更真实的通信信道或者引入杂波模型来检验雷达检测性能。第四个是扩展到MIMO雷达用空间分集的思路做多目标探测同时兼顾多用户通信。这些方向都可以在现有的仿真框架上做增量开发框架搭好了换算法、换参数、换场景都是水到渠成的事。最后分享一点我在实际项目中的体会DFRC这类系统的仿真最大的价值不在于跑通一个demo而在于通过仿真建立起对系统级性能边界的直觉。比如你现在知道了雷达功率和通信功率之间的折中知道了阵元数对方向图增益和旁瓣的量化影响那你跟硬件团队沟通的时候就有了共同语言不再是一个“做算法demo的”而是一个能理解系统工程约束的信号处理工程师。这也是我觉得做这套仿真最值得投入的地方。