☰
基于无人机与NOMA的蜂窝边缘计算任务卸载仿真与优化
2026/10/10 4:35:08 网站建设 项目流程

1. 先搞清楚这个项目到底在解决什么问题

做无线通信仿真的朋友,应该都遇到过这个场景:小区边缘用户明明有卸载计算任务的需求,但蜂窝链路质量差,传给基站的速率上不去,任务排队久了,时延和能耗双双超标。如果这时候有一架无人机飞到用户附近当空中节点,再把非正交多址(NOMA)加进来,让多个用户共享同一个资源块,边缘用户的卸载体验会好很多。这个项目做的就是把“无人机、NOMA、蜂窝任务卸载”三者放在同一个框架里,做性能分析和优化研究,最后用Matlab把中断概率、吞吐量、能耗和能效曲线全部跑出来。

这篇内容适合正在做无线通信方向课题的学生、刚接触边缘计算仿真的工程师,以及想快速搭建UAV-NOMA卸载仿真平台的开发者。你不需要有非常深的数学功底,但至少要熟悉Matlab的基本脚本编写,了解瑞利衰落、信噪比、SIC这些基础概念。我会把系统模型怎么搭、指标怎么算、优化怎么迭代、代码怎么组织都拆开讲清楚,你在自己电脑上也能复现出一套完整的仿真结果。

1.1 蜂窝网络里的卸载痛点到底在哪

传统蜂窝卸载的思路很直接:用户设备把计算任务通过上行链路发给基站,基站接到任务后再放到边缘服务器上处理。问题在于,基站覆盖半径内的用户信道差异很大。离基站近的用户,信道增益高,卸载速率快;边缘用户信道增益低,即使把发射功率调满,仍然容易达不到目标速率,任务只能留在本地计算。

本地计算也不是不能做,但代价是能耗和时延。移动设备电池有限,CPU算力受限,一个大任务在本地跑几百毫秒,功耗就上去了。我见过不少仿真里把本地计算建模成“固定CPU频率乘任务计算量”,听起来没问题,但实际跑出来边缘用户的时延和能耗曲线都很难看。这就是卸载场景里最核心的矛盾:想卸载但链路不够好,留在本地但资源不够用。

无人机在这个场景里的价值是“补位”。它可以临时升高到空中,形成一条比地面直射更稳定、损耗更低的空中链路。尤其当用户被建筑物遮挡,地面链路处于深度衰落时,无人机悬停在合适位置可以大幅改善信道增益。这个项目把无人机当作空中基站或转发节点,就是从系统层面给边缘用户多一条卸载路径。

1.2 为什么偏偏是无人机加NOMA

很多人会问,既然无人机已经能改善信道了,为什么还要引入NOMA?答案很简单:频域资源有限。如果每个用户都独占一个子信道,大量边缘用户同时卸载时,带宽就分不过来。NOMA允许同一个子信道叠加多个用户的信号,接收端用串行干扰消除(SIC)按顺序解出不同用户的数据,本质上是用“功率域的正交性”换“频谱域的共享性”。

在UAV辅助场景下用NOMA还有一个额外的好处:无人机到不同用户的信道差异可能非常大。一个用户在空中链路下信道增益很高,另一个用户稍微偏远但链路仍可用,这种“强用户带弱用户”的配对,正好是NOMA最舒服的工作区间。强用户用低功率、弱用户用高功率,接收端先解弱用户再解强用户,频谱效率和用户公平性都比正交多址好。

当然,NOMA不是万能的。SIC对信道估计误差特别敏感,功率分配因子设计不好,强用户可能解不干净干扰,弱用户也可能达不到目标速率。所以这个项目里,我把功率分配、无人机位置、用户配对放进了优化问题,目标就是把这套系统的潜力真正压榨出来。

2. 系统模型和技术链路拆解

2.1 网络拓扑和信道模型

这个项目采用的网络拓扑是典型的“无人机辅助蜂窝边缘计算”结构:一个地面基站覆盖半径为R的小区,小区内有两个用户通过同一子信道向基站卸载任务。无人机悬停在小区上空,既可以作为转发中继帮用户把数据传向基站,也可以把它看作一个携带边缘服务器的空中节点。为了控制变量,我建议仿真第一阶段先把无人机建模为中继或基站辅助节点,等基线结果跑通后再加入机载计算模型。

信道模型是仿真能不能写对的关键。对于无人机到用户的空中链路,通常使用海拔相关的LoS概率模型:

P_LoS(θ) = 1 / (1 + a * exp(-b * (θ - a)))

