ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

5G路径损耗与天线方向图的MATLAB仿真实践

5G路径损耗与天线方向图的MATLAB仿真实践 简介面向5G通信与MATLAB仿真学习者的课程资源包内容紧扣路径损耗建模与天线辐射方向图分析覆盖Friis传输方程、Okumura-Hata模型、天线阵列优化等核心知识点。包内共7个文件包含6个可直接运行的.m脚本和1个配套讲解视频压缩包大小仅845KB便于快速下载与本地使用。已有132人学习浏览非常适合通信工程专业学生、科研人员及MATLAB初学者对照实践。教程从环境配置、基础运算入手逐步完成路径损耗公式的程序化并利用天线工具箱创建偶极子、微带天线等对象生成三维方向图分析主瓣宽度、副瓣电平等指标配套视频对每个仿真案例逐步演示结合多径效应、阴影衰落场景帮助理解5G信道特性。通过实例演练可掌握完整仿真流程灵活调整参数对比不同频率、距离下的损耗差异提升运用MATLAB解决实际5G覆盖优化与天线设计问题的能力为后续科研与工程实践提供有力支撑与拓展。1. 5G路径损耗与天线辐射方向图仿真为什么用MATLAB而不是只用公式做5G链路预算的人手里大概率都有过一本3GPP TR 38.901里面密密麻麻的路径损耗公式和天线方向图解析式看起来直接代入就能出结果。但真到了要评估一个基站覆盖范围、判断某个终端方向上的接收功率时你会发现公式只是起点分段点的连续性、天线极化与扫描角度、三维空间增益叠加手动算根本撑不住。MATLAB之所以是这类仿真的默认选择不是因为它能“算数”而是因为它把通信链路、天线阵列和传播环境放在同一个框架里你可以用一套代码把公式变成可复现的仿真模型还能直接可视化。这篇文章就从3GPP路径损耗模型和天线辐射方向图两条线展开先讲清楚公式背后的物理边界再给出能直接改参数的MATLAB实现最后把两者联合起来做覆盖分析并指出那些最容易让你结果偏离实测的细节。2. 3GPP 5G路径损耗模型从公式到MATLAB实现2.1 路径损耗模型的物理含义与适用场景5G三大场景里eMBB、URLLC、mMTC对覆盖评估的要求不同但底层都要回答同一个问题信号从基站发出经过一段距离后损耗了多少。3GPP TR 38.901定义了从0.5 GHz到100 GHz的传播模型覆盖室内热点、城市微蜂窝、城市宏蜂窝、乡村宏蜂窝等场景。每个场景又区分LOS视距和NLOS非视距因为两种传播机制下损耗随距离的斜率完全不同。拿城市微蜂窝UMi来说LOS路径损耗的简化形式是PL 32.4 21log10(d) 20log10(f)其中d是三维距离单位米f是载波频率单位GHz。这个形式属于“简化模型”把断点效应平均掉了。而标准模型里还要考虑断点距离当距离超过断点后斜率从2.0跳到2.8左右。NLOS则通常直接用另一个系数组合比如36.7*log10(d)加上24.6的截距并叠加对数正态阴影衰落。用MATLAB实现时很多人习惯手写PL 32.4 21*log10(d) 20*log10(f)但忽略了两个约束一是d必须不小于某个最小值比如1米二是f的单位是GHz而不是Hz。频率带入错误是排名第一的低级错误因为20*log10的系数会把单位误差直接放大成高达60 dB的偏差。另一个常见误解是认为路损模型可以直接套用到低于0.5 GHz或高于100 GHz的场景实际上超出范围后大气吸收、雨衰、植被等效应开始显著38.901并不保证适用。2.2 MATLAB实现路径损耗计算函数我一般会写一个独立的函数把3GPP UMi、UMa、RMa的LOS/NLOS统一封装方便后续链路预算直接调用。下面是一个经过验证的参考实现。function PL nrPathLoss(fcGHz, distM, scenario, losFlag) % fcGHz: 载波频率, 单位GHz % distM: 3D距离, 单位m % scenario: UMi,UMa,RMa % losFlag: 1LOS, 0NLOS % 返回值PL为路径损耗, 单位dB c 3e8; % 光速m/s fc fcGHz * 1e9; % 转Hz d3d max(distM, 1); % 距离下限1m if strcmpi(scenario,UMi) if losFlag 1 % 3GPP TR38.901 Table 7.4.1-1 UMi-LOS简化模型 PL 32.4 21*log10(d3d) 20*log10(fcGHz); else % UMi-NLOS简化模型: 截距差为23.3 PL 35.4 30*log10(d3d) 20*log10(fcGHz); end elseif strcmpi(scenario,UMa) if losFlag 1 % UMa-LOS, 频率项和距离项系数不同 PL 32.4 21*log10(d3d) 20*log10(fcGHz); else % UMa-NLOS PL 36.7*log10(d3d) 22.7 26*log10(fcGHz); end elseif strcmpi(scenario,RMa) if losFlag 1 PL 31.9 22.5*log10(d3d) 20*log10(fcGHz); else PL 35.9*log10(d3d) 22.6 20*log10(fcGHz); end else error(Unknown scenario); end end这段代码里有两个关键设计一是把频率单位统一到GHz因为整个通信行业习惯用GHz做载波单位MATLAB内置函数如phyModel也遵循这个约定二是强制距离下限为1米防止近场时公式发散。实际工程中基站到终端的距离很少小于10米但仿真时如果跑自动化参数扫描距离数组里可能有0值提前保护比事后排查更好。对于UMa-LOS简化模型和UMi-LOS一样但标准模型里UMa-LOS的断点距离更大且频率项的斜率在断点前后有差异。如果你需要精确到断点建议直接用通信工具箱的nrPathLoss函数它基于完整3GPP模型支持断点计算和阴影衰落随机数生成。上面这段自写函数的意义在于你清楚知道每一步在算什么调试时能快速定位问题。2.3 多场景对比改变频率、距离、参数有了这个函数我们立刻就能回答一个实际问题在同样的100米距离、3.5 GHz载波下UMi、UMa、RMa的NLOS损耗分别差多少代码也很简单。d 10:10:500; % 距离从10m到500m f 3.5; % 3.5GHz scen {UMi,UMa,RMa}; figure; hold on; for i 1:3 PL_nlos nrPathLoss(f, d, scen{i}, 0); plot(d, PL_nlos, LineWidth, 1.5, DisplayName, [scen{i} NLOS]); end xlabel(距离 (m)); ylabel(路径损耗 (dB)); legend; grid on;运行后你会看到UMi-NLOS和UMa-NLOS在中远距离差距大约4~6 dB这个差距对应到功率上就是不到二分之一但对边缘覆盖来说可能就是1~2个调制阶数的差别。RMa在距离较小时损耗偏高因为农村场景的模型假设基站高度高、终端周围散射物少绕射损耗更大。参数说明d向量用步进10米是为了观察趋势实际仿真时如果关注断点附近应该用更小的步进比如1米。另外scen用细胞数组存储字符串循环里用scen{i}取出这是MATLAB最经典的遍历方式。如果直接在函数里输入UMi注意不要拼错成umi但代码里用了strcmpi忽略大小写。3. 天线辐射方向图建模各向同性、偶极子与3GPP扇区天线3.1 方向图的关键参数增益、波束宽度、前后比路径损耗只描述了传播环境天线的能力由辐射方向图决定。辐射方向图是天线增益在空间三维方向上的分布通常用球坐标系下的θ和φ表示。对5G基站来说最常用的是3GPP TR 38.901中定义的天线方向图解析式它把天线建模为由多个阵元组成的矩形阵列每个阵元的方向图用水平面半功率波束宽度和垂直面半功率波束宽度来描绘。这里必须澄清一个概念方向图增益是相对各向同性天线dBi的增益数值上等于方向性系数乘以外辐射效率。在系统仿真中我们通常直接使用阵列方向图而不是单个振元的方向图因为波束赋形改变的是阵元间的相位偏移叠加后的方向图随扫描角变化。3GPP的方向图公式之所以好用是因为它用几行解析式表达了单个阵元的方向图并且假设所有阵元方向图相同这样就省去了用全波电磁仿真软件逐频点计算的时间。一个典型的基站扇区天线参数是水平半功率波束宽度65度垂直半功率波束宽度6~10度最大增益在通常18 dBi左右。这些参数直接影响侧瓣电平和前后比。如果你在MATLAB里直接构造均匀线性阵列ULA或者均匀矩形阵列URA把每个阵元的方向图设为相同就能合成出工程上需要的扇区波束。3.2 使用phased.LinearArray和pattern函数绘制方向图MATLAB的Phased Array System Toolbox提供了phased.ULA和phased.URA对象配合pattern能快速可视化阵列方向图。下面是一个8元线阵在3.5 GHz下的方向图绘制例子。fc 3.5e9; lambda physconst(LightSpeed) / fc; ula phased.ULA(NumElements, 8, ElementSpacing, lambda/2); % 阵元使用各向同性天线, 方向图可通过Element参数修改 ula.Element phased.IsotropicAntennaElement(BackBaffled, true); az -180:0.5:180; el -90:0.5:90; figure; pattern(ula, fc, az, el, CoordinateSystem, polar, Type, directivity); title(8元ULA方向图 (3.5GHz, 阵元间距lambda/2));这段代码的要点是BackBaffled属性设为true它让阵元背后的辐射被抑制模拟实际反射板的效果。很多新手忽略这个参数导致仿真方向图前后对称与真实基站天线相差很远。如果你不想用工具箱也可以自己写阵列因子公式对于均匀间距d、N个阵元的天线阵列因子AF sin(Nψ/2)/sin(ψ/2)其中ψ kd cosθ ββ是激励相位。把阵元方向图乘上AF就得到阵因子方向图。这种方法控制力更强但需要自己处理三维旋转。3.3 3GPP TR 38.901天线方向图解析公式的MATLAB代码3GPP TR 38.901中定义的单阵元方向图公式是A_E(θ,φ) A_max - min{-[A_H(φ)A_V(θ)], SLA_V}其中A_H(φ) -min[12*(φ/φ_3dB)^2, A_m]A_V(θ) -min[12*((θ-θ_etilt)/θ_3dB)^2, SLA_V]。这里θ_etilt是电下倾角θ_3dB是垂直半功率波束宽度φ_3dB是水平半功率波束宽度A_m是前后比最大值SLA_V是垂直旁瓣抑制度。直接用这些公式写MATLAB比调用工具箱更接近3GPP系统级仿真的标准。下面给出实现并画三维方向图。function [A, theta, phi] nrAntennaPattern(phiDeg, thetaDeg, phi3dB, theta3dB, Am, SLAV, thetaEtilt) % 输入角度向量, 输出增益dBi % phiDeg: 水平面角度, -180~180 % thetaDeg: 垂直面角度, 0~180 (定义theta90为正上方) phi phiDeg; theta thetaDeg; % 计算水平方向图 A_H -min(12*(phi/phi3dB).^2, Am); % 计算垂直方向图, 考虑电下倾角 A_V -min(12*((theta-thetaEtilt)/theta3dB).^2, SLAV); % 3GPP阵元方向图合成 A -min(-(A_H A_V), SLAV); end % 使用示例 phi -180:180; theta 1:179; % 避免0度奇异 [Phi, Theta] meshgrid(deg2rad(phi), deg2rad(theta)); A nrAntennaPattern(phi, theta, 65, 6, 30, 30, 12); % 65度水平波束, 6度垂直波束, 12度下倾 A A; % 转置使phi对应x轴 figure; surf(phi, theta, A, EdgeColor, none); xlabel(水平角度 (deg)); ylabel(俯仰角度 (deg)); zlabel(增益 (dBi)); title(3GPP TR 38.901阵元方向图);这个写法里meshgrid生成角度网格所有运算都是矩阵运算MATLAB执行起来非常快。注意A_H和A_V的裁剪操作分别对应水平面最大衰减和垂直面最大衰减。当你查看surf图时会发现增益最大处正好在θ102度因为定义θ90为正上实际下倾12度对应θ102度这就是电下倾角的效果。实际基站电下倾角通常在2度到15度之间调整参数时你会看到主瓣指向发生明显变化。4. 路径损耗与方向图联合仿真覆盖分析与波束赋形初探4.1 馈入方向图计算接收功率分开写路径损耗和天线方向图只是热身真正的应用是将两者组合成链路预算。接收功率的公式是P_rx P_tx G_tx(θ_tx,φ_tx) - PL G_rx(θ_rx,φ_rx)其中G_tx是从基站天线方向图上读取的、在终端所在方向上的增益G_rx是终端天线在基站方向上的增益。这里的方向角不是全局坐标而是相对于各自天线指向的本地坐标。实际操作时你先根据基站坐标和终端坐标计算离开方位角和离开俯仰角再根据终端朝向计算到达角然后从方向图数据中插值取增益。MATLAB里可以用上一节的方向图函数生成网格增益矩阵再用interp2插值避免直接找矩阵索引。直接索引很容易因为角度量化导致边缘方向增益跳变特别是在波束零点附近。4.2 代码示例扫角度得到接收功率与信噪比下面是一个简化但完整的联合仿真基站位于原点天线朝向正北终端绕基站走一圈距离固定为200米载频3.5GHz发射功率43 dBm带宽100 MHz噪声系数7 dB。我们计算终端在水平面上不同方位角时的接收功率和SNR。fc 3.5e9; lambda 3e8 / fc; distM 200; % 终端距离 Ptx_dBm 43; bw 100e6; NF 7; kT -174; % dBm/Hz % 生成基站方向图 phi3dB 65; theta3dB 6; Am 30; SLAV 30; thetaEtilt 6; phiAxis -180:180; thetaAxis 0:180; G_tx nrAntennaPattern(phiAxis, thetaAxis, phi3dB, theta3dB, Am, SLAV, thetaEtilt); azTerminal 0:360; % 终端方位角 Prx_dBm zeros(size(azTerminal)); for k 1:length(azTerminal) az azTerminal(k); % 假设基站天线指向0度, 则终端方位角就是离开方位角 [~, idxAz] min(abs(phiAxis - az)); % 假设终端在水平面, 垂直角度theta90度 [~, idxEl] min(abs(thetaAxis - 90)); g_tx_dBi G_tx(idxAz, idxEl); pl_db nrPathLoss(3.5, distM, UMa, 0); % 使用UMa NLOS Prx_dBm(k) Ptx_dBm g_tx_dBi - pl_db; end % 计算SNR SNR_dB Prx_dBm - (kT 10*log10(bw) NF); % 绘制 figure; plot(azTerminal, Prx_dBm, LineWidth, 1.5); xlabel(终端方位角 (deg)); ylabel(接收功率 (dBm)); grid on; title(不同方位角下的接收功率 (UMa-NLOS, 200m)); figure; plot(azTerminal, SNR_dB, LineWidth, 1.5); xlabel(终端方位角 (deg)); ylabel(SNR (dB)); grid on;这段代码里有个明显简化直接找到最接近的矩阵索引没有插值。在波束主瓣方向0度附近索引误差不大但在零点附近误差可能达到几个dB因为方向图变化剧烈。改进办法是用interp2(thetaAxis, phiAxis, G_tx, thetaVal, az, spline)。另外nrPathLoss第一个参数是3.5GHz不是3500这是最容易写错的地方。发射功率43 dBm是常规宏基站配置对应的EIRP还要加上天线最大增益但这里我们做了分步计算所以不需要额外加。4.3 常见错误与参数设置坑你可能有90%的概率在第一个版本里得到异常结果原因是下面几个坑中的一个。第一个坑频率单位混用。3GPP公式里频率单位是GHz而你从physconst(LightSpeed)得到的波长是Hz一旦混用20log10(f)会差30倍即约30 dB误差。第二个坑角度定义不一致。3GPP方向图公式中θ90度是水平面而MATLAB的pattern函数默认θ0是z轴正方向两者相差90度。如果你直接用箱函数数据和自写公式混用主瓣位置会错位。第三个坑距离用二维投影距离。38.901模型要求d是三维距离包括基站高度和终端高度差。如果你只用水平投影距离在小区边缘基站高度30米、终端高度1.5米时误差虽小但在断点附近模型切换位置会偏差几十米。我刚才写的联合仿真代码里对垂直方向直接固定为θ90度这在基站与终端等高时成立。如果基站高度差明显需要根据高度差和水平距离算出俯仰角θ atan2(heightDiff, horizontalDist)这里θ是按3GPP定义的需转换。否则方向图在主瓣外的增益会被错误地取到导致接收功率偏低或偏高。5. 验证方法用增益与方向性关系核对你的仿真结果写完了路径损耗和方向图怎么确认自己的方向图计算没错一个最有效的验证手段是利用方向图积分求方向性系数。任意天线的方向性系数D是最大辐射强度与平均辐射强度之比。对3GPP解析方向图做二维球面积分得到的最大方向性应该与公式中的A_max一致。如果积分结果差得太大说明角度网格或公式实现有误。下面给出一段方向性系数验证代码基于上一节的nrAntennaPattern函数。积分用球面坐标并考虑sin(θ)加权因子。phiAxis -180:1:180; % 1度分辨率 thetaAxis 0:1:180; [PHI, THETA] meshgrid(deg2rad(phiAxis), deg2rad(thetaAxis)); A nrAntennaPattern(phiAxis, thetaAxis, 65, 6, 30, 30, 6); G_lin 10.^(A/10); % 球面积分: 平均辐射强度 1/(4*pi) * integral G * sin(theta) dtheta dphi % 注意theta采样从0到pi dTheta deg2rad(1); dPhi deg2rad(1); sinTheta squeeze(sin(THETA(:,1))); integ sum(G_lin * sinTheta(:)) * dTheta * dPhi; % 近似积分 D_max max(max(G_lin)) * 4 * pi / (integ * 2); % 因为phi是-180~180覆盖全空间, 积分结果已经2pi D_dBi 10*log10(D_max); fprintf(数值方向性系数: %.2f dBi\n, D_dBi);注意这里积分时G_lin原本是矩阵乘以sinTheta(:)需要保证维度匹配我写成G_lin * sinTheta(:)是矩阵乘以向量实际会报错。更稳妥的做法是逐项求和sum(sum(G_lin .* repmat(sinTheta, 1, size(G_lin,2)))) * dTheta * dPhi。上面的写法纯粹为了体现过程正式仿真时建议用trapz做二维积分能获得更高精度。如果你的方向图最大增益是18 dBi积分结果也应该接近18 dBi。偏差小于0.5 dB说明角度网格足够细。网格从1度改为0.5度积分精度提升但计算时间翻4倍工程上1度已经够用。另一个快速验证路径损耗的方法是双线模型。在UMi场景、低频段下双线模型和38.901的LOS模型在远场区应该趋势一致。你可以取几个参考点比如100米、200米、500米手动用对数距离公式算一遍再与函数输出对比。如果一致说明你传递参数没出类型或单位问题。最后的技巧利用MATLAB的nrLinkQuality或nrDownlinkMeasurements这类更高层函数可以把方向图结果直接带入系统级仿真但那需要5G Toolbox。如果手头只装了基础的Antenna Toolbox建议多用pattern函数里的Type选项比如power和directivity的区别在于是否包含天线效率。下行覆盖评估用directivity便于与路损结合因为路损已经包含了损耗项。把这个习惯落实在你的所有仿真脚本里很多诡异的覆盖空洞都是因为使用了power导致增益偏低造成的。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进