简介面向无线通信学习与研究人员的信道建模资源聚焦移动通信中常用大尺度路径损耗模型系统覆盖自由空间损耗、Okumura-Hata、COST231 Hata及802.16中SUI模型并通过MATLAB脚本对上述模型进行仿真对比分析路径损耗随距离变化的特性及功率谱密度表现。资源共21个文件其中20个.m源码文件分别对应各模型及信道特性的仿真实现便于读者运行、修改与扩展另附1份Word论文对无线信道的重要性、模型原理、适用频段与场景、仿真结果分析等做了系统阐述整体压缩包约323KB。目前已有1042人学习下载。借助该资料读者可快速掌握典型信道模型的搭建与仿真流程直观理解不同模型在宏蜂窝、微蜂窝及固定无线接入等场景下的差异同时参考论文写作框架完成实验报告、课程设计或毕业设计适合通信工程专业学生及从事链路预算、覆盖规划与无线信道研究的工程技术人员。1. 自由空间损耗模型仿真的真实用途拿着公式算覆盖最容易栽在选错模型上自由空间损耗模型是无线覆盖仿真里最常被拿来当起点的公式几乎所有链路预算都会从它开始。但真正做仿真分析时Okumura-Hata、COST231 Hata、SUI信道模型一出现很多人就卡住了每个公式都带一堆修正项画出来的曲线差距又很大不知道拿哪条去定覆盖半径。这篇文章要解决的就是这个问题先讲清楚每个模型的适用频段、天线高度修正和参数口径再给出一套可以直接跑的 Python 仿真脚本最后把结果整理进 word 论文。适合正在做网络规划仿真、写通信方向课程设计或硕士论文的工程师和学生。2. 自由空间损耗公式与 Python 基线仿真先画出“理想上界”曲线再说2.1 自由空间损耗的公式里单位口径比公式本身更容易出错自由空间损耗描述的是电磁波在无遮挡、无反射、无吸收的理想路径中传播时的能量扩散衰减。公式本身非常简单L_fs(dB) 20 * log10(d_km) 20 * log10(f_MHz) 32.44这里 d 用公里f 用兆赫兹。32.44 这个常数来自 4π/λ 推导时对真空光速和单位换算的折算。具体点说把距离换成米、频率换成 Hz 后波长 λ 300 / f_MHz 米最后整理出来就是 20 * log10(4 * π * 1000 * d_km * f_MHz / 300)前面那一坨对数值正好约等于 32.44。记住这个推导过程有好处以后看到别的常数版本比如 d 用英里、f 用 GHz你就能自己验算不会被网上抄来抄去的公式带偏。这个公式的工程意义是“理想上界”。现实路径中只要存在地面反射、建筑物绕射、树叶吸收损耗只会比它大不会比它小。所以自由空间损耗模型通常用来回答两个问题一是这条链路理论上最多能打多远二是作为基线给后面 Okumura-Hata、COST231 Hata、SUI 信道模型的仿真结果做对照。如果某个经验模型算出来的损耗比自由空间还低不用犹豫参数大概率错了。另一个容易栽跟头的地方是适用边界。自由空间损耗成立的前提是天线的远场条件已经满足并且第一菲涅尔区净空。远场条件和天线尺寸、频率有关一般工程上按 d ≥ 2D²/λ 粗估第一菲涅尔区净空则意味着路径中间不能有障碍物切进去。换句话说微波中继视距链路里直接用它没问题但城区蜂窝网络里它只能当“下限参考”不能用来预测真实覆盖半径。拿着自由空间损耗去设计室内覆盖或者城市宏站结果一定乐观得离谱。2.2 用 Python 把自由空间损耗曲线跑通700/1800/2600MHz 三线对比先把基线仿真跑出来。下面这段代码用 NumPy 生成距离数组再分别算 700 MHz、1800 MHz、2600 MHz 三个频段下的损耗曲线import numpy as np import matplotlib.pyplot as plt def fs_loss(d_km, f_mhz): # 自由空间损耗距离单位 km频率单位 MHz # 32.44 由 4*pi/c 折算得到换单位就必须重算常数 return 20 * np.log10(d_km) 20 * np.log10(f_mhz) 32.44 d_km np.linspace(0.1, 20, 200) # 0.1km 到 20km共 200 个点 for f_mhz in [700, 1800, 2600]: plt.plot(d_km, fs_loss(d_km, f_mhz), labelf{f_mhz} MHz) plt.xlabel(距离 (km)) plt.ylabel(路径损耗 (dB)) plt.grid(True) plt.legend() plt.show()这段代码的逻辑不复杂先用linspace生成 0.1 到 20 公里的等差序列再把距离和频率同时喂进损耗函数。注意 NumPy 的广播机制d_km是数组f_mhz是标量函数内部的log10会自动对每个距离点计算最后画出来的就是连续曲线。频率越高曲线越高这个趋势要刻在脑子里覆盖半径想做大低频永远是更划算的选择。参数说明linspace(0.1, 20, 200)里起点 0.1 km 是为了躲开近场区域终点 20 km 是为了和后面 Hata 系列模型的距离范围对齐。如果只用来看自由空间损耗距离可以在 1 到 100 km 之间随意扩展但一旦后面要叠加 Okumura-Hata 或 COST231 Hata 做对比距离轴就建议固定到 1~20 km避免超出经验模型适用范围后曲线出现假趋势。这条曲线在 1800 MHz、1 km 处约为 97.5 dB可以作为手算校验点如果你的代码在这个频点误差超过 0.5 dB先回头查单位。提示自由空间损耗公式里没有天线增益也没有系统损耗。工程计算时要另加收发天线增益和馈线损耗别把公式结果直接当链路预算。3. Okumura-Hata 与 COST231 Hata 怎么选两代宏站经验公式的差异和适用边界3.1 Okumura-Hata 的大中城市公式和修正项900MHz 时代的主力Okumura-Hata 模型是 Hata 对 Okumura 在日本东京地区大量实测曲线做解析拟合得到的经验公式本质是回归式子不是物理推导。它工作在 150 MHz 到 1500 MHz基站高度 30 到 200 m移动台高度 1 到 10 m距离 1 到 20 km。这套适用区间是硬约束超出之后曲线形状会失真。大中城市标准公式长这样L_urban 69.55 26.16 * log10(f_MHz) - 13.82 * log10(h_bs) (44.9 - 6.55 * log10(h_bs)) * log10(d_km) - a_hm其中 a_hm 是移动台高度修正因子分三档大城市、频率高于 300 MHza_hm 3.2 * (log10(11.75 * h_ms))² - 4.97大城市、频率低于 300 MHza_hm 8.29 * (log10(1.54 * h_ms))² - 1.1中小城市a_hm (1.1 * log10(f_MHz) - 0.7) * h_ms - (1.56 * log10(f_MHz) - 0.8)之所以要分档是因为 Okumura 实测发现移动台高度对路径损耗的影响在大城市高楼环境下不再是简单线性低频和高频的行为也不一样。做仿真时如果直接用统一修正因子900 MHz 城市场景偏差能到 3 到 5 dB论文数据就站不住脚。除了城市修正还有两个常用的场景修正项。郊区修正L_suburban L_urban - 2 * (log10(f/28))² - 5.4。开阔地修正L_open L_urban - 4.78 * (log10(f))² 18.33 * log10(f) - 40.94。仿真时如果题目要求“农村开阔地”别套城市公式直接出图那会被评审一眼看穿。3.2 COST231 Hata 做了哪些扩展从 1.8GHz 到 2GHz 的补丁式升级COST231 Hata 是欧洲 COST231 委员会在 Okumura-Hata 基础上为 1800 MHz 频段做的扩展适用频率拉到了 1500 到 2000 MHz距离、天线高度范围不变。公式结构相似L 46.3 33.9 * log10(f_MHz) - 13.82 * log10(h_bs) - a_hm (44.9 - 6.55 * log10(h_bs)) * log10(d_km) C_mC_m 只有两个取值大城市市中心 3 dB中小城市和郊区 0 dB。这个 C_m 其实是在补偿高楼密集区域额外增加的绕射和反射损耗。对比两个公式前两个系数从 69.55/26.16 变成了 46.3/33.9频率修正变强常数项变低结果是在 1500~2000 MHz 区间内曲线更加陡峭。要特别注意COST231 Hata 并不是 Okumura-Hata 的“升级版”而是补丁式扩展。频率低于 1500 MHz 时不要强行使用许多文章在这个点翻车。两者参数对比如下指标Okumura-HataCOST231 Hata频段范围150 ~ 1500 MHz1500 ~ 2000 MHz距离范围1 ~ 20 km1 ~ 20 km基站高度30 ~ 200 m30 ~ 200 m移动台高度1 ~ 10 m1 ~ 10 m大城市中心修正无 C_m 项C_m 3 dB常用场景900 MHz GSM 宏站1800 MHz 城区宏站这张表建议直接复制进你的 word 论文参数设置小节评审一眼就能看出你确实做过模型适用性筛选。3.3 两族 Hata 放同一张图里的 Python 脚本与曲线解读下面代码把 Okumura-Hata 和 COST231 Hata 同时实现并画出各自适用频段下的城市曲线import numpy as np import matplotlib.pyplot as plt def okumura_hata(d_km, f_mhz, h_bs, h_ms, citylarge): # Okumura-Hata 大中城市公式仅适用 150-1500 MHz if city large: if f_mhz 300: a_hm 3.2 * (np.log10(11.75 * h_ms)) ** 2 - 4.97 else: a_hm 8.29 * (np.log10(1.54 * h_ms)) ** 2 - 1.1 else: a_hm (1.1 * np.log10(f_mhz) - 0.7) * h_ms - (1.56 * np.log10(f_mhz) - 0.8) return (69.55 26.16 * np.log10(f_mhz) - 13.82 * np.log10(h_bs) - a_hm (44.9 - 6.55 * np.log10(h_bs)) * np.log10(d_km)) def cost231_hata(d_km, f_mhz, h_bs, h_ms, citylarge): # COST231-Hata仅适用 1500-2000 MHz if city large: cm 3 a_hm 3.2 * (np.log10(11.75 * h_ms)) ** 2 - 4.97 else: cm 0 a_hm (1.1 * np.log10(f_mhz) - 0.7) * h_ms - (1.56 * np.log10(f_mhz) - 0.8) return (46.3 33.9 * np.log10(f_mhz) - 13.82 * np.log10(h_bs) - a_hm (44.9 - 6.55 * np.log10(h_bs)) * np.log10(d_km) cm) d_km np.linspace(1, 20, 200) h_bs, h_ms 30, 1.5 plt.figure(figsize(8, 6)) plt.plot(d_km, okumura_hata(d_km, 900, h_bs, h_ms, large), labelOkumura-Hata 900MHz urban) plt.plot(d_km, cost231_hata(d_km, 1800, h_bs, h_ms, large), labelCOST231-Hata 1800MHz urban) plt.xlabel(距离 (km)) plt.ylabel(路径损耗 (dB)) plt.grid(True) plt.legend() plt.show()代码逻辑说明两个函数内部都先处理移动台修正因子 a_hm然后套各自的城市标准式。注意 Okumura-Hata 里我用f_mhz 300分支这是 300 MHz 以下大城市修正公式的边界COST231 Hata 则直接用大城市修正。参数说明基站高度 30 m移动台 1.5 m这是城市宏站的典型配置。900 MHz 的 Okumura-Hata 曲线在 1 km 附近大约 110 dB1800 MHz 的 COST231 Hata 大约 120 dB差 10 dB 左右。这 10 dB 不是模型误差而是频率从 900 MHz 翻倍到 1800 MHz 带来的真实损耗增量。做网络规划时这个增量直接体现为基站密度翻倍预算就是这么算出来的。提示同一张图里比较两个频率不同、场景不同的模型曲线高低只能反映频率差异不能说明谁“更准”。做对比仿真时必须固定频率、距离、天线高度三要素中的两个只改变一个变量才有工程结论。4. SUI 信道模型的参数如何落进仿真郊区宽带场景下比 Hata 更细的修正4.1 SUI 模型六个参数与地形类别的对应关系SUI 信道模型来自 Stanford University Interim早期为 IEEE 802.16 固定无线接入场景设计后来被广泛用于 3.5 GHz 以下宽带无线通信仿真。它和 Hata 家族最大的区别是引入了“地形类别”和“阴影衰落”两个维度路径损耗指数也不再是固定值而是由基站高度动态计算。SUI 模型基本损耗公式PL A 10 * n * log10(d_km / d_0) X_f X_h s其中 d_0 0.1 kmA 20 * log10(4 * π * d_0 / λ)λ 由频率换算。n 是路径损耗指数由三个地形参数决定n a - b * h_bs c / h_bs。X_f 是频率修正项X_h 是接收天线高度修正项s 是零均值对数正态阴影衰落随机变量。标准参数表如下地形类别典型环境abcs (dB)A山区、茂密树林4.60.007512.610.6B郊区、稀疏树林4.00.006517.19.6C平原、开阔地3.60.00520.08.2这张表里的 s 是阴影衰落标准差。做均值曲线时一般取 0做蒙特卡洛链路仿真时就按正态分布随机加。许多人对 SUI 的第一印象是“参数怎么这么多”其实拆开看就三个关键输入地形类别决定 a/b/c基站高度算 n频率由 X_f 修正。4.2 接收天线高度修正 X_h 和阴影衰落 s 在仿真里怎么处理X_f 和 X_h 的计算方式是 SUI 模型里最容易出错的地方单独拉出来说。频率修正项X_f 6.0 * log10(f_MHz / 2000)这个式子把模型基准频率定在 2000 MHz往低频外推时 X_f 为负相当于损耗减小往高频外推时为正。所以 SUI 模型在 900 MHz 也能算但论文里最好注明“SUI 原始校准频段在 2 GHz 附近低频外推结果仅作参考”。接收天线高度修正项 X_h 分地形地形 A、BX_h -10.8 * log10(h_ms / 2)地形 CX_h -20.0 * log10(h_ms / 2)这里的参考高度是 2 m正好是固定无线接入终端常见安装高度。如果 h_ms 大于 2 mX_h 为负损耗减小小于 2 m损耗增大。注意地形 C 的修正系数是 -20比 A/B 地形更敏感因为开阔地没有树木和建筑物遮挡接收天线升高带来的增益更直接。阴影衰落 s 在确定性仿真里是个黑匣子不少人直接忽略但如果论文里需要画“接收信号强度波动范围”就要用 NumPy 的np.random.normal(0, s, size)生成每条链路的随机损耗。做对比仿真时建议算两次一次 s0 的均值曲线一次加随机值的区间曲线两条放在一起论文里特别显专业。4.3 Python 实现 SUI 并与 COST231 Hata 对比的完整示例SUI 模型的代码实现不复杂关键是把参数表和公式拆开写便于后面换地形类别def sui_loss(d_km, f_mhz, h_bs, h_ms, terrainC, shadowFalse): # SUI 信道模型d_km 需大于 0.1km d0 0.1 # km lam 300 / f_mhz # 波长单位 m因为 300/f_MHz 得到米 A 20 * np.log10(4 * np.pi * d0 * 1000 / lam) params { A: (4.6, 0.0075, 12.6, 10.6), B: (4.0, 0.0065, 17.1, 9.6), C: (3.6, 0.005, 20.0, 8.2) } a, b, c, s params[terrain] n a - b * h_bs c / h_bs Xf 6.0 * np.log10(f_mhz / 2000) if terrain in (A, B): Xh -10.8 * np.log10(h_ms / 2) else: Xh -20.0 * np.log10(h_ms / 2) base A 10 * n * np.log10(d_km / d0) Xf Xh if shadow: noise np.random.normal(0, s, sizenp.shape(d_km)) return base noise return base d_km np.linspace(0.1, 20, 200) plt.figure(figsize(8, 6)) plt.plot(d_km, sui_loss(d_km, 1800, 30, 1.5, B), labelSUI terrain B 1800MHz) plt.plot(d_km, sui_loss(d_km, 1800, 30, 1.5, C), labelSUI terrain C 1800MHz) plt.plot(d_km, cost231_hata(d_km, 1800, 30, 1.5, large), --, labelCOST231-Hata 1800MHz urban) plt.xlabel(距离 (km)) plt.ylabel(路径损耗 (dB)) plt.grid(True) plt.legend() plt.show()代码逻辑说明lam 300 / f_mhz是利用“频率 300 MHz 对应波长 1 米”这个换算关系避免写光速长串数字。A 项把 d0 从公里换算成米后再和波长取比值这是和 Hata 系列公式最大的结构差异——SUI 是从物理公式出发再叠加统计修正Hata 纯粹是回归拟合。参数说明shadowFalse时返回确定性曲线适合做模型对比shadowTrue时会叠加随机阴影衰落适合做链路级仿真。每次运行结果不同是正常现象需要固定随机种子np.random.seed(42)才能复现。曲线结果通常表现为地形 B 比地形 C 高一截COST231 Hata 在城市中心比 SUI 地形 C 高不少这正是场景差异的体现。5. 四种模型一起仿真的避坑指南曲线拉不开间距时依次查这五个位置5.1 四模型联合仿真脚本一张图看趋势一分钟定覆盖把自由空间、Okumura-Hata、COST231 Hata、SUI 放同一张图里是论文里最常见的做法也是最容易画出“四线合一”或“四线乱飞”的操作。下面给一个推荐脚本函数沿用前文定义直接调用d_km np.linspace(1, 20, 200) f_mhz 900 h_bs, h_ms 30, 1.5 plt.figure(figsize(9, 6)) plt.plot(d_km, fs_loss(d_km, f_mhz), labelFree Space 900MHz) plt.plot(d_km, okumura_hata(d_km, f_mhz, h_bs, h_ms, large), labelOkumura-Hata urban 900MHz) # COST231-Hata 不适用 900MHz这里仅做趋势演示正式仿真不要这样用 plt.plot(d_km, cost231_hata(d_km, f_mhz, h_bs, h_ms, large), --, labelCOST231-Hata out of range) plt.plot(d_km, sui_loss(d_km, f_mhz, h_bs, h_ms, C), labelSUI terrain C 900MHz) plt.axhline(120, colorgray, ls:, lw1) plt.text(1, 121, max allowed loss 120 dB) plt.xlabel(距离 (km)) plt.ylabel(路径损耗 (dB)) plt.ylim(80, 165) plt.grid(True) plt.legend() plt.show() # 反推覆盖半径找到 SUI / Okumura-Hata 首次大于 120 dB 的距离 mask okumura_hata(d_km, f_mhz, h_bs, h_ms, large) 120 print(Okumura-Hata 覆盖半径约 %.2f km % d_km[mask].max()) mask_sui sui_loss(d_km, f_mhz, h_bs, h_ms, C) 120 print(SUI 地形 C 覆盖半径约 %.2f km % d_km[mask_sui].max())代码逻辑说明axhline(120)画的水平线代表最大允许路径损耗由发射功率、接收灵敏度、天线增益和系统余量反推。比如发射功率 20 dBm接收灵敏度 -100 dBm收发增益合计 0最大允许损耗就是 120 dB。曲线与这条水平线的交点横坐标就是该模型预测的覆盖半径。用mask数组找出最后一个小于等于 120 dB 的距离点直接打印结果。这个脚本的价值不在代码复杂度而在“用同一组参数把所有模型考核一遍”的规范性。只要参数表统一曲线图一出来谁高谁低、覆盖半径多少、频率敏感性怎么样全部一目了然。5.2 参数口径校准频率、高度、距离这三个维度最容易翻车四个模型混在一起仿真不在同一个口径下比较曲线就失去意义。频率维度要先查适用范围Okumura-Hata 别超过 1500 MHzCOST231 Hata 别低于 1500 MHzSUI 模型在 900 MHz 外推时要注明。很多仿真分析图里出现“COST231 Hata 在 900 MHz 比 Okumura-Hata 低 15 dB”的奇怪现象不是公式错了是拿超范围的模型硬算。天线高度维度要注意 h_bs 的定义。Hata 系列和 SUI 里的 h_bs 是基站天线的有效高度不是铁塔高度更不是海拔高度。在平坦地面上两者一致在起伏地形里需要用天线海拔减去周围 1 km 范围内的平均地面海拔差值才是有效高度。论文里如果只写“基站高度 30 m”而不解释有效高度评审追问一次就可能翻车。距离维度的边界也要统一。Hata 系列适用范围是 1~20 kmSUI 模型要求 d 0.1 km。对比时距离轴最好都从 1 km 开始避免在近距离段出现 Hata 公式失真导致的曲线扭曲。如果题目场景是微站500 m 覆盖半径就别硬套 Hata选自由空间加阴影衰落更合理。5.3 五个踩坑案例现象、原因和解决方法案例 1Okumura-Hata 算 2.4 GHz结果比想象中低太多。现象是 2.4 GHz 卫通或 WiFi 覆盖用 Okumura-Hata 算出来 20 km 只要 130 dB明显不合理。原因是频率超出 1500 MHz 上限经验回归式外推后斜率失真。解决办法2 GHz 以上优先用 SUI 模型或者改用 ITU-R P.1238 等专门模型。案例 2自由空间损耗比 Okumura-Hata 还高。现象是短距离0.5 km 左右时自由空间曲线跑到 Hata 曲线上方。原因是 Hata 在 1 km 以下超出适用区间回归公式在近距离段根本不参与拟合。解决办法对比图从 1 km 开始画并在论文文字里注明“Hata 系列距离下限 1 km”。案例 3SUI 模型结果比 COST231 Hata 低 20 dB怀疑代码写错。现象是同一频率同一距离SUI 地形 C 比城市 COST231 低很多。原因是场景差异SUI 地形 C 是开阔地COST231 是大城市中心本来就该差 15 到 20 dB。解决办法先对比相同场景——SUI 地形 B 与 COST231 郊区项放在一起看差异会小很多。案例 4单位混用导致全线偏移。现象是整组曲线正常但整体高了 60 dB 或低了 60 dB。原因是距离写成米、频率写成 GHz却仍然套 32.44 常数。解决办法在脚本开头统一做单位换算并加一个 1 km 处的手算校验断言例如 1800 MHz 自由空间损耗约等于 97.5 dB偏差超过 1 dB 立刻中止程序。案例 5四条曲线挤在一起论文里写不出差异化结论。现象是 1~20 km 范围内四模型差距只有 5 dB。原因是场景选择太极端比如全选开阔地且低频段经验模型修正项差异本来就不大。解决办法改成双图对比一张画 900 MHz 城区宏观趋势另一张画 1800 MHz 郊区地形 A/B/C 对比再把阴影衰落区间画进去曲线自然拉开。6. 把仿真结果写进 word 论文参数表、图表口径和可复现性的三个习惯6.1 论文不要只贴图参数表先写清楚曲线才有可信度写 word 论文时最容易出现的批评是“仿真参数不完整”。代码里定了什么频率、什么高度、什么地形正文必须有一张表完整交代。我一般会在仿真开始前就把参数表建好包含模型名称、频率、距离范围、基站有效高度、移动台高度、地形/城市类别、修正项取值。这张表放在仿真设置那一节图和表之间用“如图 X 所示”“见表 Y”互相引用评审就挑不出大毛病。6.2 图表口径坐标轴、图例和公式编号按期刊习惯来图要注意三个细节坐标轴必须带单位路径损耗标 dB距离标 km图例里的模型英文名大小写与正文一致曲线用不同线型或颜色区分黑白色纸印也要能认清。公式建议在 word 里用自带公式编辑器重排一遍别直接截图代码里的 LaTeX。每个公式编号后正文至少提一次“式 (X)”否则公式就是摆设。6.3 把 Python 脚本归档进附录给“可复现”留一条路论文附录里附上完整脚本并加一小段说明运行环境为 Python 3 NumPy Matplotlib输入参数对应正文表 X函数注释里标明的公式编号与正文一一对应。这样读者即使不看代码也能按参数表重新算出曲线。自己留档时再加一份 CSV 导出数据把每条曲线的距离、损耗值存下来后面改论文方向或重新画图都不用重跑仿真。写这类仿真分析我最早翻过的车就是把 COST231 Hata 直接套在 900 MHz 上曲线比 Okumura-Hata 低出一截还不自知直到评审问了一句“频率适用范围查过没”。从那以后每个模型函数注释的第一行都是适用区间每次出图前先手动算一个频点校验。希望你这次仿真和论文推进顺利希望帮到你。本文还有配套的精品资源点击获取