
简介这是WINNER信道模型的MATLAB实现代码可视为3GPP SCM信道的增强版面向无线通信与信道建模领域的研究者、工程师及相关专业学生用于多天线信道仿真、链路级与系统级性能评估及新一代移动通信信道算法验证。压缩包共47个文件大小约639KB主体为41个m程序文件覆盖信道系数生成、路径损耗、天线极化与阵列响应、散射簇参数生成、视距存在概率计算等核心模块另有4个p文件作为预编译函数辅以1册PDF版介绍文档和1份TXT版本说明可帮助梳理参数配置与调用流程。目前已有1654人学习下载借助示例脚本和WIM2文档使用者可从场景设定、布局生成一路做到信道矩阵输出复现典型信道场景同时可通过修改参数适配自选传播环境为二次开发提供清晰起点。 读研那阵子导师把一个winner2信道模型的 MATLAB 代码包丢给我说“拿去跑个链路仿真”。我当时以为有代码、有论文跑通也就是半小时的事结果一个下午过去命令行里全是报错连 H 矩阵长什么样都没看到。后来把官方示例一行行读明白又把 20 条多径拆开逐条验证才算真正把这套代码用顺了。如果你也在用 MATLAB 做 MIMO 信道仿真或者想在链路级仿真里给系统加一个足够真实的衰落信道这篇就把我这几年用 Winner II 的配置经验、踩坑记录和扩展方法一次讲完。1. Winner II 到底是个什么信道模型为什么至今还在用1.1 从 SCM 到 Winner II一个“能用”的 MIMO 衰落信道Wireless World Initiative New Radio Phase 2简称 WINNER II是欧盟 WINNER 项目第二阶段提出的一套信道模型。它的前身是 3GPP 在 Release 6 时期搞出来的 SCMSpatial Channel Model后来 WINNER 项目组在 SCM 基础上扩展了大量场景把频率范围从 2GHz 附近扩到 2-6GHz带宽支持到 100MHz并且能生成带极化信息、角度信息和天线阵列响应的完整 MIMO 信道矩阵。为什么这么多年过去这套模型还在用因为学术圈和工业界的“链路级仿真”需要的是一个不依赖具体厂商、可复现、公开代码的 MIMO 衰落信道。Winner II 的 MATLAB 代码完全开放场景覆盖面广从室内小房间到乡村宏峰窝都有参数化程度高。做 5G 物理层算法验证时即使标准已经更新到 3GPP TR 38.901很多人依然喜欢先用 Winner II 跑一遍基线因为它足够简单、足够稳。值得注意的是Winner II 不是标准而是“可参考的模型”。它和带标准地位的 SCM、SCME、IMT-Advanced 信道模型有很多交集但在场景覆盖和多径簇结构上做了自己的调整。你在论文里用的时候一般写“基于 Winner II 信道模型进行仿真”而不是“符合 3GPP 协议”这个表述要准确。1.2 “几何随机”四个字到底是什么意思Winner II 属于几何随机信道模型GSCM。所谓“几何”指的是发射机和接收机周围会按概率分布撒出若干散射簇每簇对应一组特定方向的角度所谓“随机”是指散射簇位置、角度、延迟、功率都不是固定值而是服从特定的概率分布每次运行都会生成一个不同的信道实现。代码里默认生成 20 条多径。这个“20”不是拍脑袋定的而是 WINNER 项目组在保真度和复杂度之间做的折中。继续增加路径数统计特性提升有限计算量却线性上涨路径数太少比如只留 5 条时延扩展和角度扩展就会明显偏离实测统计值。所以在实际仿真里除非你要做低复杂度验证否则建议保留默认 20 条不要为了“省时间”盲目减到个位数。这套模型最核心的输出是复信道冲激响应 H它包含了路径损耗、阴影衰落、小尺度衰落、多普勒频移、天线极化耦合以及收发天线阵列响应。也就是说拿到一组 H你的链路仿真里几乎不用再另外加信道相关性的处理直接把 H 作用到发送符号上就行。2. 从下载到跑通MATLAB 代码包的打开方式2.1 代码包去哪找、目录里有什么搜索“WINNER II Channel Model for MATLAB”就能在 MathWorks File Exchange 上找到官方发布版本另外一些实验室的 GitHub 仓库里也有镜像。下载后解压你会看到一个典型结构根目录下有一堆.m文件子目录包含wim核心算法模块、parameter_sets各场景参数、demo示例脚本等。不同版本的文件名会有差异但核心模块的划分基本一致。第一件要做的事不是打开主函数而是先把整个目录加进 MATLAB 搜索路径addpath(genpath(你的解压路径/WINNER2));强烈建议用genpath因为代码内部会调用大量子目录函数只把根目录加进去会出现各种 “Undefined function” 报错。2.2 三步跑通第一个示例每个版本的 demo 脚本名字不一样一般形如winner2_example.m、demo_winner2.m打开后直接运行即可。我第一次跑通时实际只做了三件事加路径、运行初始化脚本、运行 demo 主脚本。如果包内没有现成 demo按下面的简化流程走% 1. 加路径 addpath(genpath(WINNER2)); % 2. 初始化全局参数不同版本函数名可能不同以包内文档为准 wim_defaults; % 3. 配置基本参数 cfg struct( ... scen, B1, ... % 场景城市微蜂窝 num_bts, 1, ... num_ms, 1, ... fc, 2.0e9, ... % 载频 2GHz sample_rate, 20e6, ... % 采样率 20MHz ms_velocity_kmh, 30, ... % 移动速度 30km/h N, 20); % 多径数 20 % 4. 配置布局 layout struct( ... bts_pos, [0, 0, 32], ... % 基站坐标 (x,y,z) ms_pos, [200, 50, 1.5], ... % 移动台坐标 ms_track, [0, 1.5, 0]); % 移动速度和方向 % 5. 调用核心函数生成信道 [H, chan] winner2(cfg, layout);我需要强调不同版本的官方代码结构体字段名可能有细微差别比如有的版本用scen有的用scenario有的布局参数要求写成矩阵而不是结构体。所以上面这段代码是“思维模板”不是万能脚本。最稳妥的打开方式仍然是先跑通自带 demo再在 demo 基础上改数值和字段。千万不要一上来就自己从零写配置我见过太多人把时间浪费在接口细节上。3. 核心参数逐个说清楚照着 demo 抄作业的进阶版3.1 场景字符串A1、B1、B3、C2 怎么选Winner II 定义了很多场景代码里直接用场景字符串表示。最常用的四个场景如下表场景环境典型覆盖半径常见用途A1室内办公室/大厅小于 100m室内热点、厂房无线B1城市微峰窝100m-500m街道级覆盖、小站B3城市宏峰窝500m-3km城区连续覆盖C2乡村宏峰窝1km-5km广域覆盖、高速移动选择场景时不仅要看覆盖半径还要注意该场景对应的时延扩展、角度扩展和路径损耗模型是否匹配你的仿真假设。比如你要做的是高铁场景选 B1 就会出现很奇怪的时延扩展选 C2 才更贴近广域高速环境。另外每个场景内部还区分 LoS视距和 NLoS非视距状态。代码里一般有两种方式控制一种是靠场景参数里的概率自动判定另一种是强制指定。如果你希望固定某一个状态需要找到对应开关而不是只改场景名。3.2 载频、带宽、采样率和移动速度载频fc直接影响路径损耗和天线的电尺寸。Winner II 的公开标定范围是 2-6GHz比如 2GHz、2.6GHz、3.5GHz 都没问题。如果你硬塞一个 28GHz代码不一定报错但生成的信道统计特征没有实际测量数据支撑结果会不可信。做毫米波仿真要换模型这个后面再说。带宽和采样率是两回事。信道模型的时延分辨率取决于带宽带宽越大多径的可分辨性越强。而采样率决定了最终输出的离散冲激响应在时间维的步进。实际链路仿真时采样率应当和你的系统基带采样率一致。比如 OFDM 系统用 20MHz 带宽、30.72MHz 采样率那sample_rate就设置成 30.72e6这样后面把 H 接到信号模型上时不会出现时间轴对不齐的问题。移动速度决定多普勒频移的大小。Wi-Fi 场景下 3km/h 即可车联网场景 60-120km/h高铁场景建议至少 250km/h。速度越高信道随时间变化越快仿真输出的时间维采样点也会越多内存压力越大。可以先低速跑通再调到目标速度。3.3 天线阵列和极化参数MIMO 仿真最容易被忽略的配置是天线阵列。阵列的天线个数、阵元间距、极化方式都必须写清楚。Winner II 代码里支持线阵、面阵和不同极化方向图。如果你的仿真只关心空间分集不关心极化可以把极化耦合系数设成默认值一旦涉及极化分集或双极化天线就必须把收发两端天线的极化倾角配置与系统设计对齐。阵元间距和载频要匹配。比如 2GHz 对应的半波长约 7.5cm如果你的阵列模块里配置的天线间距和实际射频设计不一致生成的信道空间相关性就会失真。做 4x4 MIMO 时一般按半波长等间距配置做大规模 MIMO 时很多人会用紧密阵这时候模型是否还适用需要格外小心。4. 拿到 H 矩阵之后如何接进 OFDM 链路仿真4.1 H 矩阵长什么样很多新手第一次用 Winner II看到输出的 H 就懵了不知道哪个维度是天线、哪个维度是时间。我用最笨的办法解决在命令行里打印size(H)然后逐维用squeeze观察。不同版本维度顺序可能不同但大体上可以理解为前两维分别是接收天线数和发射天线数然后是路径数、时间采样点和段数。假设你配置了 1 个发射天线、1 个接收天线、20 条路径那么某个时刻某条路径上的信道增益可以这样取% 取第1段、第1个时间采样点、所有路径 h_slice squeeze(H(1, 1, :, 1, 1)); % 20x1 的复列向量这里的h_slice就是当前时刻的 20 条多径复增益。把它的功率做归一化可以检查是否符合预期。如果功率明显偏大或偏小多数情况是布局里的收发距离和路径损耗模型不匹配而不是代码出问题。4.2 从复增益到频域响应的简化流程OFDM 链路仿真里通常不需要每时每刻的全维 H而需要每个子载波上的频域信道响应。做法是把多径增益按时间延迟排好补零到 FFT 点数后做离散傅里叶变换Nfft 1024; h_delay zeros(1, Nfft); h_delay(1:length(h_slice)) h_slice; % 将多径增益放在时延抽头 H_freq fft(h_delay, Nfft); % 每个子载波的频域响应这个流程虽然简化但思想是对的Winner II 输出的多径增益本来就是离散时延抽头放进 OFDM 的循环前缀长度内就能直接用于频域均衡。需要特别留意的是循环前缀长度如果信道的最大时延扩展大于 CP会产生符号间干扰这不是信道模型的问题而是 OFDM 参数设计的问题。我实际做链路仿真时习惯先跑一次纯 AWGN 信道再切到 Winner II 信道对比 BER 曲线的平台拐点。如果两者性能差异在预期范围内说明 H 的接法没问题如果出现异常低的地板优先检查时延对齐和功率归一化。5. 运行中的五个高频坑和我的处理方式5.1 “WIM 全局变量没初始化”这是我第一次使用时卡得最久的问题。官方代码里有很多参数放在一个全局结构体中比如WIM必须先运行初始化函数它才会被写进 MATLAB 工作区。直接调用winner2时会报 “Undefined function or variable wim” 或 “Reference to a cleared variable wim”。解决办法很直接确保每次新开 MATLAB 会话后都重新运行初始化脚本。如果你在做批量仿真建议把 addpath 和初始化写进同一个初始化脚本最前面用run(init_winner2.m)统一调起来。不要依赖别人给的“已经跑好的 .mat 变量”因为不同配置下全局变量的内容差异很大。5.2 换了 MATLAB 版本之后的兼容性问题这个代码包毕竟是十几年前的东西在 R2021b、R2023a 这些新版本上偶尔会出现不兼容告警。最常见的一类是“Index exceeds array bounds”往往不是你的参数越界而是老代码内部对离散角度表做了近似索引某些边界值上的浮点误差会触发越界。我的处理方法是遇到这类报错先不慌调出断点看索引变量当前值再和数组实际维数对比。如果确实是差 1 或差几就用min(max(idx, 1), size(...))做一层保护。改完以后要重新跑一遍自带 demo 确认统计特性没有被破坏不能改完就完事。另一个更省事的做法是装一个 MATLAB R2015b 或 R2016b 的旧版本专门跑这个模型但那太麻烦不建议。5.3 大 MIMO 把内存跑爆默认 20 条路径、1 发 1 收、几百个采样点H 矩阵小到可以忽略。可一旦换成 64x64 MIMO或者把仿真时长拉长到几万个采样点H 矩阵的大小会暴涨直接卡死 MATLAB。更合理的做法是分段生成、分段使用。比如一次只生成一段信道做完这一段的误码率统计后立即释放变量再生成下一段。另外可以先用小天线数跑通整条链路确认逻辑没问题后再逐步增加天线数和样本长度。内存问题不是代码 bug而是仿真策略没做好。5.4 角度坐标系和你的波束成形对不上Winner II 的角度定义遵循特定坐标系一般以天线阵列法线方向为 0 度水平角正方向可能是逆时针也可能是顺时针。这和你自己在链路里写波束成形权矢量时的 DOA 约定很容易不一致。我踩过一次很深的坑把 Winner II 的 H 接到某个自适应波束成形算法里方向图总是偏了几十度查了半天才发现是角度方向符号相反。后来我在做角度相关分析前总会先拿官方 demo 里的角度输出和论文给出的角度扩展参考值对一遍。确认坐标系一致再开始调后续算法。5.5 LoS/NLoS 状态切不过来有时候你明明把场景设成了 B1却怎么都看不到直射径。原因通常是两个一是该场景在对应距离下按概率自动判定为 NLoS没有走 LoS 分支二是你修改的use_los_path开关只控制部分函数没能传到核心多径生成模块。判断直射径是否存在有个笨办法把 H 的功率谱画出来看第一径是不是明显比其他径强很多。如果第一径功率很弱说明当前实现很大概率是 NLoS。需要强制 LoS 时要同时检查场景参数、距离、概率开关三个地方而不是只改一个字段。这个检查步骤我写进了自己的仿真脚本模板里每次换场景都会看一遍。6. 从 Winner II 向上走扩展思路6.1 升级到 QuaDRiGa 或 3GPP 38.901如果你做完 Winner II 的基线仿真下一步想贴近 5G 标准可以考虑 QuaDRiGa。它实现了 Winner 以及部分 3GPP 38.901 模型支持大规模天线阵列、3D 角度和连续轨迹移动MATLAB 接口比老代码更友好文档也完善得多。它的核心思想依然是几何随机信道模型所以你在 Winner II 上学到的散射簇、时延扩展、角度扩展概念可以无缝迁移过去。另一个思路是直接使用 3GPP 38.901 里面推荐的信道系数生成流程MATLAB 5G Toolbox 也有相关函数。但要注意协议实现和论文复现之间的差异标准文档里的参数表和参考代码统计特性未必完全一致需要保持怀疑。6.2 大规模 MIMO 和高频段的注意点Winner II 的默认参数并不是为大规模 MIMO 设计的。把天线数设成 128 端口也能出结果但天线间距、阵元方向图和互耦效应等细节就很勉强了。真正做 massive MIMO 仿真时建议把阵列模型拆出来用实际阵列响应矩阵替换掉 Winner II 内置的阵列响应模块这样信道矩阵才能体现空间相关性。毫米波方面Winner II 的 2-6GHz 标定范围不再适用。高频信道里散射簇更稀疏、穿透损耗更严重簇内时延扩展也更小直接用 Winner II 参数会高估信道丰富度。可以先去读 38.901 的高频参数表或者用 NYUSIM 做毫米波专属建模簇数一般设为 17-19 个角扩展也完全不同。最后再分享一个实用习惯不管模型多熟每次拿到新版本代码我都会在固定 SNR 下把channel capacity和一个已知参考实现做对比。如果容量曲线能对上说明信道系数统计特性基本正确如果对不上就先别急着做后续算法。这个习惯帮我挡掉了大量由代码误用导致的无效仿真省下的时间远超投入。本文还有配套的精品资源点击获取