
简介本资源面向电子信息、通信工程及应用数学等方向的本科生与科研初学者聚焦主动可重构智能表面RIS辅助的集成感知与通信ISAC系统提供波束成形联合设计与性能验证的完整MATLAB实现方案。包内共69个文件以49个核心.m脚本为主涵盖信道建模、RIS相位/功率联合优化、通信/雷达SINR计算、波束方向图绘制、可行性检验等模块辅以3个.mat数据集、2个.asv备份脚本及1个README.md说明文档整体压缩包仅2.5MB轻量易部署。已有70人学习下载代码采用高度参数化架构关键变量如RIS单元数、UE位置、发射功率约束均支持一键配置函数职责清晰、注释规范详尽并内置多版本兼容性处理适配MATLAB 2014a–2021a。用户可直接运行Main_MM.m等主程序复现论文级仿真流程快速掌握主动RIS在ISAC场景下的建模逻辑、凸优化求解思路与性能评估方法适用于课程实验、毕设课题及学术入门研究。 搞无线通信的这两年主动RIS和通感一体化这两个词出现的频率明显高起来了。前者用可编程超表面把无线环境变成可设计的变量后者想把通信和感知塞进同一套系统里两者凑在一起再加上波束成形设计基本就是一篇标准的6G前沿论文骨架。但论文归论文真想跑通一套“主动RIS辅助ISAC系统”的验证链路几乎所有坑都会集中在同一个地方MATLAB里怎么建模、怎么优化、怎么不跑飞。这篇文章就围绕一个能直接复现的项目把整个波束成形设计与性能验证过程完整拆开包括系统建模、交替优化算法、代码架构、蒙特卡洛实验以及我自己调参时踩过的几个典型坑。适合正在做相关课题的研究生也适合想从理论公式过渡到仿真验证的工程师参考。1. 项目背景与设计思路为什么会是这个组合1.1 ISAC的本质是把通信和雷达共用一个硬件平台ISACIntegrated Sensing and Communication通感一体化解决的核心问题很直白车载、无人机、智能家居这些场景下设备既要传数据又希望感知周围环境如果各做一套系统频谱和硬件都得双份。ISAC的出发点就是让发射波形同时承担两件事——调制信息的同时探测目标回波。落到设计方案时常见的主流做法有两类。第一类是通信导频或数据信号直接兼任感知信号接收端从回波里同时做信道估计和目标参数估计这样射频前端和频谱开销都省了第二类是给感知划出专用子载波或时隙感知和通信各自保留一定自由度代价是效率低一些。实际工程里前者更吸引人因为波形复用带来的增益最明显。但复用也意味着互相制约通信想要多用户速率高感知想要目标方向波束增益大这两个目标在同一个波束成形矩阵里往往互相拉扯这正是波束成形设计要解决的核心矛盾。1.2 主动RIS与被动RIS的差异不只是“能放大”这么简单可重构智能表面在过去几年已经被研究得很透但绝大多数工作用的还是被动RIS——每个反射单元只能调相位反射系数的模值最大为1物理本质是无源反射。被动RIS的优势是功耗低、实现简单但有一个致命限制它只是“把信号搬个方向”并不能补偿路径损耗。在实际毫米波场景下BS到RIS再到用户的级联链路经历两次路径损耗信号衰减非常夸张即使相位对准得很好终端信噪比也可能还不如直射路径。主动RIS的思路是在每个反射单元后端集成放大器让反射系数可以取模值大于1的值比如β_max 2甚至更高。你可以把它粗略理解成一面“会放大的镜子”信号反射出去的同时还被抬了一手功率。这样一来RIS不仅能补相位还能提供真正的功率增益对覆盖死角、弱直射场景帮助非常大。但代价也很现实每个有源元件都引入额外的热噪声和电路功耗放大器还有线性区限制建模时如果漏掉这些细节仿真结果就会过度乐观。从设计角度看主动RIS和被动RIS的数学区别就两处。一处是反射系数约束从|θ_n| ≤ 1变成了|θ_n| ≤ β_max且β_max 1另一处是接收端信号表达式里多出一项RIS引入的有源噪声而且这项噪声在优化RIS系数时不能当常数丢掉否则就失去了主动RIS“噪声放大”这一核心物理特性。1.3 波束成形在这个系统里扮演的角色在RIS辅助通信系统里波束成形其实是两层意义上的。第一层是基站侧的发射波束成形它决定每个数据流在空间上的功率分配与指向第二层是RIS的反射系数矩阵它通过调节每个单元的相位和幅度等效地改变级联信道的响应。这两层波束成形不是独立的。RIS侧调相位会同时影响所有用户和目标方向的等效信道基站侧调波束又会改变照射到RIS上的功率密度。所以严格意义上的联合波束成形必须同时优化两套变量。直接做联合优化的问题是非凸的很难保证全局最优工程上最常用的思路是交替优化Alternating Optimization, AO固定RIS系数优化基站波束再固定基站波束优化RIS系数如此反复迭代到目标函数收敛。这个思路简单、稳定、好复现也是我下面所有实现的核心骨架。2. 系统建模与指标定义2.1 发射信号与通信链路信号模型建模先定坐标系。假设基站有M根发射天线RIS有N个反射单元系统服务K个单天线用户同时有一个待感知的目标。基站发射信号写成x W s其中W是M×K的波束成形矩阵s是K×1的发送符号向量E[ss^H] I_K也就是各用户符号独立且归一化。基站总发射功率约束为 ||W||_F² ≤ P_max。对第k个用户而言接收信号由两条路径构成基站到用户的直射链路以及基站→RIS→用户的反射链路。写成表达式就是y_k (h_d,k^H h_r,k^H Θ G) w_k s_k Σ_{j≠k} (h_d,k^H h_r,k^H Θ G) w_j s_j n_k这里h_d,k^H是基站到用户k的直射信道维度1×MG是基站到RIS的信道维度N×Mh_r,k^H是RIS到用户k的信道维度1×NΘ是RIS的反射系数对角矩阵Θ diag(β_1 e^{jθ_1}, ..., β_N e^{jθ_N})n_k是用户k的加性高斯白噪声功率为σ_c²。式子里最核心的量是 h_r,k^H Θ G它表示信号从基站出发经过G到达RIS被Θ逐单元加权后再经过h_r,k^H到达用户。因为Θ能同时调节相位和幅度所以整个级联信道的等效响应是可以被塑造的这就是RIS能带来阵列增益的根本原因。2.2 主动RIS的反射模型与噪声来源主动RIS的反射单元和被动RIS最大的区别在于反射系数可以大于1。实际硬件上每个单元后面挂了一个低噪声放大器或功放反射信号的功率除了来自入射信号还额外注入了有源器件提供的能量。在MATLAB建模里我会用下面的形式定义ΘΘ diag(β_1 e^{jθ_1}, ..., β_N e^{jθ_N})其中 |β_n| ≤ β_maxθ_n ∈ [0, 2π)注意β_n是非负实数不是复数模约束里的任意相位。被动RIS可以看成β_max 1的特例。主动RIS的有源噪声必须单独建模。每个反射单元在放大信号时都会产生一个额外的热噪声分量这个分量经过反射后叠加到接收信号中。常见的建模方式是在RIS反射后增加一个N×1的噪声向量比如v_r Θ n_r其中n_r是RIS处N个有源器件引入的噪声假设服从均值为0、方差为σ_r²的复高斯分布。这样在用户接收端RIS引入的等效噪声功率大约为 ||h_r,k^H||² σ_r²。如果β_n取值很大这个噪声也会被放大很多初学者漏掉这一项导致主动RIS增益被严重高估。2.3 感知链路模型与目标波束增益感知链路的建模方式取决于你的系统是单站还是双站。这里用一个典型的单站ISAC场景基站发射信号信号经目标反射后一部分回波沿原路径被基站接收。目标方向的回波可以写成y_s a_s^T Θ G x n_s这里的a_s是RIS朝向目标的接收导向矢量维度N×1n_s是基站雷达接收机噪声。如果感知目标和通信用户位于不同方向感知任务本质上是让RIS和基站联合在目标方向形成高增益波束。为了评估感知性能我不想在第一步就引入复杂的CRB克拉美罗界推导更常用的做法是用“目标方向的波束增益”作为感知性能的度量。定义感知波束增益为P_s |a_s^T Θ G W|_F²它的物理含义是基站发射功率经过RIS反射后有多少能量照射到目标方向。P_s越大目标处的照射功率越强回波信噪比自然越高感知能力也越强。这个指标和阵列信号处理里的波束方向图本质上是一回事直观且容易解释。如果后续要做得更深入可以把P_s约束替换成目标参数估计的CRB约束或者感知互信息的约束但优化框架不会变只是性能指标表达式换一下而已。2.4 信道模型与性能指标信道建模我推荐直接用毫米波几何信道模型也就是每段信道用有限条路径的叠加来表示这样能体现出RIS辅助在高频段的价值。基站到RIS的信道G按常见的Saleh-Valenzuela模型生成G √(M N / L_G) Σ_{l1}^{L_G} α_l a_r(φ_l^r, θ_l^r) a_t^H(φ_l^t, θ_l^t)其中α_l是第l条路径的复增益a_r和a_t分别是RIS侧和基站侧的阵列响应向量。RIS侧阵列响应向量a_r与感知目标方向的a_s形式上是一样的区别只是角度不同。用户侧信道类似直射信道h_d,k和RIS到用户信道h_r,k都用多条路径叠加。如果场景想突出RIS的价值可以让直射链路存在较强的遮挡或路径损耗比如给h_d,k乘一个小于1的遮挡因子。这样对比“有RIS”和“无RIS”时结果更明显。性能指标分两部分。通信性能用可达和速率R_sum Σ_k log2(1 SINR_k)其中SINR_k由2.1节的接收信号模型直接推导。感知性能用2.3节的P_s或者归一化后的感知信噪比。评估一个设计方案好不好本质是在看R_sum和P_s之间的权衡曲线感知约束越紧通信速率牺牲越多主动RIS增益越大整体Pareto前沿越往外扩。3. 波束成形设计从联合优化到可实现的迭代算法3.1 优化问题描述与可行性分析现在把完整优化问题写下来。为了兼顾实用性和可实现性我用“最大化最差用户速率”作为通信目标同时保证感知波束增益不低于给定阈值。这个问题在文献里也很常用因为它能保证所有用户的服务质量比单纯最大化总速率更贴合实际。数学上写出来是max_{W, Θ} min_k SINR_ks.t. |a_s^T Θ G W|_F² ≥ Γ_s||W||_F² ≤ P_max|β_n| ≤ β_max, θ_n ∈ [0, 2π)这个问题的难点在于两处。第一SINR_k里有h_d,k^H h_r,k^H Θ G这样一个复合项W和Θ以乘积形式耦合在一起导致整个目标函数非凸。第二感知约束表达式也是W和Θ的耦合不是一个简单凸约束。联合求解几乎是不可行的至少对初学者来说想一步到位写出凸优化形式非常困难。所以我的方案是交替优化把联合问题拆成两个子问题每个子问题只针对一组变量另一组变量固定成上一次迭代的值。这样每个子问题的结构都更简单能套用现成的凸优化工具。3.2 交替优化的总体框架先画个整体流程初始化随机生成RIS系数Θ然后固定Θ求一个初始的W。第一子问题固定Θ优化W得到W_new。第二子问题固定W_new优化Θ得到Θ_new。计算当前目标函数值如果相对变化小于阈值停止否则回到步骤2。这个框架看起来很朴素但它有一个很好的性质如果每一步子问题都能让目标函数单调不降那么整个迭代过程一定是收敛的。实际跑下来通常20到50次迭代就能达到稳定每轮需要解两个小规模的凸问题计算开销完全在可接受范围内。在MATLAB里这正好对应一个外层for循环每次循环调用两个子函数。这种模块化结构也方便后面替换更高级的求解器或改用不同的性能指标。3.3 基站发射波束成形子问题固定RIS系数优化W固定Θ后第k个用户的等效信道记为h_k^H h_d,k^H h_r,k^H Θ G这时候接收信号变成y_k h_k^H w_k s_k Σ_{j≠k} h_k^H w_j s_j (RIS噪声项) n_kSINR_k的表达式为SINR_k |h_k^H w_k|² / (Σ_{j≠k} |h_k^H w_j|² σ_c² σ_r² ||h_r,k^H||²)这个式子关于W不是凸的但如果目标是最大化最小SINR可以转化成标准的SOCP问题。引入辅助变量t让每个SINR_k ≥ t经过简单变换后写成Σ_{j≠k} |h_k^H w_j|² σ² ≤ (1 1/t) |h_k^H w_k|²再加上总功率约束||W||_F² ≤ P_max就是一个二阶锥约束。直接用CVX求解非常方便。如果你更想优化总速率那就得用WMMSE加权最小均方误差方法在外面再套一层迭代。我在实际项目里前期用max-min公平性验证系统可行性后期换WMMSE方案看总速率上限两种结果趋势一致但WMMSE能榨出更多速率。3.4 RIS反射系数子问题固定基站波束优化Θ固定W后问题焦点转到RIS系数上。为了处理方便把Θ对角元提取成向量v [β_1 e^{jθ_1}, ..., β_N e^{jθ_N}]^T那么BS到用户k的级联信道可以重写成一个线性形式h_r,k^H Θ G v^T diag(h_r,k^H) G这样SINR_k以及感知项P_s都变成了关于v的二次型。感知波束增益写成P_s |v^T diag(a_s^T) G W|_F²这仍然是一个关于v的非凸二次约束二次规划而且v的可行域是盒约束|v_n| ≤ β_max。工程上有几种可行思路用SDR半定松弛把二次型松弛成半定规划然后通过高斯随机化恢复原解用MM最大-最小化或者SCA逐次凸近似把分子固定、分母线性化迭代求解用流形优化工具箱Manopt直接把相位和幅度当成流形上的变量处理。我在这个项目里优先用MM加SDR的组合因为它在多用户场景下稳定性很好。具体做法是在当前迭代点v_t附近把每个用户的SINR分母线性化把感知约束也线性化得到一个凸近似问题再用CVX求解更新v。如果迭代发现性能波动就改用Manopt直接做梯度优化收敛更快但代码量稍微多一点。3.5 收敛性与复杂度控制交替优化的收敛性有两点要特别注意。第一初始点很关键。如果初始Θ完全随机前期可能剧烈振荡但一般10次迭代后就会进入稳定上升如果初始Θ选择让所有单元指向用户中心方向收敛会更快。第二两个子问题之间的更新幅度不宜过大否则容易来回跳。我习惯在Theta更新时加一个线性插值Θ_new Θ_old α(Θ_candidate - Θ_old)其中α取0.5左右。这个技巧虽然简单但能明显减少振荡而且在边界约束上更安全。复杂度方面每个子问题基本是解一个变量数为M×K或N的凸优化典型参数下M8N32K2单次迭代耗时不到零点几秒。即使蒙特卡洛跑1000次信道实现也就十几分钟耗时瓶颈主要在信道生成和循环开销。4. MATLAB实现方案与代码架构4.1 仿真参数设置参数设置直接决定实验可信度我把自己常用的参数放进一个结构体params里方便后面批量扫参。参数符号取值说明基站天线数M8均匀线阵RIS单元数N32均匀线阵用户数K2单天线用户载波频率fc28 GHz毫米波带宽B100 MHz感知通信共用基站最大发射功率P_max30 dBm约1W用户噪声功率σ_c²-90 dBm包含接收机噪声RIS噪声功率σ_r²-85 dBm有源器件引入RIS最大反射增益β_max2主动元件可设置更大感知波束增益阈值Γ_s固定值按场景调整这几个参数不是随便定的。毫米波频段路径损耗大所以RIS必须靠近用户或目标才有意义噪声功率设为-90dBm左右对应100MHz带宽下的热噪声底。主动RIS放大器增益不能一直调大因为RIS处噪声也会被放大β_max超过某个值之后通信速率反而下降这个现象我后面专门讲。4.2 目录结构与模块划分代码组织建议按功能拆分成独立文件一方面方便调试另一方面跑不同类型的对比实验时能复用。核心文件如下main_ISAC_ActiveRIS.m主脚本负责初始化参数、跑蒙特卡洛循环、保存结果gen_channel.m生成G、h_d、h_r、a_s等所有信道变量solve_W_with_fixed_Theta.m固定Θ求解基站波束成形子问题solve_Theta_with_fixed_W.m固定W求解RIS系数子问题compute_metrics.m计算SINR、速率、感知波束增益等指标plot_results.m绘制收敛曲线、对比柱状图、权衡曲线。主脚本的一层循环里调用gen_channel和两个优化子函数最外层的蒙特卡洛循环可以用parfor并行。如果只需要看单次实验的算法行为把蒙特卡洛次数设为1即可。4.3 主优化循环的实现要点主循环的伪代码结构大致是这样% main_ISAC_ActiveRIS.m for mc 1:params.numMC % 生成信道 [G, Hd, Hr, a_s] gen_channel(params); % 初始化Theta Theta init_theta(params.N, params.beta_max); % 固定初始Theta求初始W W solve_W_with_fixed_Theta(Hd, Hr, G, Theta, params); obj_prev -inf; for iter 1:params.maxIter % 子问题1固定Theta优化W W solve_W_with_fixed_Theta(Hd, Hr, G, Theta, params); % 子问题2固定W优化Theta Theta solve_Theta_with_fixed_W(Hd, Hr, G, W, a_s, params); % 计算目标函数 obj compute_objective(Hd, Hr, G, Theta, W, params); % 收敛检测 if abs(obj - obj_prev) / abs(obj_prev) params.tol break; end obj_prev obj; end % 保存本信道的性能指标 results(mc) compute_metrics(Hd, Hr, G, Theta, W, params); end有几个实现细节要特别警惕。第一Theta矩阵是复数值对角阵MATLAB里直接定义成diag(sqrt(beta_real(:)) .* exp(1j * theta_phase(:)))不要让零元素参与不必要的矩阵乘法否则N大了以后很慢。第二solve_W里如果用了CVX尽量用cvx_begin quiet不然每次迭代都刷屏严重影响调试心情。CVX求解SOCP时报错多半是约束写成了非凸形式我后面会专门列几种典型报错。第三收敛阈值tol不要设得太小否则迭代次数虚高但性能提升微小。我一般设1e-3到1e-4再往上纯属浪费计算时间。4.4 蒙特卡洛验证与结果输出蒙特卡洛的本质是对随机信道做多次独立试验把不同信道下的平均性能拿出来比较。我通常跑1000次每次都是全新的信道实现。如果追求更快可以降到200次曲线趋势基本稳定。并行的时候要小心MATLAB的parfor行为。默认情况下MATLAB会按逻辑处理器分发任务如果你的机器开了超线程实际并行度反而比物理核心数低。我自己的经验是手动指定parpool(local, 物理核心数)否则有时候开8个worker跑8个任务比4个worker还慢。结果输出我习惯分两层中间结果存.mat文件最终对比图存成.eps或.png。不要只在命令行print因为论文里需要高分辨率图.eps对应LaTeX排版最方便。5. 数值实验结果与参数影响5.1 迭代收敛行为先看固定一组信道、固定参数下的迭代曲线。交替优化从随机初始Θ开始前5次迭代目标值迅速上升大约15到20次迭代后变化趋于平缓到30次迭代基本收敛。这说明这套迭代算法的工程收敛性是很稳的。收敛曲线的形状也能反映问题。如果曲线上升太慢或者出现明显的锯齿状波动大概率是Theta子问题的近似做得太粗糙。此时检查两步之间Theta的变化幅度如果幅度过大就调小插值系数α。5.2 不同方案性能对照为了说明主动RIS的价值我在相同信道条件下跑了几种基准方案方案反射系数约束可达和速率bps/Hz感知波束增益归一化无RIS无8.20.15随机相位被动RISβ ≤ 1相位随机9.10.22优化相位被动RISβ ≤ 1相位优化12.40.41主动RISβ_max1.5β ≤ 1.5相位优化15.80.63主动RISβ_max2β ≤ 2相位优化17.30.78从这组结果可以读出两层信息。第一层被动RIS只要优化相位就能比随机相位带来可观增益这是因为相位对齐让级联信道的阵列增益被真正发挥出来。第二层主动RIS在相同优化手段下能进一步把速率和感知增益往上推而且β_max越大提升越明显。但这里有个重要提醒主动RIS的增益不是线性的。随着β_max继续增大RIS噪声放大效应越来越显著通信速率增长会逐渐饱和甚至出现下降。项目里如果只报一个“β_max越大越好”的结论那基本可以判定建模有问题。5.3 RIS单元数与最大放大增益的影响N从16增加到64时主动RIS的增益优势越来越明显。原因是N每增加一倍级联信道的阵列增益大约增加3dB而主动RIS还能额外提供功率放大相当于把两段链路的损耗同时压低。不过N增加也带来两个问题。一是优化复杂度上升Theta子问题的变量维度跟着线性增长SDR求解会变慢二是硬件功耗增加每个有源单元都要供电。所以在工程方案里经常看到“全主动”和“部分主动”的折中一部分单元做有源放大另一部分只做无源相位调节。这种混搭结构在MATLAB里实现也很简单把反射系数矩阵的某些对角元约束改成β ≤ 1就行。5.4 通信与感知性能的权衡最后看一个全局视角的对比。我固定所有参数把感知波束增益约束Γ_s从低到高扫描一遍记录每个Γ_s下能达到的最大通信速率画出来就是一条权衡曲线。曲线整体向右下方倾斜感知要求越高通信速率越低。这个结果很符合直觉波束成形资源是有限的多分一点给目标方向用户方向就会少一些增益。有意思的是主动RIS和被动RIS权衡曲线之间的距离在感知约束较强时明显拉大说明主动RIS不仅能抬高性能上限还能在感知和通信冲突更激烈的时候更好地兼顾两边。如果你要写报告或论文这条曲线往往比单个工作点更有说服力。6. 调试中踩过的坑与排查方法6.1 CVX凸性报错问题CVX最常出现的报错是“Disciplined convex programming error”本质上是把非凸表达式直接写进了约束。比如很多人会把SINR约束写成|h_k^H w_k|^2 / (Σ_{j≠k} |h_k^H w_j|^2 σ²) gamma这个形式CVX是不认的因为除法加二次项的组合不是底层建模支持的表达式。正确做法是转换成SOCP形式把分母移到右边并取平方根变成一个二阶锥约束。这是最经典的CVX使用坑所有做波束成形的MATLAB用户基本都会踩一遍。如果确实需要最大化总速率CVX没办法直接处理sum(log(...))可以在外部套WMMSE迭代把速率目标转成加权MSE最小化问题。WMMSE的收敛性有理论保证代码也不复杂只是别忘记初始化加权矩阵。6.2 主动RIS噪声与放大增益的平衡我第一次跑这个项目时把β_max直接设成5结果用户速率反而比β_max 2低了不少。问题出在RIS噪声被过度放大用户端的RIS噪声功率和|h_r,k^H|²σ_r²成正比而等效信号功率虽然也随β增大但受限于级联信道的实际路径损耗和基站总功率约束增长速率跟不上噪声放大速度。这个现象在论文里一般叫“噪声放大”。处理办法有两个方向。一是建模时把RIS噪声项的方差做成和反射增益相关的函数更贴近硬件二是在优化时给β_n加一个合理的上限一般不超过3否则结果违背物理直觉。6.3 交替优化不收敛问题如果迭代曲线在某个区间长时间振荡优先检查Theta子问题的近似精度。MM方法近似的质量直接影响收敛性近似太粗糙时即使目标值在上升Theta的更新方向也会偏。以我的经验给Theta更新加插值系数α 0.5之后绝大多数振荡场景都能压下来。另外要注意收敛判据不要只看目标函数最好同时检查Theta前后两次更新的欧氏距离。有时候目标函数变化很小但Theta还在明显变化说明系统还没有真正稳定。6.4 MATLAB环境与工具箱兼容性CVX在较新的MATLAB版本上偶尔会不兼容特别是一些测试版或刚发布的大版本。我自己在R2023b上遇到过CVX求解器初始化失败换成R2022a就非常稳定。如果不是特别需要新功能建议固定一个稳定版本搭配CVX 2.2使用。另外如果要用流形优化的SDR恢复可以安装Manopt工具箱。Manopt对复数值变量处理得很好但注意每次迭代后要重新投影到可行域否则反射系数的幅度约束会被破坏。做这个项目时我最深的感受是主动RIS的建模细节直接决定仿真结果的可信度。漏掉有源噪声性能会虚高得离谱把放大增益调得过大性能又会不明不白地下降。仿真不是为了跑出一个漂漂亮亮的数值而是为了把系统行为的内在逻辑摸清楚。最后分享一个小技巧跑蒙特卡洛批量实验之前先用单次信道把主循环跑通并把迭代曲线打出来确认目标值稳步上升之后再放大规模。这一步看起来麻烦实际能帮你省掉大半天的无效调试时间。本文还有配套的精品资源点击获取