WINNER II 3D-MIMO信道仿真实战:从参数配置到空间相关性验证
2026/9/16 16:54:41 网站建设 项目流程

简介:面向无线通信研究者的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 到 wim

2.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]; % 终端坐标,Z=1.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:方向图的近似表达与质量检查

EADF(Effective 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 配置失效。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询