• 快速拓展随机树(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()

  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters
    记一次odoo创建新的模块时,但是在odoo web界面找不到应用的案例
    python实现格式化输出9*9乘法表
    format和urlencode的使用对比
    python字典小知识
    01
    深浅拷贝再回顾
    DRF的路由生成类的使用
  • 原文地址:https://www.cnblogs.com/yangmingustb/p/9013534.html
Copyright © 2020-2023  润新知