作为长期做无人机通信链路仿真的人,我几乎每隔一阵就会遇到有人问同一个问题:在楼宇密集的城区里,无人机对地面的信道到底怎么建模才靠谱。实验室里用自由空间模型算出来的链路余量,一到实飞就翻车,原因无外乎是城区环境的遮挡、反射和多径效应完全没被考虑进去。今天这篇,我就围绕密集城市环境下的空对地路径损耗(U2G)研究,把我的建模思路、参数选取、Matlab代码实现和踩过的坑一次性整理出来,希望能给做无人机通信仿真、链路预算或者覆盖规划的朋友一些参考。
这篇内容主要聚焦三个核心点:密集城市场景下U2G信道的物理特性与关键参数、基于几何统计的路径损耗建模方法、以及一套可直接运行的Matlab实现框架。无论你是刚接触信道仿真的学生,还是有实飞经验但需要精细化传播模型的工程人员,这篇文章都能帮你把“从哪下手”这个问题解决掉。与其他类型的信道仿真正相反,U2G场景最麻烦的地方不是数学公式,而是如何把三维城市几何信息合理地融合进传播模型里——这是本文反复强调的主线。
1. 项目背景与研究思路拆解
1.1 为什么密集城区的U2G路径损耗不能套用传统模型
空对地信道与传统的地对地(T2G)信道最大的不同在于:无人机的海拔高度变化范围很大,从几十米到数百米不等,而地面终端的海拔通常是固定的。这意味着信道不再是一个相对稳定的二维平面问题,而是带有明显“三维倾斜”特征的传播问题。
在密集城市环境中,最大的麻烦是建筑物遮挡。我们实测中经常遇到的情况是:无人机在楼顶上空飞的时候,信号路径可能是视距(LOS);但只要横向偏移一点,楼宇遮断了直射路径,信号突然跌到非视距(NLOS)状态,接收功率可能出现30dB以上的骤降。这种剧烈的突变,如果还用固定衰减因子去拟合,误差会大到不可接受。
另一个很容易被忽略的因素是地面反射和多径效应。城市楼宇的玻璃幕墙、金属外墙、路面都构成反射面,无人机端的天线视角又通常朝下,这导致接收信号里面包含了相当强的地面反射分量。在低空、低速这种场景下,多径衰落特征与传统的瑞利衰落差异很大,更偏向莱斯分布,但莱斯因子又会随着无人机位置变化而剧烈波动。研究者们常用几何统计模型来解决这个问题,也就是将三维城市模型中的建筑物分布参数化,用蒙特卡洛方式计算每条链路的LOS概率和路径损耗期望值,而不是尝试精确追踪每一条射线。
1.2 研究目标、方法选型与整体框架
我做这个项目的时候,给自己定了一个明确目标:不追求教科书级别的完整信道建模,而是搭建一个足够准确、可以快速迭代的仿真工具,让用户只需输入城市区域的建筑物分布数据、无人机航迹、频率和天线参数,就能得到每一条链路的路径损耗预测曲线。换言之,这是一套工程级仿真方案,而不是纯学术推导。
基于这个目标,我在方法选型上做了三个决策:
- 几何建模采用二维地图投影+建筑物高度栅格化,这样计算起来比完整三维射线追踪快得多;
- LOS/NLOS判定用高度角投影法:把无人机位置和地面终端位置投影到二维平面,判断连线与建筑物轮廓是否存在交集;
- 路径损耗公式采用“LOS概率加权”的双状态模型,不直接假设信道要么是LOS要么是NLOS,而是根据城市统计参数计算概率,再用概率对两种状态的损耗做加权平均。
整体框架分四个模块:城市场景生成器、传播路径判别器、路径损耗计算器、以及结果可视化模块。这套框架用Matlab实现特别顺手,因为矩阵运算和内置的地理数据工具能省下不少时间。
1.3 模型的适用边界与已知局限
需要提前说明的是,这个模型不是万能的。它最适合的场景是无人机高度在50到300米、地面终端处于街道或广场、频率在0.8到6GHz范围内的链路仿真。对于更高频段(比如毫米波)或者无人机低空穿越深街峡谷的场景,这套模型的精度会明显下降,因为高频信号对绕射损耗的敏感性更强,深街峡谷中多重反射占主导,几何统计模型的假设会失效。这也是我在代码注释里反复提醒用户的地方:使用前务必确认应用场景处于模型适用范围内。
2. 核心方法与关键参数解析
2.1 路径损耗的物理机制与组成
在密集城市环境中,U2G链路的路径损耗主要由自由空间传播损耗、建筑物遮挡损耗、地面反射损耗和多径干涉损耗四部分构成。工程上通常不会把这四部分完全拆开计算,而是采用等效模型:先算一条基准的自由空间损耗,再加上与场景相关的额外损耗项。
自由空间损耗用经典公式:
L_fs = 20*log10(4*pi*d/lambda);这里的d是无人机到地面终端的直线距离,lambda是波长。这个公式本身没有任何城市环境信息,但它提供了基准线。后续要叠加的,就是城市环境在这一基准线上的“额外惩罚”。
城市环境带来的额外损耗怎么量化?业内用得比较普遍的处理方式是基于ITU-R建议和3GPP TR 36.777中的无人机信道模型思路,把链路状态分为LOS、NLOS和NLOS反射三类,对每一类分别拟合一个包含距离和高度角参数的损耗公式。例如在3GPP模型中,U2G的LOS概率与无人机高度、建筑物平均高度、街道宽度和建筑物覆盖率密切相关。
2.2 关键参数:频率、高度、建筑物分布
参数选取得当与否,直接决定仿真结果能不能反映真实场景。我实际跑下来,有四个参数最敏感,必须认真标定:
- 载波频率f:频率越高,绕射损耗越大,NLOS状态下频率带来的额外损耗越明显。代码中我设置了默认2.1GHz,如果换成5.8GHz,就得同步调整绕射修正项;
- 建筑物平均高度h_b:这个值直接决定LOS概率曲线的拐点位置。城市区域平均楼高30米,无人机在50米高度时还有较高的LOS概率,但要是平均楼高40米,同样的50米高度LOS概率会明显下降;
- 建筑物覆盖率alpha:反映区域内建筑物占用地面的比例。取值0.3到0.5之间,数值越大,遮蔽越严重;
- 无人机高度h_u和航迹倾角:高度越高,地面终端附近的遮挡概率越小,但路径长度增加会导致基准损耗上升。所以实际仿真中经常能看到一条先下降后上升的损耗曲线,先下降是因为LOS概率增加带来的“收益”,后上升是因为几何距离增大占主导。
2.3 LOS/NLOS状态判定方法
判定LOS/NLOS的核心是判断无人机到地面终端的视线连线是否被建筑物遮挡。我采用的方法是构建一个二维剖面:
- 把无人机与地面终端投影到水平面上,生成一条连线;
- 遍历连线穿过的所有栅格,读取栅格对应的建筑物高度;
- 将地球曲面简化为直线,比较视线高度与建筑高度的关系,如果存在某一点上建筑高度超过视线高度,则判定为NLOS。
这里有一个细节:判断时视线高度不是线性插值的,而是要按球面几何修正。虽然U2G场景相对距离通常就几百米,球面效应不明显,但我在代码里还是加了可选的曲率修正开关,方便做远距离仿真的时候使用。判定结果直接影响后续使用哪一套损耗公式,所以这个模块的准确度极其重要。
3. Matlab实现与代码设计
3.1 城市场景生成器的实现
城市场景生成器输入参数为区域尺寸、建筑密度、平均楼高和楼高标准差,输出为一张建筑物高度矩阵。我用的是随机生成方案:先按泊松分布布点确定建筑中心位置,再在每个中心点周围生成矩形或L形建筑轮廓,建筑高度服从截断正态分布。这样生成出来的场景在统计意义上符合密集城区的特征,虽然不还原任何真实街道,但用来做链路仿真足够。
生成核心代码如下:
function building_map = generateCity(L, W, rho, avg_h, std_h) % L,W: 区域长宽; rho: 建筑物覆盖率; avg_h/std_h: 楼高统计参数 x_all = rand(1, round(rho*L*W/400)) * L; y_all = rand(1, round(rho*L*W/400)) * W; building_map = zeros(round(L), round(W)); for k = 1:length(x_all) h = max(5, avg_h + std_h*randn()); rx = max(4, 10*rand()); ry = max(4, 10*rand()); x0 = max(1, round(x_all(k))); y0 = max(1, round(y_all(k))); x1 = min(size(building_map,1), x0+ceil(rx)); y1 = min(size(building_map,2), y0+ceil(ry)); building_map(x0:x1, y0:y1) = max(building_map(x0:x1, y0:y1), h); end end这段代码的思路是用栅格矩阵存储楼高,矩阵分辨率默认1米,这样后续在做LOS判断时可以直接按索引读取高度值。实际使用中我建议分辨率不要低于2米,否则内存消耗大,而且建筑边缘的锯齿会引入不必要的计算偏置。
3.2 传播路径判别与损耗计算模块
传播路径判别模块的输入是无人机三维坐标、地面终端坐标和城市高度矩阵。在这个模块中,需要先计算水平投影连线,再沿线采样判断LOS状态。为提升计算速度,我用的是Bresenham直线算法进行栅格遍历,这样不需要对整个二维平面求交,只需要遍历连线穿过的少数栅格。直线上每个采样点的高度,通过读取building_map矩阵获得。
判断完成后,进入路径损耗计算。双状态加权模型的公式如下:
function PL = computeU2GPL(freq, d2d, h_u, h_g, P_LOS, PL_LOS, PL_NLOS) c = 2.99792458e8; lambda = c/freq; L_fs = 20*log10(4*pi*d2d/lambda); PL = L_fs + P_LOS.*PL_LOS + (1-P_LOS).*PL_NLOS; end这里的PL_LOS和PL_NLOS并不是一个固定常数,它们依赖于水平距离、无人机高度和地面终端高度差。我的实现中给出了两种选择:一种是根据ITU-R P.1411的建议直接套公式;另一种是用实测数据拟合的斜率和截距。两种方式默认都带参数文件,方便替换。需要提醒的是,P_LOS(视距概率)的计算是整个算法的灵魂,务必要用符合城市建筑统计特征的公式,而不能简单拍脑袋给个常数。
3.3 主程序流程与标准化接口设计
整个仿真主程序遵循“参数读取 - 场景生成 - 航迹生成 - 逐点计算 - 结果保存”的固定流程。为了便于批量实验,我把所有可变参数封装到一个结构体config中,用户可以用excel表格或者脚本统一修改配置,而不用去翻动核心函数。
主程序关键片段:
cfg.freq = 2.1e9; cfg.city_size = 500; % 区域边长, 单位米 cfg.building_density = 0.4; cfg.building_avg_h = 28; cfg.altitude = 100; % 无人机相对地面高度, 单位米 cfg.radius = 300; % 水平扫描半径 cfg.ground_h = 1.5; building_map = generateCity(cfg.city_size, cfg.city_size, ... cfg.building_density, cfg.building_avg_h, 8); [dist2d_grid, PL_map] = computeCoverageMap(building_map, ... cfg.altitude, cfg.ground_h, cfg.freq, cfg.radius);这种接口设计的好处是,你可以方便地接入自己定义的无人机航迹文件,比如读取一个csv格式的航点列表,在主循环里逐点调用computeU2GPL,最终把所有链路的路径损耗汇总输出,方便后期做链路预算或者中继部署规划。
4. 仿真结果分析与工程应用
4.1 典型结果解读:高度、距离与损耗曲线
我跑过一个典型场景:无人机在500m×500m的密集城区上空飞行,平均楼高28米,建筑覆盖率0.4,载波频率2.1GHz,飞行高度变化取50米、100米、200米三档,地面终端位于区域中心。仿真结果表明,在水平距离小于200米时,50米飞行高度反而比200米高度有更低的路径损耗,因为近距离传播时几何距离才是主要矛盾,高度带来的LOS概率优势尚未显现。当水平距离超过300米后,200米高度的优势开始反转,损耗明显低于50米高度。
这个现象背后是LOS概率与几何距离的博弈。很多工程人员习惯固定高度然后画距离损耗曲线,其实飞行高度本身就是优化变量。在做无人机中继覆盖规划时,这个结论很有价值:合适的飞行高度可以显著减少覆盖盲区,但“越高越好”并不准确,必须结合覆盖半径和建筑分布统计来综合评估。
4.2 覆盖图的可视化输出
覆盖图的输出我建议用pcolor或者surf函数绘制二维图像,X轴和Y轴分别代表水平位置,Z轴代表路径损耗映射。把无人机投影点作为原点,周围区域按损耗值着色,能够得到很直观的“热区/冷区”图像。
展示仿真结果的核心代码:
figure; pcolor(x_axis, y_axis, PL_map); shading interp; colormap(jet); colorbar; caxis([90 160]); % 按实际损耗范围调整 xlabel('Horizontal Distance (m)'); ylabel('Horizontal Distance (m)'); title('U2G Path Loss Map (h_u=100m, f=2.1GHz)');这张图配合航线轨迹叠加显示,基本可以定位盲区位置和严重遮蔽区域。实测中我确实遇到过,在某些位置由于两栋高楼形成“峡谷”,损耗比周围高出近40dB,但只看单个点损耗曲线完全发现不了问题,只有画成覆盖图才能一目了然。
4.3 与实测数据对比的思路
仿真结果做出来之后,一定要与实测对比,否则只能叫“展示”,不能叫“验证”。对比时我的做法是这样的:先在同一地理位置记录无人机航点坐标和对应的接收信号强度指示(RSSI),再根据发射功率和天线增益换算成路径损耗,最后把实测损耗与仿真预测曲线叠加画在同一张图上。两者之间的偏差包含系统误差(天线方向图、馈线损耗)和随机误差(多径衰落)。通过观察偏差的分布,可以判断建模误差是否可以被接受。实际项目中,我们通常将平均误差控制在6到8dB以内作为验收线。因为U2G信道本身的随机波动就可能达到5dB,要求仿真完全拟合实测既不现实也不科学。
5. 常见问题与调试经验实录
5.1 仿真结果明显偏大的检查顺序
仿真损耗结果比预期大得多,大多数情况下问题不出在损耗公式本身,而是出在LOS概率参数或者高度图生成逻辑上。根据经验,按下列顺序检查能少走很多弯路:
- 检查building_map的尺寸单位和坐标原点。一个很常见的低级错误是建筑物高度矩阵的单位用成了厘米或者千米,直接导致后续计算全乱;
- 检查无人机高度基准是否与建筑物高度一致。城市数字高程通常是海拔,无人机气压计高度可能也是海拔,但不能保证两者是同一个高程基准;
- 检查P_LOS的计算是否使用了水平距离而非直线距离。LOS概率公式中的距离参数必须是水平投影距离,用错会带来系统性偏差;
- 检查天线参数是否默认全向。如果实际场景中无人机端天线是朝下的定向天线,那么需要在损耗中额外叠加角度相关的天线增益修正。
5.2 常见问题速查表
| 问题现象 | 可能原因 | 排查与解决方式 |
|---|---|---|
| 损耗曲线整体偏高 | 自由空间距离计算错误 | 确认使用的是三维直线距离,而非仅水平距离 |
| 损耗曲线出现异常尖刺 | 建筑物高度矩阵存在异常高值 | 对building_map做峰值值滤波,检查是否生成不合理高楼 |
| 覆盖图出现规则条纹 | 栅格分辨率过低导致锯齿偏重 | 提高栅格分辨率,并用插值平滑显示 |
| NLOS与LOS损耗差偏小 | 绕射损耗参数设置不当 | 调整绕射修正系数,参考对应频段的绕射损耗经验值 |
| 同一位置多次结果不一致 | 场景随机生成无固定随机种子 | 设置rng固定值,保证实验可复现 |
5.3 提高仿真可信度的几条经验
最后分享几条我做这套仿真积累的实操经验。第一,随机场景生成一定要固定随机种子,否则你连实验之间的对比都没法做,更别谈论文或者报告里的“可复现性”。第二,不要一上来就跑覆盖图,先用单链路做数值验证,确认LOS和NLOS损耗在几个典型点位上符合预期,再做二维或者三维扩展。第三,把模型中的每一项修正单独设置开关,调试时逐个开关查偏差来源,这是最快定位问题的方式。
还有一点需要提醒:路径损耗模型不是越复杂越好。对于工程应用,你真正需要关心的可能只是某几条航线的覆盖率,一个双状态模型往往比全三维射线追踪更实用。相反,如果你要做的是高精度覆盖规划,那么简易模型就显得单薄,应该考虑换用更细致的电磁计算方法。做仿真最忌讳的就是脱离需求谈精度,合理评估精度需求和算力成本之间的平衡,才是工程上真正成熟的表现。
我个人做这套U2G仿真最大的体会就是:信道建模百分之七十的精力要花在场景参数的标定上,而不是花在公式推导上。你把城市统计特征摸清楚,LOS概率和损耗公式用成熟模型就够了;反过来,城市参数一塌糊涂,再精细的模型也只是“花式拟合”而已。另外一个小技巧:在做仿真前,花半小时把无人机航迹的姿态抖动、天线朝向晃动这些硬件变量考虑进去,加一点随机扰动项,仿真结果会更接近真实飞行。这个细节我第一次没有处理,后来对比实测时发现低频的慢衰落抖动完全对不上,加上扰动项后整体贴合度提高了不少,强烈建议有条件的朋友尽早把这个因素纳入仿真框架。