
简介面向无线通信研究者的WINNER II模型MATLAB实现聚焦3D-MIMO信道仿真与性能评估适合通信工程专业学生、算法工程师以及相关课题研究人员。压缩包共52个文件以44个m脚本为核心涵盖信道参数生成、天线阵列响应、路径损耗与角度计算等模块另有4个p文件封装部分函数辅以mlx实时脚本、asv备份与说明文档包体仅202KB便于快速部署。已有485人学习下载。代码内含三个完整实例可学习构建3D-MIMO信道模型、设置收发天线阵列并处理信道估计与信号检测同时覆盖LOS/NLOS传播、空间分集/复用/波束赋形等关键知识点并支持误码率、吞吐量等性能指标评估。通过研读这些源码能够掌握从随机几何场景生成到天线参数配置的完整仿真链路为后续无线通信系统设计和学术研究提供可复用的参考基础。1. 3D-MIMO信道仿真为什么绕不开WINNER II做 3D-MIMO 链路级仿真的人多半遇到过这种尴尬基站侧已经换成 8×8 平面阵下倾角也按规划调好了但仿真信道矩阵算出来的秩分布和实测对不上。问题往往不在波束赋形算法而在信道模型根本没有把仰角维度送进多径生成流程。WINNER II 是这类场景里最常用的几何随机信道模型它按场景参数表生成 LOS/NLOS 概率、时延扩展、方位角与仰角、极化和天线响应链路级仿真需要的传播维度全覆盖而这套 MATLAB 源码把 3D 天线响应、垂直角度生成和完整信道冲激响应输出全部开放。适合要做 3D-MIMO 信道复现、天线阵列配置对比和容量评估的工程与研究人员。要复现出可信的 3D 结果参数体系、天线响应和示例脚本三个层面都要能自洽逐层拆比直接跑 example 更有把握。2. WINNER II 的建模链路与参数体系从 wimparset、layoutparset 到 wim2.1 三段式初始化参数结构、布局结构与信道主入口WINNER II 的源码按“参数—布局—信道”三段组织。wimparset.m 维护全参数结构layoutparset.m 消费这些参数生成站点布局wim.m 与 wim_core.m 再消费布局输出信道系数。这个分层在工程上很实用对比不同天线阵列时只改 arrayparset 相关字段重跑 wim 即可布局不用重新生成换场景或移动用户位置时则更新 wimparset 和 layoutparset天线方向图保持不动。wim_core.m 内部还会调用 generate_bulk_par.m 批量生成大尺度参数再按 layout2link.m 把布局展开成一条条具体链路链路级仿真里关心哪一个站点、哪一对收发天线看这一层的数据结构最直接。cfg wimparset; cfg.CenterFrequency 3.5e9; % 5G中频段3D波束扫描常用 cfg.Scenario C2; % 城市微蜂窝垂直角度扩展明显 cfg.ElevationAngle 1; % 开启3D角度生成2D/3D模式的分水岭 cfg.NumPaths 20; % 每条链路的多径数 cfg.NumBSPosition [0 0 25]; % 基站坐标第三维是挂高25 m cfg.NumMSPosition [50 30 1.5]; % 终端坐标Z1.5 m模拟行人高度 cfg.NumMSPerBS 1; cfg.SampleDensity 16; % 每码片采样点数影响时域分辨率 layout layoutparset(cfg); % 生成链路布局含速度与天线朝向 [chan, delays, weights] wim(cfg, layout);这段代码是跑通模型的最短路径。ElevationAngle 置 1 后多径会同时生成方位角与仰角这是 3D-MIMO 与老式 2D 模型的本质差别NumBSPosition 和 NumMSPosition 的第三个分量是基站挂高与终端高度直接决定链路在垂直面的几何关系SampleDensity 是每个码片内的采样点数取值越大信道矩阵在时间维上越能体现多普勒和微小径变化但内存按采样点线性增长调试期用 16大批量跑性能评估时降到 4 或 8 是常见做法。wim 的返回值里chan 的维度在源码头部注释写明按 Tx 阵元数 × Rx 阵元数 × 径数 × 采样点数组织是复数矩阵delays 是每条径的绝对时延weights 是该径的功率权重。layout 结构体里保留了每条链路的站点 ID、坐标和速度向量做移动性管理或切换仿真时这些字段会被直接读取不要在执行 wim 之后立刻 clear layout。2.2 场景映射与 LOS/NLOS 判定WINNER II 把信道统计参数按场景组织在内部配置表里。ScenarioMapping.m 把 C2 这类字符场景名翻译成内部数字 ID后续的 pathloss.m、ds.m、DoA-profile_NLoS.m 全部通过这个 ID 查表。需要注意改场景不是只改一个字符串场景切换同时替换时延扩展、角度扩展、阴影衰落标准差和 LOS 概率曲线所以对比仿真结果时务必要确认 ScenarioMapping 的输出 ID 与预期一致否则几组数据之间没有可比性。LOSprobability.m 负责判断链路是 LOS 还是 NLOS它按场景和二维距离给出概率并在链路初始化时输出 0/1 标志。3D-MIMO 里这个判定比 2D 更敏感因为仰角扩展和方位角扩展在 LOS 与 NLOS 下的分布差异很大直接影响协方差矩阵的秩复现时不要图省事把这段输出直接置常量。场景 ID环境描述3D-MIMO 里的典型用途A1室内办公室室内分布式天线、室内定位B1城市宏蜂窝常规宏站覆盖仰角扩展较小B4城市微蜂窝街边杆站垂直面覆盖差异明显C2城市微蜂窝3D 波束管理与垂直增益评估D1乡村宏蜂窝长距离 LOS 链路角度扩展小C2 的垂直角度扩展通常比 B1 大一截原因不复杂微蜂窝基站离用户近用户高度从 1.5 m 到楼顶几米的变化会直接在仰角上拉开差异而宏站覆盖距离远这个差异被距离稀释。所以做 3D-MIMO 波束管理验证时优先选 C2 或 B4更容易看到垂直维度带来的容量和覆盖变化。2.3 路径损耗、时延扩展与三维角度剖面pathloss.m 根据场景 ID、载频、距离和 LOS/NLOS 标志计算路径损耗与阴影衰落标准差ds.m 负责生成 RMS 时延扩展DoA-profile_NLoS.m 处理 NLoS 链路的三维到达角剖面是 3D-MIMO 下方位角与仰角数据的直接来源。这个文件名里的 DoA 是 Direction of Arrival对应的还有发射端离开角剖面源码里放在 fixedAods.m 和 fixedAoas.m 中做固定角度注入用于对比实验或者复现某些实测环境。scen ScenarioMapping(cfg.Scenario); [inLOS, pLOS] LOSprobability(scen, dist_2d, cfg.NumMSs); [PL, PLstd] pathloss(cfg, layout, scen, inLOS); [aoa_profile, zoa_profile] DoA_profile_NLoS(cfg, layout); size(aoa_profile) % 与链路数、径数对应 size(zoa_profile) % 3D模式下才有非空输出aoa_profile 是方位角到达zoa_profile 是仰角到达。wim_core 在生成每条径的阵列响应时会按发射端 AoD/ZoD 和接收端 AoA/ZoA 两组角度去查天线方向图所以 DoA_profile 的输出质量直接影响最终信道矩阵。调试时如果发现 zoa_profile 全为零或者维度对不上优先检查 ElevationAngle 是否为 1再看布局里基站与终端是否真的存在高度差高度差为零时仰角退化成常量3D 模式形同虚设。3. 3D 天线阵列与垂直维度arrayparset、AntennaResponse 与坐标旋转3.1 阵列拓扑从 ULA 到 UPA 的配置代价3D-MIMO 的天线阵列配置集中在 arrayparset.m 与 ArrayPreprocess.m 里。arrayparset 定义每个站点的阵列类型、阵元数量、间距与朝向ArrayPreprocess.m 在链路初始化时把这些配置翻译成每个阵元的本地坐标与极化向量。StationNumElements.m 返回每个站点的阵元总数这个返回值在后续波束赋形权向量初始化时经常用到别在脚本里硬编码阵元数否则换阵列配置时很容易漏改。arr arrayparset; arr.BSArrayType {UCA,UPA,ULA}; % 圆阵、平面阵、线阵三选一 arr.NumBSElements [8 8]; % 8x8 平面阵行列可不等 arr.BSSpacing [0.5 0.5]; % 归一化间距0.5 为半波长 arr.BSAzimuth 0; % 阵面水平朝向单位度 arr.BSElevation -15; % 下倾角垂直面覆盖关键 arr.BSPolarization {VH,VH}; % 极化方式VH 为垂直水平BSElevation 是 3D-MIMO 新引入的自由度。阵面下倾 15 度后同一个全局 AoD 对应的阵列响应相位随之改变波束主瓣在垂直面整体下压。这个参数在 2D 模型里不存在在 3D 模型里却直接参与天线响应的复数运算所以不要只把下倾角写进系统级脚本而忘记同步到 arrayparset。三种典型阵列在 3D 场景下的选择逻辑差别较大整理如下。阵列类型水平孔径垂直孔径3D-MIMO 适用性ULA大无仅水平扫描垂直面靠下倾角固定UPA大可调水平垂直二维扫描波束管理首选UCA各向近似小360 度水平覆盖垂直分辨率有限UPA 的间距建议从 0.5 波长起步需要更高垂直分辨率时缩小垂直间距并增加阵元数。代价是信道矩阵维度线性增长仿真时长相比较快大批量跑之前先用小阵列验证脚本流程。3.2 天线方向图与极化AntennaResponse、dipole 与 EADF 近似AntennaResponse.m 返回每个阵元的复数方向图dipole.m 提供理想偶极子的解析方向图antenna_pol_vect.m 计算极化方向的单位向量。实测或仿真的天线方向图在角度维上经常是不均匀采样直接插值会在相位上引入人为失真源码里对应放了 interpbp.m 做带保护带的插值以及 example_EADF_approx.m 做方向图近似。az_grid -180:1:180; el_grid -90:1:90; [pattern, pol] AntennaResponse(arr, BS, 1, az_grid, el_grid); pattern3d 3D_AntennaResponse(pattern, az_grid, el_grid, arr.BSElevation);AntennaResponse 的输入是方向图网格输出是复数电场方向图包含幅度和相位两路信息3D_AntennaResponse 再把方向图与下倾角合成得到带三维倾斜的阵列响应。使用实测方向图时不要跳过 interpbp 直接从原始网格取数否则主瓣零点位置在 3D 波束扫描里会出现几度偏移这个问题在窄波束、高阵元数场景下尤其明显。3.3 坐标链全局角度到阵列局部角度的旋转多径角度先在全局坐标里生成但阵列响应计算必须在阵列局部坐标里完成这条转换链由 mycart2sph.m、mysph2cart.m、rotate_vector.m 与 unrotate_vector.m 串联。mycart2sph 把直角坐标转为球坐标得到方位角和仰角rotate_vector 把全局方向转到阵面局部系unrotate_vector 做逆变换用于从局部测量结果反推全局方向。% 把全局坐标下的一条径方向转到阵面局部坐标 [az_l, el_l, r] mycart2sph(...); aoa_local rotate_vector(aoa_glob, zoa_glob, arr.BSAzimuth, arr.BSElevation);rotate_vector 的入参是全局方位角、全局仰角和两个朝向角出参是局部角度。三个角度的单位必须统一源码内部混用度和弧度的位置不少手写调用时建议全部转成度并在调用后检查输出范围是否落在 -180 到 180 之间。超出说明角度折返没有处理好后续阵列响应相位会出现跳变最终信道矩阵里表现为不可解释的随机毛刺。4. 复现三个 example 脚本从合成阵列到完整信道冲激响应4.1 example_syntetic_arrays.m用合成阵列验证响应维度这个脚本用合成阵列快速验证整条链路。所谓合成阵列是不从外部文件读方向图直接按阵元位置计算阵列因子适合在换真实天线数据之前先确认代码路径没有断点。文件名里的 syntetic 沿用了源码作者的原始拼写不影响执行。cfg wimparset; cfg.ElevationAngle 1; cfg.NumPaths 8; layout layoutparset(cfg); % 取第一条链路第一个时刻的完整信道矩阵 [chan, delays, weights] wim(cfg, layout); H squeeze(chan(:, :, :, 1)); size(H) % Tx 阵元 × Rx 阵元 × 径数跑这个脚本最常见的两个现象一是 size(H) 与预期阵元数不符原因是 wimparset 里的默认阵列配置和 layoutparset 里的站点编号不一致改了 cfg 之后没有重新执行 layoutparset二是仰角全为 0说明 ElevationAngle 未打开此时输出退化为 2D 信道后续任何 3D 波束扫描结论都不可信。把这两个点写进自动化检查脚本能省掉大量无效跑批。4.2 example_channel_matrix.m完整信道冲激响应与频域转换这个示例生成完整信道冲激响应并给出转换成频域响应的处理方式。链路级仿真通常需要把 CIR 转换到频域才能继续算 BER、吞吐量等指标所以这个脚本里频域变换的顺序值得参考。H_cir squeeze(chan(:, :, 1, :)); % 取第一条径保留时间采样维 Nfft 256; % 与OFDM子载波数对齐 H_fre fftshift(fft(H_cir, Nfft, 3), 3); % 沿时间维做FFT再居中Nfft 取决于 OFDM 系统的子载波数常用 128 或 256。fft 的维度参数要与 H_cir 中时间采样所在的维度对齐源示例里先 squeeze 去掉单例维度再做变换顺序不能颠倒。把 H_fre 的幅度谱画出来如果高频部分出现异常抖动优先检查 weights 是否被错误归一化多径功率谱的包络应该相对平滑而不是逐径跳变。4.3 example_EADF_approx.m方向图的近似表达与质量检查EADFEffective Aperture Distribution Function是用二维傅里叶基对天线方向图做周期近似把任意角度网格上的方向图压缩成一组谐波系数。它的价值在于实测方向图往往角度采样不均匀常规插值会自动平滑掉相位细节而 EADF 保留复数域近似幅度和相位同时保真。order 16; [approx, err] EADF_approx(pattern3d, order);order 是保留的谐波阶数。order 太低方向图被磨平主瓣宽度变大order 太高则把测量噪声一起拟合旁瓣出现毛刺。工程上从 8 开始往上加观察 err 随阶数下降的曲线误差进入平台期时取该阶数即可。把 approx 与原始 pattern3d 的主瓣零点作对比能直接看出近似是否引入了波束指向偏移。这个脚本值得在每次导入新的天线硬件数据后跑一遍当作方向图质量检查的固定步骤。5. 用空间相关性校验 3D 信道矩阵验证步骤与边界条件5.1 用单径相关系数对照理论值信道矩阵生成后先别急着算容量。取单径、单时刻的信道矩阵计算接收阵元之间的空间相关系数并与自由空间均匀线阵的理论值对照。理论相关系数由阵元间距和到达角谱决定这一对照能确认角度参数是否真的进入了信道矩阵属于成本最低的 3D 模式自检。H squeeze(chan(:, :, 1, 1)); % 单径单时刻Tx × Rx H H / norm(H, fro); % 能量归一化 R H * H; % 接收端相关矩阵 corr12 abs(R(1, 2)); % 第1、2个接收阵元的相关系数corr12 应该落在 0 到 1 之间。两个阵元间距半波长且到达角谱集中在正前方时corr12 通常接近 0.8 到 0.95角度扩展大时相关性明显下降。corr12 几乎等于 1 说明角度谱过窄角度参数可能退化成了单跳模型corr12 接近 0 则要检查阵元间距和极化配置是否被错误缩放。源码目录里的 LScorrelation.m 正是这类相关系数计算的底层实现直接调用它比手写矩阵运算更稳妥。5.2 三个容易翻车的位置第一ElevationAngle 置 1 后 layoutparset 必须重新执行因为布局里的链路几何缓存了旧的二维标记只改 wimparset 会让部分链路仍然走二维分支。第二下倾角与坐标旋转要配套改 arrayparset 的 BSElevation 后记得同步 rotate_vector 的入参否则全局角度与阵列局部角度错位阵列响应主瓣不会随下倾角移动。第三固定随机种子。WIM 内部用随机数生成多径角度和功率对比仿真时要在 wimparset 里固定种子否则两次实验的差异混合了信道随机性和算法改进结论不具备可比性。提示检查 zoa_profile 是否全是常量也能判断 3D 模式有没有真开起来。仰角剖面在 NLoS 场景下必然有波动恒定输出基本就是 ElevationAngle 配置失效。本文还有配套的精品资源点击获取