
简介面向无线通信学习者的MATLAB大尺度衰落模型模拟资料聚焦路径损耗与阴影衰落两大核心因素适合通信工程专业学生、科研人员以及需要开展无线网络规划与覆盖评估的工程师参考。资源以ZIP压缩包形式提供体积约59KB目前压缩包内文件条目数显示为0具体文件类型明细暂未提供但描述中已给出完整的仿真思路与可直接套用的MATLAB代码片段。内容覆盖大尺度衰落模型概述、路径损耗公式PL(d)PL(d0)10nlog10(d/d0)的推导应用、利用randn函数模拟对数正态阴影衰落的实现步骤以及将两者叠加后绘制距离-接收功率曲线的完整流程。已有1860人学习通过这份资料可以快速掌握大尺度衰落建模的数值仿真方法理解环境参数对信号传播的影响为后续的通信系统性能分析和网络优化提供实验基础。1. 大尺度衰落模型不是“距离越远信号越差”这么简单它是覆盖规划的底层语法大尺度衰落模型是无线通信里最不性感、却最不能错的一块它决定接收功率在几十米到几公里尺度上怎么衰减覆盖半径、链路预算、小区边缘用户速率全是这套模型算出来的。反直觉的是多径衰落更出名但真正决定覆盖边界的是这套大尺度模型。做 5G/6G 系统级仿真、网络规划、射频链路预算的工程师都应该先把它在本地跑通。这篇直接用代码和参数把它落地讲清楚选型、实现、调参和最容易翻车的几个点。2. 先立住物理概念路径损耗、阴影衰落和模型选型为什么不能混在一起2.1 路径损耗是“可算”的骨架阴影衰落是“不可算”的抖动大尺度衰落模型在工程上通常写成接收功率的 dB 形式P_r P_t G_t G_r - PL(d) - X_σP_t 是发射功率G_t、G_r 是收发天线增益PL(d) 是路径损耗X_σ 是阴影衰落。路径损耗是确定性的、可计算的骨架它只跟距离、频率、天线高度这类宏观几何参数有关同一套站址配置下任何人复算都能得到同一个数。阴影衰落则是对数正态分布的随机抖动σ 是它的标准差单位是 dB反映树木、楼宇、地形起伏对信号的遮挡。为什么要区分这两部分因为它们在仿真里的职责完全不同。路径损耗决定覆盖中位数也就是“平均来看信号衰减到多少”阴影衰落决定覆盖尾部也就是“有多少用户落在中位数以下的深坑里”。做系统级仿真时如果只算路径损耗你会得到一个过度乐观的覆盖圆如果只算阴影衰落你会连半径都不知道怎么收敛。路径损耗的经典起点是自由空间损耗FSPL(dB) 20·log10(4π·d·f/c)这里 d 是距离f 是频率c 是光速。自由空间里斜率是 20 dB/decade也就是距离翻 10 倍损耗加 20 dB。但真实传播环境里地面反射、建筑绕射会让斜率变大宏蜂窝场景常见的是 30 到 45 dB/decade。模型之间最大的分歧点就在这里谁在什么距离上从 20 变成 40就是所谓的“断点距离”breakpoint distance。3GPP TR 38.901 的 UMa城区宏站LOS 场景是典型的双斜率模型。断点之前 PL1 接近自由空间斜率约 22 dB/decade断点之后 PL2 斜率变成 40 dB/decade。断点距离可以近似看成第一菲涅尔区被地面障碍物遮挡的分界。用公式算断点距离时天线高度差和频率都会影响它的位置频率越高、挂高越高断点越远。这个参数是后面所有调参里第一个容易出错的点后面避坑章节会专门展开。2.2 工程里常用的大尺度衰落模型一张对比表实际项目里我见过四种主流选择很多新人上来直接挑最熟悉的用结果频段或场景根本不匹配。模型典型适用场景频率与距离范围工程特点与坑Okumura-Hata150 MHz - 1.5 GHz 宏蜂窝1 km - 20 km经典但公式的城区修正项依赖查曲线频率上限低5G 中频段用不了COST 231-Hata1.5 GHz - 2 GHz 宏蜂窝1 km - 20 kmHata 的扩展版覆盖 2G/3G 主频段高于 3.5 GHz 直接失效ITU-R P.1238室内单点覆盖0.3 GHz 以上给的是穿墙和楼层衰减参考值不适合宏站扇区仿真3GPP TR 38.9015G/6G 城区、郊区、室内0.5 GHz - 100 GHz10 m - 5 kmUMa/UMi/RMa 全套含 LOS 概率、O2I 穿透损耗最适合 NR 系统级仿真NYUSIM毫米波点对点0.5 GHz - 100 GHz侧重空间一致性等射线级细节参数多跑系统级仿真时太重选型逻辑其实很简单先确认频段和场景。做 5G 中低频宏站COST 231-Hata 在 2 GHz 内还能凑合过了 3.5 GHz 就必须换。做室内覆盖P.1238 提供的楼层穿透损耗比任何自由空间外推都靠谱。做毫米波系统级仿真38.901 或 NYUSIM 二选一前者参数是表格式的、容易批量生成后者更靠近射线追踪但代价是计算量。2.3 为什么默认首选 3GPP TR 38.901我的习惯是无脑默认 38.901除非有明确理由换掉。原因有三条。第一频段覆盖 0.5 GHz 到 100 GHz从 LTE 低频到 5G 毫米波都不需要换模型体系换场景只需要换表。第二它把 LOS 判定、路径损耗、阴影衰落、室外到室内穿透损耗写在同一个标准里场景切换时不至于自己去拼凑不同来源的参数。第三38.901 的 UMa/UMi 公式做了断点平滑处理数值稳定性好不像一些老模型在断点附近给出跳变的损耗导致仿真曲线出现不自然的台阶。需要注意边界38.901 只解决平均衰落趋势和阴影抖动快衰落不归它管快衰落要另配 TDL 或 CDL 抽头模型。这个边界很多人工程上没分清在同一个仿真里把两者混算最终覆盖概率怎么算都是错的。3. 用 Python 在本地跑通大尺度衰落模型UMa/UMi 最小可复现实现3.1 最小环境与目录结构不需要任何重型框架Python 3.9 以上加 numpy 和 matplotlib 就够。工程目录我一般这么建mkdir large_scale_fading cd large_scale_fading python3 -m venv venv source venv/bin/activate pip install numpy matplotlib建虚拟环境是为了隔离依赖避免后面接系统级仿真时 numpy 版本冲突。matplotlib 只用来画 CDF 验证结果不参与核心计算。整个模型核心逻辑只有三个函数路径损耗、LOS 概率、蒙特卡洛抽样。3.2 实现 UMa/UMi 路径损耗双斜率与断点距离这是 38.901 Table 7.4.1-1 里最常用的两组公式。先实现断点距离和 UMa 的 LOS/NLOS 路径损耗import numpy as np C 3e8 # 光速m/s def breakpoint_distance(fc_ghz: float, h_bs: float, h_ue: float) - float: TR 38.901 断点距离 d_BPh_bs/h_ue 是站点和 UE 相对地面的高度单位 m fc_hz fc_ghz * 1e9 return 4 * (h_bs - 1.0) * (h_ue - 1.0) * fc_hz / C def pl_uma(d3d: np.ndarray, fc_ghz: float, h_bs: float, h_ue: float, los: bool) - np.ndarray: UMa 路径损耗d3d 是三维距离单位 m d_bp breakpoint_distance(fc_ghz, h_bs, h_ue) fc fc_ghz if los: pl1 28.0 22 * np.log10(d3d) 20 * np.log10(fc) pl2 28.0 40 * np.log10(d3d) 20 * np.log10(fc) - 9 * np.log10(d_bp ** 2 (h_bs - h_ue) ** 2) return np.minimum(pl1, pl2) # UMa NLOS适用距离 10 m ~ 5000 m return 13.54 39.08 * np.log10(d3d) 20 * np.log10(fc) - 0.6 * (h_ue - 1.5)这段代码做的事是先把断点距离算出来再在 LOS 场景下同时计算断点前后两条路径损耗曲线用 np.minimum 取较小值。工程上建议用 min 而不是显式 if 分段因为两条曲线在断点附近天然连续分段写法一旦边界错位曲线会出现一个肉眼可见的台阶。PL2 里的 d_bp 平方项加上 (h_bs - h_ue) 平方是标准里防止距离趋于 0 时的数值奇异抄代码时别嫌啰嗦删掉。NLOS 公式里最后一项 -0.6·(h_UE - 1.5)UE 越高损耗越小这是 UMa 特有的修正项。UMi 的公式结构完全一样只是常数不同LOS 的 PL1 用 32.4 21·log10(d3d) 20·log10(fc)NLOS 用 32.4 20·log10(fc) 31.9·log10(d3d)。RMa 的 NLOS 涉及平均建筑高度和街道宽度做郊区仿真时直接查 38.901 的表别凭记忆抄参数。3.3 加入 LOS/NLOS 概率与对数正态阴影衰落路径损耗算的是 LOS 或 NLOS 两种分支但一个 UE 到底走哪条分支在仿真里是个随机过程。38.901 给了距离相关的 LOS 概率def los_probability_uma(d2d: np.ndarray) - np.ndarray: UMa LOS 概率d2d 是水平距离单位 m p np.ones_like(d2d, dtypefloat) mask d2d 18 p[mask] 18 / d2d[mask] np.exp(-d2d[mask] / 63) * (1 - 18 / d2d[mask]) return p def los_probability_umi(d2d: np.ndarray) - np.ndarray: p np.ones_like(d2d, dtypefloat) mask d2d 18 p[mask] 18 / d2d[mask] np.exp(-d2d[mask] / 36) * (1 - 18 / d2d[mask]) return p关键点来了LOS 概率是用来做伯努利抽样的不是用来做线性加权的。每个 UE 要么是 LOS要么是 NLOS不能把一个 UE 拆成 LOS 分支和 NLOS 分支的混合体。做系统级仿真时UE 是物理世界里的一个终端它面对基站只有看得见和看不见两种状态。具体做法是生成均匀随机数与概率比较rng np.random.default_rng(42) is_los rng.random(n_ue) los_probability_uma(d2d)LOS 分支的阴影衰落标准差是 4 dBUMa NLOS 是 6 dBUMi NLOS 是 7.82 dBRMa NLOS 是 8 dB。标准差不同边缘用户的表现会差很多这部分参数最容易被混用后面避坑会细说。3.4 一次蒙特卡洛仿真的输出与验证把上面所有函数拼起来跑一轮完整采样def simulate_uma(n_ue5000, fc_ghz3.5, h_bs25.0, h_ue1.5, d_min30.0, d_max800.0, seed42): rng np.random.default_rng(seed) d2d rng.uniform(d_min, d_max, n_ue) d3d np.sqrt(d2d ** 2 (h_bs - h_ue) ** 2) is_los rng.random(n_ue) los_probability_uma(d2d) pl np.empty(n_ue) pl[is_los] pl_uma(d3d[is_los], fc_ghz, h_bs, h_ue, losTrue) pl[~is_los] pl_uma(d3d[~is_los], fc_ghz, h_bs, h_ue, losFalse) shadow_std np.where(is_los, 4.0, 6.0) pl pl shadow_std * rng.standard_normal(n_ue) return d2d, is_los, pl建议把 seed 固定下来任何一个参数改动之后结果都可复现、可对比。随机撒点范围选 30 m 到 800 m是因为 38.901 的 UMa NLOS 公式要求距离大于 10 m近距离样本取 30 m 起稳一点。验证结果画 CDF 并做链路预算闭合import matplotlib.pyplot as plt pl_sorted np.sort(pl) cdf np.arange(1, n_ue 1) / n_ue plt.plot(pl_sorted, cdf) plt.xlim(70, 180) plt.xlabel(Path loss shadow (dB)) plt.ylabel(CDF) plt.title(UMa large-scale fading CDF) plt.show() eirp_dbm 53.0 # 典型 5G 宏站 40 W 每通道加天线增益后的等效全向辐射功率 sensitivity_dbm -95.0 # 数据信道解调门限随 MCS 和带宽变化 rx_dbm eirp_dbm - pl coverage_prob np.mean(rx_dbm sensitivity_dbm) print(fLOS ratio: {is_los.mean():.3f}, coverage probability: {coverage_prob:.3f})这段代码的意图是双重的CDF 曲线让你直观检查 PL 分布的形状是否合理链路预算闭合则把损耗换算成覆盖概率如果 EIRP 和 sensitivity 用实际工程值最后算出来的覆盖概率应该和网规经验值同量级。如果 LOS 占比超过 50%或者覆盖概率接近 100%基本可以断定抽样距离范围取近或 LOS 概率函数用错下一步就去查参数而不是怀疑链路预算。4. 大尺度衰落模型参数怎么调从 3.5 GHz 到 28 GHz 的路线图4.1 一份可以直接抄的参数表调参的前提是知道每个参数动谁、动了影响哪段曲线。下面这份是我做系统级仿真时常用的默认值和调参方向参数UMa/UMi/RMa 默认调参方向对结果的影响fc3.5 GHz28/39 GHzNLOS 和高频穿透损耗显著增加支持范围明显收窄h_BSUMa 25 m / UMi 10 m / RMa 35 m按实际站点挂高影响断点距离和 NLOS 高度修正项h_UE1.5 m车联可设 1.5-2 m无人机需单独建模影响断点距离与 UMa NLOS 最后一项shadow_stdUMa LOS 4 / NLOS 6UMi NLOS 7.82 / RMa NLOS 8值越大边缘用户 CDF 尾部越厚d2D 范围UMi 10-2000 m / UMa 10-5000 m不能外推距离越远 LOS 占比越低NLOS 主导室外到室内 O2I无低频 10-20 dB28 GHz 25-35 dB不叠加会让高频覆盖虚高 20 dB 以上4.2 频率从 3.5 GHz 换到 28 GHz哪些参数必须跟着动把 fc 从 3.5 GHz 改成 28 GHz公式里的 20·log10(fc) 会自动增加约 18 dB 损耗但这只是自由空间部分。真实高频仿真还必须同时改三件事。第一室外到室内穿透损耗。38.901 的 UMa NLOS 模型假设 UE 在户外开阔环境如果把用户放在楼内28 GHz 下混凝土墙和双层玻璃的穿透损耗可能到 25 dB 到 40 dB远高于 3.5 GHz 的 10 dB 到 20 dB。第二大气吸收。28 GHz 的氧气和水汽吸收大约是每公里零点几 dB短距离仿真可以忽略但小区半径超过 1 km 时必须叠加 ITU-R P.676 的曲线。第三雨衰。这不是 38.901 的范畴如果仿真场景涉及降雨可用性指标要单独叠加 ITU-R P.838。除了这些附加项LOS 概率函数在 28 GHz 不变还是基于距离的那个公式。原因在于 LOS 判定本质上是几何遮挡问题频率本身不改变“看得见/看不见”的物理事实。很多人在这里踩坑以为高频 LOS 概率要打折结果覆盖率被砍得面目全非。4.3 输出判据不要只看平均路径损耗调完参数后我一般看三个数字和一张图中位数路径损耗、第 95 百分位路径损耗、覆盖概率以及路径损耗的 CDF 曲线。中位数反映整体站型是否合理95 百分位反映边缘深坑用户会不会失联覆盖概率则把三者综合成一个业务指标。CDF 曲线的头部和尾部分别对应近点和远点。如果头部曲线出现明显的“拐弯台阶”通常是断点距离或 LOS 概率写错如果尾部比预期厚很多先怀疑 shadow_std 用了哪个场景的值。一个快速自检的基准UMa、3.5 GHz、站点高 25 m、UE 高 1.5 m在 500 m 距离附近的中位路径损耗应该落在 130 dB 到 145 dB 之间LOS 占比约三到四成。如果算出来完全不在这个区间先别急着调 EIRP回头检查公式里的常数和距离单位单位错误是大尺度衰落仿真里最常见的翻车原因。5. 大尺度衰落模型常见问题排查五个必查的避坑点5.1 LOS 概率当成线性加权覆盖圆直接虚高现象仿真算出来的覆盖概率异常高CDF 曲线整体左移哪怕把 EIRP 降到 40 dBm 边缘用户依然“全都连得上”。原因新手常把路径损耗写成 PL P_LOS · PL_LOS (1 - P_LOS) · PL_NLOS这在数学上看着像期望值但物理上不成立。一个 UE 不可能同时处于 LOS 和 NLOS 两种状态的混合体。这条近似的实质是把所有用户都放在了两种状态的中间地带而中间地带的损耗恰好比 NLOS 低很多。解决用伯努利抽样每个 UE 根据概率掷一次骰子只走 LOS 或 NLOS 其中一支。抽完样后可以统计实际 LOS 占比和理论概率曲线做对比来验证抽样器是否正确。5.2 站点高度用了海拔断点距离全线崩溃现象断点距离算出来要么几百米、要么几百公里LOS 曲线在近距离就出现异常弯曲。原因GIS 数据里常见的是天线海拔高度而 38.901 公式里的 h_BS 是天线相对地面的挂高。如果基站建在山顶海拔高度比地面相对高度大几百米断点距离公式里的 (h_BS - 1) 会被放大成一个荒谬的值。解决h_BS 天线海拔 - 地面海拔必须用相对地面的有效挂高。城区宏站典型值 25 m郊区宏站典型值 35 m微站 10 m。做仿真前先写一个小函数从 DEM 数据里提取地面高度别手填。5.3 阴影衰落标准差混用CDF 尾部失真现象UMa 场景的 95 百分位路径损耗比其他工具算出的同一场景偏大或偏小好几 dB换了模型又对不上。原因38.901 给的是分场景的标准差UMa NLOS 是 6 dBUMi NLOS 是 7.82 dBRMa NLOS 是 8 dB。有人把查到的 UMi 值套到 UMa尾部分布就厚了快 2 个 dB有人统一用 4 dB边缘覆盖被严重乐观化。解决shadow_std 做成一个按场景索引的字典代码里强制从字典取不要裸写数字。室内场景还要单独定义O2I 的额外损耗和阴影叠加规则跟室外完全不同。5.4 dB 与线性域混算均值漂移还看不出来现象路径损耗中位数看起来正常但覆盖概率或者平均接收功率总是差 1 dB 到 2 dB怎么调 EIRP 都对不齐。原因阴影衰落是对数正态分布在 dB 域是对称的但在线性域不对称。如果先把某条链路在 dB 域算完再转线性功率求平均平均功率会比中位数功率高如果反过来把线性功率平均再转 dB又会得到一个偏大的“平均损耗”这个偏置和 σ² 相关。解决仿真里分清两个量dB 域的中位路径损耗用来画 CDF线性域的平均功率用来算业务指标。不能在一条计算链里混着用。5.5 高频仿真忽略 O2I28 GHz 覆盖半径比实测翻倍现象28 GHz 仿真显示小区边缘 500 米外 RSSI 还够用实测同一站址 200 米外已经连不上。原因38.901 的 UMa NLOS 并不包含穿墙损耗。高频信号对建筑材料的穿透衰减极其敏感混凝土外墙加金属玻璃幕墙在 28 GHz 下可能达到 30 dB 以上。这个损耗比路径损耗本身的增长速度还快忽略它等于把 NR 高频当低频规划。解决把所有 UE 按室内/室外比例拆分室内 UE 叠加平均穿透损耗低频3.5 GHz建议 10 到 20 dB高频28 GHz建议 25 到 35 dB具体墙体材料用 ITU-R P.1238 或厂家实测插损表。长距离室外链路再叠加 ITU-R P.676 气体吸收两条链路加起来才是完整的大尺度衰落。6. 把大尺度衰落模型接进系统级仿真之前先和射线追踪数据对拍一次统计模型跑顺之后我会多做一步拿同一张数字地图用射线追踪工具WinProp、Wireless InSite 或自研射线引擎算一批真实的路径损耗样本和 38.901 模型输出做距离分箱对比。这一步不是为了证明统计模型“准”而是为了找出场景里有没有系统性的偏差比如地形遮挡、街道峡谷效应、水面反射这类 38.901 感知不到的因素。对拍方法不复杂把射线追踪算出的每条链路的路径损耗、距离导出来按距离分箱箱内取中位数差。采用中位数而不是均值是因为个别被极端遮挡的样本会把均值带偏。def compare_with_raytracing(d2d, pl_rt, pl_model, bin_edges): idx np.digitize(d2d, bin_edges) for b in range(1, len(bin_edges)): mask idx b if mask.sum() 20: continue median_delta np.median(pl_rt[mask] - pl_model[mask]) print(f{bin_edges[b-1]:.0f}-{bin_edges[b]:.0f} m: delta median {median_delta:.2f} dB)箱内至少 20 个样本再统计否则中位数不稳定。如果某个距离箱的偏差超过 1.5 dB我会先检查射线追踪场景里是否有明显的街道峡谷或大型遮挡物确认没有之后再考虑在统计模型基础上加一个场景偏差修正项。这个方法同样适用于实测路测数据用 GNSS 轨迹对齐距离按同样的分箱逻辑算模型与实测的偏差。我做这类仿真有个习惯每次换频段、换城市形态、换站高都强制自己先跑一轮对拍再进系统级仿真。原因很简单统计模型给的是“平均世界的答案”而你的场景里总有那么几栋楼、几座山不按平均值来。对拍一次心里就有底。希望这些参数、代码和排查思路能帮你在做 5G/6G 覆盖仿真时少走几趟弯路。本文还有配套的精品资源点击获取