1 """ 2 version1.1,2018-05-09 3 《基于智能优化与RRT算法的无人机任务规划方法研究》博士论文 4 《基于改进人工势场法的路径规划算法研究》硕士论文 5 6 """ 7 8 import matplotlib.pyplot as plt 9 import random 10 import math 11 import copy 12 13 show_animation = True 14 15 16 class Node(object): 17 """ 18 RRT Node 19 """ 20 21 def __init__(self, x, y): 22 self.x = x 23 self.y = y 24 self.parent = None 25 26 27 class RRT(object): 28 """ 29 Class for RRT Planning 30 """ 31 32 def __init__(self, start, goal, obstacle_list, rand_area): 33 """ 34 Setting Parameter 35 36 start:Start Position [x,y] 37 goal:Goal Position [x,y] 38 obstacleList:obstacle Positions [[x,y,size],...] 39 randArea:random sampling Area [min,max] 40 41 """ 42 self.start = Node(start[0], start[1]) 43 self.end = Node(goal[0], goal[1]) 44 self.min_rand = rand_area[0] 45 self.max_rand = rand_area[1] 46 self.expandDis = 1.0 47 self.goalSampleRate = 0.05 # 选择终点的概率是0.05 48 self.maxIter = 500 49 self.obstacleList = obstacle_list 50 self.nodeList = [self.start] 51 52 def random_node(self): 53 """ 54 产生随机节点 55 :return: 56 """ 57 node_x = random.uniform(self.min_rand, self.max_rand) 58 node_y = random.uniform(self.min_rand, self.max_rand) 59 node = [node_x, node_y] 60 61 return node 62 63 @staticmethod 64 def get_nearest_list_index(node_list, rnd): 65 """ 66 :param node_list: 67 :param rnd: 68 :return: 69 """ 70 d_list = [(node.x - rnd[0]) ** 2 + (node.y - rnd[1]) ** 2 for node in node_list] 71 min_index = d_list.index(min(d_list)) 72 return min_index 73 74 @staticmethod 75 def collision_check(new_node, obstacle_list): 76 a = 1 77 for (ox, oy, size) in obstacle_list: 78 dx = ox - new_node.x 79 dy = oy - new_node.y 80 d = math.sqrt(dx * dx + dy * dy) 81 if d <= size: 82 a = 0 # collision 83 84 return a # safe 85 86 def planning(self): 87 """ 88 Path planning 89 90 animation: flag for animation on or off 91 """ 92 93 while True: 94 # Random Sampling 95 if random.random() > self.goalSampleRate: 96 rnd = self.random_node() 97 else: 98 rnd = [self.end.x, self.end.y] 99 100 # Find nearest node 101 min_index = self.get_nearest_list_index(self.nodeList, rnd) 102 # print(min_index) 103 104 # expand tree 105 nearest_node = self.nodeList[min_index] 106 107 # 返回弧度制 108 theta = math.atan2(rnd[1] - nearest_node.y, rnd[0] - nearest_node.x) 109 110 new_node = copy.deepcopy(nearest_node) 111 new_node.x += self.expandDis * math.cos(theta) 112 new_node.y += self.expandDis * math.sin(theta) 113 new_node.parent = min_index 114 115 if not self.collision_check(new_node, self.obstacleList): 116 continue 117 118 self.nodeList.append(new_node) 119 120 # check goal 121 dx = new_node.x - self.end.x 122 dy = new_node.y - self.end.y 123 d = math.sqrt(dx * dx + dy * dy) 124 if d <= self.expandDis: 125 print("Goal!!") 126 break 127 128 if True: 129 self.draw_graph(rnd) 130 131 path = [[self.end.x, self.end.y]] 132 last_index = len(self.nodeList) - 1 133 while self.nodeList[last_index].parent is not None: 134 node = self.nodeList[last_index] 135 path.append([node.x, node.y]) 136 last_index = node.parent 137 path.append([self.start.x, self.start.y]) 138 139 return path 140 141 def draw_graph(self, rnd=None): 142 """ 143 Draw Graph 144 """ 145 print('aaa') 146 plt.clf() # 清除上次画的图 147 if rnd is not None: 148 plt.plot(rnd[0], rnd[1], "^g") 149 for node in self.nodeList: 150 if node.parent is not None: 151 plt.plot([node.x, self.nodeList[node.parent].x], [ 152 node.y, self.nodeList[node.parent].y], "-g") 153 154 for (ox, oy, size) in self.obstacleList: 155 plt.plot(ox, oy, "sk", ms=10*size) 156 157 plt.plot(self.start.x, self.start.y, "^r") 158 plt.plot(self.end.x, self.end.y, "^b") 159 plt.axis([self.min_rand, self.max_rand, self.min_rand, self.max_rand]) 160 plt.grid(True) 161 plt.pause(0.01) 162 163 def draw_static(self, path): 164 """ 165 画出静态图像 166 :return: 167 """ 168 plt.clf() # 清除上次画的图 169 170 for node in self.nodeList: 171 if node.parent is not None: 172 plt.plot([node.x, self.nodeList[node.parent].x], [ 173 node.y, self.nodeList[node.parent].y], "-g") 174 175 for (ox, oy, size) in self.obstacleList: 176 plt.plot(ox, oy, "sk", ms=10*size) 177 178 plt.plot(self.start.x, self.start.y, "^r") 179 plt.plot(self.end.x, self.end.y, "^b") 180 plt.axis([self.min_rand, self.max_rand, self.min_rand, self.max_rand]) 181 182 plt.plot([data[0] for data in path], [data[1] for data in path], '-r') 183 plt.grid(True) 184 plt.show() 185 186 187 def main(): 188 print("start RRT path planning") 189 190 obstacle_list = [ 191 (5, 1, 1), 192 (3, 6, 2), 193 (3, 8, 2), 194 (1, 1, 2), 195 (3, 5, 2), 196 (9, 5, 2)] 197 198 # Set Initial parameters 199 rrt = RRT(start=[0, 0], goal=[8, 9], rand_area=[-2, 10], obstacle_list=obstacle_list) 200 path = rrt.planning() 201 print(path) 202 203 # Draw final path 204 if show_animation: 205 plt.close() 206 rrt.draw_static(path) 207 208 209 if __name__ == '__main__': 210 main()