
去年年底我接了一个应急通信的仿真评估需求在一片由19个六边形蜂窝小区组成的区域里地面基站因为灾害中断了一部分需要评估用无人机作为空中基站补上去之后覆盖范围和可靠性到底能恢复多少。这个题目听起来直接真做起来坑不少——六边形网格的坐标计算、无人机空地链路模型、SINR统计口径每一环都会影响最终结论。这篇博文就把我用Matlab完整跑通这套仿真方案的过程、代码和踩坑记录分享出来给做通信仿真、应急组网或者毕业设计的同学一个可以直接参考的路线。整个方案的核心思路很简单先用几何方法生成19个六边形小区的网络拓扑再在部分小区引入无人机空中基站用成体系的链路预算和蒙特卡洛撒点统计覆盖率和中断概率最后对比有无无人机的性能差异。下面按我的实际推进顺序来写。1. 为什么是19个蜂窝地面网络的盲区与空中基站补盲逻辑1.1 地面蜂窝网在哪些场景下会“漏人”蜂窝网络在规划之初是按“基站铺满、平滑覆盖”来设计的但现实里总有覆盖不到或者覆盖不够的地方。我把常见的场景归成三类做仿真之前建议先想清楚自己要对齐哪一种地貌遮挡山区、峡谷、密集城区的高楼阴影区信号被地形和建筑物挡掉大部分形成永久性弱覆盖区域。容量突增大型活动、演唱会、体育赛事人数短时间暴涨宏基站可以覆盖但容量完全不够用户体验断崖式下跌。基础设施故障台风、地震、断电导致基站退服形成成片的通信孤岛。我的仿真主要对标第三种场景因为“空中基站”最有说服力的应用场景就是快速恢复通信。地面基站一旦退服恢复周期是以小时甚至天计算的无人机升空只需要几十分钟而且可以从空中绕开一部分遮挡直接和用户建立视距链路。1.2 无人机空中基站和地面基站的本质差异很多人以为无人机基站就是“把基站搬上天”信号自然变好了这个理解太粗糙。两者差异集中在三个维度第一是高度带来的视距优势。地面基站天线高度一般在20到50米用户又在复杂环境中移动信号经常走非视距传播无人机飞到100米以上用户看到它的仰角变大视距链路概率显著提升路径损耗要小得多。第二是部署成本的差异。地面基站需要机房、供电、传输回传建设周期以周计无人机基站本身就是一个可以快速部署的节点前提是回传链路和供电续航解决。第三是覆盖半径的形态差异。地面基站的覆盖像一个压在纸面上的圆饼无人机基站的覆盖更像一个以机身为球心的三维球体在地面上的投影。这个特性决定了无人机高度一高覆盖半径变大但单用户链路距离也变长干扰范围同样变大所以覆盖不是简单“越高越好”后面我会专门用曲线演示。一开始想明白了这三点后续选模型、定参数就不会跑偏。2. 六边形网格的数学底子小区坐标生成与Matlab画图2.1 19这个数字是怎么来的蜂窝网络为什么偏爱六边形不是因为它好看而是因为它是能用正多边形无缝铺满平面、且形状最接近圆形的方案。正方形无缝但角落离中心远三角形无缝但单位覆盖面积需要的基站数太多六边形在“无缝覆盖”和“覆盖效率”之间取了平衡。19个小区的结构是中心1个小区紧贴它一圈是6个再往外一圈是12个1加6加12正好等于19。这也是蜂窝网络经典的两层干扰分析规模中心层用来研究服务区的典型性能第一层和第二层用来捕捉小区间同频干扰的主要来源。仿真规模定在19既能把干扰关系体现出来又不会让计算量大到跑不动。2.2 用整数坐标生成小区中心而不是硬算角度我在写网格生成时踩过坑用极坐标逐层摆六边形绕一圈容易漏点。正确做法是把问题转换到整数坐标系再把整数坐标变换成笛卡尔坐标。定义两个基向量一个沿水平方向一个沿60度方向长度都等于相邻基站间距。小区半径为R时相邻六边形中心距是√3R所以e1 [sqrt(3)*R, 0]; e2 [sqrt(3)*R/2, 1.5*R];任意小区中心可以写成 (a, b)对应实际坐标 ae1 be2其中a、b是整数。要生成19个小区只需要把满足条件的整数对找出来以两层环为半径即 |a|≤2、|b|≤2、|ab|≤2。这个条件本质上描述了一个六边形形状的整数点阵。对应函数如下function centers generateHexCenters(R, ringCount) % ringCount 2 时生成 19 个小区中心 coords []; for a -ringCount:ringCount for b -ringCount:ringCount if max([abs(a), abs(b), abs(ab)]) ringCount coords(end1, :) [a, b]; end end end e1 [sqrt(3)*R, 0]; e2 [sqrt(3)*R/2, 1.5*R]; centers coords * [e1; e2]; end调用R 1000; % 小区半径单位米 bsCenters generateHexCenters(R, 2);跑完以后bsCenters就是19个基站位置坐标。这个方法比手写x、y数组强在两点一是任意层数都能直接生成二是位置关系由几何保证不容易出现两个小区重叠或者间距不一致的低级错误。2.3 绘制六边形边界的便捷函数有了中心坐标画六边形也不难。六边形有六个顶点外接圆半径R从正北方向开始按60度间隔取点然后闭合function drawHex(cx, cy, R, faceColor) if nargin 4 faceColor [0.9 0.95 1]; end angles linspace(0, 2*pi, 7) pi/6; x cx R * cos(angles); y cy R * sin(angles); patch(x, y, faceColor, EdgeColor, [0.3 0.3 0.3], LineWidth, 1.2); end画图时遍历所有中心点就能得到完整的19小区蜂窝图。我自己调试时习惯先用这个函数画一遍网格确认中心坐标无误后再往里填用户这一步能省下大量查错时间。3. 无人机飞多高才合适空地链路模型与部署策略的权衡3.1 空地链路的LOS概率模型给无人机算路径损耗不能套地面基站的公式。地面基站的信号在街巷里穿行基本是非视距无人机在天上用户抬头就能看见的概率高很多。这个概率随仰角变化工程上常用ATTI模型或3GPP TR 36.777里的空地信道模型。这里我采用ATTI形式的视距概率theta atan2(h, dHoriz) * 180 / pi; % 仰角单位度 pLos 1 ./ (1 9.61 * exp(-0.16 * (theta - 9.61)));其中h是无人机高度dHoriz是用户与无人机的水平距离9.61和0.16是城市环境的经验参数。仰角越大用户越接近“正上方看飞机”pLos越接近1用户在地平线远处pLos就掉到零点几。这个模型非常直观非常合适教学演示。路径损耗分视距和非视距两套公式最后按pLos概率加权d3d sqrt(h^2 dHoriz^2); plLos 20*log10(4*pi*fc*d3d/c) 1; % LOS额外损耗1dB plNlos 20*log10(4*pi*fc*d3d/c) 20; % NLOS额外损耗20dB plUav pLos .* plLos (1 - pLos) .* plNlos;注意这里用的单位是瓦特相关的线性域公式载频fc取2GHz光速c取3e8算出来的路径损耗单位是dB。3.2 高度与覆盖半径的反直觉关系我在第一次跑仿真时默认无人机飞得越高越好结果被数据教育了。高度升高会带来两个方向相反的作用力仰角变大LOS概率上升路径损耗下降对覆盖有利斜距d3d拉长自由空间损耗按20log10(d3d)增长对覆盖不利。这两个因素叠加会让覆盖率随高度呈现一种先升后降的单峰形态。在低空段升高带来的LOS增益超过斜距损耗过了某个最优高度斜距损耗占了上风覆盖就往下掉。所以做无人机覆盖仿真最优高度不能拍脑袋定必须做高度扫描。我扫描的区间取50米到300米步长10米每秒跑一次完整蒙特卡洛统计画出来的曲线就是下面代码的效果hVec 50:10:300; covRatio zeros(size(hVec)); for i 1:numel(hVec) covRatio(i) runSimulation(hVec(i)); % 每次完整统计 end plot(hVec, covRatio * 100, o-); xlabel(无人机高度 (m)); ylabel(覆盖率 (%));这个曲线的峰值位置才是该场景下无人机的最佳飞行高度。不同城市环境、不同小区半径峰值位置会变所以要重新扫描。3.3 无人机群怎么摆中心补热 vs 边缘补盲无人机部署位置也很讲究。我在仿真里对比过两类策略中心补热把无人机放在中心小区上方服务高密度用户区提升热点区域的容量和可靠性。边缘补盲把无人机放到第二环外侧或者直接悬停在退服基站的正上方把该小区被切断的信号接回来。从可靠性角度边缘补盲更有价值因为它恢复的是“通信孤岛”从业务收益角度中心补热更划算因为服务的人数多。工程上不会只放一架无人机而是按优先级调度哪个基站退服影响面大无人机先去哪里。我在仿真代码里把无人机位置做成可配置参数跑对比时只需要改一个坐标矩阵uavPos [500, 0, 120]; % 每行 [x, y, 高度]这里是单无人机示例配合后面要讲的高度扫描可以同时看“位置-高度-覆盖率”的三维关系。4. 覆盖增益不能靠感觉SINR、覆盖率和中断概率的评估体系4.1 从接收功率到SINR的完整链条评估覆盖不能只看信号强不强还要看干扰大不大。接收功率算出来后SINR才是用户实际体验的核心指标。接收功率的计算分两步对每一个用户找到它归属的服务基站然后根据链路类型计算接收功率function prx calcRxPower(uePos, bsPos, bsType, Ptx) % bsType: ground 或 uav d sqrt(sum((bsPos - uePos).^2, 2)); if strcmp(bsType, ground) pl 128.1 37.6 * log10(max(d / 1e3, 0.01)); else h bsPos(3); dHoriz sqrt(sum((bsPos(1:2) - uePos(1:2)).^2)); theta atan2(h, dHoriz) * 180 / pi; pLos 1 / (1 9.61 * exp(-0.16 * (theta - 9.61))); d3d sqrt(dHoriz^2 h^2); plLos 20*log10(4*pi*fc*d3d/3e8) 1; plNlos 20*log10(4*pi*fc*d3d/3e8) 20; pl pLos * plLos (1 - pLos) * plNlos; end prx Ptx - pl; % dBm end地面基站路径损耗我用的城市宏小区模型128.1 37.6log10(d_km)距离单位换算成公里。这是个被广泛引用的拟合式适合2GHz载频、宏站到用户的典型场景。仿真里做对比时两套链路模型的口径差异一定要分开算混用会让结论完全失真。4.2 噪声底计算与SINR统计口径热噪声功率的计算公式是N0 -174 10*log10(B) NF;-174dBm/Hz是常温下的热噪声功率谱密度B是带宽HzNF是接收机噪声系数通常取9dB。对10MHz带宽来说N -174 10*log10(10e6) 9; % 约 -95 dBm这个数很重要SINR计算要用它。我见过不少Demo把噪声忽略了直接拿接收功率当覆盖判据结果几公里外还能“正常通信”明显失真。SINR的计算逻辑servicePwr prxAll(sub2ind(size(prxAll), 1:nUe, serveIdx)); % 服务信号 interference sum(prxAll, 2) - servicePwr; % 线性域相减前先转毫瓦 sinr servicePwr - 10*log10(10.^(interference/10) 10^(N/10));注意干扰项不能直接在dB域相减要先把dBm转回毫瓦线性域求和再取log。4.3 覆盖率和中断概率怎么统计覆盖率的定义可以按业务需求调整。我通常用两个口径弱覆盖门限接收功率低于-110dBm算未覆盖中断门限SINR低于-3dB算链路中断。在仿真里覆盖率就是所有用户中满足门限条件的比例covRatio mean(sinr thrSinr); outageRatio mean(sinr thrSinr);因为用户是随机撒的单次结果有抖动所以要跑蒙特卡洛多次撒点求平均。我建议至少跑200次撒点或者一次撒足够多的用户比如每小区100个用户两种方式都行。固定随机种子也很重要否则调参数前后对比时曲线抖得看不出趋势。5. 完整仿真流程落地从参数配置到结果可视化的Matlab实现5.1 参数表与初始化先给出一组我在仿真里实际使用的参数直接抄就能跑通参数取值说明小区半径 R1000 m六边形外接圆半径载频 fc2 GHzLTE/5G Sub-6G典型频段带宽 B10 MHz单载波带宽地面基站发射功率46 dBm约40W典型宏站无人机发射功率33 dBm约2W受机载电源限制用户噪声系数9 dB终端接收机典型值覆盖门限-3 dBSINR中断门限用户数19×100每小区均匀随机100个5.2 主仿真流程分块整体流程我拆成四步生成拓扑、撒用户、算链路、统计性能。省略纯界面绘图部分后核心逻辑如下% 1. 生成19个地面基站坐标 bsPos generateHexCenters(R, 2); nBs size(bsPos, 1); % 2. 配置无人机可留空表示不启用 uavPos [500, 500, 120]; % [x, y, 高度] nUav size(uavPos, 1); % 3. 每基站撒Nusers个用户 rng(42); % 固定随机种子 nUserPerCell 100; ueList zeros(nBs * nUserPerCell, 2); for b 1:nBs idx (b-1)*nUserPerCell 1 : b*nUserPerCell; ueList(idx, :) sampleHexCell(bsPos(b,:), R, nUserPerCell); end % 4. 把所有基站含无人机拼成一个服务节点池 allBs [bsPos(:,1:2), zeros(nBs,1)]; % 地面站高度0 allTypes [repmat({ground}, nBs, 1); repmat({uav}, nUav, 1)]; allPos [allBs; uavPos]; % 5. 对每个用户选最近服务节点简化版实际可按小区归属 prxAll zeros(size(ueList,1), size(allPos,1)); for k 1:size(allPos,1) prxAll(:,k) calcRxPower(ueList, allPos(k,:), allTypes{k}, ... strcmp(allTypes{k},ground) * PtxGround strcmp(allTypes{k},uav) * PtxUav); end % 6. 算SINR、覆盖率、中断率 [sINR, covFlag] computeSINR(prxAll, serveIdx, N); covRatio mean(covFlag);撒用户时要保证落在六边形边界内不能把撒点中心设在基站就完事否则会有用户跑到六边形外面去。用极坐标撒点再判断是否在六边形内更稳或者直接用六边形重心坐标系的均匀采样函数。5.3 可视化输出与调试技巧可视化最容易看出问题我的调试顺序永远是先画拓扑再画链路再画热力图figure; hold on; for i 1:size(bsPos,1) drawHex(bsPos(i,1), bsPos(i,2), R, [0.9 0.95 1]); end plot(bsPos(:,1), bsPos(:,2), ks, MarkerFaceColor, k); if nUav 0 plot(uavPos(:,1), uavPos(:,2), r^, MarkerFaceColor, r, MarkerSize, 10); end axis equal;把无人机位置用红色三角标出来一眼就能看出部署逻辑对不对。再进一步可以把每个用户点的颜色映射成SINR值做出类似覆盖热力图的效果这个图用来写报告特别有用scatter(ueList(:,1), ueList(:,2), 8, sinr, filled); colormap(jet); colorbar;我强烈建议在调试阶段把SINR阈值线同时画出来比如把低于门限的用户用灰色标出这样“补盲效果”是不是真的存在肉眼就能判断。6. 结果能说明什么高度扫描、频率复用的坑和一些小心得6.1 高度扫描覆盖率的单峰曲线与最优高度选取跑完高度扫描你会得到一条“倒U形”的覆盖率曲线。我测到的典型结果100米以下覆盖率随高度快速上升120到150米之间达到峰值超过200米后缓慢下降。峰值高度的具体数值取决于小区半径和干扰环境但“存在最优高度”这个结论是稳定的。这条曲线的工程价值在于无人机升空后不是随便悬停而是应该根据当前网络拓扑算出最优高度再由飞控系统去执行。飞太低了LOS增益不够飞太高了又变成“在头顶放了个大干扰源”覆盖反而恶化。6.2 三个容易翻车的细节第一个是边界用户归属问题。19个小区是有限网络边缘没有更外面的小区兜底第二环边缘用户的最近基站距离会异常大拉低整体指标。如果你只关心内部覆盖统计时可以只统计第一环以内的用户但要说明白口径否则结论会误导人。第二个是全同频假设下的干扰过重。全部基站用同一个频率SINR会非常低这是保守上限。实际工程里会用频率复用或波束赋形降低干扰。我在代码里默认全同频目的是做最坏情况评估写报告时我会再跑一版7色复用的对比两者的差距能直接体现频率规划的价值。第三个是无人机回传链路没建模。空中基站要和核心网连通必须靠无线回传这段链路同样消耗频谱和功率。我的仿真把回传理想化处理现实里回传带宽限制会直接压缩用户可用速率。如果你是做工程落地评估别忘了把这段链路加进约束条件。6.3 还能往哪个方向扩展这套仿真框架继续往下走的空间很大。我做完了高度扫描后下一步计划是:把无人机位置用强化学习优化而不是手动摆点。思路是把每架无人机的水平坐标和高度作为动作把覆盖率或吞吐量作为奖励用DQN或PPO训练部署策略。加入多无人机协同几架无人机在相邻小区上空组成临时网络机间距离和频段分配都会影响整体性能。把用户按真实流量分布建模而不是均匀撒点。热点区域用户密集时无人机的最优位置会明显偏向热点一侧。我自己跑完这套仿真最大的体会是空中基站最大的价值不是“离用户更近”而是“让用户看得见”。无人机飞到合适高度后视距链路概率大幅提升路径损耗比地面绕射少了十几甚至二十个dB这个增益远比拉近几百米距离带来的变化大。这也是为什么标题里“覆盖范围”和“可靠性”两个词是绑在一起的——覆盖不只是信号够不够强更是链路中断概率够不够低。新手建议从单架无人机开始调通链路和统计逻辑再把规模扩到多机协同一上来就铺19个站容易陷进调试泥潭。