├── Agent ├── Agent.py ├── User │ └── PoI.py └── Worker │ └── UAV.py ├── Arguments └── FaEArgs.py ├── Env └── Env.py ├── Function ├── CommFuction.py ├── EnergyFuction.py └── ToolFunciton.py └── Test └── FaEEnv.py /Agent/Agent.py: -------------------------------------------------------------------------------- 1 | class Agent(object): 2 | """ 3 | 创建一个智能体 4 | 5 | """ 6 | 7 | def __init__(): 8 | """ 9 | 初始化Agent的状态 10 | """ 11 | pass 12 | 13 | def reset(): 14 | """ 15 | 重置Agent的状态 16 | """ 17 | pass 18 | if __name__ == "__main__": 19 | new_Agent = Agent() 20 | -------------------------------------------------------------------------------- /Agent/User/PoI.py: -------------------------------------------------------------------------------- 1 | from Agent.Agent import Agent 2 | import numpy as np 3 | from Function import ToolFunciton 4 | from Arguments.FaEArgs import arglists 5 | 6 | class PoI(Agent): 7 | """ 8 | 创建PoI 9 | """ 10 | 11 | def __init__(self, arguments): 12 | """ 13 | 初始化PoI 14 | 15 | :param boundary_radius: (int) PoI的边界范围 16 | :param world_size: (int) 地图的边界范围 17 | :param poi_exploited_flag: (bool) 用于标记PoI是否被探索,值为0表示该PoI未被探索,值为1表示该PoI已被探索 18 | :param covered_time: (int) PoI的被覆盖时间 19 | :param can_comm: (bool) 表示PoI目前能否正常通信,为0表示不能,为1表示能 20 | :param covered_flag:(bool) 表示该PoI目前是否被覆盖,为0表示未被覆盖,为1表示已经被覆盖 21 | """ 22 | super(PoI, self).__init__() 23 | # 继承Agent的属性 24 | self.boundary_radius = arguments.boundary_radius 25 | self.world_size = arguments.world_size 26 | self.poi_exploited_flag = arguments.poi_exploited_flag 27 | # 初始PoI未被覆盖,赋值为0 28 | self.covered_time = arguments.covered_time 29 | self.exploiters = [] 30 | # 存储覆盖该PoI的实例,初始为空 31 | self.temp_exploiters = [] 32 | self.can_comm = arguments.can_comm 33 | # 暂存覆盖该PoI的实例,初始为空 34 | def poi_position_reset(self, state, arguments): 35 | """ 36 | 重置PoI的位置,被覆盖时间,被覆盖的UAV列表 37 | 38 | :param state: (array) PoI的位置信息,state[0]为PoI的x轴坐标,state[1]为PoI的y轴坐标 39 | """ 40 | self.state.poi_pos = state[0:2] 41 | #该PoI的位置 42 | self.covered_time = arguments.poi_exploited_flag 43 | self.poi_exploited_flag = arguments.poi 44 | self.can_comm = arguments.can_comm 45 | self.exploiters = [] 46 | self.temp_exploiters = [] 47 | def exploit_init(self, uav_agents_pos): 48 | """ 49 | 计算所有UAV距离该PoI的距离, 50 | 51 | :param uav_agents: (array)UAV智能体的实例组 52 | :param uav_agents.pos: (array)UAV组的位置信息,其中uav_agents.pos[:, 0]表示UAV智能体组的所有横坐标,uav_agents.pos[:, 1]表示UAV智能体组的所有纵坐标 53 | """ 54 | temp_dist_matrix = np.vstack([uav_agents_pos[:, 0:2], self.state.poi_pos]) 55 | # 构成一个n行2列的矩阵,第一列为UAV智能体组以及PoI的横坐标,第二列为UAV智能体以及PoI的纵坐标 56 | 57 | distances = ToolFunciton.get_euclid_distances(temp_dist_matrix) 58 | #计算PoI与每个UAV智能体组中每个UAV的欧式距离,distance[i]为PoI距离第i个UAV的欧式距离 (float) 59 | dist_to_uavs = distances 60 | 61 | self.temp_exploiters = list(np.where(dist_to_uavs < self.boundary_radius)[0]) 62 | # 更新poi范围内的所有UAV实体 63 | 64 | if len(self.temp_exploiters) > 0: 65 | self.poi_exploited_flag = 1 66 | #PoI范围内存在UAV,就把被探索标志设为1 67 | 68 | def step(self, uav_agents_pos, uav_agents_energy): 69 | """ 70 | PoI进行一次action 71 | 72 | :param uav_agents: 73 | :return: 74 | """ 75 | self.exploiters = [] 76 | temp_dist_matrix = np.vstack([uav_agents_pos[:, 0:2], self.state.poi_pos]) 77 | # 构成一个n行2列的矩阵,第一列为UAV智能体组以及PoI的横坐标,第二列为UAV智能体以及PoI的纵坐标 78 | 79 | distances = ToolFunciton.get_euclid_distances(temp_dist_matrix) 80 | # 计算PoI与每个UAV智能体组中每个UAV的欧式距离,distance[i]为PoI距离第i个UAV的欧式距离 (float) 81 | 82 | dist_to_uavs = distances 83 | self.temp_exploiters = list(np.where(dist_to_uavs < self.boundary_radius)[0]) 84 | # 更新poi范围内的所有UAV实体 85 | if len(self.temp_exploiters)>0: 86 | self.covered_flag = 1 87 | 88 | uav_have_energy = False 89 | #用来标记PoI范围内是否有具有电量的UAV 90 | 91 | if len(self.temp_exploiters) > 0: 92 | for i in self.temp_exploiters: 93 | if uav_agents_energy[i] > 0: 94 | uav_have_energy = True 95 | #寻找PoI范围内具有电量的UAV 96 | 97 | if self.poi_exploited_flag == 1: 98 | self.poi_exploited_flag = 0 99 | self.exploiters = self.temp_exploiters 100 | #存储探索该PoI的实例 101 | if uav_have_energy: 102 | self.can_comm = 1 103 | else: 104 | self.can_comm = 0 105 | #判断该PoI此时能否通信 106 | if __name__ == "__main__": 107 | args = arglists() 108 | new_PoI = PoI(args) 109 | print(new_PoI.boundary_radius) 110 | 111 | -------------------------------------------------------------------------------- /Agent/Worker/UAV.py: -------------------------------------------------------------------------------- 1 | import Agent 2 | import numpy as np 3 | import random 4 | from Arguments.FaEArgs import arglists 5 | from Function.ToolFunciton import get_euclid_distances 6 | class UAV(Agent): 7 | """ 8 | 创建UAV 9 | """ 10 | 11 | def __init__(self, arguments): 12 | """ 13 | 初始化UAV 14 | 15 | :param comm_radius: (float) UAV的通信范围 16 | :param boundary_radius: (float) PoI的覆盖范围 17 | :param energy: (int) UAV目前的能量 18 | # :param uav_obs_pos: (array) UAV的当前位置,array[0]表示横坐标,array[1]表示纵坐标 19 | # :param uav_over: (array) array[i]=0表示第i个UAV没有越过边界,array[i]=1表示第i个UAV越过了边界 20 | :param uav_now_num: (int) 当前UAV的数量 21 | :param poi_now_num: (int) 当前poi的数量 22 | :param world_size: (int) 此时Env的边界范围 23 | :param is_wall: (int) 判断UAV飞行途中是否撞墙,为0表示没有撞墙,为1表示撞墙 24 | :param delta_energy: (int) UAV消耗的能量 25 | :param n_step: (int) Env中目前全局的时隙数 26 | :param max_line_v: (int) UAV飞行的最大线速度50 27 | :param max_angle_v: (int) UAV飞行的最大角速度2π 28 | """ 29 | super(UAV, self).__init__() 30 | # 继承父类的属性 31 | self.energy = arguments.energy 32 | # 3 33 | self.comm_radius = arguments.comm_radius 34 | self.boundary_radius= arguments.boundary_radius 35 | self.energy = arguments.energy 36 | self.uav_now_num = arguments.uav_now_num 37 | self.poi_now_num = arguments.poi_now_num 38 | self.world_size = arguments.world_size 39 | self.is_wall = arguments.is_wall 40 | self.delta_energy = arguments.delta_energy 41 | # 0 42 | self.n_step = arguments.n_step 43 | self.max_line_v = arguments.max_line_v 44 | # 50 cm/s 45 | self.max_angle_v = arguments.max_angle_v 46 | # 2π 47 | 48 | 49 | def uav_state_reset(self, state, arguments): 50 | """ 51 | 利用随机化算法重新设置UAV的位置 52 | 53 | :param state: (array)state[0]表示UAV的横坐标,state[1]表示UAV的纵坐标,state[2]表示UAV目前的方向 54 | :param init_line_v: (float) UAV的初始线速度为0 55 | :param init_angle_v: (float) UAV的初始角速度为0 56 | """ 57 | self.state.uav_pos = state[0:2] 58 | self.state.uav_pos[0] = random.randint(0, 100) 59 | self.state.uav_pos[1] = random.randint(0, 100) 60 | # 将uav的横纵坐标在0~100里随机选取 61 | self.state.uav_orientation = state[2] 62 | self.state.line_v = arguments.init_line_v 63 | self.state.angle_v = arguments.init_angle_v 64 | # uav飞行线速度和角速度设置为0 65 | self.energy = arguments.energy 66 | self.delta_energy = arguments.delta_energy 67 | # 重置UAV的能量和消耗的能量 68 | 69 | def get_observation(self, uav_pos, pois_pos, timestep): 70 | """ 71 | 计算与环境中所有PoI的距离,并判断此时UAV是否撞墙 72 | 73 | :param pois_pos: (array) poi_pos[i][0]表示第i个poi的横坐标,poi_pos[i][1]表示第i个poi的纵坐标 74 | :param uav_pos: (array) uav_pos[0]表示该UAV的横坐标,uav_pos[1]表示该UAV的纵坐标 75 | :param timestep: (int) UAV已经使用的时间步数 76 | :return obs: (arrays) 第一列为每个poi距离UAV的距离, 77 | """ 78 | 79 | dist_to_pois = get_euclid_distances(np.vstack(pois_pos, uav_pos)) 80 | # 所有poi距离该UAV的距离 81 | local_obs = np.zeros(2) 82 | if self.torus is False: 83 | if np.any(self.state.uav_pos <= 1) or np.any(self.state.uav_pos >= 999): 84 | self.wall = 1 85 | else: 86 | self.wall = 0 87 | local_obs[0] = self.wall 88 | local_obs[1] = float(timestep) / self.n_step 89 | # local_obs[0]表示UAV是否撞墙,local_obs[1]存UAV已使用的时间步数的归一化值 90 | 91 | for i in range(self.poi_now_num): 92 | normal_dist_to_pois = dist_to_pois[i] / self.obs_radius 93 | # 计算每个Poi距离UAV的归一化距离 94 | return dist_to_pois 95 | if __name__ == "__main__": 96 | args = arglists() 97 | new_UAV = UAV(args) 98 | print(new_UAV.energy) 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /Arguments/FaEArgs.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import numpy as np 3 | def arglists(): 4 | parser = argparse.ArgumentParser() 5 | #UAV的具有默认值的参数 6 | parser.add_argument("--energy", type=int, default=3, help="UAV默认初始能量", ) 7 | parser.add_argument("--comm_radius", type=float , default=10.0, help="UAV默认通信范围",) 8 | parser.add_argument("--uav_now_num", type=int, default=10, help="UAV默认当前数量", ) 9 | parser.add_argument("--is_wall", type=bool, default=0, help="默认UAV没有撞墙,正常飞行", ) 10 | parser.add_argument("--delta_energy", type=int, default=0, help="默认UAV初始消耗的能量为0", ) 11 | parser.add_argument("--max_line_v", type=float, default=50, help="UAV的最大线速度为50cm/s", ) 12 | parser.add_argument("--max_angle_v", type=float, default=2*np.pi, help="UAV的最大角速度为2π", ) 13 | parser.add_argument("--init_line_v", type=float, default=0, help="UAV的初始线速度") 14 | parser.add_argument("--init_angle_v", type=float, default=0, help="UAV的初始角速度") 15 | #UAVEnv的具有的默认参数值 16 | parser.add_argument("--world_size", type=int, default=1000, help="默认的边界范围", ) 17 | parser.add_argument("--max_uav_num", type=int, default=100, help="默认的Env中UAV的最大数量") 18 | parser.add_argument("--max_poi_num", type=int, default=100, help="默认的Env中PoI的最大数量") 19 | parser.add_argument("--n_step", type=int, default=1024, help="默认UAV初始可以使用的时隙数", ) 20 | parser.add_argument("--now_step", type=int, default=0, help="默认的当前的时隙数") 21 | parser.add_argument("--is_terminal", tpye=bool, default=0, help="默认值为0表示游戏正在继续") 22 | #PoI的具有默认值的参数 23 | parser.add_argument("--poi_exploited_flag", type=bool, default=0, help="标记PoI是否被覆盖,默认值为0未被覆盖", ) 24 | parser.add_argument("--boundary_radius", type=float, default=20, help="PoI的边界范围", ) 25 | parser.add_argument("--poi_now_num", type=int, default=10, help="PoI默认当前数量", ) 26 | parser.add_argument("--covered_time", type=int, default=0, help="PoI的被覆盖时间,默认为0", ) 27 | parser.add_argument("--can_comm", type=bool, default=0, help="标记PoI此时能否正常通信", ) 28 | parser.add_argument("--covered_flag", type=bool, default=0, help="标记该PoI是否已被UAV覆盖,默认为0表示没有被覆盖") 29 | return parser.parse_args() 30 | -------------------------------------------------------------------------------- /Env/Env.py: -------------------------------------------------------------------------------- 1 | from Agent.User.PoI import PoI 2 | from Agent.Worker.UAV import UAV 3 | from Function.ToolFunciton import get_normalized_distance 4 | from Function.ToolFunciton import get_uav_angle 5 | from Function.CommFuction import get_uav_state 6 | import numpy as np 7 | import torch 8 | import scipy.io 9 | import random 10 | import numpy as np 11 | import matplotlib.pylab as pylab 12 | import matplotlib.pyplot as plt 13 | import matplotlib.ticker as mtick 14 | class Env(object): 15 | """ 16 | 创造一个Env环境 17 | """ 18 | def __init__(self, arguments): 19 | """ 20 | 初始化Env环境 21 | :param torus: (int) 判断Env是否是循环地图,为1表示Env是循环,为0表示Env不是循环的 22 | :param world_size: (int) Env中的边界大小 23 | :param uav_max_num: (int) Env中可以容纳UAV的最大数量 24 | :param timestep_limit: (int) Env中的最大时隙数 25 | :param n_steo: (int) Env中表示全局目前的时隙数 26 | :param now_step: (int) Env中当前的时隙数 27 | :param comm_radius: (float) UAV的通信范围 28 | :param boundary_radius: (float) PoI的覆盖范围 29 | :param uav_now_num: (int) 当前UAV的数量 30 | :param poi_now_num: (int) 当前poi的数量 31 | :param is_terminal: (bool) 当前游戏是否终止,为1终止,为0不终止 32 | :param covered_flag:(bool) 表示该PoI目前是否被覆盖,为0表示未被覆盖,为1表示已经被覆盖 33 | """ 34 | self.covered_flag = arguments.covered_flag 35 | self.torus = arguments.torus 36 | self.world_size = arguments.world_size 37 | self.uav_max_num = arguments.uav_max_num 38 | self.poi_max_num = arguments.poi_max_num 39 | self.n_step = arguments.n_step 40 | self.now_step = arguments.now_step 41 | self.uav_now_num = arguments.uav_now_num 42 | self.poi_now_num = arguments.poi_now_num 43 | self.agents = [UAV(self) for i in range(self.uav_now_num)] 44 | [self.agents.append(PoI(self)) for _ in range(self.poi_now_num)] 45 | #创建一个agents列表,前uav_now_num个元素是当前的UAV,后poi_now_num个元素是当前的PoI 46 | self.dist_matrix = np.zeros((self.uav_now_num, self.poi_now_num)) 47 | # 创建一个距离矩阵,横轴是PoI,纵轴是UAV 48 | self.uavs_angle = np.zeros(self.uav_now_num) 49 | # 创建一个弧度矩阵,第i列为第i个UAV的角度 50 | self.pois_angle = np.zeros(self.poi_now_num) 51 | # 创建一个弧度矩阵,第i列为第i个poi的角度 52 | self.uavs_energy = np.zeros(self.uav_now_num) 53 | # 创建一个能量矩阵,第i列为第i个UAV的能量 54 | self.pois_covered = np.zeros(self.poi_now_num) 55 | # 创建一个覆盖标记矩阵,第i列为第i个PoI是否被标记 56 | 57 | def env_reset(self, arguments): 58 | self.torus = arguments.torus 59 | self.world_size = arguments.world_size 60 | self.uav_max_num = arguments.uav_max_num 61 | self.poi_max_num = arguments.poi_max_num 62 | self.n_step = arguments.n_step 63 | self.now_step = arguments.now_step 64 | self.uav_now_num = arguments.uav_now_num 65 | self.poi_now_num = arguments.poi_now_num 66 | self.dist_matrix = np.zeros((self.uav_now_num, self.poi_now_num)) 67 | def agents_reset(self): 68 | """初始化agents""" 69 | self.agents = [UAV(self) for i in range(self.uav_now_num)] 70 | [self.agents.append(PoI(self)) for _ in range(self.poi_now_num)] 71 | 72 | def position_reset(self): 73 | """重置Env中的UAV,PoI的位置信息""" 74 | uavs_pos = np.zeros((self.uav_now_num, 2)) 75 | pois_pos = np.zeros((100, 2)) 76 | for i in range(10): 77 | for j in range(10): 78 | pois_pos[int(i * 10 + j)][0] = 50 + i * 100 79 | pois_pos[int(i * 10 + j)][1] = 50 + j * 100 80 | #重置poi的位置,100个poi均匀分布在1000*1000的地图里 81 | self.uavs_pos = uavs_pos 82 | self.pois_pos = pois_pos 83 | #存入重置后的位置 84 | def update_uav_energy(self): 85 | """更新UAV的能量""" 86 | for i in self.uav_now_num: 87 | new_UAV = UAV(self) 88 | self.uavs_energy[i] = new_UAV.energy 89 | 90 | def update_dist(self): 91 | """计算并更新PoI组和UAV组之间的距离""" 92 | for i in self.uav_now_num: 93 | new_UAV = UAV(self) 94 | temp_dist = new_UAV.get_observation(self.uavs_pos[i,:], self.pois_pos ,self.now_step) 95 | self.dist_matrix[i,:] = temp_dist 96 | def update_uav_angle(self): 97 | """计算并更新Env里所有UAV的角度""" 98 | for i in self.uav_now_num: 99 | self.uavs_angle[i] = get_uav_angle(self.uavs_pos) 100 | 101 | def update_poi_angle(self): 102 | """计算并更新Env里所有poi的角度""" 103 | for i in self.poi_now_num: 104 | self.pois_angle[i] = get_uav_angle(self.pois_pos) 105 | def update_poi_cover(self): 106 | """更新poi的被覆盖情况""" 107 | for i in self.poi_now_num: 108 | new_PoI = PoI(self) 109 | new_PoI.step(self.uavs_pos, self.uavs_energy) 110 | if self.covered_flag == 1: 111 | self.pois_covered[i] = 1 112 | else: 113 | self.pois_covered[i] = 0 114 | 115 | def step(self, action=None): 116 | """ 117 | 更新经过action选择后的状态和奖励 118 | 119 | :param action: (arry) action的第一列为当前UAV的横坐标,UAV的第二列为当前UAV的纵坐标 120 | """ 121 | self.now_step += 1 122 | uav_normal_distance = [] 123 | uav_normal_distance = get_normalized_distance(action[:, 0:2]) 124 | #计算每个UAV的归一化距离 125 | uav_new_angle = get_uav_angle(action[:, 0:2]) 126 | #计算每个UAV的角度 127 | next_state = get_uav_state(uav_normal_distance, uav_new_angle, self.agents[0:self.uav_now_num], self.now_step) 128 | #更新经过这一步后的状态 129 | dones = np.zeros(self.uav_now_num) 130 | dones[0] = self.is_terminal 131 | info = [{}] 132 | return next_state, dones, info 133 | 134 | def greedy(self): 135 | """ 136 | 对每个UAV更新角度并且,找到UAV范围内没有被覆盖的PoIs 137 | :param arguments: 138 | :return: 139 | """ 140 | ac = np.zeros((self.uav_now_num, 2)) * 0.5 141 | for i in self.uav_now_num: 142 | temp_uav_to_pois = self.dist_matrix[i, :] 143 | index_dist_argsort = np.argsort(temp_uav_to_pois) 144 | #排序后根据距离从近到远找到第一个没有被覆盖的PoIs的下标,以及它的角度 145 | for j in index_dist_argsort: 146 | if self.pois_covered[index_dist_argsort[j]] == 0: 147 | ac[i, 1] = self.pois_angle[index_dist_argsort[j]] 148 | break 149 | actions = torch.FloatTensor([[a[0], a[1]] for a in ac]) 150 | # action的第i行的第一列为0.5, 第二列为UAV距离最近的没有被访问过的PoI的角度 151 | 152 | def render(self, agent_pos0): 153 | """ 154 | :param agent_pos0: (array) 第一列为UAV的横坐标,第二列为UAV的纵坐标 155 | :return: 156 | """ 157 | temp_x = agent_pos0[:, 0] 158 | temp_y = agent_pos0[:, 1] 159 | x0 = temp_x[0: self.uav_now_num] 160 | y0 = temp_y[0: self.uav_now_num] 161 | myparams = { 162 | 'axes.labelsize': '20', 163 | 'xtick.labelsize': '18', 164 | 'ytick.labelsize': '18', 165 | 'lines.linewidth': 1.3, 166 | 'legend.fontsize': '18', 167 | 'font.family': 'Times New Roman', 168 | 'figure.figsize': '7, 7', # 图片尺寸 169 | 'grid.alpha': 0.1 170 | 171 | } 172 | plt.style.use("seaborn-deep") 173 | pylab.rcParams.update(myparams) 174 | ''' 175 | params = { 176 | 'axes.labelsize': '35', 177 | 'xtick.labelsize': '27', 178 | 'ytick.labelsize': '27', 179 | 'lines.linewidth': 2, 180 | 'legend.fontsize': '27', 181 | 'figure.figsize': '12, 9' # set figure size 182 | } 183 | 184 | pylab.rcParams.update(params) # set figure parameter 185 | # line_styles=['ro-','b^-','gs-','ro--','b^--','gs--'] #set line style 186 | ''' 187 | plt.plot(x0, y0, marker='^', markersize=6) 188 | #所有点形成轨迹 189 | plt.plot(x0[0], y0[0], marker='o', markersize=8) 190 | #标记初始点 191 | fig1 = plt.figure(1) 192 | ax_values = [0, 1000, 0, 1000] 193 | plt.axis(ax_values) 194 | plt.axhline() 195 | plt.axvline() 196 | # axes = plt.subplot(111) 197 | # axes = plt.gca() 198 | # axes.set_yticks([0, 50, 100, 150, 200, 250]) 199 | # axes.set_xticks([0, 50, 100, 150, 200]) 200 | # axes.grid(True) # add grid 201 | 202 | plt.legend(loc="lower right") # set legend location 203 | plt.ylabel('y_coordinate') # set ystick label 204 | plt.xlabel('x_coordinate') # set xstck label 205 | 206 | r = 150 207 | center = (x0[0], y0[0]) 208 | x = np.linspace(center[0] - r, center[0] + r, 5000) 209 | y1 = np.sqrt(r ** 2 - (x - center[0]) ** 2) + center[1] 210 | y2 = -np.sqrt(r ** 2 - (x - center[0]) ** 2) + center[1] 211 | plt.plot(x, y1, 'k--') 212 | plt.plot(x, y2, 'k--') 213 | x = center[0] 214 | y = center[1] 215 | # plt.plot(x, y, color="black", marker="o", markersize=4) 216 | 217 | for i in range(10): 218 | for j in range(10): 219 | x = 50 + i * 100 220 | y = 50 + j * 100 221 | plt.plot(x, y, color="black", marker="o", markersize=6, alpha=0.5) 222 | #为PoI作图 223 | plt.savefig('plot.pdf', bbox_inches='tight') 224 | plt.show() 225 | 226 | 227 | if __name__ == "__main__": 228 | new_Env = Env() 229 | -------------------------------------------------------------------------------- /Function/CommFuction.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import math 3 | def get_uav_state(matrix_distance, matrix_angle,matrix_agent,now_step): 4 | """ 5 | 更新UAV的状态 6 | 7 | :param matrix_distance:(array) matrix_distance[i]为第i个UAV的归一化距离 8 | :param matrix_angle:(array) matrix_angle[i]为第i个UAV的角度(弧度制) 9 | :param matrix_agent:(array) matrix_agent[i]为第i个UAV智能体实例 10 | :param now_step:(int) 当前的时隙数 11 | :return: new_state:(array) 更新后UAV智能体组的状态 12 | """ 13 | 14 | new_state = [[], [], [], 0, ] 15 | new_state[:][0] = matrix_distance 16 | new_state[:][1] = matrix_angle 17 | new_state[:][2] = matrix_agent 18 | new_state[0][3] = now_step 19 | return new_state 20 | -------------------------------------------------------------------------------- /Function/EnergyFuction.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppphuchen/UAV-simulation-system-based-on-reinforcement-learning/9c285fdf4711ce10a4be86df6501644d51e67826/Function/EnergyFuction.py -------------------------------------------------------------------------------- /Function/ToolFunciton.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.spatial as ssp 3 | import scipy.stats as sst 4 | import math 5 | def get_euclid_distances(matrix): 6 | """ 7 | :param matrix: (array)第一列为UAV智能体组以及PoI的横坐标,第二列为UAV智能体以及PoI的纵坐标 8 | :return: temp_matrix: (array) temp_matrix[i]表示该PoI距离第i个UAV的距离 9 | """ 10 | temp_matrix = [] 11 | rows = matrix.shape(0) 12 | temp_poi_x = matrix[rows][0] 13 | temp_poi_y = matrix[rows][1] 14 | for i in (rows-1): 15 | temp_matrix[i] = ((matrix[i][0] - temp_poi_x)**2 + (matrix[i][1] - temp_poi_y)**2)**0.5 16 | return temp_matrix 17 | 18 | def get_normalized_distance(matrix): 19 | """ 20 | :param matrix: (array) 第一列为UAV智能体的横坐标,第二列为UAV智能体的纵坐标 21 | :return: temp_matrix: (array) temp_matrix[i]表示第i个UAV的归一化距离 22 | """ 23 | temp_euler_distance = [] 24 | temp_matrix = [] 25 | temp_max = 0.0 26 | rows = matrix.shape(0) 27 | for i in range(rows): 28 | temp_euler_distance[i] = (matrix[i][0]**2 + matrix[i][1]**2)**0.5 29 | if temp_euler_distance[i] > temp_max: 30 | temp_max = temp_euler_distance[i] 31 | for i in range(rows): 32 | temp_matrix[i] = temp_euler_distance[i]/temp_max 33 | 34 | return temp_matrix 35 | 36 | def get_uav_angle(matrix): 37 | """ 38 | :param matrix: (array) 第一列为UAV智能体的横坐标,第二列为UAV智能体的纵坐标 39 | :return: temp_matrix: (array) temp_matrix[i]表示第i个UAV的角度(弧度制) 40 | """ 41 | rows = matrix.shape(0) 42 | temp_matrix = [] 43 | for i in range(rows): 44 | temp_matrix[i] = math.atan2(matrix[i][1], matrix[i][0]) 45 | return temp_matrix 46 | 47 | -------------------------------------------------------------------------------- /Test/FaEEnv.py: -------------------------------------------------------------------------------- 1 | from Agent import Agent 2 | from Agent.User.PoI import PoI 3 | from Agent.Worker.UAV import UAV 4 | import numpy as np 5 | import random 6 | from Arguments.FaEArgs import arglists 7 | 8 | def test_PoI(): 9 | """ 10 | 对PoI文档进行测试 11 | :return: 12 | """ 13 | args = arglists() 14 | new_PoI = PoI(args) 15 | state = np.zeros(2) 16 | new_PoI.poi_position_reset(state, args) 17 | 18 | uav_agents_pos = np.zeros(100,2) 19 | #生成一个100行 2列的uav_pos矩阵 第一列为uav的横坐标,第二列为uav的纵坐标 20 | uav_agents_energy = np.zeros(100) 21 | #生成一个100个uav的数组,每个uav的能量初始为0 22 | new_PoI.exploit_init(uav_agents_pos) 23 | new_PoI.step(uav_agents_pos, uav_agents_energy) 24 | def test_UAV(): 25 | """ 26 | 对UAV文档进行测试 27 | :return: 28 | """ 29 | args = arglists() 30 | new_UAV = UAV(args) 31 | state = np.zeros(1,3) 32 | #生成一个1行3列的state矩阵,第一列为uav的横坐标,第二列为uav的纵坐标,第三列为uav的角度 33 | new_UAV.reset(state, args) 34 | distance_from_poi = np.zeros(1,100) 35 | #生成一个1行100列的矩阵,每一列表示第i个poi距离该uav的距离 36 | new_UAV.get_observation(distance_from_poi,timestep=100) 37 | def test_Env(): 38 | """ 39 | 对Env文档进行测试 40 | :return: 41 | """ 42 | args = arglists() 43 | new_Env = UAV(args) 44 | new_Env.reset(args) 45 | new_Env.agents_reset() 46 | new_Env.position_reset() 47 | action = np.zeros(100,2) 48 | #第一列为当前uav的横坐标,第二列为当前uav的纵坐标 49 | new_state = new_Env.step(action) 50 | if __name__ == "__main__": 51 | test_Env() 52 | test_PoI() 53 | test_UAV() 54 | --------------------------------------------------------------------------------