尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于WINNER II的3D MIMO信道模型MATLAB实现与扩展指南

基于WINNER II的3D MIMO信道模型MATLAB实现与扩展指南 简介一份面向无线通信研究者与工程人员的 3D-MIMO 信道仿真 MATLAB 源码包目标是基于 WINNER II 模型完成三维空间场景下的信道建模与性能评估适合通信专业学生或需要快速搭建仿真平台的开发人员。压缩包共 52 个文件以 44 个 .m 脚本为主配合 4 个 .p 加密函数、.mlx 实时脚本和说明文本整体约 202KB源码包含信道生成、天线响应、路径损耗、信道估计等独立模块并附三个可直接运行的示例分别覆盖不同 MIMO 配置下的参数设置、传输策略与信号检测流程。通过研读和复用这些代码可以学习视距/非视距传播建模、天线阵列设计、误码率与吞吐量统计等关键环节为课题研究、算法验证或标准评估提供可扩展的仿真基础该套代码也可作为波束成形、干扰协调等后续方向的实验入口。该资源已有 485 人学习/下载。1. WINNER II 的 MATLAB 源码包为什么做 3D MIMO 还得回头翻它3GPP 38.901 已经给出了完整的信道建模方法但很多做 3D MIMO 的团队手边仍留着一份 WINNER II 的 MATLAB 源码。原因不是怀旧而是这套代码把“场景参数表 → 大尺度参数 → 小尺度参数 → 信道冲激响应”的每一步都摊开成了可单步调试的 MATLAB 函数加仰角维度、把线阵换成面阵、画一张 MIMO 信道容量图像改几行就能重跑。标题里的 zip 是 IST-WINNER 项目公开的 MATLAB 实现“3D——mimo”不是官方版本号而是社区补上仰角扩展后的常见用法。这篇文章把 WINNER II 的代码结构、最小运行方式、以及向 3D MIMO 改造要动的关键位置讲清楚适合要在 MATLAB 里复现信道、又不想从零写几何随机信道模型的工程师和研究人员。2. WINNER II 模型的结构与那套 MATLAB 代码的核心组成2.1 从几何随机信道模型看 WINNER II 的计算流程WINNER II 属于几何随机信道模型Geometry-based Stochastic Channel ModelGSCM和 3GPP 早期的 SCM、SCME 一脉相承38.901 里的 CDL/TDL 流程也大量继承了它的套路。它的基本思想是散射环境不直接测量而是按场景从统计分布里“掷”出来。每一次掷骰子生成一套大尺度参数Large-Scale ParametersLSP包括时延扩展、基站侧角度扩展、终端侧角度扩展、阴影衰落标准差和莱斯 K 因子再基于 LSP 生成小尺度参数Small-Scale ParametersSSP即每个簇的时延、功率、出发角AOD和到达角AOA以及簇内子径的细化角度。这套流程决定了代码的组织方式。解压出来的包表面上看是一堆 MATLAB 函数实际在跑一条固定顺序的流水线先按 Scenario 查表拿到 LSP 分布参数再生成簇级参数最后把每个簇的能量按角度拆到 20 条子径上逐簇叠加出信道系数。这也是为什么 2D 模型下仰角是被“焊死”的——原生代码里每条子径的俯仰角固定为 90°即认为能量只在水平面内传播。后续做 3D 扩展时只需动角度生成和天线响应两个环节时延生成和场景表都不用碰。包内场景与用途对照按 D1.1.2 交付文档的编号习惯整理如下场景编号名称典型用途A1室内办公室室内热点、类似 InHB1城市微小区UMiLOS/NLOS 环境B4室外到室内O2I 穿透场景C1郊区宏小区大覆盖、低密度C2城市宏小区UMa3D MIMO 研究最常用D1农村移动网络高移动性、大时延扩展选场景不是随便填缩写。C2 的时延扩展和角度扩展中值都偏大天线相关性相对低做 3D MIMO 容量仿真容易看出算法差异如果一开始就选 D1大尺度参数会让信道更“稀疏”结论容易被极端传播条件带偏。我一般先在 C2 上验证代码改对了再换其他场景对比。2.2 压缩包里的 MATLAB 程序框架主函数、场景表与天线阵列典型的 WINNER II MATLAB 包不同流传版本略有差异可以拆成四个功能块主入口函数一般叫winner2.m负责读仿真设置、组织上面那套流水线、返回上下行两个方向的信道场景参数块把 D1.1.2 里的 LSP 分布表塞进结构体或查找表天线阵列与方向图块定义收发天线个数、阵元间距、极化方式和方向图射线与簇合成块做时延、角度、多普勒相位的累加。拿到包之后第一步不是急着跑而是把winner2.m开头十几行注释和参数默认值脚本读一遍。不同来源的包把参数放在不同位置有的写在函数默认参数里有的单独放一个 config 脚本但入口调用基本一致都是构造一个SimulationSettings结构体传给winner2。这一点非常关键网上大量的报错和“结果不对”的帖子根因就是照抄别人博客里的字段名而两份包的字段命名并不相同。常见的调用形式是[BS_MS_channel, MS_BS_channel, propagationCondition, linkParams] winner2(SimulationSettings);这段代码里前两个返回值分别对应基站到终端、终端到基站两个方向的信道响应。注意不同版本的返回参数个数有差异解压后先看主函数里nargout相关的注释缺哪个就少接哪个否则 MATLAB 会报输出参数过多。提示先看包内自带的示例或默认配置脚本以它为准对齐字段名再改自己的参数。2.3 信道系数公式里决定 MIMO 维度的三项流水线最后落在簇级合成公式上对应 D1.1.2 第 5 章的系数表达式这里略去归一化因子H_{u,s,n}(t) sqrt(P_n) × Σ_m [ F_rx,u(θ_m, φ_m)^T · X_{n,m} · F_tx,s(θ_m, φ_m) ] × exp(j k(θ_m,φ_m)·r_rx) × exp(j k(θ_m,φ_m)·r_tx) × exp(j 2π f_D t)其中 P_n 是第 n 簇功率m 是簇内子径序号F_rx 和 F_tx 是收发天线方向图响应X_{n,m} 是 2×2 交叉极化矩阵k 是三维波矢量r_rx 和 r_tx 是阵元位置向量。理解 3D MIMO 只需要盯住三处。第一波矢量 k 同时含仰角 θ 和方位角 φ2D 模型里 θ 被固定为 90°等于把散射平面压到水平面第二r_tx 和 r_rx 决定阵元间相位差空间相关和阵列流形都由它控制面阵与线阵的区别全在这里第三X 矩阵里的交叉极化鉴别度 XPD 决定双极化 MIMO 能拿到多少独立自由度。这三项在代码里对应三个相对独立的函数或片段。改造时只动它们场景表和时延生成逻辑基本不用碰。下一章先把原生代码跑通建立正确的输出预期再谈怎么改。3. 在 MATLAB 中把 WINNER II 跑出第一组 MIMO 信道3.1 最小调用设置 SimulationSettings 并执行 winner2先给最小可运行配置。以城市宏小区 C2 场景、3.5 GHz 载频、基站 2×4 面阵、终端双天线为例% 1) 仿真级配置 cfg.Scenario C2; % 城市宏小区 cfg.Seed 20240317; % 固定随机种子保证可复现 cfg.NumBSSectors 1; % 基站扇区数 cfg.NumMSSectors 1; % 终端扇区数 cfg.NumBSPatterns 1; % 基站方向图套数 cfg.NumMSPatterns 1; % 终端方向图套数 cfg.NumTimeSamples 64; % 时域采样点数 cfg.SampleDensity 2; % 每个波长内采样点数 cfg.CenterFrequency 3.5e9; % 载频单位 Hz % 2) 基站 2x4 面阵横竖都是半波长间距 lambda 3e8 / cfg.CenterFrequency; [py, px] meshgrid((0:3)*lambda/2, (0:1)*lambda/2); cfg.BSArray.ElementPositions [px(:).; py(:).; zeros(1,8)]; % 3) 终端 2 元水平 ULA cfg.MSArray.ElementPositions ... [0, lambda/2; 0, 0; 0, 0]; % 4) 主调用 [BS_MS_channel, ~, linkParams] winner2(cfg);代码第 2 步的 meshgrid 是通用的面阵坐标生成方式第一行存 x 坐标第二行存 y 坐标第三行全 0 表示阵元都在水平面内单位是米。第 4 步返回的三个值里第一个是基站到终端的信道第三个 linkParams 里带着时延信息和传播条件。如果报“未定义函数 winner2”说明 MATLAB 当前路径没加到解压目录用addpath(解压目录)加进去再跑如果报字段不存在按 2.2 节说的对齐你自己这份包的默认配置脚本。提示终端移动速度字段在不同版本里命名不同常见的有 Velocity、MSVelocity或者藏在 CartesianCoordinates 里。先把速度设为 0排除多普勒干扰验证通道正确后再打开。3.2 影响 MIMO 结果的 5 个参数与取值建议跑通后就要面对参数调优。下面这 5 个参数对结果影响最大也是检索里问得最多的点参数建议初值影响ScenarioC2决定 LSP 分布和簇数改场景后时延扩展、角度扩展整体变化CenterFrequency3.5e9决定波长进而决定天线间距与多普勒改它必须同步改天线坐标SampleDensity2每波长采样数太小多普勒会混叠太大会内存爆炸NumTimeSamples64~256信道矩阵时间维做容量统计建议 1000 以上天线间距半波长决定空间相关矩阵特征值分布是 MIMO 秩的直接来源场景换成 D1 农村宏小区后时延扩展明显变大、角度扩展变小信道更“稀”空间相关性更高C2 则介于中间是 3D MIMO 论文里最常引用的基准。CenterFrequency 和天线间距必须是一对很多“为什么我的信道不相关”的报错其实是把 2.6 GHz 的配置搬到了 5 GHz阵元间距变成了接近一个波长相关性被拉低了。SampleDensity 在速度非零时尤其重要低于 1 时多普勒频移直接叠到相邻采样点之间时域信道看起来像噪声。3.3 输出数组的维度解读从信道系数到每个时延抽头的 H 矩阵跑通之后先别急着用做一次维度体检size(BS_MS_channel) % 确认各维含义 pdp mean(abs(BS_MS_channel).^2, [1 3]); pdp squeeze(pdp); plot(10*log10(pdp/max(pdp))); % 功率时延谱第一行看维度。不同版本的返回数组里收发天线维与时间维的先后顺序可能不同以size输出为准不要让代码里写死的索引绑架你。pdp 是功率时延谱横轴是采样点序号真正的时间要乘linkParams里的延时间隔。如果 pdp 只有一个尖锐峰先别慌——终端速度为 0、场景又是 LOS 时K 因子大会让能量集中到第一个簇这是正常现象换 NLOS 场景或把速度打开再看。拿到形状正确的数组之后下一步就是把最强时延抽头取出来重组成 nRx×nTx 的平衰落 MIMO 矩阵供容量、预编码验证用。这个重组逻辑要写成函数后面每一章都会用到它。4. 向 3D MIMO 扩展给 WINNER II 补上仰角维度4.1 原生模型的 2D 假设卡在哪θπ/2 与线性阵列原生 WINNER II 代码里的 2D 假设藏在两个地方。第一个是角度生成每个簇和每条子径的俯仰角被固定为 90°AOD 和 AOA 都只有方位分量这意味着信道在垂直方向没有角度选择性3D MIMO 里最看重的“垂直维度自由度”根本不存在。第二个是天线阵列基站侧配置的 ElementPositions 第三行全为 0所有阵元共面无法在高度方向形成波束。两个假设合起来的效果是即使你把方向图函数改成带垂直瓣的信道也不会对仰角产生任何反应。所以改造必须两头同时做给簇和子径补上天顶角ZOD/ZOA再让阵列和波矢量支持三维坐标。只改其中一边结果就是相关性和容量曲线“看起来变了但说不出哪里对”。4.2 给簇生成 ZOD/ZOA角度扩展从一维变二维仰角扩展的统计特性从 WINNER 的 D5.3 和 3GPP TR 36.873 的测量表里来城市宏小区环境下基站侧天顶角扩展典型在 4°~8° 量级终端侧更大。给各个簇补上天顶角的代码numClusters 12; % 取包内生成的簇数 meanZoD 95; % 基站到终端平均天顶角度 sigmaZoD 4; % 基站侧仰角扩展度 zod meanZoD sigmaZoD * randn(1, numClusters); zod(zod 0 | zod 180) meanZoD; % 越界拉回平均角 meanZoA 85; % 终端侧平均天顶角 sigmaZoA 7; zoa meanZoA sigmaZoA * randn(1, numClusters);这里的角度用天顶角约定90° 表示水平方向小于 90° 表示终端在基站上方。分布形式用高斯只是为了快速验证正式仿真建议换拉普拉斯分布和 36.873 的测量拟合更接近。视线传播时有个例外第一簇的天顶角不要随机生成直接按几何关系atan2(hBS - hMS, d2D)换算成度数固定下来否则 LOS 径的角度会抖动K 因子再大也救不回来。4.3 面阵、3D 波矢量与改写后的簇合成天线侧要写两个小函数一个是三维面阵坐标一个是含仰角的波矢量function pos planar_array(Mh, Mv, dh, dv) % Mh: 水平元数, Mv: 垂直元数, dh/dv: 水平/垂直间距 y (0:Mh-1) * dh; x (0:Mv-1) * dv; [yy, xx] meshgrid(y, x); pos [xx(:).; yy(:).; zeros(1, Mh*Mv)]; end function a steer3d(pos, lambda, thetaDeg, phiDeg) % thetaDeg: 天顶角(0朝天顶, 90水平), phiDeg: 方位角 th deg2rad(thetaDeg); ph deg2rad(phiDeg); k 2*pi/lambda * [sin(th)*cos(ph); sin(th)*sin(ph); cos(th)]; a exp(1j * (k. * pos)).; % 每个阵元一个相位 endsteer3d 里波矢量的 z 分量是 cos(th)这是仰角影响阵列响应的关键。2D 模型里 th 恒为 90°cos 项为 0z 方向阵列响应退化为常数面阵的垂直元间距 dv 一旦不为 0这部分就必须算对。簇合成的关键片段改成for n 1:numClusters for m 1:20 % 每簇 20 条子径 th zod(n) offsetZod(m); % 子径在簇内叠加小偏移 ph aodCluster(n) offsetAod(m); aTx steer3d(posBS, lambda, th, ph); aRx steer3d(posMS, lambda, zoa(n), aoaCluster(n)); H H sqrt(Pn(n)/20) * (aRx * aTx) * exp(1j*phaseRand(m)); end end这段是示意结构实际改造时把原生代码里“固定 90° 的位置”替换成 zod/zoa 逐簇取值。最容易出错的不是公式本身而是角度约定WINNER II 原代码里很多地方用“相对水平面的仰角”而 steer3d 用天顶角换算关系是 thetaZenith 90 - elevation。符号反了或补角没做阵列相位全错表面症状是空间相关性“怎么调都不对”。建议把换算写成一个独立函数所有角度进 steer3d 前统一过一次。5. 验证与两个坑拿到 3D MIMO 数据后怎么确认算对了5.1 用空间相关、时延扩展和信道容量图做自检改完代码第一件事不是看容量曲线漂不漂亮而是做三个低成本自检。第一个是相邻阵元空间相关度和各向同性散射的理论值比量级H1 squeeze(Hmax(:,1)); H2 squeeze(Hmax(:,2)); rhoSim abs(H1*H2) / (norm(H1)*norm(H2)); rhoTheo besselj(0, 2*pi*0.5); % d lambda/2各向同性理论值半波长间距下 rhoTheo 约 0.22 左右。仿真值比它低太多说明仰角或方位角扩展被放大了高太多说明角度生成有偏差或簇数太少。第二个是时延扩展用 pdp 的功率加权二阶中心矩算 RMS 时延扩展和 D1.1.2 对应场景表中值比数量级差一个数量级以上就要回头查时延生成逻辑。第三个就是标题里的“mimo 信道容量图像”snrDb 0:5:30; Ccap zeros(size(snrDb)); for i 1:numel(snrDb) snr 10^(snrDb(i)/10); Ccap(i) real(log2(det(eye(nRx) snr/nTx * (Hmax*Hmax)))); end plot(snrDb, Ccap, o-);容量曲线应随 SNR 近似线性上升且 4×4 明显高于 2×2。如果 4×4 和 2×2 拉不开差距优先怀疑面阵垂直方向是否真的吃到了仰角扩展——把 sigmaZoD 调到 0 再跑一遍容量曲线几乎不动说明垂直维度没生效。5.2 旧 MEX 与角度约定的两个坑最后两个高频坑。第一老版本包里偶发带编译好的 MEX 文件用新版 MATLAB 调用时直接报“无效 MEX 文件”。处理方式是定位调用它的函数把相关路径指到对应的 .m 源文件或在新版本环境重新编译而不是删除功能。第二角度约定不一致如 4.3 节说的天顶角与仰角混用。这与物理无关纯粹是代码习惯问题但排错时最耗时间因为表现成“相关性偏高 20%”“容量低 0.5 bit/s/Hz”这类模糊症状。把角度换算集中到一个函数里并在注释里写上约定方向是所有后续改造里性价比最高的一步。本文还有配套的精品资源点击获取
返回列表