快速拓展随机树(RRT)路径规划,python

  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()

posted @ 2018-05-09 12:41  最后的绝地武士  阅读(6026)  评论(0编辑  收藏  举报