双向rrt算法python代码
时间: 2023-07-23 09:18:28 浏览: 266
以下是双向RRT算法的Python代码示例:
```python
import random
import math
import matplotlib.pyplot as plt
class RRTNode:
def __init__(self, x, y):
self.x = x
self.y = y
self.parent = None
class BiRRT:
def __init__(self, start, goal, obstacle_list, rand_area, expand_dist=0.5, goal_sample_rate=20, max_iter=500):
self.start_node = RRTNode(start[0], start[1])
self.goal_node = RRTNode(goal[0], goal[1])
self.obstacle_list = obstacle_list
self.min_rand = rand_area[0]
self.max_rand = rand_area[1]
self.expand_dist = expand_dist
self.goal_sample_rate = goal_sample_rate
self.max_iter = max_iter
self.node_list1 = [self.start_node]
self.node_list2 = [self.goal_node]
self.path = []
def planning(self):
for i in range(self.max_iter):
if random.randint(0, 100) > self.goal_sample_rate:
rnd = self.get_random_node()
else:
rnd = self.goal_node
nearest_node1 = self.nearest_node(self.node_list1, rnd)
nearest_node2 = self.nearest_node(self.node_list2, rnd)
new_node1 = self.steer(nearest_node1, rnd, self.expand_dist)
new_node2 = self.steer(nearest_node2, rnd, self.expand_dist)
if self.check_collision(new_node1) and self.check_collision(new_node2):
self.node_list1.append(new_node1)
self.node_list2.append(new_node2)
self.connect(new_node1, new_node2)
if self.calc_dist(new_node1, self.goal_node) < self.expand_dist:
final_node = self.steer(new_node1, self.goal_node, self.expand_dist)
if self.check_collision(final_node):
self.path = self.get_path(final_node)
return self.path
self.node_list1, self.node_list2 = self.node_list2, self.node_list1
def steer(self, from_node, to_node, extend_length=float("inf")):
new_node = RRTNode(from_node.x, from_node.y)
dist, angle = self.calc_distance_and_angle(new_node, to_node)
if dist < extend_length:
extend_length = dist
new_node.x += extend_length * math.cos(angle)
new_node.y += extend_length * math.sin(angle)
new_node.parent = from_node
return new_node
def connect(self, from_node, to_node):
from_node.parent = to_node
def get_path(self, node):
path = [[node.x, node.y]]
while node.parent:
node = node.parent
path.append([node.x, node.y])
return path
def nearest_node(self, node_list, node):
nearest_node = node_list[0]
for n in node_list:
if self.calc_dist(n, node) < self.calc_dist(nearest_node, node):
nearest_node = n
return nearest_node
def calc_dist(self, from_node, to_node):
return math.sqrt((from_node.x - to_node.x) ** 2 + (from_node.y - to_node.y) ** 2)
def calc_distance_and_angle(self, from_node, to_node):
dx = to_node.x - from_node.x
dy = to_node.y - from_node.y
dist = math.sqrt(dx ** 2 + dy ** 2)
angle = math.atan2(dy, dx)
return dist, angle
def check_collision(self, node):
for (ox, oy, size) in self.obstacle_list:
if math.sqrt((node.x - ox) ** 2 + (node.y - oy) ** 2) <= size:
return False
return True
def get_random_node(self):
if random.randint(0, 100) > self.goal_sample_rate:
rnd = RRTNode(random.uniform(self.min_rand, self.max_rand), random.uniform(self.min_rand, self.max_rand))
else:
rnd = self.goal_node
return rnd
def plot_path(self):
plt.plot([x for (x, y) in self.path], [y for (x, y) in self.path], '-r')
for (ox, oy, size) in obstacleList:
circle = plt.Circle((ox, oy), size, color='b')
plt.gcf().gca().add_artist(circle)
plt.plot(self.start_node.x, self.start_node.y, 'xr')
plt.plot(self.goal_node.x, self.goal_node.y, 'xr')
plt.axis('equal')
plt.show()
if __name__ == '__main__':
obstacleList = [(5, 5, 1), (3, 6, 2), (3, 8, 2), (5, 10, 2), (7, 9, 2), (9, 10, 2)]
start = [0.0, 0.0]
goal = [10.0, 10.0]
rrt = BiRRT(start, goal, obstacleList, [-2, 12])
path = rrt.planning()
if path:
print(path)
rrt.plot_path()
else:
print("Cannot find path!")
```
请注意,此示例仅用于演示双向RRT算法,并且可能需要根据您的具体需求进行修改。
阅读全文