拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

5G信道容量随距离衰减仿真:从香农公式到3GPP路径损耗模型

5G信道容量随距离衰减仿真:从香农公式到3GPP路径损耗模型 简介面向通信工程学习者与5G研究人员这份MATLAB仿真源码包聚焦通信距离增加时信道容量的变化规律。项目基于香农公式综合考虑自由空间传播损耗、多径衰落、阴影效应、毫米波频段衰减以及MIMO天线配置等实际因素通过可运行的脚本模拟信噪比随距离下降而导致信道容量衰减的过程同时展示功率控制、混合预编码对容量损失的补偿作用。压缩包共八个文件全部为MATLAB脚本大小约九千字节涵盖耦合矩阵、导向矢量、非视距路径损耗、MIMO复用与混合预编码、氧气吸收损耗及CDL平均容量等模块文件规模虽小但功能独立便于按需修改和扩展对比。目前已有一百四十四人学习可直接用于5G信道仿真入门、课程实验或二次开发帮助读者直观理解距离、信噪比与信道容量之间的量化关系进而为实际网络部署中的功率策略与覆盖优化提供理论参考。1. 信道容量随距离衰减一张仿真图背后的两套模型把 5G 通信系统里“信道容量”和“通信距离”放在一起做仿真很多人第一反应是画一条单调下降的曲线距离越远容量越低。实际把源码跑起来后你会发现这条曲线在几十米到几百米之间经常出现一个明显的“折点”折点之后容量下降速度陡然变快。这个折点不是 bug而是 3GPP 信道模型里路径损耗分段函数的边界——也就是基站覆盖从“近场视距”切换到“远场非视距”的位置。本文要做的就是把这条容量-距离曲线背后的模型公式、仿真源码、参数设置和常见踩坑完整讲透让新手能直接跑出图让熟手能根据自己的频段、站高、天线配置调出更贴合真实 5G 基站的曲线。2. 从香农公式到链路预算容量仿真里必须写对的三层公式2.1 信道容量的定义单位带宽上的香农极限容量仿真的核心永远是香农公式的离散化实现。单条 AWGN 信道上容量 C 等于带宽 B 乘以 log2(1 SNR)SNR 是接收端的信噪比单位是线性比值不是 dB。这个式子看起来简单但一放到 OFDM 系统里就要做三处扩展带宽要拆成子载波带宽信噪比要换成每个子载波上的 SINR天线要从一根变成多根。工程上常见的做法是先算子载波级容量再求和得到系统总容量。比如 5G NR 在 100 MHz 带宽、30 kHz 子载波间隔下有效子载波约 3276 个每个子载波带宽 30 kHz总容量就是 3276 个 B_sc·log2(1SINR_k) 的和。SINR_k 是第 k 个子载波上的信干噪比它由接收功率、噪声功率和干扰功率共同决定。做 4G/5G 通讯链路仿真时干扰项要不要加取决于仿真目标是单用户极限还是多用户容量本文先按无干扰的链路预算算干扰的影响在最后一章验证部分单独讨论。还有一个容易忽略的前提香农公式给的是理论上限实际系统用 LDPC 编码能达到的速率通常要打个折扣。比如 5G 的峰值速率计算里会乘一个 0.9 左右的编码效率系数。如果你拿仿真结果和“5g峰值速率计算公式”算出来的理论值对比差的那部分主要就是编码效率、导频开销和保护间隔占掉的资源。2.2 3GPP TR 38.901路径损耗模型近距离与远距离是两套公式信道容量随距离下降本质上是路径损耗随距离上升。5G 仿真最常用的是 3GPP TR 38.901 里定义的 UMaUrban Macro城区宏站模型它把视距LOS和非视距NLOS分成两套公式其中 LOS 又按断裂点Break Point分近距离和远距离两段。近距离 LOS 路径损耗公式是PL 28.0 22·log10(d) 20·log10(fc)其中 d 是基站到终端的距离单位米fc 是载波频率单位 GHz。可以看到距离项系数只有 22说明在近场视距下路径损耗随距离增长得比较慢近似自由空间传播的平方律。远距离 LOS 公式变成PL 28.0 40·log10(d) 20·log10(fc) - 9·log10(d_BP² (h_BS - h_UT)²)距离项系数从 22 跳到 40意味着超过断裂点之后路径损耗每十倍距离增加 40 dB比近场陡得多。断裂点 d_BP 由天线高度决定d_BP 2π·h_BS·h_UT·fc / ch_BS 是基站高度h_UT 是终端高度c 是光速。以典型的宏站参数 h_BS25 m、h_UT1.5 m、fc3.5 GHz 来算断裂点约在 2749 米。这就是为什么很多仿真把横轴范围设到 500 m 以内时全程都是近距离 LOS 模型看不到那个“折点”。想看到容量曲线的拐点要么把距离拉到几公里要么降低基站高度比如把 h_BS 降到 10 米断裂点会缩短到 1 公里左右。NLOS 模型不区分近距离远距离直接是PL 13.54 39.08·log10(d) 20·log10(fc) - 0.6·(h_UT - 1.5)适用范围是 10 m 到 5000 m。这套模型的好处是没有任何概率性参数复现起来确定性强适合做容量对比实验。缺点也在这里真实场景里终端从视距切换到非视距是渐变的还有 LOS 概率问题这个在第 5 章具体讲。2.3 从SNR到容量OFDM子载波与MIMO的占位有了路径损耗接收功率 Pr Pt - PL单位都是 dBm噪声功率 Pn -174 dBm/Hz 10·log10(B) NFNF 是接收机噪声系数通常取 7 dB。SNR 就是 Pr - Pn单位 dB代入香农公式前要换算回线性值。这里我给出一份完整的链路参数表后面的源码都按这张表跑参数值说明载波频率 fc3.5 GHz5G 中频主流频段系统带宽 B100 MHz对应 273 个 RB子载波间隔 SCS30 kHz5G NR 基础配置有效子载波数3276273 RB × 12 子载波基站发射功率43 dBm典型宏站 20 W基站高度 h_BS25 mUMa 场景默认终端高度 h_UT1.5 m手持终端噪声系数 NF7 dB包含馈线损耗噪声谱密度-174 dBm/Hz常温热噪声MIMO 的容量写法要注意如果做 2×2 天线配置且信道理想正交容量可以近似写成 B·log2(1 2·SNR)增益体现在 SNR 前的系数上。真实 MIMO 信道有相关性不会达到 2 倍线性增益仿真里要体现这一点就要生成空间相关信道矩阵。本文第 3 章的源码先给单天线和理想 2×2 两套对照第 6 章再讲怎么验证 MIMO 增益是否合理。3. 用Python搭建容量-距离仿真源码结构与关键参数3.1 环境依赖与脚本骨架这个仿真只需要 NumPy 和 Matplotlib 两个库Python 3.8 以上就能跑。我把整个仿真拆成四个函数路径损耗计算、信道生成、容量计算、主循环绘图。这样的结构方便你单独替换某个模块比如把 UMa 换成 UMi城区微站或者 Rural 场景只需要改路径损耗函数。# capacity_vs_distance.py import numpy as np import matplotlib.pyplot as plt # ---- 链路参数 ---- FC 3.5e9 # 载波频率 3.5 GHz B_SC 30e3 # 子载波间隔 30 kHz N_SC 3276 # 有效子载波数100 MHz / 30 kHz B_TOTAL B_SC * N_SC # 系统带宽约 98.28 MHz PT_DBM 43.0 # 基站发射功率 43 dBm NF_DB 7.0 # 接收机噪声系数 7 dB H_BS 25.0 # 基站高度 H_UT 1.5 # 终端高度 NOISE_PSD -174.0 # 噪声谱密度 dBm/Hz这里的关键是把“系统带宽 100 MHz”拆成“子载波间隔 × 有效子载波数”。273 个 RB 乘以 12 个子载波得到的 3276 是 5G NR 100 MHz 带宽在 30 kHz SCS 下的典型有效子载波数实际还要去掉 DC 子载波和边缘保护子载波但对容量仿真影响很小可以忽略。噪声功率在代码里用噪声谱密度加带宽换算保证单位是 dBm 而不是 dBm/Hz。3.2 路径损耗与信道生成函数路径损耗函数严格按 3GPP TR 38.901 UMa 模型实现分 LOS 近距离、LOS 远距离和 NLOS 三段。断裂点距离用上一章的公式算出来这里注意频率必须用 Hz 代入算出的断裂点才是米。def break_point(fc, h_bs, h_ut): 计算 LOS 断裂点距离单位米fc 单位 Hz c 3e8 return 2 * np.pi * h_bs * h_ut * fc / c def path_loss_uma(d, fc_ghz, h_bs, h_ut, losTrue): UMa 路径损耗d 单位米fc_ghz 单位 GHz 返回 PL 单位 dB d_bp break_point(fc_ghz * 1e9, h_bs, h_ut) if los: if d d_bp: return 28.0 22 * np.log10(d) 20 * np.log10(fc_ghz) else: return (28.0 40 * np.log10(d) 20 * np.log10(fc_ghz) - 9 * np.log10(d_bp**2 (h_bs - h_ut)**2)) else: return 13.54 39.08 * np.log10(d) 20 * np.log10(fc_ghz) - 0.6 * (h_ut - 1.5)这段代码里最容易出错的是 d_bp 的单位一致性。break_point 函数里 h_bs、h_ut 单位都是米fc 单位是 Hz算出来的 d_bp 是米。但 path_loss_uma 里的 d 是入参的距离也叫米两者之间不需要单位换算。我在第一个版本里把 fc_ghz 直接当成 GHz 代入断裂点计算算出来的 d_bp 小了三倍容量曲线在 800 米左右提前拐弯调了半天才发现是单位问题。这段代码算出的 NLOS 路径损耗在近距离时会低于 LOS覆盖了部分场景是符合 38.901 公式本身的特征的不要觉得是 bug。3.3 蒙特卡洛容量统计与曲线绘制衰落信道下的容量不能只用一次信道实现就算完。瑞利衰落导致瞬时 SNR 服从指数分布必须做蒙特卡洛统计平均。这段代码对每个距离点生成多次信道实现每次算容量后取平均最终画出一条平滑的平均容量曲线。def rayleigh_channel_power(n_sc, n_tx, n_rx): 生成瑞利衰落信道返回每个子载波上的信道功率增益线性 n_tx/n_rx 为发射/接收天线数这里简化成独立同分布 h (np.random.randn(n_sc, n_rx, n_tx) 1j * np.random.randn(n_sc, n_rx, n_tx)) / np.sqrt(2) # 单天线场景取信道幅度平方的平均 if n_tx 1 and n_rx 1: return np.abs(h[:, 0, 0])**2 # MIMO 场景理想正交假设下用所有特征信道功率和 return np.sum(np.abs(h)**2, axis(1, 2)) def capacity_at_distance(d, n_tx, n_rx, n_trials2000): 对单个距离点做蒙特卡洛平均容量统计 pl_db path_loss_uma(d, FC / 1e9, H_BS, H_UT, losTrue) pr_dbm PT_DBM - pl_db pn_dbm NOISE_PSD 10 * np.log10(B_TOTAL) NF_DB snr_linear 10**((pr_dbm - pn_dbm) / 10) cap_sum 0.0 for _ in range(n_trials): g rayleigh_channel_power(N_SC, n_tx, n_rx) # 每个子载波的 SNR 是平均 SNR 乘上该子载波上的信道增益 snr_k snr_linear * g cap_sum np.sum(B_SC * np.log2(1 snr_k)) return cap_sum / n_trials / 1e6 # 单位 Mbit/s蒙特卡洛次数 n_trials 设为 2000每个距离点要循环 2000 次每次算 3276 个子载波的容量。距离点设 50 个时总循环是 50×2000×3276约 3.3 亿次操作NumPy 向量化后大概几十秒能跑完。如果嫌慢可以先把 N_SC 降到 600等效只仿真中心频段附近的 20 MHz结果趋势不变但数值会整体变小。主循环里距离画在 log 坐标上从 10 m 到 5000 m 取 50 个点这样近距离和远距离的曲线形态都能看全。3.4 2x2 MIMO对照容量随距离的增益表现MIMO 的对照实验这样设计同样一条路径损耗曲线下分别跑 SISO 和 2×2 MIMO 的容量画在同一张图上。理想 2×2 的容量增益不是恒定的 2 倍而是在高 SNR 时接近 2 倍、低 SNR 时小于 2 倍。用下面这段代码把两个配置的结果对比出来。def run_simulation(): dists np.logspace(np.log10(10), np.log10(5000), 50) cap_siso [capacity_at_distance(d, 1, 1) for d in dists] cap_mimo [capacity_at_distance(d, 2, 2) for d in dists] plt.figure(figsize(9, 5)) plt.semilogx(dists, cap_siso, labelSISO) plt.semilogx(dists, cap_mimo, label2x2 MIMO) plt.xlabel(Distance (m)) plt.ylabel(Capacity (Mbit/s)) plt.legend() plt.grid(True, whichboth, linestyle--, alpha0.5) plt.title(5G Channel Capacity vs Distance (UMa LOS)) plt.savefig(capacity_vs_distance.png, dpi150) plt.show()画出来的图就是“mimo信道容量图像”里最常见的形态两条曲线在近距离都趋于饱和MIMO 曲线比 SISO 明显高随着距离增大两条曲线先后进入快速下降段下降斜率受路径损耗指数 22 和 40 控制。注意这里的 MIMO 是理想正交假设下的上界真实空间相关信道会让曲线低一些还能用容量图像观察相关性导致的“容量饱和效应”——天线越多相关性对容量的拖累越明显这部分在第 6 章展开。4. 频段、带宽与基站高度调参后容量曲线怎么变4.1 载波频率从2.1GHz换到3.5GHz再看曲线把 FC 从 3.5 GHz 改成 2.1 GHz重新跑一遍仿真你会看到整条容量曲线向上平移。原因是 38.901 路径损耗公式里频率项系数是 20·log10(fc)频率从 3.5 GHz 降到 2.1 GHz路径损耗减少约 20·log10(3.5/2.1) ≈ 4.4 dB。4.4 dB 在香农公式里对应容量变化大约 10% 到 15%近距离时更明显远距离时因为路径损耗已经很大容量本来就被压得很低绝对变化反而小。这个现象给出来的工程启示是低频覆盖距离远的本质不是“低频容量高”而是“低频路径损耗小把同样的容量推到更远的距离”。2.1 GHz 和 3.5 GHz 在密集城区做容量仿真时差距往往不是容量大小本身而是达到相同容量目标比如下行 100 Mbit/s的最远距离差了 30% 左右。在你的源码里只需要改 FC 一个变量两张曲线的对比就能写成一段结论5G 中频组网时容量目标覆盖半径的决定因素一半是频率一半是站高和场景。4.2 带宽对容量的线性抬升与定位差异带宽的影响最直接容量公式里带宽是乘性因子带宽翻倍容量接近翻倍。但这里有一个隐含条件——噪声功率也会跟着带宽翻倍因为 Pn N0·B所以 SNR 里带宽的影响被抵消了。也就是说从 40 MHz 换到 100 MHz容量增长不是线性到 2.5 倍而是小于这个比例。实际仿真的结论是这样的在干扰受限区域靠近基站SNR 很高log2(1SNR) 接近饱和此时容量增长主要由带宽贡献100 MHz 相比 40 MHz 能带来接近 60% 的容量提升在噪声受限区域小区边缘SNR 接近 0 dB 甚至更低log2(1SNR) 随 SNR 线性变化带宽翻倍带来的额外噪声会吃掉一部分带宽增益容量提升只剩 40% 到 50%。这段分析直接回答了“5G 峰值速率计算公式里为什么要乘带宽”以及“边缘用户换了大带宽为什么没感觉到速率翻倍”两个问题。做多带宽对比仿真时代码里需要同步改两个地方B_TOTAL 和有效子载波数 N_SC。40 MHz 在 30 kHz SCS 下对应 106 个 RBN_SC 设为 106×121272100 MHz 对应 273 个 RBN_SC3276。只改 B_TOTAL 不改 N_SC 的话相当于用一个 100 MHz 的载波算容量却只用 40 MHz 的噪声功率结果会偏高 20% 以上。4.3 基站高度与断裂点位置的关系断裂点距离 d_BP 和基站高度、终端高度的乘积成正比。h_BS 从 25 米降到 10 米断裂点从约 2749 米缩短到约 1099 米。这意味着低站高场景下容量曲线在 1 公里附近就会出现斜率突变而宏站 25 米场景下仿真到 3 公里都看不到明显的“折点”。这个细节在工程上有实际意义5G 室外补热站点常常挂在 10 到 12 米的路灯杆或楼顶抱杆上这类站点的覆盖半径本来就在 300 到 500 米此时断裂点出现在覆盖范围边缘附近容量衰减特性比宏站更陡峭。仿真时如果你的目标是“判断这个 10 米站点能不能覆盖到 400 米处并保证 50 Mbit/s 下行容量”把 h_BS 改成 10 米跑一遍就是最直接的方法。修改时注意断裂点重新计算不要把 25 米站高下的 d_BP 硬带进新场景否则曲线拐点位置会失真。4.4 阴影衰落标准差对容量波动的影响前面所有仿真都是确定性路径损耗没有加阴影衰落。真实 5G 基站覆盖里建筑物遮挡会引起 4 到 8 dB 的对数正态阴影衰落UMa 场景的标准差一般取 6 dB。加了阴影衰落之后每个距离点上的接收功率不再是一个固定值而是围绕均值波动的随机变量。阴影衰落对容量的影响分成两层。第一层是“均值偏移”由于香农容量对 SNR 是凹函数SNR 的随机波动会让平均容量低于确定性模型的容量这个现象在数学上叫詹森不等式效应。第二层是“覆盖边界模糊”确定性模型算出的覆盖半径是一个清晰的距离加了阴影衰落之后边缘地带的容量变成一个分布仿真时要改为统计“容量大于某阈值”的概率这种指标叫覆盖概率或容量中断概率。跑这种统计仿真时蒙特卡洛次数要加到 5000 以上否则 5% 概率区间的数值抖动很大。实现阴影衰落只需要在接收功率上叠加一个高斯随机量def apply_shadow_fading(pr_dbm, sigma_db6.0): 叠加对数正态阴影衰落sigma_db 是标准差单位 dB return pr_dbm np.random.normal(0, sigma_db, sizepr_dbm.shape)注意这段代码要放在路径损耗函数之后、噪声功率计算之前。阴影衰落的标准差不要设成 0否则公式里 ln(0) 会出问题很多新手在这里翻车。5. 信道容量仿真常见踩坑五个必须知道的边界5.1 容量曲线在断裂点附近出现跳变现象仿真出的容量-距离曲线在某个距离附近不是平滑过渡而是出现一个明显的“台阶”近处容量和远处容量在拐点处不连续。原因38.901 的近距离 LOS 公式和远距离 LOS 公式在断裂点处的路径损耗计算值本身就不完全连续两个公式在 d_BP 处的差值可达 1 到 2 dB。解决如果只关心容量趋势可以在断裂点前后各取一段距离做线性插值过渡或者直接忽略这个跳变在论文和报告里标注“断裂点处模型自身存在不连续”。我一般会用后者因为插值过渡反而会引入人为的“平滑假象”。5.2 距离单位混用dB公式里的m和km现象把距离从米改成千米后容量曲线整体偏移了几十 dB甚至出现负容量。原因38.901 路径损耗公式里 d 的单位是米log10(d) 直接代入如果 d 是 0.5 km必须代入 500 而不是 0.5。一些参考代码习惯先把距离转成 km 再处理导致公式形式和 3GPP 原始定义不一致。解决所有距离变量在代码里统一用米单位转换只发生在绘图时——横轴用 plt.semilogx 时自动标注“Distance (m)”不要手动除以 1000。我用这个规矩避免过至少三次单位事故。5.3 单次信道实现的容量没有参考意义现象只做一次信道生成就画曲线结果曲线毛糙不堪相邻距离点的容量差异能达到 20%。原因瑞利衰落下的瞬时 SNR 波动范围很大一次实现的容量是“瞬时容量”不是“平均容量”。解决蒙特卡洛次数至少 1000 次取容量均值后再画图。如果你每次跑出来的曲线形态还不稳定把次数提到 5000 并且固定随机种子保证可复现。这里有个血泪经验固定随机种子是必须写的否则每次调参后曲线形状都对不上很难判断是参数影响还是随机性翻车。5.4 用dBm直接代入线性信噪比公式现象容量算出来非常大或者全是 NaN。原因SNR 的单位换算错了。香农公式里 log2(1SNR) 的 SNR 必须是线性比值而接收功率和噪声功率算出来都是 dBm直接相减得到的是 dB 单位的 SNR代入公式等于把 30 dB 当成了线性 30 倍来算容量明显偏大。解决先算 SNR_dB Pr - Pn再换算 SNR_linear 10^(SNR_dB/10)最后代入香农公式。5.5 近距离仿真用NLOS模型导致曲线整体偏低现象只跑到 100 米范围内的容量结果最大容量只有 200 Mbit/s明显低于 5G 中频的百兆量级预期。原因近距离时终端大概率是视距传播直接用 NLOS 路径损耗距离项系数 39.08会让接收功率低 15 到 25 dB容量被严重低估。解决在 LOS 概率未建模的情况下默认按 LOS 模型算近距离只有仿真 3 公里以上的远距离覆盖时才需要用 NLOS。如果你想做一个更真实的折中可以按 3GPP 给出的 LOS 概率公式 P_LOS min(18/d, 1)·(1 - exp(-d/36)) exp(-d/36) 来随机切换两套模型这会让曲线在 200 到 600 米之间出现一个容量显著下滑的“阴影区”也更符合用户对“走远一点容量掉一半”的直觉。6. 容量仿真的自我验证退化、峰值速率与MIMO对照6.1 退化测试把路径损耗关掉看容量是否回到香农极限给仿真源码加一个“无损耗模式”把 PL 强制设为 0 dB此时 SNR 只由发射功率和噪声功率决定。以 43 dBm、100 MHz、NF7 dB 的参数算SNR 约等于 43 - (-174 10·log10(98.28e6) 7) ≈ 43 - (-174 79.9 7) 43 87.1 130.1 dB。代入香农公式 C 100e6·log2(1 10^13.01)约等于 100e6 × 43.3 ≈ 4.33 Gbit/s这就是这个链路配置下的容量天花板。如果你跑出来的“零损耗容量”明显偏离这个值优先检查带宽和噪声功率的单位换算。6.2 与5G峰值速率计算公式对照5G 的峰值速率有一个业界惯用的理论计算公式峰值速率 (RB数 × 每RB子载波数 × 每符号比特数 × OFDM符号速率 × 层数 × 编码率)。100 MHz、30 kHz SCS、273 RB、下行 256QAM、4 层 MIMO、编码率 0.926 的配置下算出来的峰值速率约 2.3 Gbit/s比香农极限低不少。原因在于峰值速率公式已经扣掉了导频开销、控制信道开销和循环前缀开销而香农容量算的是纯数据传输的理论极限。仿真容量应该在香农极限之下、峰值速率附近偏高一点如果仿真容量高出 4.3 Gbit/s 很多说明你把噪声功率算小了如果低于 1 Gbit/s说明路径损耗或蒙特卡洛次数有问题。我习惯把这两个值写死在代码注释里作为参考锚点。6.3 MIMO增益随SNR变化的趋势检验理想 2×2 MIMO 的容量增益在低 SNR 时接近 1 倍线性高 SNR 时接近 2 倍。你可以把某个固定距离上的容量抽出来改变发射功率从 20 dBm 扫到 50 dBm画出“功率-容量”曲线看两条曲线的间距是否随功率增大而变宽。如果间距恒定说明信道生成或容量聚合可能写成了先合并再取 log把 MIMO 的阵列增益效果吃掉了。正确的做法是每个天线上单独算 SINR再按并行信道容量公式 C Σ B_sc·log2(1 SINR_k,l) 对所有空间层求和。这也是我和同事在仿真 32 通道大规模 MIMO 时经常被问到的点——天线数超过 8 之后理想正交假设的误差越来越大要和实测容量图像做偏差校准。这套容量-距离仿真做到最后我最大的体会是曲线形态完全由路径损耗分段模型和蒙特卡洛统计质量决定换参数不如先把模型写对。断裂点位置、单位换算、噪声功率这三件事每次调代码都会遇到与其靠直觉改参数不如先把这六个验证步骤跑一遍。希望帮到你。本文还有配套的精品资源点击获取
返回列表