其中θ是无人机到用户之间的仰角,a和b是环境参数,城市环境一般取a=9.61、b=0.16。如果链路为LoS,路径损耗用自由空间模型;如果为NLoS,还要加一个额外的穿透损耗。小尺度衰落我用的瑞利模型,实际调参时也可以替换成莱斯模型,因为飞行高度较高时LoS分量占比大,莱斯K因子会给结果带来明显差异。

注意一个容易被忽略的点:无人机悬停高度变化时,仰角会变化,LoS概率也随之变化,所以信道增益不是简单随距离单调变化的。我在第一次仿真时直接把UAV当成普通地面节点处理,用固定路径损耗指数算信道,结果中断概率曲线形状完全不对。后来改成角度相关LoS概率模型,曲线才恢复了合理的物理趋势。

2.2 上行NOMA与SIC解码机制

在这个系统里,两个用户共享同一个子信道,上行发送。假设用户1是信道较好的近用户,用户2是信道较差的远用户。按照NOMA的功率分配原则,弱用户分到更大的发射功率,强用户分到更小的发射功率,这样基站接收端可以用SIC先解码弱用户,再解码强用户。

具体来说,基站收到的叠加信号可以写成:

y = h1 * sqrt(P1) * x1 + h2 * sqrt(P2) * x2 + n

其中P1小于P2。SIC解码时,基站先尝试解码用户2的信号,此时用户1的信号被当作干扰;如果用户2的目标速率大于阈值且解码成功,基站就把用户2信号从接收信号中减去,再解码用户1,这时用户1的等效信噪比只受噪声影响。

这个过程的本质是“用强用户的复杂度换弱用户的服务质量”。仿真时一定要把两个阶段的门限分别计算:第一阶段用户2的SINR要大于它的目标门限,第二阶段用户1的信噪比也要大于目标门限,两个条件同时成立才算一次成功传输,否则就记一次中断。很多刚上手的人只算了用户2的SINR就结束,中断概率会偏低,这是不对的。

2.3 任务卸载建模:本地计算与边缘计算

蜂窝卸载里还需要把计算任务模型建出来。我采用的模型比较通用:每个用户有一个计算任务,大小用L表示,单位是bit;任务复杂度用C表示,单位是cycles/bit。用户可以选择本地计算,也可以选择卸载到边缘服务器。

本地计算的时延就是本地CPU频率的倒数乘任务计算量,能耗是电容参数乘频率平方再乘计算时间。边缘计算的时延包括上行传输时延、边缘服务器排队和处理时延,还有下行回传时延。在这个项目里,边缘服务器算力充足,排队和处理时间可以近似为固定值,所以卸载时延的主要变量是上行传输速率,也就是由NOMA链路的SINR决定。

这样一来,整个性能分析就串起来了:信道决定SINR,SINR决定传输速率,传输速率决定卸载时延和能耗,中断概率决定总体的可靠性。项目的优化目标既可以写成“在中断约束下最小化总时延”,也可以写成“最大化系统能效”,两种写法难度差别不大,但后者在论文里更常见。

3. 性能指标推导:中断概率、吞吐量与能效

3.1 中断概率的闭式近似从哪里来

中断概率是这套系统最核心的可靠性指标。对于一个目标速率R_t,对应一个SINR门限γ_t = 2^(R_t/B) - 1。如果实际SINR低于门限,就认为这次传输中断。在NOMA上行链路中,中断事件是两个用户解码事件的交集,所以系统中断概率可以分解为:

P_out = 1 - P(γ2→1 ≥ γ_t2) * P(γ1→2 ≥ γ_t1)

第一项是基站成功解码远用户(用户2)的概率,第二项是SIC之后成功解码近用户(用户1)的概率。

如果信道增益服从指数分布(瑞利衰落),中断概率是可以写出闭式表达式的。具体推导过程中会用不完全伽马函数或指数积分,Matlab里可以直接用gammainc。不过我自己调试时发现,闭式表达式特别容易因为参数单位不一致而出错,比如路径损耗指数算出的信道增益是线性值还是dB值,直接决定后面指数积分里的参数写法。稳妥的做法是先用蒙特卡洛仿真把中断概率跑出来,再和闭式结果画在同一张图上对比,对不上就去查单位换算。

3.2 系统吞吐量与卸载时延怎么换算

吞吐量在卸载场景里直接等于“成功传输的比特数除以传输时长”。对于NOMA链路,系统总吞吐量是用户1和用户2成功传输速率之和,但要注意成功传输条件是SIC两步都成功,如果其中一步失败,本次块内两个用户的吞吐量都归零。这个细节在写仿真代码时特别容易漏。

