Ⅰ、论文笔记
一、研究背景与相关工作
(一)研究背景
物联网技术发展促使设备数量剧增,对通信系统的数据速率和覆盖率要求提升,且设备能量供应面临挑战。5G、6G 及相关技术如 WPT 为解决这些问题提供了支撑,无人机在无线网络中的应用也日益受到关注,其与 WPT 结合成为物联网网络关键部分,但也带来了新的优化难题。
(二)相关工作
以往研究在无人机辅助无线供电物联网网络优化方面取得了一定成果。在数据和能量传输协议上,有收获 - 传输协议及全双工混合接入点(HAP)相关研究。优化目标多样,包括最大化上行吞吐量、最小化数据信息年龄、最小化能耗等。然而,这些研究大多针对单个目标或未充分考虑物联网设备数据优先级的动态变化及复杂网络环境下无人机的高效决策问题。
二、系统模型与问题表述
(一)系统模型
- 物联网设备:随机分布于有限区域,通过时分多址协议上传数据,数据生成率服从泊松分布。其数据量随时间变化,受硬件限制有最大存储容量,根据数据量与存储容量比例及生成率确定上传优先级,确保及时上传数据以避免数据丢失。
①数据生成率:物联网设备在单位时间内产生数据的数量或频率。物联网设备的数据生成率服从泊松分布,且不同设备的泊松分布参数各异。这意味着每个设备在时刻产生数据的速率具有随机性和独特性。
②根据数据量与存储容量比例及生成率确定上传优先级,确保及时上传数据以避免数据丢失。
- 无人机:在固定高度飞行,采用飞 - 悬停 - 通信协议,装备全双工 HAP。飞行受速度和偏航角限制,速度影响推进功率消耗,其计算涉及叶型、诱导和寄生功率等因素,不同速度下功耗不同,且有最大续航速度。无人机的直流电和能量传递范围有限,仅对覆盖范围内设备操作。
①无人机飞行高度为10m。装备全双工 HAP。飞行受速度和偏航角限制,偏航角角度为(-Π,Π),速度影响推进功率消耗。最大飞行速度为20m/s,最佳续航速度为10m/s.能量传输范围10m或者30m。
- 信道模型:综合考虑视距(LoS)和非视距(NLoS)链路构建空对地信道模型。根据相关公式计算信道功率增益和传播损耗,LoS 概率受载波频率、环境类型及通信双方相对位置影响,通过特定公式计算,进而确定整体信道状况。
- 能量收集模式:无人机悬停时以全双工模式工作,向物联网设备发射 RF 信号进行能量传输。采用非线性 EH 模型为设备充电,该模型考虑电路饱和限制,相比线性模型更贴合实际情况,通过特定公式计算设备接收和收集的能量。
①无人机采用非线性 EH 模型为互联网设备充电。
(二)问题表述
旨在最大化总数据速率和总收获能量,同时最小化无人机能耗。总数据速率与无人机访问设备数量、悬停数据速率相关;总收获能量受悬停次数、覆盖设备数量及距离影响;能耗需考虑飞行和通信能耗。由于设备分布随机、数据生成动态且目标相互冲突,传统方法难以求解,需借助先进算法。
①mmo目标:最大化总数据速率和总收获能量,同时最小化无人机能耗。(总数据速率与无人机访问设备数量、悬停数据速率相关;总收获能量受悬停次数、覆盖设备数量及距离影响;能耗需考虑飞行和通信能耗。)
三、强化学习基础
强化学习基于马尔可夫决策过程(MDP),由五元组 <S, a, r, P, γ> 构成。其中,S 为状态集合,a 为动作集合,r 为奖励函数,P 为状态转移概率,γ 为折现因子。策略定义智能体行为,价值函数辅助寻找最优策略。原始 RL 算法如基于表的 Q 学习不适用于高维状态和动作,DQN 虽改进但仅用于离散低维动作空间,策略梯度算法及 actor - critic 方法应运而生,DDPG 算法在此基础上进一步发展,可有效解决连续动作空间的复杂问题,为无人机飞行决策提供了可行的技术途径。
四、MODDPG 算法
(一)环境模型
- 状态空间:涵盖无人机自身位置、累计飞出限制区次数、目标设备位置、数据丢失设备数量等关键信息。通过提取这些少量必要信息,避免了采集全部设备信息带来的资源占用和时延问题,使无人机能较好地感知环境并做出决策,克服了物联网系统中网络信息缺失的难题。
①状态空间:连续状态空间。涵盖无人机自身位置、累计飞出限制区次数、目标设备位置、数据丢失设备数量。
- 行动空间:由飞行速度和偏航角决定,二者均为连续值,飞行速度在 [0, vmax] 区间,偏航角在 [−π, π] 区间。这种连续值的设定增加了无人机的控制自由度,相比离散动作空间能实现更高效的控制方案,有利于无人机在复杂环境中灵活调整飞行状态。
①行动空间:连续行动空间。飞行速度、偏航角。
- 奖励:设计为四维向量,分别对应总数据速率最大化、总收获能量最大化、无人机能耗最小化三个优化目标及一个辅助目标。根据无人机不同的工作状态(如悬停或飞行)及目标完成情况给予相应奖励或惩罚,辅助目标有助于引导无人机完成基本任务,如靠近目标设备、避免飞出限制区域和数据溢出等,促使无人机学习到有效的控制策略。
①辅助奖励:。和为目标装置与无人机在直角坐标系下的距离;记录了无人机在时间前连续超过限制区域的累计次数;为数据丢失设备数量。(当无人机距离目标设备较远时,它的值会很小,这有助于无人机识别目标设备的位置,从而接近目标设备。此外,如果无人机试图飞出限制区域或由于未能及时收集数据导致物联网设备数据溢出,就会获得负奖励。)
(二)MODDPG 算法
基于 DDPG 架构,维护行动者网络 μ(s|θμ) 和批评家网络 Q (s|θQ),其权重分别从截断正态分布初始化,偏置也进行了相应设置。在训练过程中,从重放内存均匀采样小批量经验元组,将奖励向量通过线性加权求和转换为标量形式,以便计算目标值。利用梯度下降法更新批评家网络使损失函数最小化,通过最大化行动者网络损失函数更新其权重,并采用 “软” 目标更新目标网络参数,同时应用探索策略保证对连续动作空间的充分探索,适用于多目标优化问题,能根据不同权重参数调整策略。
①经验回放:智能体将得到的经验数据放入Replay Buffer中,更新网络参数时按照批量采样。
②目标网络:在Actor网络和Critic网络外再使用一套用于估计目标的Target Actor网络和Target Critic网络。(目标网络的参数更新相对缓慢,能够为训练提供相对稳定的目标值参考,避免因主网络参数的快速变化而导致训练过程的不稳定。)采用软更新方式。
③噪声探索:确定性策略输出的动作为确定性动作,缺乏对环境的探索。在训练阶段,给Actor网络输出的动作加入噪声,从而让智能体具备一定的探索能力。
五、仿真结果及讨论
(一)实验设置
设置物联网设备数量为 100,任务周期 10 分钟,分布在 400 米 ×400 米正方形区域,无人机飞行高度 10 米。确定了无人机和物联网设备的发射功率、数据缓存更新周期及相关参数,如带宽、噪声功率、信道增益等,同时设定了 MODDPG 网络结构和训练参数,包括学习率、奖励折扣、重放内存大小、批次大小等,为仿真提供了基础条件。
(二)算法性能
训练结果表明,MODDPG 算法使智能体能够快速学习并稳定收敛。随着训练进行,累积奖励先波动后稳定在较高水平,网络损失先上升后下降,同时总数据速率和总收获能量增加,能耗降低。与以最大速度或最大续航速度飞行的策略相比,在数据速率、收获能量和能耗等方面表现更优,能根据数据采集覆盖半径调整策略,实现多目标协调优化,体现了算法的有效性。
(三)权重参数影响
通过设置不同权重参数实验,如分别将总数据率、总收获能量和能耗相关权重单独设为 1.0 进行对比。结果显示,算法可根据权重调整最优策略,在不同偏好下产生合适结果。在大多数情况下,综合考虑三个目标的策略在数据速率和收获能量上表现较好,而单独优化某一目标的策略在对应目标上最优,但其他目标表现较差,验证了算法在多目标优化方面的灵活性和有效性。
六、研究结论
本研究针对无人机辅助无线供电物联网网络的多目标优化问题,提出了 MODDPG 算法。通过理论分析和仿真实验,证明了该算法的有效性,能够根据不同的权重参数生成优化策略,实现总数据速率、总收获能量和能耗的多目标协调优化。同时指出未来可进一步研究无人机群在无线物联网网络中的协同任务与资源分配等问题,为该领域的发展提供了新的研究方向和思路。
七、名词解释
全双工模式:数据通信中数据可以朝两个方向同时传输。
MOO(多目标优化)。
衍生决策:是基于原始数据通过加工、处理、分析等方法产生的新的决策依据。
无线电力传输技术(WPT):不通过传统电线传输电能。
射频信号(RF):高频交流变化电磁波。
无线链路:无线信号在空中建立的通信连接。
RF信号同时携带能量和信息,WPT与无线信号传输技术(WIT)相结合。
WPT和WIT集成技术有三种设计:同步无线信号和电力传输、无线供电通信网络、无线供电后向散射通信。
无人机与WPT技术结合。
DC(数据收集)
Harvest-then-transmit (HTT) protocol :指在无线能量传输和信息传输网络中,用户设备首先从信号基站(例如接入点或电源站)收集无线能量,然后使用这些收集到的能量来传输信息的一种通信协议。
吞吐量:它通常用来描述数据传输速率,特别是在网络通信和数据处理领域。
Age of Information (AoI): 是一个衡量信息新鲜度的关键指标,它量化了从信息生成到被接收的时间间隔。
Full-duplex HAP:一个能够同时在两个方向上进行数据传输的混合接入点。
改进:不再将系统的全部信息作为神经网络的输入,而是提取与无人机飞行决策密切相关的少量信息组成状态向量。
双天线无人机:使用两个GPS天线来提高导航精度和航向测量的准确性。
双天线无人机工作:通过一个天线将能量传输到下行链路的物联网设备,同时通过另一个天线从上行链路的物联网设备收集数据。
时分多址(TDMA):是一种通信技术,用于在一个通信信道上实现多个用户或信号的传输。把时间划分成周期性的帧(frame),每一帧再分割成若干个时隙(slot)。每个时隙就是一个通信信道,分配给不同的用户。
下行链路:信号从基站(Base Station)或者中心节点传输到用户终端(User Equipment)的链路。
上行链路:从用户终端向基站发送信号的链路。
旋翼固体度:旋翼桨叶面积总和与旋翼桨盘面积之比。
视距链路:发射端与接收端之间没有障碍物阻挡,信号可以沿直线传播的通信链路。简单来说,就是从发射设备到接收设备之间,能直接看到对方,中间不存在山脉、大型建筑物等遮挡视线的物体。
通信通道增益:衡量信号在信道中传输过程中衰减或放大的程度的一个指标。
“对于总数据速率,其最大值取决于UAV任务周期内上传数据的设备数量,”“即悬停总次数K和每次悬停的数据速率。”
“一方面,UAV应该以更高的速度飞行,以便它可以访问更多的物联网设备。另一方面,悬停位置应靠近目标设备,以提高数据速率,同时缩短每次悬停的通信时间。”
无人机在悬停阶段以全双工模式工作,通过上行信道接收目标设备信息的同时,持续向具有恒定发射功率 的设备发射RF信号,覆盖范围内的其他设备可被充电。
AC算法中正态分布:Actor 的任务是根据当前状态输出一个动作,而当动作空间是连续的时候,正态分布可以为动作的选择提供一种概率分布。智能体(Agent)学习的是正态分布的参数(均值和标准差),而不是直接学习动作本身。这样,通过调整这些参数,智能体可以控制动作的分布,使其更有可能产生带来高回报的动作。
Ⅱ、代码笔记
一、环境代码
1、模块导入
import sys
import numpy as np
import time
import math
import copy
from gym import spaces
from gym.utils import seeding
2、导入Tkinter 模块
if sys.version_info.major == 2:
import Tkinter as tk
else:
import tkinter as tk
作用:用于创建图形用户界面(GUI),以便直观地展示模拟环境。
3、常量和全局变量定义
WIDTH = 10 # 地图的宽度
HEIGHT = 10 # 地图的高度
UNIT = 40 # 每个方块的大小(像素值)
LDA = [4., 8., 15., 20.] # 泊松分布的参数
max_LDA = max(LDA)
C = 5000 # 传感器的容量
P_u = pow(10, -5) # 传感器的发射功率
P_d = 10 # 无人机下行发射功率
H = 10. # 无人机固定悬停高度
R_d = 30. # 无人机充电覆盖范围
N_S_ = 100 # 设备个数
V = 20 # 无人机最大速度
b_S_ = np.random.randint(0, 500, N_S_) # 初始化传感器当前数据缓存量
Mj = 9.079 * pow(10, -6)
aj = 47083
bj = 2.9 * pow(10, -6)
Oj = 1 / (1 + math.exp(aj * bj))
np.random.seed(1)
内容:地图大小、传感器参数、无人机参数等。
4、UAV 类
class UAV(tk.Tk, object):
def __init__(self, R_dc=10., R_eh=30.):
super(UAV, self).__init__()
# POI位置
self.N_POI = N_S_ # 传感器数量
self.dis = np.zeros(self.N_POI) # 距离的平方 存储距离的平方而不是距离本身可以避免频繁的平方根运算
self.elevation = np.zeros(self.N_POI) # 仰角
self.pro = np.zeros(self.N_POI) # 视距概率
self.h = np.zeros(self.N_POI) # 信道增益参数 信道增益是一个重要的参数,它会影响信号的强度、传输的质量等。
self.N_UAV = 1 # 无人机数量
self.max_speed = V # 无人机最大速度 20m/s
self.H = 10. # 无人机飞行高度 10m
self.X_min = 0
self.Y_min = 0
self.X_max = (WIDTH) * UNIT
self.Y_max = (HEIGHT) * UNIT # 地图边界
self.R_dc = R_dc # 水平充电覆盖距离 10m
self.R_eh = R_eh # 水平覆盖距离 30m
self.sdc = math.sqrt(pow(self.R_dc, 2) + pow(self.H, 2)) # 最大DC服务距离
self.seh = math.sqrt(pow(self.R_eh, 2) + pow(self.H, 2)) # 最大EH服务距离
self.noise = pow(10, -12) # 噪声功率为-90dbm
self.AutoUAV = []
self.Aim = []
self.N_AIM = 1 # 选择服务的用户数
self.FX = 0. # 无人机越界次数
self.SoPcenter = np.random.randint(10, 390, size=[self.N_POI, 2]) #生成一个二维数组,并将结果存储在 self.SoPcenter 属性中。
# 以 v in [0,1],theta in [-1,1]为动作
# spaces.Box 通常来自 gym 库(常用于强化学习环境),它表示一个连续的动作空间。
self.action_space = spaces.Box(low=np.array([0., -1.]), high=np.array([1., 1.]),
dtype=np.float32)
self.state_dim = 6 # 状态空间为最高优先级用户位置与无人机的相对位置,无人机位置,是否撞墙,数据溢出数
self.state = np.zeros(self.state_dim) # 创建了一个长度为 self.state_dim 的零数组
self.xy = np.zeros((self.N_UAV, 2)) # 无人机位置 创建一个self.N_UAV行2列的零数组
# 假设有4类传感器,即有4个不同的泊松参数,随机给传感器分配泊松参数
CoLDA = np.random.randint(0, len(LDA), self.N_POI)
self.lda = [LDA[CoLDA[i]] for i in range(self.N_POI)] # 给传感器们指定数据增长速度
self.b_S = np.random.randint(0., 500., self.N_POI).astype(np.float32) # 初始化传感器当前数据缓存量
self.Fully_buffer = C
self.N_Data_overflow = 0 # 数据溢出计数
self.Q = np.array(
[self.lda[i] * self.b_S[i] / self.Fully_buffer for i in range(self.N_POI)]) # 数据收集优先级
self.idx_target = np.argmax(self.Q) # 返回输入数组 self.Q 中最大元素的索引
self.updata = self.b_S[self.idx_target] / self.Fully_buffer
'''
# 指定一块区域环境对传感器有影响
for i in range(self.N_POI):
if all(self.SoPcenter[i] >= [120, 120]) and all(self.SoPcenter[i] <= [280, 280]):
self.lda[i] += 3.
'''
self.title('MAP')
self.geometry('{0}x{1}'.format(WIDTH * UNIT, HEIGHT * UNIT)) # Tkinter 的几何形状
self.build_maze()
①spaces.Box(low=np.array([0., -1.]), high=np.array([1., 1.]), dtype=np.float32)
:- 这是使用
gym
库中的spaces.Box
来定义一个连续动作空间。 low
和high
分别指定了动作空间的下限和上限,这里定义了一个二维的动作空间,第一个维度v
范围是[0., 1.]
,第二个维度theta
范围是[-1., 1.]
。dtype=np.float32
表示动作空间的数据类型是 32 位浮点数。
- 这是使用
②np.random.randint(10, 390, size=[self.N_POI, 2])
:- 生成一个形状为
(self.N_POI, 2)
的随机整数数组,范围在[10, 390)
之间,用于表示服务点的中心位置。 - 服务点将在地图上随机分布,为后续的模拟提供了多样性。
- 生成一个形状为
③np.argmax(self.Q)
:- 找出数组
self.Q
中最大值的索引,这里是找出具有最高数据收集优先级的服务点的索引。 - 这个索引将帮助无人机决定先服务哪个服务点,是基于数据收集优先级的决策。
- 找出数组
5、创建地图方法 build_maze
def build_maze(self):
# 创建画布 Canvas.白色背景,宽高。
self.canvas = tk.Canvas(self, bg='white', width=WIDTH * UNIT, height=HEIGHT * UNIT)
'''
# 标记出特殊区域
for c in range(120, 280, UNIT * 4 - 1):
x0, y0, x1, y1 = c, 120, c, 280
self.canvas.create_line(x0, y0, x1, y1)
for r in range(120, 280, UNIT * 4 - 1):
x0, y0, x1, y1 = 120, r, 280, r
self.canvas.create_line(x0, y0, x1, y1)
'''
# 创建用户
self.tmp_list = []
for i in range(self.N_POI):
# 创建椭圆,指定起始位置。填充颜色
if self.lda[i] == LDA[0]:
tmp = self.canvas.create_oval(
self.SoPcenter[i][0] - 5, self.SoPcenter[i][1] - 5, # 椭圆的左上角坐标
self.SoPcenter[i][0] + 5, self.SoPcenter[i][1] + 5, # 是椭圆的右下角坐标
fill='pink') # 指定椭圆的填充颜色
elif self.lda[i] == LDA[1]:
tmp = self.canvas.create_oval(
self.SoPcenter[i][0] - 5, self.SoPcenter[i][1] - 5,
self.SoPcenter[i][0] + 5, self.SoPcenter[i][1] + 5,
fill='blue')
elif self.lda[i] == LDA[2]:
tmp = self.canvas.create_oval(
self.SoPcenter[i][0] - 5, self.SoPcenter[i][1] - 5,
self.SoPcenter[i][0] + 5, self.SoPcenter[i][1] + 5,
fill='green')
elif self.lda[i] == LDA[3]:
tmp = self.canvas.create_oval(
self.SoPcenter[i][0] - 5, self.SoPcenter[i][1] - 5,
self.SoPcenter[i][0] + 5, self.SoPcenter[i][1] + 5,
fill='red')
self.tmp_list.append(tmp)
print(self.tmp_list)
# 创建无人机
self.xy = np.random.randint(100., 300., size=[self.N_UAV, 2])
for i in range(self.N_UAV):
L_UAV = self.canvas.create_oval(
self.xy[i][0] - R_d, self.xy[i][1] - R_d,
self.xy[i][0] + R_d, self.xy[i][1] + R_d,
fill='yellow')
self.AutoUAV.append(L_UAV)
print(self.AutoUAV)
# 用户选择
pxy = self.SoPcenter[np.argmax(self.Q)]
L_AIM = self.canvas.create_rectangle( # 创建一个矩形
pxy[0] - 10, pxy[1] - 10,
pxy[0] + 10, pxy[1] + 10,
fill='red')
self.Aim.append(L_AIM)
print(self.Aim)
self.canvas.pack() # 显示画布
①创建了一个白色的画布,根据传感器的不同泊松参数使用不同颜色的椭圆表示传感器,并在画布上创建了表示无人机的黄色圆形和表示当前目标的红色矩形。
6、重置方法 reset
def reset(self):
self.render()
for i in range(self.N_UAV):
self.canvas.delete(self.AutoUAV[i])
self.AutoUAV = []
for i in range(len(self.Aim)):
self.canvas.delete(self.Aim[i])
# 随机初始化无人机位置
self.xy = np.random.randint(100, 300, size=[self.N_UAV, 2]).astype(float)
print(self.xy, '----------------')
for i in range(self.N_UAV):
L_UAV = self.canvas.create_oval(
self.xy[i][0] - R_d, self.xy[i][1] - R_d,
self.xy[i][0] + R_d, self.xy[i][1] + R_d,
fill='yellow')
self.AutoUAV.append(L_UAV)
self.FX = 0.
self.b_S = np.random.randint(0, 500, self.N_POI) # 初始化传感器当前数据缓存量
self.b_S = np.asarray(self.b_S, dtype=np.float32)
self.N_Data_overflow = 0 # 数据溢出计数
self.Q = np.array([self.lda[i] * self.b_S[i] / self.Fully_buffer for i in range(self.N_POI)]) # 数据收集优先级
# 初始化状态空间值
self.idx_target = np.argmax(self.Q)
self.updata = self.b_S[self.idx_target] / self.Fully_buffer
self.pxy = self.SoPcenter[self.idx_target] # 初始选择优先级最大的
L_AIM = self.canvas.create_rectangle(
self.pxy[0] - 10, self.pxy[1] - 10,
self.pxy[0] + 10, self.pxy[1] + 10,
fill='red')
self.Aim.append(L_AIM)
self.state = np.concatenate(((self.pxy - self.xy[0]).flatten() / 400., self.xy.flatten() / 400., [0., 0.]))
return self.state
① 重置环境,包括重新生成无人机位置、删除并重新创建无人机和目标的图形元素,重新计算传感器缓存、数据溢出、数据收集优先级等,并更新状态。
7、step_move 方法
def step_move(self, action, above=False):
if above == True: # 计算在x,y距离的移动
detX = action[:self.N_UAV] * self.max_speed
detY = action[self.N_UAV:] * self.max_speed
else:
detX = action[0] * self.max_speed * math.cos(action[1] * math.pi)
detY = action[0] * self.max_speed * math.sin(action[1] * math.pi)
state_ = np.zeros(self.state_dim)
xy_ = copy.deepcopy(self.xy) # 位置更新
Flag = False # 无人机是否飞行标识
for i in range(self.N_UAV): # 无人机位置更新
xy_[i][0] += detX
xy_[i][1] += detY
# 当无人机更新后的位置超出地图范围时
if xy_[i][0] >= self.X_min and xy_[i][0] <= self.X_max:
if xy_[i][1] >= self.Y_min and xy_[i][1] <= self.Y_max:
self.FX = 0.
Flag = True
else:
xy_[i][0] -= detX
xy_[i][1] -= detY
self.FX += 1. # 越界计数
else:
xy_[i][0] -= detX
xy_[i][1] -= detY
self.FX += 1.
if Flag:
# 飞行能耗
V = math.sqrt(pow(detX, 2) + pow(detY, 2))
ec = 79.86 * (1 + 0.000208 * pow(V, 2)) + 88.63 * math.sqrt(
math.sqrt(1 + pow(V, 4) / 1055.0673312400002) - pow(V, 2) / 32.4818) + 0.009242625 * pow(V, 3)
else:
ec = 168.49 # 悬停能耗
for i in range(self.N_UAV):
self.canvas.move(self.AutoUAV[i], xy_[i][0] - self.xy[i][0], xy_[i][1] - self.xy[i][1])
self.xy = xy_
# 无人机位置更新后,判断服务点接受服务的情况
self.N_Data_overflow = 0 # 记录每时隙数据溢出用户数
self.b_S += [np.random.poisson(self.lda[i]) for i in range(self.N_POI)] # 传感器数据缓存量更新
for i in range(self.N_POI): # 数据溢出处理
if self.b_S[i] >= self.Fully_buffer:
self.N_Data_overflow += 1 # 数据溢出用户计数
self.b_S[i] = self.Fully_buffer
self.updata = self.b_S[self.idx_target] / self.Fully_buffer
# 状态空间归一化
state_[:2] = (self.pxy - xy_).flatten() / 400. # 更新用户与无人机相对位置
state_[2:4] = xy_.flatten() / 400. # 无人机绝对位置
state_[4] = self.FX / 400. # 无人机越境次数/总步数
state_[5] = self.N_Data_overflow / self.N_POI # 数据溢出用户占比
Done = False
# 奖励的定义——尽快到目的地/不要撞墙/减小能耗
reward = -(abs(state_[0]) + abs(state_[1])) * 100 - self.FX * 10 - self.N_Data_overflow * 5
self.Q_dis() # 获取所有用户与无人机的信道增益
ehu = 0 # 充电覆盖用户
data_rate = 0 # 数据率
eh = 0 # 总充电量
if (above == False and self.dis[self.idx_target] <= self.sdc) or (
above == True and abs(state_[0]) <= 0.002 and abs(state_[1]) <= 0.002):
Done = True
reward += 500
# 只给目标用户收集数据
data_rate = math.log(1 + P_u * self.h[self.idx_target] / self.noise, 2) # 2.397~4.615
self.b_S[self.idx_target] = 0
for i in range(self.N_POI):
if self.dis[i] <= self.seh and i != self.idx_target:
ehu += 1
eh += self.Non_linear_EH(P_d * self.h[i]) # 输入是10-4W~10-5W,输出是0.6751969599046135~7.418403066937866
# print(sum_rate,ehu,eh)
self.state = state_
return state_, reward, Done, data_rate, ehu, eh, ec # 状态值,奖励,是否到达目标,总数据率, 覆盖到的用户,收集能量,无人机能耗
①
根据输入的动作更新无人机的位置,更新传感器缓存和状态信息,计算奖励,检查是否到达目标,并计算数据速率、充电量和能耗。
八、其他方法
def step_hover(self, hover_time):
# 无人机不动,所以是s[:5]不变
self.N_Data_overflow = 0 # 记录每时隙数据溢出用户数
self.b_S += [np.random.poisson(self.lda[i]) * hover_time for i in range(self.N_POI)] # 传感器数据缓存量更新
for i in range(self.N_POI): # 数据溢出处理
if self.b_S[i] >= self.Fully_buffer:
self.N_Data_overflow += 1 # 数据溢出用户计数
self.b_S[i] = self.Fully_buffer
self.updata = self.b_S[self.idx_target] / self.Fully_buffer
self.state[5] = self.N_Data_overflow / self.N_POI # 数据溢出用户占比
step_hover
方法:当无人机悬停时更新传感器缓存和数据溢出信息。
def Q_dis(self):
for i in range(self.N_POI):
self.dis[i] = math.sqrt(
pow(self.SoPcenter[i][0] - self.xy[0][0], 2) + pow(self.SoPcenter[i][1] - self.xy[0][1], 2) + pow(
self.H, 2)) # 原始距离
self.elevation[i] = 180 / math.pi * np.arcsin(self.H / self.dis[i]) # 仰角
self.pro[i] = 1 / (1 + 10 * math.exp(-0.6 * (self.elevation[i] - 10))) # 视距概率
self.h[i] = (self.pro[i] + (1 - self.pro[i]) * 0.2) * pow(self.dis[i], -2.3) * pow(10,-30 / 10) # 参考距离增益为-30db
Q_dis
方法:计算无人机与所有用户的距离、仰角和路径增益。
def Non_linear_EH(self, Pr):
if Pr == 0:
return 0
P_prac = Mj / (1 + math.exp(-aj * (Pr - bj)))
Peh = (P_prac - Mj * Oj) / (1 - Oj) # 以W为单位,Oj = 1 / (1 + math.exp(aj * bj))
return Peh * pow(10, 6) # 为什么要乘以10^6
Non_linear_EH
方法:根据输入功率计算非线性能量收集。
def linear_EH(self, Pr):
if Pr == 0:
return 0
return Pr * pow(10, 6) * 0.2
linear_EH
方法:根据输入功率计算线性能量收集。
def CHOOSE_AIM(self):
for i in range(len(self.Aim)):
self.canvas.delete(self.Aim[i])
# 重选目标用户
self.Q = np.array([self.lda[i] * self.b_S[i] / C for i in range(self.N_POI)]) # 数据收集优先级
self.idx_target = np.argmax(self.Q)
self.updata = self.b_S[self.idx_target] / self.Fully_buffer
self.pxy = self.SoPcenter[self.idx_target]
L_AIM = self.canvas.create_rectangle(
self.pxy[0] - 10, self.pxy[1] - 10,
self.pxy[0] + 10, self.pxy[1] + 10,
fill='red')
self.Aim.append(L_AIM)
self.state[:2] = (self.pxy - self.xy[0]).flatten() / 400.
self.render()
return self.state
CHOOSE_AIM
方法:重新选择目标用户。
def render(self, t=0.01):
time.sleep(t)
self.update()
render
方法:更新 Tkinter 界面。
def sample_action(self):
v = np.random.rand()
theta = -1 + 2 * np.random.rand()
return [v, theta]
sample_action
方法:生成随机动作。