简介:面向通信工程与电子信息类专业毕业设计的 ISAC(通感一体化)论文解读与 Matlab 代码复现资源,围绕毫米波大规模 MIMO 系统中集成感知与通信的混合波束成形这一热点课题,给出从论文研读到代码实现的完整路径。资源包含 5 个核心 Matlab 脚本、1 篇配套论文 PDF 与 1 份说明文档,共 7 个文件,压缩包约 354KB,结构清晰,可对照混合波束成形等关键模块逐步理解算法流程。代码源自个人毕业设计,已在 Matlab 环境测试运行成功,答辩评审平均分达 96 分,目前已有 55 人学习。下载后建议先阅读说明文档掌握整体框架,再结合源码中的波束成形与集成感知通信实现进行复现,可逐步调试并验证算法性能;既适合需要完成毕设、课设或项目初期演示的高年级本科生与研究生,也适合希望入门通感一体化方向并开展二次开发的初学者。
1. 通感一体化与混合波束成形:ISAC 毕业设计为什么从源码入手更稳
ISAC(通感一体化,Integrated Sensing and Communication)在 6G 规划里不是可选项而是必选项——同一副毫米波天线要同时吞吐通信数据和雷达回波,传统“全数字”波束成形要求每根天线对应一条完整射频链路,64/128 单元阵列的硬件成本和功耗几乎不可接受。混合波束成形(Hybrid Beamforming)把波束成形拆成“少量射频链路的数字域预编码”加“大量天线的模拟域移相网络”两级,用工程可实现的折中结构逼近全数字性能,恰是 ISAC 系统里连接理论模型和硬件约束的关键技术。东南大学 SEU SISE 毕业设计公开的这份 ISAC 通感一体化资源,基于 Matlab 完整复现了 Qi 等 2022 年毫米波 MIMO ISAC 混合波束成形论文的仿真链路,压缩包包含主脚本、波束成形辅助函数和 README 文档,代码已测试可运行,适合通信、计算机相关专业的学生用于毕设复现和课程设计。这篇文章用一套可操作的阅读路径,把源码背后的系统模型、优化思路和落盘细节讲透。
2. ISAC 系统模型与混合波束成形的数学骨架
2.1 通信与感知共用一份发射信号
ISAC 发射端沿用经典多流发射模型:
x = F_RF · F_BB · s
其中 s 是 Ns×1 的符号向量,F_BB 是 Nrf×Ns 的数字预编码矩阵,F_RF 是 Nt×Nrf 的模拟波束成形矩阵。模拟端由移相器网络构成,F_RF 每个元素必须满足恒模约束 |F_RF(i,j)| = 1,这是混合波束成形优化区别于全数字设计的根本原因。
通信端,第 k 个用户接收:
y_k = H_k^H · x + n_k
H_k 是 Nt×Nr 的下行信道矩阵。毫米波信道常用 Saleh-Valenzuela 几何信道描述,由 Nc 个散射簇、每簇 Nray 条射线叠加:
H = sqrt(Nt·Nr/(Nc·Nray)) · Σ_{c=1}^{Nc} Σ_{l=1}^{Nray} α_{c,l} · a_r(φ_{c,l}) · a_t^H(θ_{c,l})
α 是复高斯路径增益,a_t 和 a_r 分别是收发阵列响应向量。以均匀线阵(ULA)为例,发送端响应为
a_t(θ) = (1/sqrt(Nt)) · [1, e^{jπ sin(θ)}, ..., e^{jπ(Nt-1)sin(θ)}]^T
针对大维度 Nt,直接循环双求和会非常慢。Matlab 实现里一般先对角度网格预计算导向矢量矩阵再取列索引,避免每次调用都重复计算指数:
function A = ula_response(theta_grid, N) % 均匀线阵导向矢量矩阵,theta_grid 为弧度制角度向量 n = (0:N-1).'; A = exp(1j * pi * n * sin(theta_grid(:).')) / sqrt(N); end参数说明:theta_grid 可以是扫描角向量(比如 -pi/2:0.01:pi/2),返回矩阵 A 的维度是 N×length(theta_grid)。在 ISAC 仿真里这一步通常只在初始化时做一次,后续波束图匹配和阵列响应都从 A 里取列或做矩阵乘法,能明显减少重复计算。
感知端接收的是发射信号的反射波。目标位于 θ_t,回波可写成:
z = β · a_t^T(θ_t) · x + n_rad
β 是包含路径损耗、RCS 的复反射系数。比较 y_k 和 z 两个式子会发现:通信期望信号指向用户方向尽量收敛,感知希望发射波束恰好在目标方向有足够增益,或者反过来在干扰方向放置零陷。F_RF 与 F_BB 被两套性能指标同时约束,这就是 ISAC 联合设计的耦合点。
2.2 感知性能的度量方式:波束图匹配还是 CRB
ISAC 文献里感知性能最常用三种度量,区别直接影响仿真里目标函数的写法:
| 感知度量 | 数学形式 | 实现难度 | 适用场景 |
|---|---|---|---|
| 波束图匹配 | min Σθ w(θ)· | P(θ)-P_d(θ) | ² |
| CRB(克拉美-罗界) | min Tr(CRB) 或 det(CRB) | 中 | 高精度测角、测距 |
| 雷达接收 SINR | max SINR_rad | 中 | 目标检测、恒虚警处理 |
P(θ) = |a_t^T(θ)·F_RF·F_BB|² 是实际发射波束图,P_d(θ) 是理想模板,w(θ) 可以给特定角度域的权重,比如主瓣区域权重大、旁瓣区域权重小。波束图匹配的代价函数是凸的,但嵌套了恒模约束后整体非凸。
CRB 度量则从估计理论出发。对单目标角度估计,CRB 正比于信号在目标方向的波束增益和有效孔径的倒数,数学上可以写成 FIM(Fisher 信息矩阵)求逆的对角元。在仿真里计算 CRB 需要先求 FIM,公式相对固定,但每次迭代都做一次矩阵求逆,复杂度明显高于波束图匹配。项目主脚本里如果目的是复现论文曲线,通常先用波束图匹配验证整体波束形状,再切到 CRB 看具体估计精度。
需要明确的是,Qi 等人的论文实际做的是联合优化:目标函数由通信频谱效率和感知 CRB 的加权和构成,权重系数 λ 从 0 到 1 扫描,得到通信-感知性能的帕累托前沿。这种写法比单一波束图匹配更贴近 ISAC 系统设计场景,也正是这个毕业设计代码里值得细读的地方。
2.3 为什么用交替最小化而不是直接联合求导
回到混合波束成形的约束:F_RF 恒模、F_BB 无约束但维度受 Nrf 限制,目标函数对两个变量联合非凸。常见做法是交替最小化:固定其中一个变量,优化另一个;两步交替迭代直到目标函数变化小于阈值。
交替优化的基本流程是:
- 初始化 F_RF 为 DFT 码本前 Nrf 列,或者按目标角度对应的导向矢量组合来初始化。
- 固定 F_RF,把 F_BB 视为无约束变量,用最小二乘或加权最小二乘解出 F_BB。
- 固定 F_BB,F_RF 的更新要求恒模,通常把无约束解投影回单位复圆:F_RF_new(i,j) = exp(1j·angle(F_RF_unconstrained(i,j)))。
- 计算新目标函数,若相对变化小于 tol(比如 1e-4)则停止,否则回到第 2 步。
投影回单位圆这一步是对“移相器只能改变相位”这个硬件约束的数学落实。代码里常见写法:
FRF = exp(1j * angle(X_train)); % X_train 是上一步无约束解注意 angle() 返回 [-π, π],exp 之后自动满足 |FRF(i,j)|=1。这个操作本身很简单,但在迭代后期,如果步长或初始化不当,相位在所有元素上同时跳变会导致目标函数震荡,所以仿真时要把迭代曲线打印出来观察是否单调下降。一般来说,交替最小化能收敛到局部最优,但 F_RF 的初始点决定了最终解的波束质量,同一个信道跑十次取最好结果也是毕设论文里常见的数据处理方式。
3. Matlab 源码逐模块拆解:主脚本、辅助函数与矩阵维度
3.1 资源包文件结构与建议阅读顺序
压缩包解开后是 ISAC-main 目录,核心文件就这几个:
| 文件 | 作用 | 运行优先级 |
|---|---|---|
| README.md | 环境要求、运行顺序、参数说明 | 必须先读 |
| Hybrid_Beamforming_ISAC.m | 仿真主脚本,涵盖信道生成、波束成形、绘图 | 先于其他 .m 运行 |
| beamforming.m | 波束成形辅助函数,可能包含全数字对比算法的实现 | 被主脚本调用 |
| try.m / my.m / untitled.m | 中途实验脚本,用于验证某个模块 | 单独调试时用 |
| Qi 等 2022 论文 PDF | 算法与公式的原始出处 | 对照阅读 |
我拿到任何仿真资源都先看主脚本的变量表和注释头,再看 README 里是否有 Matlab 版本或工具箱要求。这个项目对工具箱依赖很轻,主要用到了 Matlab 自带的矩阵运算、svd/pinv、绘图函数,R2020b 及之后版本即可运行。
建议的阅读顺序是:README → Hybrid_Beamforming_ISAC.m 的头部参数区 → 中间的主循环 → 最后回到 beamforming.m 看被调用的具体函数。try.m 和 untitled.m 一般是开发过程中的临时文件,只要确认它们不产生额外路径依赖,就可以忽略。
3.2 主脚本参数区:改哪些值会影响仿真结果
直接从主脚本里抽出最关键的参数:
%% 系统参数配置 Nt = 64; % 发射天线数量 Nrf = 4; % 射频链路数量 Ns = 2; % 数据流数量 K = 4; % 通信用户数量 L = 2; % 感知目标数量 SNR_dB = 10; % 通信信噪比 %% 角度设置 theta_comm = [-30, 0, 30, 60]; % 通信用户方向(度) theta_sens = [35, 110]; % 感知目标方向(度) %% 理想波束模板设置 main_beam_width = 10; % 主瓣半宽(度)这些参数之间的约束关系是:Ns ≤ Nrf ≤ Nt;用户数 K 会影响通信信道的行数,感知目标数 L 决定 CRB 矩阵的维度。theta_comm 和 theta_sens 通常要拉开角度间隔,否则通信波束和感知波束重叠,干扰太强,算法收敛后得到的帕累托平衡点表现会比较差。
调参时最容易踩的坑是 Nrf 设置过小。Nrf 代表数字域自由度数,小于 Ns 时 F_BB 无法满足秩约束,仿真会直接报矩阵秩不足错误;Nrf 等于 Nt 时混合结构退化成全数字结构,恒模约束不影响 F_BB,算法退化为普通数字预编码。要观察混合波束成形的价值,Nrf 应保持在 Nt 的 1/8 到 1/4 之间。
3.3 毫米波信道生成函数:维度错位多数出在这里
信道生成是整个项目报错率最高的位置。原因在于三维矩阵的维度极易错位:Nt、Nr、K、Nc、Nray 五个维度的乘法顺序,一不留神就把 H 的尺寸从 Nr×Nt 变成 Nt×Nr。
一般写成:
function H = generate_mmwave_channel(Nt, Nr, K, Nc, Nray, theta_comm) % 输入: Nt 发射天线, Nr 接收天线, K 用户数 % Nc 散射簇数, Nray 每簇射线数 % theta_comm 用户出发角度 (deg) % 输出: H 为 K×Nr×Nt 的三维复数矩阵 H = zeros(K, Nr, Nt); for k = 1:K Hk = zeros(Nr, Nt); for c = 1:Nc for ray = 1:Nray alpha = (randn + 1i*randn) / sqrt(2); theta = theta_comm(k) + 15*randn; % 用户方向加簇内偏移 at = exp(1i*pi*(0:Nt-1).'*sind(theta)) / sqrt(Nt); phi = 60*rand; % 到达角 ar = exp(1i*pi*(0:Nr-1).'*sind(phi)) / sqrt(Nr); Hk = Hk + alpha * ar * at'; end end H(k,:,:) = Hk * sqrt(Nt*Nr/(Nc*Nray)); end end参数说明:外层循环按用户展开,每个用户独立生成一个 Nr×Nt 的信道切片;内层是散射簇的组合叠加,alpha 满足零均值单位方差;at 和 ar 分别对应发射端和接收端导向矢量。sind() 接受度作为单位,很多“波形不对”的 bug 其实是一处用了 sin() 另一处用了 sind(),导致角度单位不一致,阵列响应直接偏掉。
这里 H 的输出维度设计成 K×Nr×Nt 而不是一层循环返回 K 个矩阵,是为了方便主脚本里随时取 H(k,:,:) 单独做用户级处理。判断信道生成是否正确,可以先打印 size(H),然后做一次发射功率归一化检查:norm(H(k,:,:),'fro')^2 应接近 Nr×Nt 量级,如果出现数值为 0 或 Inf,大概率是循环里某一步的维度塌掉了。
3.4 混合波束成形核心:从无约束解到恒模投影
主脚本调用的波束成形函数大致可以抽象成以下流程。先对通信信道做 SVD 取奇异向量作为理想数字预编码,再把理想解投影到混合结构上,交替迭代细化:
function [FRF, FBB] = hybrid_bf_isac(H, A_sens, Nrf, Ns, lambda, tol) % H : K×Nr×Nt 三维信道 % A_sens : 感知目标导向矢量矩阵, Nt×L % lambda : 通信权重 (1-lambda 是感知权重) [~, ~, V] = svd(squeeze(H(1,:,:))); % 以第一个用户做示例 F_opt = V(:, 1:Ns); % 全数字最优预编码 % 初始化:从最优预编码里取幅度最大的相位方向 FRF = exp(1i * angle(F_opt(1:Nt, 1:Nrf))); for iter = 1:50 % 固定 FRF,解 FBB FBB = pinv(FRF) * F_opt; % 固定 FBB,更新 FRF(恒模投影) X = F_opt * FBB' / (FBB * FBB'); FRF = exp(1i * angle(X(1:Nt, 1:Nrf))); % 计算目标函数 P_actual = abs(FRF * FBB).^2; E_bf = norm(P_actual - abs(F_opt).^2, 'fro')^2; if E_bf < tol, break; end end end参数说明:svd 是全数字上限,F_opt 是它的前 Ns 列;pinv(FRF) 是最小二乘意义上的数字域求解,要求 Nrf ≥ Ns 才有唯一解;FRF 的更新公式 X = F_opt * FBB' / (FBB * FBB') 本质是解一个最小二乘问题的闭式解,再对 X 取相位完成恒模约束。
这段实现里最需要注意的是 F_opt 的列数:Ns 是数据流数,Nrf 是射频链数,如果 F_opt(:, 1:Nrf) 取了超出 Ns 的列,后面 FBB = pinv(FRF) * F_opt 的维度就会错乱。调试时建议在循环外加一行 assert(size(FRF,1) == Nt && size(FRF,2) == Nrf),把维度错误提前暴露出来。
4. 改参数、换场景、画对比曲线:从复现到二次开发
4.1 三处最低限度的参数改动
最低成本的改动是调整天线数、信噪比扫描范围和感知目标角度。把 Nt 从 64 改成 128,主瓣半功率宽度近似减半,CRB 也降低,但计算量几乎翻倍;把 SNR_dB 改成向量 -10:5:20,主脚本会输出频谱效率和 CRB 随信噪比变化的曲线,这份曲线图在毕设答辩里是最好讲的一页。
另一种有深度的场景改动是把单目标感知改成多目标。L 从 1 改到 3,CRB 矩阵从标量变成 3×3 的对角矩阵,FIM 的求逆从 1×1 变成 3×3,需要确认代码里的求逆操作用的是 inv() 还是 pinv()。常见做法是:矩阵为方阵且条件数良好时用 inv,条件数很差或维度不定时用 pinv。多目标场景下 FIM 的秩可能不足,pinv 会更稳。
4.2 画论文同款对比曲线的 Matlab 写法
复现论文曲线通常要对比三组:全数字最优(F_opt)、混合波束成形(FRF*FBB)、纯模拟波束成形(只有 FRF,FBB 退化为标量或单位阵)。只需在同一个信噪比循环里多算两组:
SNR_dB_list = -10:5:20; for idx = 1:length(SNR_dB_list) SNR_dB = SNR_dB_list(idx); % 全数字上限 se_full(idx) = compute_se(F_opt, H, SNR_dB); % 混合波束成形 [FRF, FBB] = hybrid_bf_isac(H, A_sens, Nrf, Ns, 0.5, 1e-4); se_hybrid(idx) = compute_se(FRF*FBB, H, SNR_dB); % 纯模拟 se_analog(idx) = compute_se(FRF, H, SNR_dB); end figure('Position',[100 100 420 320]); plot(SNR_dB_list, se_full, '--k', 'LineWidth', 1.5); hold on; plot(SNR_dB_list, se_hybrid, '-b', 'LineWidth', 1.5); plot(SNR_dB_list, se_analog, '-.r', 'LineWidth', 1.5); legend('全数字', '混合波束成形', '纯模拟', 'Location', 'northwest'); xlabel('SNR (dB)'); ylabel('频谱效率 (bit/s/Hz)'); grid on;compute_se 是频谱效率计算函数,核心是:
se = sum(log2(1 + |diag(W_MMSE·H·F)|² / (|其它项|² + σ²)))
用户间干扰的项在分母要保留,否则曲线看起来会异常平坦。具体到这个项目,beamforming.m 里应该已经实现了类似函数,主脚本只需把三种预编码轮流传进去。
4.3 改动量从 min 到 mid:把单目标扩展成多目标感知
比调参数复杂一个级别的改动是把感知部分从波束图匹配换成 CRB 优化。改动点集中在目标函数部分:
% 原:波束图匹配误差 P_actual = abs(A_sens.' * FRF * FBB).^2; E_bm = norm(P_actual - P_d, 'fro')^2; % 改:CRB 加权项 FIM = compute_fim(A_sens, FRF * FBB, SNR_dB); CRB_loss = trace(inv(FIM)); J = lambda * se_loss + (1 - lambda) * (10 * log10(CRB_loss));改动的基本逻辑是先把波束图匹配误差换成 CRB,再把它放进和频谱效率同一个量纲的加权函数里。这里有个实际坑:CRB 数值通常很小(10^-3 量级),频谱效率是 10^0 量级,直接相加会造成感知项被忽略;常见做法是给感知项乘一个放大系数,或者对 CRB 取对数,保证两项在同一个数量级再叠加。
4.4 验证改动是否正确的三个检查点
跑完任何改动,先做这三件事。第一,打印最终波束图,肉眼确认主瓣指向 theta_comm 和 theta_sens 的方向,旁瓣不超过 -10 dB。如果主瓣指向错误,多半是阵列响应公式里的 sin/sind 混用,或角度单位没统一。第二,检查收敛曲线,把交替优化每步的目标函数值存下来,画出来应该是单调下降或在前几步快速下降后趋于平稳,如果震荡,把步长改成半程回退(目标函数上升时退回上一步)。第三,对比全数字界的差距。
| 检查项 | 指标 | 通过标准 |
|---|---|---|
| 波束图 | 主瓣指向 | 与 theta_comm / theta_sens 一致,旁瓣低于 -10 dB |
| 收敛曲线 | 每轮目标值 | 单调下降,最后两轮相对差小于 1e-3 |
| 与全数字差距 | 频谱效率比 | 5% ~ 20% 以内,且不低于全数字 |
混合波束成形的频谱效率应该略低于全数字,差距在 5% 到 20% 之间是正常的;如果差距超过 50%,说明 F_RF 的初始化方向有问题或迭代没收敛。感知性能(CRB)同理,混合结构比全数字高 2~3 倍属于常见区间,数量级一致即可。
5. 答辩前必查的复现细节:随机种子、内存与预计算缓存
5.1 随机种子与跨版本差异
把随机种子固定在开头(rng(42)),否则每次运行结果不一样,答辩时讲不清楚。不同 Matlab 版本(R2020b vs R2023b)在 svd() 的数值行为和 randn() 的实现细节上可能有细微差异,但 CRB 和频谱效率曲线一般不会差出可见距离。如果跑大参数集(Nt=128, Nrf=8, SNR 扫 7 个点)出现内存错误,把预计算变量转成 single 精度,或者把 H 的生成移到循环外,避免在每次信噪比迭代里都重新生成一次信道,能显著节省内存。
5.2 预计算缓存命名:让实验结果可以重复调用
把仿真结果保存到 .mat 文件,答辩演示时完全不用现场跑,避免现场卡顿或矩阵维度报错。通用存法:
save(sprintf('results_Nt%d_Nrf%d_seed%d.mat', Nt, Nrf, seed), ... 'se', 'crb', 'SNR_dB_list', 'theta_comm', 'theta_sens');再用 load 一个约定名称加载对比结果。比复制粘贴数据可靠,也比现场运行快一个数量级。命名里带上 Nt、Nrf 和 seed,是为了防止不同实验组之间互相覆盖;如果要跑权重扫描(lambda 从 0.1 到 0.9),把 lambda 也拼进文件名,这样所有帕累托点的数据都可以一次加载完成。
最后可以再核一遍功率归一化:F_RF·F_BB 的总发射功率应该约等于 Ns(或归一化为 1),如果偏差明显,检查 F_BB 的缩放因子。
本文还有配套的精品资源,点击获取