卸载时延的计算则更偏系统层面。每个用户如果选择卸载,时延至少包含三部分:上行传输时延L/R_up、边缘处理时延L*C/f_edge、下行回传时延L/R_down。上行速率R_up由NOMA链路的实际SINR决定,下行回传一般假设有足够带宽,速率是常数。整个项目在画时延曲线时,经常会看到“用户2时延先降后升”的现象,原因是无人机高度增加时LoS概率上升让信道变好,但距离也变长,两者折中后存在最优高度。

3.3 能效定义和折中关系

能效(Energy Efficiency)通常定义为系统总吞吐量除以系统总能耗,单位是bits/Joule。系统总能耗包括用户发射能耗、电路能耗,以及无人机悬停和通信消耗的能耗。无人机能耗不能忽略,因为无人机功耗随悬停高度和位置变化明显。

我在实际优化中发现,能效和时延是天然矛盾的。如果一味追求高能效,系统会倾向于降低发射功率并选择较近的无人机位置,但这样会推高时延;如果只压时延,发射功率和无人机能耗又会上升。所以论文里经常把能效最大化问题加上“最大允许时延”约束,或者把时延最小化问题加上“最低能效”约束,本质上都是做折中。这个项目我建议把两个约束都写上,方便后面分析Pareto前沿。

4. 优化建模:功率、部署和用户配对

4.1 优化问题怎么写才不虚

把上面的物理过程转成数学优化问题,决策变量有三个:NOMA功率分配因子α(用户1占总功率的比例)、无人机水平位置(xu, yu)、无人机高度H。目标函数可以选系统能效最大化,也可以选加权时延最小化。约束条件包括最大发射功率、SIC解门限、最小目标速率、无人机飞行高度范围,以及用户配对约束(如果用户不只是两个,还需要决定谁和谁配对)。

一个常见的写法是:

max EE = R_total / P_total

s.t. γ1 ≥ γ_t1, γ2 ≥ γ_t2

0 < α < 0.5

H_min ≤ H ≤ H_max

(xu^2 + yu^2) ≤ R_uav^2

注意这里α约束写成小于0.5,是因为近用户分配的功率不能超过远用户,否则NOMA的SIC解码顺序就失效了。

这个优化问题非凸,尤其是无人机位置和高度变量进入信道表达式后,目标函数很难保证凸性。我采用的方法是“块坐标下降+一维搜索”:固定无人机位置,优化功率分配;固定功率分配,优化无人机位置;交替迭代若干次,虽然不能保证全局最优,但工程上已经够用,而且能稳定收敛。

4.2 功率分配:固定其他变量怎么解

固定无人机位置和高度后,信道增益就定了,此时能效最大化问题在α上有没有闭式解取决于目标函数形式。如果目标函数是总速率最大化,由于SIC约束都是线性的,α的最优解出现在可行区间的边界,或者出现在某个约束等号处,直接对α求导找极点就行。但如果目标函数是能效最大化,分式结构会让问题变成凸分式规划,通常用Dinkelbach方法迭代求全局最优。

Dinkelbach的核心思想是引入一个辅助参数μ,把“最大化R/P”改写成“最大化R - μP”,然后每轮更新μ = R_current / P_current,直到收敛。这个方法在Matlab里实现起来非常简单,外层while循环,内层用fminbnd对α做一维优化。我建议你先把总速率最大化跑通,再切到能效最大化,这样调试起来不会两头出错。

4.3 无人机部署搜索与联合迭代

无人机的位置变量比功率分配复杂,因为LoS概率里含仰角反正切,路径损耗里含距离平方,都不是简单凸函数。实测下来,用网格搜索或穷举法做无人机位置优化反而最稳。在Matlab里就是把水平范围切成30×30的网格,高度范围切成10个候选值,逐个计算能效,取最大值。网格分辨率不需要太高,因为能效曲线在最优位置附近通常比较平缓,太密的网格只增加计算时间,不会带来实际精度收益。

联合迭代的流程是:先给无人机位置设一个初始值,比如悬停在两个用户中点上方100米;然后固定它,用Dinkelbach求最优α;再把α固定,网格搜索无人机位置;重复几次。我在仿真里发现,迭代3到4次能效变化就已经小于0.1%,不需要额外加复杂收敛条件。用户配对方面,如果用户数多于两个,可以用贪心算法按信道增益排序后配对,强信道用户和弱信道用户配对,剩余用户按顺序依次配对。

