-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathbi_rrt.py
137 lines (118 loc) · 3.61 KB
/
bi_rrt.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python
# coding: utf-8
import matplotlib.pyplot as plt
import math
import numpy as np
import random
import argparse
class Node:
def __init__(self, x, y):
self.x = x
self.y = y
self.path_so_far = []
def get_random_point(lc=0, rc=30):
rand_point = Node(random.uniform(lc,rc),random.uniform(lc, rc))
return rand_point
def merge_intersetion(node1, node2):
global obslist
for obs in obslist:
dr = np.hypot(node2.x-node1.x, node2.y-node1.y)
D = (node1.x-obs[0])*(node2.y-obs[1]) - (node2.x-obs[0])*(node1.y-obs[1])
d = (obs[2]*dr)**2 - D**2
if d >= 0:
return False
return True
def get_nearest_point(point, tree):
distance_list = [np.hypot(node.x - point.x, node.y - point.y)**2 for node in tree]
return distance_list.index(min(distance_list))
def get_new_point(rnd_point, old_point, delta=1):
theta = math.atan((old_point.y-rnd_point.y)/(old_point.x-rnd_point.x))
temp_p1 = Node(delta*math.cos(theta) + old_point.x, delta*math.sin(theta) + old_point.y)
temp_p2 = Node(-delta*math.cos(theta) + old_point.x, -delta*math.sin(theta) + old_point.y)
temp_tree = [temp_p1, temp_p2]
new_node = temp_tree[get_nearest_point(rnd_point, temp_tree)]
val = merge_intersetion(new_node, old_point)
if val and new_node.x >= 0 and new_node.y >=0 and new_node.x <= 30 and new_node.y <=30:
return new_node
return False
def add_point(tree):
rand_point = get_random_point()
min_dist_index = get_nearest_point(rand_point, tree)
old_point = tree[min_dist_index]
new_node = get_new_point(rand_point, old_point)
if new_node:
tree.append(new_node)
new_node.path_so_far = old_point.path_so_far + [new_node]
def merge(tree1, tree2):
flag = 0
nl = []
for node in tree1[::-1]:
for n in tree2[::-1]:
if merge_intersetion(node, n):
nl.append((node, n, len(node.path_so_far) + len(n.path_so_far)))
if nl != []:
nl.sort(key=lambda x: x[2])
path = nl[0][0].path_so_far + nl[0][1].path_so_far[::-1]
print("Done!!")
else:
print("No path found")
path = None
return path
def main(max_iter):
global obslist
obslist = [(4.5, 3, 2), (3, 12, 2), (15, 15, 3)] #[(x, y, radius)]
start_node = Node(1,1)
start_node.path_so_far.append(start_node)
goal_node = Node(20,20)
goal_node.path_so_far.append(goal_node)
start_tree = [start_node]
goal_tree = [goal_node]
for i in range(max_iter):
add_point(start_tree)
add_point(goal_tree)
path = merge(start_tree, goal_tree)
"""
Plotting
"""
if path:
figure, axes = plt.subplots()
plt.rcParams["figure.figsize"] = (15,15)
# plotting the obstacles
for obs in obslist:
obstacle = plt.Circle((obs[0], obs[1]), obs[2], color="black")
axes.add_artist(obstacle)
# plotting both the trees
trees = [start_tree, goal_tree]
color = ["blue", "green"]
lab = ["Tree from start point", "Tree from end point"]
for i,tree in enumerate(trees):
x_cord = []
y_cord = []
for v in tree:
x_cord.append(v.x)
y_cord.append(v.y)
plt.scatter(x_cord, y_cord, c=[color[i]], label=lab[i])
# plotting path
plt.plot(1,1,'kp') #start
plt.plot(20,20,'kp') #goal
x_cord = []
y_cord = []
for v in path:
x_cord.append(v.x)
y_cord.append(v.y)
plt.plot(x_cord, y_cord, "r-", linewidth=1, label='Final Path')
axes.set_aspect(1)
plt.xlim(0,30)
plt.ylim(0,30)
plt.legend()
plt.title('Configuration Space')
plt.savefig("./images/bi_rrt.png")
# plt.show()
return figure
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Bi-Directional RRT')
parser.add_argument('-i','--iter', type=int,
help='Number of iterations (integer); Default=100', default=100)
args = parser.parse_args()
max_iter = args.iter
main(max_iter)