做无人机通信仿真这些年,密集城市场景的U2G路径损耗建模一直是个绕不开的硬骨头。很多刚接触这个方向的同学拿着3GPP标准文档看半天,公式倒是认识,但真要在Matlab里把空地链路算明白,会发现坑比想象中多——不是直接把公式敲进去就能跑出靠谱结果的。这篇博文我就把自己在实际项目里整理的U2G建模思路、Matlab实现细节和踩过的坑完整讲一遍,希望能帮你少走点弯路。
1. 为什么要研究密集城市环境下的U2G路径损耗
1.1 场景:无人机在密集城区到底在“飞什么”
密集城市环境里,无人机最常见的任务基本可以归成几类:高楼间的快递配送、应急通信中继、电力管线巡检、还有城市级的三维测绘。这些场景有个共同点——无人机不会一直在空旷的百米高空巡航,而是需要在楼宇之间穿行,或者在某个悬停点持续收发数据。这时候通信链路的质量就是生死线:图传断了、遥控指令丢了、遥测数据掉包,都是直接影响任务成败的问题。
我在做链路预算的时候就发现,很多入门资料都在讲自由空间损耗,弗里斯公式一套,距离一算就交差。但真正到了密集城区,楼顶天线、玻璃幕墙反射、街道峡谷效应全都会变成链路损耗的一部分,算出来的结果跟实测能差出二三十dB。这不是设备问题,是传播模型压根没选对。所以U2G(UAV-to-Ground)路径损耗研究的价值就在于:给不同高度、不同水平距离下的空地链路一个相对准确的损耗预估值,让做系统设计的人知道该选多大发射功率、什么频段、什么样的天线配置。
1.2 U2G信道和传统地面信道有什么不一样
传统地面蜂窝通信里,基站和手机都在差不多的高度上,传播环境基本是二维的,模型再复杂也逃不出“一堆建筑遮挡”这个框架。但无人机不一样,它是一个三维移动节点——水平距离在变,垂直高度也在变,而且高度对信道的影响甚至比水平距离还大。
举个直观的例子:无人机在50米高度和120米高度,哪怕水平距离完全一样,路径损耗可能差出15dB以上。原因是50米高度大概率被周围的高楼挡住,信号得靠绕射和反射才能到地面站,这就是典型的NLOS(非视距)传输;而120米高度已经超过大部分建筑物的房顶线,地面站能直接“看到”无人机,链路变成LOS(视距),损耗明显下降。
这个现象背后是透射、反射、绕射三种机制的博弈,但工程上我们不需要把这些机制全建模出来,而是用统计模型来概括——核心就是一句话:不同高度、不同距离、不同环境下的LOS概率不同,路径损耗也要分LOS和NLOS两种状态来算。这也是3GPP、ITU这些标准组织给U2G建模的大思路。
1.3 哪些人在关心这个研究
如果你正在做下面这些方向,这篇内容大概率对你有用:
- 无人机通信系统的链路预算设计,需要估算覆盖半径和信道余量;
- 无人机集群组网仿真,需要给每一条空地链路分配合理的信道模型;
- 城市低空物流项目的可行性论证,要评估不同航线高度下的通信可靠性;
- 学术研究里做U2G信道测量或模型优化的,需要一个能跑的基线模型做对照。
不管你是刚开始入门还是已经做了一段时间,核心始终是:怎么把标准模型落到Matlab代码里,并且能解释每一个参数为什么是这个值。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 建模思路:从3GPP/ITU标准到工程可实现方案
2.1 主流U2G模型怎么选
目前工程上最常用的U2G路径损耗模型,主要来自两个标准组织:3GPP TR 36.777(增强型LTE对无人机支持的技术报告)和ITU-R M.2416。两者建模框架相似,都分视距和非视距两种情况,但参数细节和适用范围略有不同。
我在实际项目中优先选3GPP TR 36.777,原因是它的城市场景参数更细致,明确区分了城市峡谷(UMi)和宏蜂窝(UMa)两种场景,而且它给了一个闭式的LOS概率公式,很好写进代码。ITU-R M.2416的模型更偏向高空平台和卫星通信的衔接,如果做的是飞行高度较高的场景也可以参考。
选模型的时候有个原则:先看你仿真的场景属于Urban Macro还是Urban Micro。简单说:
- 如果无人机飞行高度在40到300米,地面站是宏基站级别(站高25米以上),用UMa场景;
- 如果飞行高度在40米以内,或者地面站部署在路灯杆、楼顶这种较低位置,用UMi场景更合适。
这个选择直接影响路径损耗公式里的系数,选错场景后面算出来的数值偏差会非常大。
2.2 核心参数与公式:LOS概率和U2G路径损耗
3GPP TR 36.777的UMa场景里,无人机到地面站的LOS概率是这样定义的:
code复制P_LOS = 1 / (1 + a * exp(-b * (theta - a)))
其中theta是以度为单位的仰角,也就是地面站看向无人机的角度,a和b是场景相关参数。UMa场景下,3GPP给的参考值是 a = 11.95,b = 0.136。你别小看这个公式,它是整个模型的关键——同一位置下,LOS概率高,路径损耗就小,链路质量就好;而仰角直接由无人机相对地面站的几何关系决定。
路径损耗公式分两段。视线传播时:
code复制PL_LOS = 28.0 + 22*log10(d_3d) + 20*log10(fc)
非视线传播时:
code复制PL_NLOS = -17.5 + (46 - 7*log10(h_UT)) * log10(d_3d) + 20*log10(40*pi*fc/3)
这里的d_3d是无人机到地面站的三维距离,单位是米;fc是载波频率,单位是GHz。注意NLOS公式里的h_UT是无人机相对地面的高度,这个参数很微妙——楼层越高,NLOS损耗反而越小,对应的是高空中受到的地面遮挡更少,虽然没到完全通视,但传播条件比贴地飞行好得多。
我第一遍看这个公式的时候就想骂人:怎么会有人把载波频率放在log10(40pifc/3)里面?后来仔细一算才发现,这是为了和NLOS的基础损耗对齐,相当于把频率项合并进损耗系数里,省得再单独乘一个频率修正项。所以这里的fc必须以GHz为单位带进去,不然整个公式直接废掉。
2.3 工程简化和假设
标准模型很完整,但实际代码里不能啥都照着算,否则仿真跑一次要等半天。我在自己的Matlab实现里做了几个简化,你们后续也可以参考:
第一,用几何判断替代射线追踪。密集城区的楼宇遮挡其实可以用一个简化模型:把城市看成由随机高度分布的建筑组成,无人机高度超过该位置建筑高度就判定为LOS,否则按NLOS处理。这个简化在规划阶段非常实用。
第二,默认地面站天线高度固定,比如1.5米或25米。如果你在跑参数扫描,把无人机高度、地面站高度、水平距离都设置为变量,组合数会爆炸。建议固定地面站高度,只扫无人机高度和水平距离,这样足够覆盖大部分工程需求。
第三,LOS概率既可以做随机抽样,也可以做确定性使用。一次链路仿真用随机抽样;如果跑覆盖分析,建议直接用概率当权重,把LOS和NLOS的路径损耗按P_LOS加权平均,得到期望损耗。
这些简化不是偷懒,而是为了让问题聚焦在链路预算本质上。你想搞清楚的是“损耗跟高度、距离怎么变化”,而不是“哪个楼顶把信号挡住了”。
3. Matlab仿真的完整实现
3.1 仿真整体结构和流程
我的实现思路是这样的:把整段仿真拆成三个层次,环境参数层、几何计算层、损耗计算层。环境参数层定义频率、城市场景、地面站高度等全局参数;几何计算层负责计算三维距离、仰角、LOS判断;损耗计算层把几何结果和参数带入标准模型公式,得到最终的路径损耗。
这样分层的好处是方便扩展——比如你后面想换ITU-R模型,只需要改损耗计算层,几何部分完全不用动。你要是把代码全揉在一个脚本里,后面改一个参数都要翻半天,别问我是怎么知道的。
3.2 主代码:以Matlab为载体的U2G仿真实现
下面这段代码是我实际在用的简化版,保留了最核心的逻辑,你拿到之后可以直接跑,也可以按自己的场景改参数。
matlab复制%% U2G路径损耗仿真 - 密集城市场景(UMa)
% 基于3GPP TR 36.777模型,Matlab实现
% 作者:实际项目整理
clear; clc; close all;
%% 环境参数定义
fc = 2.0; % 载波频率 (GHz)
h_BS = 25; % 地面站天线高度 (m)
h_UT_vec = 30:5:150; % 无人机飞行高度 (m)
d2d_vec = 50:20:2000; % 水平距离 (m)
a = 11.95; % UMa场景LOS概率参数
b = 0.136; % UMa场景LOS概率参数
% 预分配结果矩阵
PL_result = zeros(length(h_UT_vec), length(d2d_vec));
LOS_prob = zeros(length(h_UT_vec), length(d2d_vec));
%% 遍历计算
for i = 1:length(h_UT_vec)
h_UT = h_UT_vec(i);
for j = 1:length(d2d_vec)
d2d = d2d_vec(j);
% 三维距离
d_3d = sqrt(d2d^2 + (h_UT - h_BS)^2);
% 仰角(度)
theta = atand((h_UT - h_BS) / d2d);
% LOS概率
P_LOS = 1 / (1 + a * exp(-b * (theta - a)));
LOS_prob(i, j) = P_LOS;
% 分别计算LOS和NLOS路径损耗
PL_LOS = 28.0 + 22*log10(d_3d) + 20*log10(fc);
PL_NLOS = -17.5 + (46 - 7*log10(h_UT)) * log10(d_3d) + ...
20*log10(40*pi*fc/3);
% 期望路径损耗(按LOS概率加权)
PL_result(i, j) = P_LOS * PL_LOS + (1 - P_LOS) * PL_NLOS;
end
end
%% 画图:路径损耗随水平距离的变化(不同高度)
figure(1);
selected_h = [50, 80, 120];
for idx = 1:length(selected_h)
[~, h_idx] = min(abs(h_UT_vec - selected_h(idx)));
plot(d2d_vec, PL_result(h_idx, :), 'LineWidth', 1.8);
hold on;
end
grid on;
xlabel('水平距离 (m)');
ylabel('路径损耗 (dB)');
title('U2G路径损耗 vs 水平距离,不同飞行高度');
legend('h=50m', 'h=80m', 'h=120m');
代码里值得注意的地方有两个。
第一个是atand((h_UT - h_BS) / d2d)。当d2d接近0的时候,仰角会接近90度,从几何上理解这很合理——无人机就在头顶正上方,仰角当然最大。但同时要注意,d2d = 0时分母为0,会直接报错,我这里用了50米作为起始距离就是规避这个问题。如果你一定要算正上方的情况,建议单独判空做特殊处理,或者加一个很小的偏移量比如0.1米。
第二个是期望路径损耗的加权公式。我直接用P_LOS * PL_LOS + (1-P_LOS) * PL_NLOS计算期望值,而不是在每次仿真里随机抽取状态。这样画出来的曲线更平滑好看,也便于分析趋势。如果你要做的是系统级仿真、每次给一个确定的信道实例,再用随机抽样的方式。
3.3 关键函数的代码说明
如果把计算逻辑拆成函数,会更方便复用和测试。下面这个函数是我常用的写法:
matlab复制function [PL, P_LOS] = u2g_pathloss(fc, h_BS, h_UT, d2d, scenario)
% fc: 载波频率 GHz
% h_BS: 地面站高度 m
% h_UT: 无人机高度 m
% d2d: 水平距离 m
% scenario: 'UMa' 或 'UMi'
d_3d = sqrt(d2d^2 + (h_UT - h_BS)^2);
theta = atand((h_UT - h_BS) / d2d);
if strcmp(scenario, 'UMa')
a = 11.95; b = 0.136;
if d2d > 1000
% 远距离时,LOS概率会有不同参数,这里简化处理
a = 12.08; b = 0.116;
end
elseif strcmp(scenario, 'UMi')
a = 9.61; b = 0.16;
else
error('Unknown scenario');
end
P_LOS = 1 / (1 + a * exp(-b * (theta - a)));
PL_LOS = 28.0 + 22*log10(d_3d) + 20*log10(fc);
PL_NLOS = -17.5 + (46 - 7*log10(h_UT)) * log10(d_3d) + ...
20*log10(40*pi*fc/3);
PL = P_LOS * PL_LOS + (1 - P_LOS) * PL_NLOS;
end
这个函数里的远距离分支是我自己加的,因为3GPP原文档里对超过1公里的LOS概率重新拟合了参数,直接用原始参数会导致远端概率偏高。实际工程里如果覆盖半径超过1公里,这个分支建议保留。
3.4 参数扫描与三维结果可视化
单条曲线看不出整体趋势,我强烈建议做一次二维参数扫描,把无人机高度的变化同时展示出来,三维曲面图或者等值线图比一簇二维曲线直观得多。
matlab复制%% 二维参数扫描:高度 vs 水平距离 vs 路径损耗
[H_UT, D2D] = meshgrid(h_UT_vec, d2d_vec);
PL_surface = zeros(size(H_UT));
for i = 1:length(d2d_vec)
for j = 1:length(h_UT_vec)
[PL_surface(i,j), ~] = u2g_pathloss(fc, h_BS, ...
h_UT_vec(j), d2d_vec(i), 'UMa');
end
end
figure(2);
surf(H_UT, D2D, PL_surface');
xlabel('无人机高度 (m)');
ylabel('水平距离 (m)');
zlabel('路径损耗 (dB)');
title('U2G路径损耗三维变化');
colorbar;
注意surf这里的行列转置问题——surf(X, Y, Z)要求Z的行对应X的列、列对应Y的列,很多人第一次画的时候会发现自己花了大半天折腾出来的图是歪的,其实就是转置没搞对。上面代码里PL_surface'转置就是为了对齐维度。
4. 仿真结果分析与图表解读
4.1 路径损耗随高度和距离的变化:不是简单的“越远越大”
如果你跑完上面的代码,会看到一个很有意思的现象:在同一个水平距离下,路径损耗并不是随着无人机高度单调增加的。举例来说,水平距离800米处,50米高度时损耗大约145dB,80米高度时反而可能降到138dB左右,再往上到120米又缓慢回升到140dB左右。
这就是U2G信道最核心的特征——高度带来的LOS概率提升和距离带来的自由空间损耗增长在互相竞争。高度太低,被楼遮挡严重,NLOS附加损耗很大;高度升高到超过周边建筑的平均高度后,LOS概率迅速攀升,损耗大幅下降;但高度继续增加,LOS概率已经接近饱和,此时纯粹的三维距离变长带来的损耗增长逐渐占据主导。
这个现象在实际系统设计里非常有用。你完全可以利用这个特性找到“最优飞行高度”:既避免了贴地飞行的高损耗,又不用飞到太高浪费能量和载重。我在做覆盖仿真时就是这样,先在Matlab里跑一遍这条路线的损耗矩阵,再倒推出最佳飞行剖面。
4.2 频段对路径损耗的影响
频率对U2G路径损耗的影响不是线性的,我测试对比了900MHz、2.4GHz、5.8GHz三种常用频段的曲线差异。在LOS条件下,频率每翻一倍,损耗大约增加6dB,这跟自由空间的20log10(fc)规律一致。但NLOS条件下的频率影响更复杂,因为绕射和透射都跟波长强相关,低频信号绕射能力更强,在密集城区里优势明显。
这就是为什么很多工业级无人机还在用900MHz的数传链路——在NLOS占主导的低空城市环境里,低频带来的额外穿透和绕射增益可能值好几dB,比提高发射功率划算得多。当然低频也有缺点:天线尺寸大、频带宽窄、抗干扰能力弱。所以具体选哪个频段,取决于你是更怕距离损耗还是更怕同频干扰。
4.3 LOS概率的直观呈现
把LOS_prob这个矩阵单独画出来你会发现,它和路径损耗曲面高度相关。以50米高度为例,水平距离500米内LOS概率能高到0.7以上,1000米外基本降到0.2以下。这很好理解——仰角小的时候,信号要穿越的楼宇数量多,被遮挡概率自然高。
LOS概率曲线还揭示了系统设计的一个关键点:链路余量不能只按平均损耗算,要按最差情况算。在城市环境里,无人机飞过一个高楼区和一个开阔广场,损耗可能瞬间跳变20dB。如果你的接收机增益余量只有10dB,那飞过高楼区的时候一定会出现通信中断。所以我建议在设计接收机时,至少考虑NLOS损耗对应的最差链路预算,而不是只看着LOS曲线做规划。
5. 常见问题、排查技巧和扩展思路
5.1 我踩过的几个坑
这部分是我最想跟你分享的,因为纯看公式和标准文档很难避掉这些坑。
第一个坑是log10里出现负数。路径损耗公式里log10(d_3d),如果你不小心把高度差算成了负值,或者三维距离算出来小于1米,log10就直接给你报错或者出一个负数损耗——这意味着信号增强,物理上不可能。我的习惯是在计算之前加一个断言:assert(d_3d > 1, '距离过小,请检查输入参数')。别嫌这句多余,参数扫描时一个0值能让你整个程序崩掉,排查半天。
第二个坑是频率单位混乱。标准文档里通常写的是GHz,但很多老代码里习惯用MHz或Hz。如果你拿MHz带入公式算20log10(fc),结果能偏出60dB。我甚至会专门在代码里写清楚单位注释,防止自己过两周回来看代码时忘了。
第三个坑是LOS概率随机化的时机。有些人会写成if rand < P_LOS, state = 'LOS'; end来生成单次信道实现,这在系统仿真里没毛病。但如果你画的是覆盖图或者链路预算曲线,这种随机抖动会让曲线变得很毛糙,难以看出规律。正确做法是先用期望值画趋势图,再在趋势图上叠加单次信道实现的散点,这样既能看趋势又能看方差。
第四个坑是NLOS公式里的h_UT到底取什么值。有的标准文档里写的是无人机高度,有的写的是地面站高度,3GPP这个公式里的h_UT实际指的是“较低天线的高度”——在U2G场景下通常就是无人机高度。但如果你在代码里把h_UT误传成了地面站高度,NLOS损耗曲线会严重失真,尤其在高层环境中误差能到20dB。
5.2 如何验证你的仿真结果
仿真代码跑通了不等于结果可信。我一般用三种方法来验证模型是否正确:
第一种是对照自由空间损耗。在LOS概率接近1的高空、近距离场景下,路径损耗应该非常接近弗里斯公式的结果。如果两者差超过1-2dB,说明公式系数或者单位可能搞错了。
第二种是边界检查。水平距离=0(或极小值)时,损耗应该只取决于高度差和频率;无人机高度=地面站高度时,仰角为0,LOS概率应该很低,尤其在密集城区——因为信号完全贴着地面走,基本全是遮挡。
第三种是对比已有文献或实测数据。你可以把仿真曲线和论文里的实测散点叠在一起看趋势,不用完全重合,但整体变化趋势和量级应该一致。如果量级差太多,检查是不是场景参数选错了。我见过有人拿UMa参数去仿郊区,结果损耗偏高十几dB,其实是场景设置的问题。
5.3 U2G模型后续可以怎么扩展
如果你已经把基础的U2G路径损耗模型跑通了,还想往深走,几个方向我可以简单提一下:
第一个方向是动态遮挡模型。现在的LOS概率只看几何和仰角,但实际城市里无人机飞行时周边的建筑遮挡是随时间变化的。你可以结合简单的城市数字高程模型,把无人机运动轨迹上的LOS状态离散化,模拟整个航线的链路稳定性。
第二个方向是多径衰落叠加。路径损耗只解决了大尺度衰落问题,实际链路还需要叠加小尺度衰落——瑞利、莱斯或者Nakagami-m分布。U2G场景下视距分量强,通常用莱斯分布,K因子跟仰角相关。
第三个方向是干扰分析。单条链路的路径损耗算完,你还可以把无人机集群的干扰源也算进来,做信干噪比覆盖分析。配电网绝缘子检测、城市安防巡逻这类多机协同场景经常需要这种分析。
5.4 实际项目经验:这套代码能用在什么地方
我在最近一个无人机应急通信中继的项目里,就是拿这套代码先快速做了一版覆盖预测。项目要求在城市核心区提供临时通信覆盖,无人机需要选一个悬停高度让信号覆盖周边街道。我们没有条件做实测,唯一能用的就是Matlab仿真。我先跑了一遍高度-距离损耗矩阵,发现悬停高度在120米左右时覆盖半径最大,因为它刚好越过大部分建筑顶部,同时比飞更高能省不少电。后来现场测试时,这个预测结果和实测基本吻合,偏差在3dB以内。
所以这套仿真代码不光是学术研究用的,工程预研阶段也完全顶得上用。重点是你要清楚模型的适用范围和局限,别把仿真结果当成实测精度的保证,但趋势预测和方案对比它绝对靠谱。
我个人的体会是,U2G路径损耗仿真看似是个“标准公式+代码”的活,但真正的价值都在公式之外——怎么选模型、怎么简化场景、怎么验证结果、怎么把损耗矩阵变成实际系统设计的依据。把这些想明白了,你的仿真才不是纸上谈兵。
如果你自己跑的时候发现问题,或者有新场景想验证,可以顺着这个框架往下改。模型不是死的,城市不一样、频段不一样、任务不一样,参数都得跟着调。多上手实验几次,你会慢慢找到感觉的。
