无线覆盖规划必备:四种信道模型与MATLAB路径损耗实现对比
做无线覆盖规划最常被问到一个问题同一个基站距离从 1 公里增加到 2 公里信号到底衰减了多少 dB教材里给出的答案往往不止一个原因是路径损耗不是用一个公式通吃所有场景而是要根据工作频率、天线高度、地形环境选择不同的信道模型。模型选对了链路预算和覆盖半径估算才靠谱选错了偏差可能达到 20~30 dB对应覆盖半径误差 3~5 倍这在工程上是完全不可接受的。本文要做的不是把四个模型公式罗列一遍而是把自由空间损耗模型、Okumura-Hata 模型、COST231-Hata 模型和 SUI 信道模型的来龙去脉、适用范围和 MATLAB 实现一次讲清楚。读完你可以直接把这些函数搬进自己的仿真项目也可以照着主脚本画出对比曲线理解不同模型之间的差异到底有多大。1. 为什么信道建模在无线通信中如此重要无线通信系统设计的第一步往往不是写信号处理算法而是先回答一个问题发射端的功率经过空间传播后到达接收端还剩多少。这个“剩余多少”的计算过程核心就是路径损耗。无论是蜂窝网络的基站选址、Wi-Fi 覆盖规划、物联网终端通信距离估算还是系统级仿真中的 SINR 统计路径损耗都是最底层的输入。没有路径损耗模型链路预算就是空谈。链路预算的基本关系是接收功率 发射功率 发射天线增益 接收天线增益 - 路径损耗 - 各种余量。在发射功率和灵敏度确定的情况下路径损耗直接决定最大覆盖距离。而不同模型对同一个距离给出的损耗值可能相差很大尤其是在 1 km 以外的中远距离。工程上真实的传播环境极其复杂建筑物遮挡、植被吸收、地面反射、天气影响都会叠加进去经验模型的价值就在于用少数几个参数近似描述这种复杂环境。本文选择这四个模型的原因很简单它们覆盖了从视距传播到宏蜂窝、再到固定无线接入的典型工程场景。自由空间模型是理论下限Okumura-Hata 和 COST231-Hata 是传统蜂窝网络规划的主力SUI 模型则是固定无线接入和宽带接入中常被引用的模型。理解它们的适用边界比背住公式更重要。2. 路径损耗与信道模型的基本概念路径损耗是指电磁波在空间中传播时由于能量扩散、吸收、散射和反射造成的信号功率减少单位是 dB。它描述的是大尺度衰落也就是说接收功率随距离慢变化的趋势而不关心多径造成的快速起伏。用 dB 表示损耗的原因在于信号功率从毫瓦级到瓦级跨越多个数量级取对数后可以让乘除关系变成加减关系链路预算计算变得非常方便。自由空间模型中距离每增加一倍损耗增加约 6 dB而在实际蜂窝环境中由于地面反射和障碍物影响距离每增加一倍损耗往往增加 7~12 dB所以实际模型的斜率比自由空间更陡。信道模型可以分为确定性模型和经验模型两类。确定性模型基于电磁波传播理论和环境几何信息典型代表是射线追踪精度高但计算量大经验模型则是通过对大量实测数据进行统计回归得到的公式形式简单、计算快适合覆盖规划和链路预算。本文涉及的四个模型都属于后者但它们的适用条件差异很大。容易混淆的是路径损耗和信道衰落这两个概念。路径损耗是确定性的距离相关衰减阴影衰落描述的是大范围遮蔽造成的随机波动多径衰落则是波长尺度上的快速起伏。在系统仿真中通常将路径损耗作为基础再叠加阴影衰落和小尺度衰落。这篇文章里的 SUI 模型自带阴影衰落参数其他三个模型计算的是确定性的路径损耗中值。3. 四种常用信道模型详解与适用场景3.1 自由空间损耗模型自由空间损耗模型描述的是理想情况下电磁波在真空中传播时的能量扩散损耗没有反射、没有遮挡、没有吸收。它是所有模型的理论下限任何实际环境的平均路径损耗都不会低于这个值。公式如下[ PL 20\log_{10}(d) 20\log_{10}(f) 32.44 ]其中 (d) 的单位是 km(f) 的单位是 MHz损耗单位是 dB。这个公式的工程意义很直观频率越高损耗越大距离越远损耗越大。例如 900 MHz 信号传输 1 km 的理论损耗约为 91.5 dB。这个模型并非只能用于卫星通信或微波视距链路。在实际的无线覆盖规划中它常被用作参考基线用来衡量真实环境比理想视距环境“多损耗了多少”。例如在开阔地、海面、无人机通信等近似视距的场景中自由空间模型就是非常接近实际的选择。远场条件是使用它时需要注意的前提一般要求距离远大于天线尺寸和波长。3.2 Okumura-Hata 模型Okumura-Hata 模型是 Okumura 在东京地区做了大量实测后由 Hata 将曲线拟合成公式得到的经验模型。它针对的是 150~1500 MHz 频段的宏蜂窝场景基站天线高度 30~200 m移动台高度 1~10 m距离 1~20 km。这个模型覆盖了传统蜂窝网络的黄金频段尤其是 900 MHz 频段。城市环境下的基本公式为[ PL 69.55 26.16\log_{10}(f) - 13.82\log_{10}(h_b) - a(h_m) (44.9 - 6.55\log_{10}(h_b))\log_{10}(d) ]其中 (f) 单位是 MHz(d) 单位是 km(h_b) 和 (h_m) 单位是 m。(a(h_m)) 是移动台天线高度修正因子大城市和小城市的计算公式不同。郊区修正是在城市损耗基础上减去一个与频率有关的修正量开阔地修正还要再减去更多。这说明环境越“空旷”实际损耗越接近自由空间。工程中 900 MHz 覆盖规划经常直接使用该模型也是因为它经历了几十年的验证参数覆盖范围与中国早期蜂窝网络频段高度重叠。3.3 COST231-Hata 模型随着蜂窝网络向 1800 MHz、1900 MHz 频段扩展Okumura-Hata 模型在 1500 MHz 以上外推的误差明显增大。COST231 在 Hata 模型基础上扩展了频率范围适用于 1500~2000 MHz距离 1~20 km基站高度 30~200 m移动台高度 1~10 m。公式为[ PL 46.3 33.9\log_{10}(f) - 13.82\log_{10}(h_b) - a(h_m) (44.9 - 6.55\log_{10}(h_b))\log_{10}(d) C_m ]其中 (C_m) 在大城市中心取 3 dB中等城市和郊区取 0 dB。这 3 dB 的差别反映的是高楼林立的城市中心额外的绕射和遮挡损耗。2G/3G 时代城区 1800 MHz 基站规划中COST231-Hata 几乎是标配。它的计算复杂度很低适合大批量站址测算。3.4 SUI 信道模型SUI 模型Stanford University Interim最初是 IEEE 802.16 工作组为固定无线接入场景提出的信道模型后来在 WiMAX 和宽带接入仿真中广泛使用。它适用于 1900~3500 MHz 频段典型距离从几百米到几公里基站天线高度通常 10~80 m移动台高度 2~10 m。SUI 模型将地形分为 A、B、C 三类A 类对应山区或树木密度大的区域路径损耗最大B 类对应中等地形可作为大多数城郊场景的默认选择C 类对应平坦、低树密度区域路径损耗最小。不同于前两个模型只用一条曲线描述一个环境SUI 模型通过路径损耗指数、频率修正项、高度修正项和阴影衰落标准差组合出不同地形的行为。SUI 模型计算时特别要注意单位距离单位是 m不是 km。频率修正项的参考频率是 2000 MHz高度修正项的参考高度是 2 m。这个单位细节在代码实现中很容易出错后面会重点演示。3.5 四个模型对比模型适用频率适用距离基站高度移动台高度典型场景特点自由空间无严格限制无严格限制不敏感不敏感视距、微波、卫星理论下限参考基线Okumura-Hata150~1500 MHz1~20 km30~200 m1~10 m900 MHz 宏蜂窝城市/郊区/开阔地修正丰富COST231-Hata1500~2000 MHz1~20 km30~200 m1~10 m1800/1900 MHz 宏蜂窝大城市中心额外 3 dBSUI1900~3500 MHz0.1~8 km10~80 m2~10 m固定无线接入、FWA三类地形可配阴影衰落4. MATLAB 环境准备与项目结构本文代码基于 MATLAB 编写理论上 R2016b 之后的主流版本都可以运行因为只用到了基础数学函数和绘图函数不依赖特定工具箱。如果你使用的是 R2022a 或更新版本直接运行即可。本文演示的是通用思路版本细节以你本机环境为准。建议按以下目录结构组织文件channel_model/ ├── free_space_loss.m ├── okumura_hata_loss.m ├── cost231_hata_loss.m ├── sui_loss.m └── channel_model_compare.m四个函数文件各实现一个信道模型主脚本负责设置参数、调用函数并绘图。这种“一个模型一个函数”的组织方式便于以后在链路预算、系统仿真中单独调用也方便增加新的模型。函数命名采用小写加下划线是 MATLAB 社区比较常见的风格。如果你使用的是 Linux 环境注意 MATLAB 版本与系统库的兼容性如果你在虚拟机中运行 MATLAB绘图性能可能明显下降建议尽量在宿主机环境运行仿真脚本。5. 完整 MATLAB 代码实现5.1 自由空间损耗函数文件路径channel_model/free_space_loss.mfunction pl free_space_loss(fc, d) % free_space_loss 自由空间路径损耗模型 % 输入 % fc - 载波频率单位 MHz % d - 距离单位 km可以是标量或矩阵 % 输出 % pl - 路径损耗单位 dB % % 公式PL 20*log10(d) 20*log10(fc) 32.44 % d 单位 kmfc 单位 MHz % % 示例 % pl free_space_loss(900, 1); % 900 MHz1 km pl 20*log10(d) 20*log10(fc) 32.44; end这个函数只有一行核心公式但它给出的是所有实际模型的损耗下限。在链路预算中可以先算自由空间损耗再根据环境附加额外损耗这种思路在很多工程文档里都可以看到。5.2 Okumura-Hata 模型函数文件路径channel_model/okumura_hata_loss.mfunction pl okumura_hata_loss(fc, d, hb, hm, env) % okumura_hata_loss Okumura-Hata 路径损耗模型 % 输入 % fc - 载波频率单位 MHz推荐范围 150~1500 % d - 距离单位 km推荐范围 1~20 % hb - 基站天线高度单位 m推荐范围 30~200 % hm - 移动台天线高度单位 m推荐范围 1~10 % env - 环境类型 % urban_large 大城市 % urban_small 中小城市 % suburban 郊区 % open 开阔地 % 输出 % pl - 路径损耗单位 dB % % 示例 % pl okumura_hata_loss(900, 5, 30, 1.5, urban_small); if nargin 5 env urban_small; end if fc 150 || fc 1500 warning(频率 %.1f MHz 超出 Okumura-Hata 模型推荐范围 150~1500 MHz。, fc); end if d 1 || d 20 warning(距离 %.2f km 超出 Okumura-Hata 模型推荐范围 1~20 km。, d); end switch env case urban_large if fc 400 a_hm 3.2 * (log10(11.75 * hm))^2 - 4.97; else a_hm 8.29 * (log10(1.54 * hm))^2 - 1.1; end case {urban_small, suburban, open} a_hm (1.1 * log10(fc) - 0.7) * hm - (1.56 * log10(fc) - 0.8); otherwise error(env 参数不支持%s, env); end L_urban 69.55 26.16 * log10(fc) - 13.82 * log10(hb) ... - a_hm (44.9 - 6.55 * log10(hb)) * log10(d); switch env case urban_large pl L_urban; case urban_small pl L_urban; case suburban pl L_urban - 2 * (log10(fc / 28))^2 - 5.4; case open pl L_urban - 4.78 * (log10(fc))^2 18.33 * log10(fc) - 40.94; end end这个函数的关键在于移动台高度修正因子a_hm的环境区分。大城市和中小城市用的是不同公式不能混用。郊区修正和开阔地修正是在城市损耗基础上进一步扣减体现的是环境越空旷、损耗越低的物理直觉。频率和距离超范围时函数会给出警告但不会中断计算方便你观察外推结果同时也提醒你模型的适用边界。5.3 COST231-Hata 模型函数文件路径channel_model/cost231_hata_loss.mfunction pl cost231_hata_loss(fc, d, hb, hm, env) % cost231_hata_loss COST231-Hata 路径损耗模型 % 输入 % fc - 载波频率单位 MHz推荐范围 1500~2000 % d - 距离单位 km推荐范围 1~20 % hb - 基站天线高度单位 m推荐范围 30~200 % hm - 移动台天线高度单位 m推荐范围 1~10 % env - 环境类型 % urban 大城市中心 % medium 中等城市/郊区 % 输出 % pl - 路径损耗单位 dB % % 示例 % pl cost231_hata_loss(1800, 2, 30, 1.5, urban); if nargin 5 env medium; end if fc 1500 || fc 2000 warning(频率 %.1f MHz 超出 COST231-Hata 模型推荐范围 1500~2000 MHz。, fc); end a_hm (1.1 * log10(fc) - 0.7) * hm - (1.56 * log10(fc) - 0.8); if strcmp(env, urban) Cm 3; else Cm 0; end pl 46.3 33.9 * log10(fc) - 13.82 * log10(hb) - a_hm ... (44.9 - 6.55 * log10(hb)) * log10(d) Cm; endCOST231-Hata 和 Okumura-Hata 的差异主要体现在频率项系数和常数项上。注意Cm只有 0 和 3 dB 两种取值它代表的是大城市中心相比中等城市的额外穿透损耗不要把它当作可连续调节的余量参数。5.4 SUI 模型函数文件路径channel_model/sui_loss.mfunction pl sui_loss(fc, d, hb, hm, terrain, s_shadow) % sui_loss SUI 信道模型Stanford University Interim % 输入 % fc - 载波频率单位 MHz推荐范围 1900~3500 % d - 距离单位 m推荐范围 100~8000 % hb - 基站天线高度单位 m % hm - 移动台天线高度单位 m % terrain - 地形类型 % A 山区/树木密集损耗最大 % B 中等地形 % C 平坦/低树密度损耗最小 % s_shadow - 阴影衰落标准差单位 dB默认 0工程中可填 8.2~10.6 % 输出 % pl - 路径损耗单位 dB % % 注意SUI 模型距离 d 的单位是 米不是 km % 频率修正参考值 2000 MHz高度修正参考值 2 m。 % % 示例 % pl sui_loss(2600, 500, 30, 2, C, 8.2); if nargin 6 || isempty(s_shadow) s_shadow 0; end if nargin 5 || isempty(terrain) terrain C; end if fc 1900 || fc 3500 warning(频率 %.1f MHz 超出 SUI 模型推荐范围 1900~3500 MHz。, fc); end d0 100; % 参考距离单位 m switch upper(terrain) case A a 4.6; b 0.0075; c 12.6; Xh -10.8 * log10(hm / 2); case B a 4.0; b 0.0065; c 17.1; Xh -10.8 * log10(hm / 2); case C a 3.6; b 0.0050; c 20.0; Xh -20.0 * log10(hm / 2); otherwise error(terrain 参数不支持%s, terrain); end lambda 3e8 / (fc * 1e6); % 波长单位 m A 20 * log10(4 * pi * d0 / lambda); % 参考距离处的损耗 n a - b * hb c / hb; % 路径损耗指数 n min(max(n, 2), 6); % 限制在 2~6 之间避免异常参数 Xf 6.0 * log10(fc / 2000); % 频率修正项 pl A 10 * n * log10(d / d0) Xf Xh s_shadow; endSUI 模型是四个模型中最容易写错的一个。这里特别提醒两个单位细节第一距离是米所以调用时如果手上是 km 的距离要乘以 1000第二频率修正项里除的是 2000 MHz不是 2 MHz而高度修正项里除的是 2 m不是 2000 m。这两个数字看起来相似但在公式里含义完全不同写错一个结果可能偏差几十 dB。5.5 主仿真对比脚本文件路径channel_model/channel_model_compare.m%% channel_model_compare.m % 无线信道建模对比自由空间 / Okumura-Hata / COST231-Hata / SUI % 运行环境MATLAB R2016b 及以上 clc; clear; close all; %% 公共参数 hb 30; % 基站天线高度m hm 1.5; % 移动台天线高度m d_km 0.1:0.1:20; % 距离km d_m d_km * 1000; % 距离mSUI 模型使用 %% 场景一900 MHz 频段 fc1 900; pl_fs_900 free_space_loss(fc1, d_km); pl_oh_urban okumura_hata_loss(fc1, d_km, hb, hm, urban_small); pl_oh_sub okumura_hata_loss(fc1, d_km, hb, hm, suburban); figure(Color, w, Position, [100 100 800 500]); plot(d_km, pl_fs_900, k-, LineWidth, 1.5); hold on; plot(d_km, pl_oh_urban, b-, LineWidth, 1.5); plot(d_km, pl_oh_sub,