|
- import numpy as np
- from numpy import random
- import time
- import matplotlib.pyplot as plt
- from mpl_toolkits.mplot3d import Axes3D
- import math
-
- class UAVEnv():
- def __init__(self,uav_num):
- ###############
- # s:VAV_NUM*2 Numpy_array
- # a:VAV_NUM*1 Numpy_array
- # r:VAV_NUM*1 Numpy_array
- # s_prime:VAV_NUM*2 Numpy_array
- # done:VAV_NUM*1 Numpy_array
-
- ###env_parameters
- self.region_length = 9
- self.region_width = 9
- self.uav_move_instance = 0.5
- self.uav_num = uav_num
- self.uav_height = 1
- self.uav_coverage = 3
- self.ec_flying = 1
- self.ec_hovering = 0.5
- self.max_step = 500
-
- ##reward_function
- self.out_region_penalty = -10
- self.ALL_COVERAGE_R=16
- self.FLYING_PENELTY=-0.2
-
- self.target_region_plane = np.ones([self.region_width, self.region_length])##目标区域平面,1表示POI的位置
- self.uav_location_x = random.randint(0, (self.region_width-1)//self.uav_move_instance+1, [self.uav_num, 1])*self.uav_move_instance
- self.uav_location_y = random.randint(0, (self.region_length-1)//self.uav_move_instance+1, [self.uav_num, 1])*self.uav_move_instance
- self.state = np.hstack((self.uav_location_x, self.uav_location_y)) # np.array[self.uav_num,2]
- self.step_num = 1
- self.wkt = self.compute_ck(self.state, self.uav_coverage, self.region_length, self.region_width)
- self.ckt = self.wkt / self.step_num
- self.if_coverage = self.compute_ck(self.state, self.uav_coverage, self.region_length, self.region_width)
- ##################设置画布格式
- self.fig = plt.figure(dpi=200,figsize=(6,4),facecolor='gray')
- self.ax = Axes3D(self.fig,[-0.5,-0.2,2,2])#[left,down,width,height]
- ###################
-
- def reset(self):
- self.uav_location_x = random.randint(0, (self.region_width - 1) // self.uav_move_instance + 1,
- [self.uav_num, 1]) * self.uav_move_instance
- self.uav_location_y = random.randint(0, (self.region_length - 1) // self.uav_move_instance + 1,
- [self.uav_num, 1]) * self.uav_move_instance
- self.state = np.hstack((self.uav_location_x, self.uav_location_y)) # np.array[self.uav_num,2]
- self.step_num = 1
- self.wkt = self.compute_ck(self.state, self.uav_coverage, self.region_length, self.region_width)
- self.ckt = self.wkt / self.step_num
- self.if_coverage = self.compute_ck(self.state, self.uav_coverage, self.region_length, self.region_width)
- return self.state
-
- def step(self, action):
- #action:(self.uav_num,1) np.ndarray
- et = np.zeros([len(action),1])
- out_region_penalty_lst = np.zeros([len(action),1])
- ec_r=np.ones([len(action),1])*self.FLYING_PENELTY
- for i in range(len(action)):
- if action[i] == 0: # 向上移动,沿x轴正向
- if self.state[i][0] + self.uav_move_instance > self.region_width - 1:
- out_region_penalty_lst[i] = self.out_region_penalty
- et[i] = self.ec_hovering
- else:
- self.state[i][0] = self.state[i][0] + self.uav_move_instance
- et[i] = self.ec_flying
- elif action[i] == 1: # 向下移动,沿x轴负向
- if self.state[i][0] - self.uav_move_instance < 0:
- out_region_penalty_lst[i] = self.out_region_penalty
- et[i] = self.ec_hovering
- else:
- self.state[i][0] = self.state[i][0] - self.uav_move_instance
- et[i] = self.ec_flying
- elif action[i] == 2: # 向左移动,沿y轴负向
- if self.state[i][1] - self.uav_move_instance < 0:
- out_region_penalty_lst[i] = self.out_region_penalty
- et[i] = self.ec_hovering
- else:
- self.state[i][1] = self.state[i][1] - self.uav_move_instance
- et[i] = self.ec_flying
- elif action[i] == 3: # 向左移动,沿y轴正向
- if self.state[i][1] + self.uav_move_instance > self.region_length - 1:
- out_region_penalty_lst[i] = self.out_region_penalty
- et[i] = self.ec_hovering
- else:
- self.state[i][1] = self.state[i][1] + self.uav_move_instance
- et[i] = self.ec_flying
- else: # UAV hovering
- et[i] = self.ec_hovering
- ec_r[i] = 0
- self.step_num = self.step_num + 1
- old_coverage_num=sum(sum(self.if_coverage))
- self.if_coverage = self.compute_ck(self.state, self.uav_coverage, self.region_length, self.region_width)
- new_coverage_num=sum(sum(self.if_coverage))
- fully_coveraged_r=self.ALL_COVERAGE_R if sum(sum(self.if_coverage))==self.region_width*self.region_length else 0
- r =new_coverage_num-old_coverage_num + out_region_penalty_lst +fully_coveraged_r+ec_r
- done = np.zeros([4,1])
- return self.state, r, done
-
- def close(self):
- plt.close(self.fig)
-
- def compute_ck(self, uav_location, uav_coverage, length, width): ##计算某时刻各个POI的被覆盖情况 被覆盖(1),未被覆盖(0)
- ck = np.zeros([width, length])
- for uav in uav_location:
- for i in range(max(math.ceil(uav[0] - uav_coverage), 0), min(math.floor(uav[0] + uav_coverage), width - 1) + 1):
- for j in range(max(math.ceil(uav[1] - uav_coverage), 0), min(math.floor(uav[1] + uav_coverage), length - 1) + 1):
- if i == uav[0] or j == uav[1]:
- ck[i][j] = 1
- elif (i - uav[0]) ** 2 + (j - uav[1]) ** 2 <= uav_coverage ** 2:
- ck[i][j] = 1
- return ck
-
- def render(self):
- def plot_uav(ax, uav_x, uav_y, uav_z, r):
- ###绘制无人机及其垂直投影点
- ax.plot3D([uav_x, uav_x], [uav_y - 0.5, uav_y + 0.5], uav_z, 'b')
- ax.plot3D([uav_x - 0.5, uav_x + 0.5], [uav_y, uav_y], uav_z, 'b')
- ax.scatter3D([uav_x, uav_x, uav_x - 0.5, uav_x + 0.5], [uav_y - 0.5, uav_y + 0.5, uav_y, uav_y], uav_z,
- c='k')
- ax.scatter3D(uav_x,uav_y,0,c='k')
- ###绘制无人机覆盖区域
- a = np.arange(uav_x - r, uav_x + r + 0.01, 0.01)
- b1 = np.sqrt(np.power(r, 2) - np.power((a - uav_x), 2) + 0.00001) + uav_y
- b2 = -np.sqrt(np.power(r, 2) - np.power((a - uav_x), 2) + 0.00001) + uav_y
- ax.plot(a, b1, color='r', linestyle='-')
- ax.plot(a, b2, color='r', linestyle='-')
- plt.cla()
- self.ax.axis('off') # 去掉坐标轴
- self.ax.set_xticks([])
- self.ax.set_yticks([])
- self.ax.set_zticks([]) # 去掉刻度
- self.ax.set_xlim3d(-self.uav_coverage, self.region_width - 1 + self.uav_coverage)
- self.ax.set_ylim3d(-self.uav_coverage, self.region_length - 1 + self.uav_coverage)
- self.ax.set_zlim3d(0, self.uav_height+1)
- ##绘制目标区域线条
- for i in range(self.region_length):
- self.ax.plot([0, self.region_length - 1], [i, i], 'k')
- for i in range(self.region_width):
- self.ax.plot([i, i], [0, self.region_width - 1], 'k')
- ##绘制poi点
- #优化前
- # for i in range(self.region_width):
- # for j in range(self.region_length):
- # self.ax.scatter3D(i, j, 0, c='r' if self.if_coverage[i][j] == 0 else 'g')
- #优化后
- poi1_x,poi1_y=np.where(self.if_coverage==1)
- self.ax.scatter3D(poi1_x, poi1_y, 0, c='g')
- poi0_x, poi0_y = np.where(self.if_coverage == 0)
- self.ax.scatter3D(poi0_x, poi0_y, 0, c='r')
-
- #绘制UAV及其覆盖区域
- for i, j in self.state:
- plot_uav(self.ax, i, j, self.uav_height, self.uav_coverage)
- plt.pause(0.0001)
-
- def choose_action_random(self):
- action = random.randint(0, 5, [self.uav_num, 1])
- return action
-
-
- # 测试环境
- if __name__ == "__main__":
- env = UAVEnv(4)
- print('s:',env.reset())
- for i in range(100):
- a = env.choose_action_random()
- print('a:',a)
- env.step(a)
- env.render()
- env.close()
|