5. Matlab仿真实现与代码拆解

5.1 仿真架构和初始化参数

我建议把整套代码拆成四个文件:主脚本main.m、参数配置函数parameters.m、信道生成函数channel_generator.m、性能计算函数perf_evaluation.m。这样做的好处是改参数不用翻代码,跑对照组也更方便。下面是我常用的参数配置,你可以直接抄:

% parameters.m R = 500; % 小区半径,m Pmax_u = 23; % 用户最大发射功率,dBm Pmax_dBm = Pmax_u - 30; % 转成线性值 noise_dBm = -174; % 噪声功率谱密度,dBm/Hz B = 1e6; % 子信道带宽,Hz target_rate = 1e6; % 目标速率,bps a_los = 9.61; b_los = 0.16; % LoS概率环境参数 fc = 2e9; % 载波频率,Hz c0 = 3e8; alpha = 0.2; % NOMA功率分配因子,可优化 H_uav = 100; % 无人机高度,m pos_user1 = [100, 0]; % 近用户位置 pos_user2 = [350, 200]; % 远用户位置 pos_uav = [200, 100, H_uav]; % 无人机初始位置 mc_iter = 1e4; % 蒙特卡洛次数

这里有个很容易踩的坑:dBm和线性W之间的换算。Matlab里如果直接拿dBm值算信道增益,结果会大得离谱。我一般先用db2pow把功率转成线性,信道增益也转成线性后再乘,最后用pow2db看SINR,转换逻辑清晰,不容易错。

5.2 核心函数:信道生成与NOMA接收

信道生成函数要同时输出用户到无人机、用户到基站、无人机到基站三条链路的信道增益。对于用户到无人机的空中链路,LoS概率和路径损耗分开算:

function [g] = channel_generator(pos_u, pos_a, H_a) d_h = norm(pos_u(1:2) - pos_a(1:2)); d_3d = sqrt(d_h^2 + H_a^2); theta = atan2(H_a, d_h) * 180 / pi; P_los = 1 / (1 + a_los * exp(-b_los * (theta - a_los))); % 路径损耗,单位dB PL_free = 20 * log10(4 * pi * fc * d_3d / c0); PL = PL_free + (1 - P_los) * 20; % NLoS额外穿透损耗20dB % 小尺度瑞利衰落 h_small = (randn(1, 1) + 1j * randn(1, 1)) / sqrt(2); g = abs(h_small)^2 * 10^(-PL / 10); end

注意这里我随机生成瑞利衰落时用了复高斯除以sqrt(2),这样|h|^2的均值才是1,不会让信道增益产生系统性偏差。很多初学仿真的人直接用rand生成幅度,会造成衰落均值偏大,最终中断概率显著偏低。

NOMA接收端解码逻辑可以封装成一个函数:

function [outage] = noma_receive(g1, g2, P1, P2, noise, gamma_t1, gamma_t2) % 第一步:先解远用户(用户2),此时用户1是干扰 sinr2 = P2 * g2 / (P1 * g1 + noise); % 第二步:SIC后解近用户(用户1) sinr1 = P1 * g1 / noise; % 两个条件同时满足才算不中断 if sinr2 >= gamma_t2 && sinr1 >= gamma_t1 outage = 0; else outage = 1; end end

这个函数里的第一步尤其要小心,分母里的P1*g1不能漏。如果漏掉用户1的干扰,SINR会被高估,中断概率会偏乐观,最后画出的曲线和理论值对不上。

5.3 蒙特卡洛中断概率和吞吐量曲线

主循环里生成大量信道样本,统计中断次数和成功吞吐量:

% main.m outage_count = 0; throughput_sum = 0; for iter = 1:mc_iter g_uav1 = channel_generator(pos_user1, pos_uav, H_uav); g_uav2 = channel_generator(pos_user2, pos_uav, H_uav); % 假设只走无人机中继链路,UAV到基站链路近似理想 g1 = g_uav1; g2 = g_uav2; P1 = db2pow(Pmax_dBm) * alpha; P2 = db2pow(Pmax_dBm) * (1 - alpha); noise = db2pow(noise_dBm + 10*log10(B)); gamma_t1 = 2^(target_rate / B) - 1; gamma_t2 = gamma_t1; is_outage = noma_receive(g1, g2, P1, P2, noise, gamma_t1, gamma_t2); outage_count = outage_count + is_outage; if ~is_outage r1 = B * log2(1 + P1 * g1 / noise); r2 = B * log2(1 + P2 * g2 / (P1 * g1 + noise)); throughput_sum = throughput_sum + r1 + r2; end end P_out = outage_count / mc_iter; avg_throughput = throughput_sum / mc_iter;

我建议把mc_iter至少设成1e4,如果你要画中断概率的极低区域,比如10^-4量级,需要加大到1e6。我自己通常先跑1e4,等代码逻辑确认无误后再把蒙特卡洛次数加大做正式仿真。否则一笔误,跑1e6次需要好几个小时,效率太低。

5.4 能效优化的迭代过程

能效优化的外层代码可以用下面这个框架:

% energy_efficiency_optimization.m mu = 0; for iter = 1:10 % 固定UAV位置,优化 alpha obj_fun = @(alpha) -1 * (rate_total(alpha) - mu * power_total(alpha)); alpha_opt = fminbnd(obj_fun, 0.01, 0.49); % 固定alpha,网格搜索UAV位置 best_ee = -Inf; for x = -200:20:200 for y = -200:20:200 for H = 50:20:150 ee = comp_ee(alpha_opt, [x, y, H]); if ee > best_ee best_ee = ee; pos_best = [x, y, H]; end end end end mu = rate_total(alpha_opt) / power_total(alpha_opt); if abs(best_ee - mu) < 1e-3 break; end end

这里rate_total和power_total需要你自己根据前面的公式实现。要注意Matlab的fminbnd默认是求最小值,所以目标函数要加负号,否则优化方向会反。网格搜索的步长20米对于能效曲线来说已经够细,如果你追求更光滑的曲线,可以在最优位置附近再做一次更细的局部搜索,比如步长改为5米。

6. 实测结果、调试经验和避坑指南

6.1 我跑出来的典型曲线趋势

在默认参数下,固定功率分配时,系统中断概率随无人机高度呈现“先下降后上升”的趋势。高度从50米升高到100米时,LoS概率提升带来的增益占主导,中断概率明显下降;高度超过150米后,路径损耗增大开始压过LoS概率增益,中断概率反弹。这个现象几乎所有LoS概率模型都存在,可以作为你验证代码是否写正确的一个标志。

吞吐量曲线则不同,它在高度80到120米之间比较平稳,并不像中断概率那样有剧烈变化。原因是吞吐量主要取决于解码成功时的速率,而中断概率只反映成功与否。所以看结果时要分开解读:一个指标灵敏,一个指标稳健,这恰恰说明做性能分析不能只盯单一指标。

能效优化后的系统会比固定α和固定位置的情况高出20%到40%。我实测最优α通常在0.15到0.3之间,具体值受信道差影响。用户配对采用“强用户配弱用户”时,系统总吞吐量比随机配对提升约15%,但公平性改善更明显,远用户的中断概率可以下降近一半。

6.2 仿真调试中最容易踩的五个坑

常见问题典型症状解决办法
dBm和W换算混乱中断概率几乎为0或1统一用db2pow和pow2db,信道和功率都转线性再计算
SIC干扰项漏写远用户中断概率偏低第一步sinr表达式分母要写P1*g1+noise
LoS概率用固定值高度变化曲线单调,没有最优高度按仰角公式动态计算P_LoS
中断事件只算一个用户总中断概率和理论值对不上两个用户解码成功必须同时满足
蒙特卡洛次数太少曲线毛刺多,不稳定至少1e4次,画低概率区加1e6

另外还有一个隐性坑:如果你把无人机当纯中继,无人机到基站链路不能也建模成瑞利衰落,否则端到端信噪比表达式里会出现两个衰落项相乘,中断概率的收敛速度会慢很多。实际系统中无人机视距链路通常质量很高,我建议先把它设成理想链路,跑通后再逐步加入衰落,这样定位问题更方便。

6.3 一点个人体会和扩展方向

这套仿真我前前后后跑了两个版本,第一版把信道建模和NOMA解码拆在两个文件里,调试时来回切换文件非常痛苦;第二版把所有计算函数集中到一个文件,再通过子函数调用,效率明显提升。所以如果你是从零开始写,我真心建议先搭好最小可运行版本,再逐步加功能,不要一上来就追求模块化。

这个项目后续可以扩展的方向很多。最直接的是把两用户模型推广到多用户多信道,然后用匹配理论做用户调度;也可以给无人机加入移动轨迹优化,让它在服务完一个区域后移动到下一个区域;还可以把能量收集考虑进去,研究无人机无线充电和任务卸载的联合优化。不管往哪个方向走,这套中断概率计算、能效评估、功率和位置迭代优化的框架都能直接复用,不会白做。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询