6
6
7
7
"""
8
8
9
- import copy
10
9
import math
11
10
import os
12
11
import sys
@@ -29,21 +28,20 @@ class RRTStar(RRT):
29
28
Class for RRT Star planning
30
29
"""
31
30
32
- class Node :
31
+ class Node ( RRT . Node ) :
33
32
def __init__ (self , x , y ):
34
- self .x = x
35
- self .y = y
33
+ super ().__init__ (x , y )
36
34
self .cost = 0.0
37
- self .parent = None
38
35
39
36
def __init__ (self , start , goal , obstacle_list , rand_area ,
40
- expand_dis = 0.5 ,
37
+ expand_dis = 3.0 ,
38
+ path_resolution = 1.0 ,
41
39
goal_sample_rate = 20 ,
42
- max_iter = 500 ,
40
+ max_iter = 300 ,
43
41
connect_circle_dist = 50.0
44
42
):
45
43
super ().__init__ (start , goal , obstacle_list ,
46
- rand_area , expand_dis , goal_sample_rate , max_iter )
44
+ rand_area , expand_dis , path_resolution , goal_sample_rate , max_iter )
47
45
"""
48
46
Setting Parameter
49
47
@@ -65,11 +63,12 @@ def planning(self, animation=True, search_until_maxiter=True):
65
63
66
64
self .node_list = [self .start ]
67
65
for i in range (self .max_iter ):
68
- rnd = self .get_random_point ()
66
+ print (i , len (self .node_list ))
67
+ rnd = self .get_random_node ()
69
68
nearest_ind = self .get_nearest_list_index (self .node_list , rnd )
70
- new_node = self .steer (rnd , self .node_list [nearest_ind ])
69
+ new_node = self .steer (self .node_list [nearest_ind ], rnd , self . expand_dis )
71
70
72
- if self .check_collision (new_node , self .obstacleList ):
71
+ if self .check_collision (new_node , self .obstacle_list ):
73
72
near_inds = self .find_near_nodes (new_node )
74
73
new_node = self .choose_parent (new_node , near_inds )
75
74
if new_node :
@@ -79,7 +78,7 @@ def planning(self, animation=True, search_until_maxiter=True):
79
78
if animation and i % 5 == 0 :
80
79
self .draw_graph (rnd )
81
80
82
- if not search_until_maxiter and new_node : # check reaching the goal
81
+ if ( not search_until_maxiter ) and new_node : # check reaching the goal
83
82
d , _ = self .calc_distance_and_angle (new_node , self .end )
84
83
if d <= self .expand_dis :
85
84
return self .generate_final_course (len (self .node_list ) - 1 )
@@ -92,16 +91,36 @@ def planning(self, animation=True, search_until_maxiter=True):
92
91
93
92
return None
94
93
94
+ def connect_nodes (self , from_node , to_node ):
95
+ new_node = self .Node (from_node .x , from_node .y )
96
+ d , theta = self .calc_distance_and_angle (new_node , to_node )
97
+
98
+ new_node .path_x = [new_node .x ]
99
+ new_node .path_y = [new_node .y ]
100
+
101
+ n_expand = math .floor (d / self .path_resolution )
102
+
103
+ for _ in range (n_expand ):
104
+ new_node .x += self .path_resolution * math .cos (theta )
105
+ new_node .y += self .path_resolution * math .sin (theta )
106
+ new_node .path_x .append (new_node .x )
107
+ new_node .path_y .append (new_node .y )
108
+
109
+ new_node .parent = from_node
110
+
111
+ return new_node
112
+
95
113
def choose_parent (self , new_node , near_inds ):
96
114
if not near_inds :
97
115
return None
98
116
99
117
# search nearest cost in near_inds
100
118
costs = []
101
119
for i in near_inds :
102
- d , theta = self .calc_distance_and_angle (self .node_list [i ], new_node )
103
- if self .check_collision_extend (self .node_list [i ], theta , d ):
104
- costs .append (self .node_list [i ].cost + d )
120
+ near_node = self .node_list [i ]
121
+ t_node = self .steer (near_node , new_node )
122
+ if self .check_collision (t_node , self .obstacle_list ):
123
+ costs .append (self .calc_new_cost (near_node , new_node ))
105
124
else :
106
125
costs .append (float ("inf" )) # the cost of collision node
107
126
min_cost = min (costs )
@@ -110,9 +129,10 @@ def choose_parent(self, new_node, near_inds):
110
129
print ("There is no good path.(min_cost is inf)" )
111
130
return None
112
131
113
- new_node .cost = min_cost
114
132
min_ind = near_inds [costs .index (min_cost )]
115
133
new_node .parent = self .node_list [min_ind ]
134
+ new_node = self .steer (new_node .parent , new_node )
135
+ new_node .cost = min_cost
116
136
117
137
return new_node
118
138
@@ -141,34 +161,27 @@ def find_near_nodes(self, new_node):
141
161
def rewire (self , new_node , near_inds ):
142
162
for i in near_inds :
143
163
near_node = self .node_list [i ]
144
- d , theta = self .calc_distance_and_angle (near_node , new_node )
145
- new_cost = new_node .cost + d
164
+ edge_node = self .steer (new_node , near_node )
165
+ edge_node .cost = self .calc_new_cost (near_node , new_node )
166
+
167
+ no_collision = self .check_collision (edge_node , self .obstacle_list )
168
+ improved_cost = near_node .cost > edge_node .cost
169
+
170
+ if no_collision and improved_cost :
171
+ near_node .parent = new_node
172
+ near_node .cost = edge_node .cost
173
+ self .propagate_cost_to_leaves (new_node )
146
174
147
- if near_node .cost > new_cost :
148
- if self .check_collision_extend (near_node , theta , d ):
149
- near_node .parent = new_node
150
- near_node .cost = new_cost
151
- self .propagate_cost_to_leaves (new_node )
175
+ def calc_new_cost (self , from_node , to_node ):
176
+ d , _ = self .calc_distance_and_angle (from_node , to_node )
177
+ return from_node .cost + d
152
178
153
179
def propagate_cost_to_leaves (self , parent_node ):
154
180
for node in self .node_list :
155
181
if node .parent == parent_node :
156
- d , _ = self .calc_distance_and_angle (parent_node , node )
157
- node .cost = parent_node .cost + d
182
+ node .cost = self .calc_new_cost (parent_node , node )
158
183
self .propagate_cost_to_leaves (node )
159
184
160
- def check_collision_extend (self , near_node , theta , d ):
161
-
162
- tmp_node = copy .deepcopy (near_node )
163
-
164
- for i in range (int (d / self .expand_dis )):
165
- tmp_node .x += self .expand_dis * math .cos (theta )
166
- tmp_node .y += self .expand_dis * math .sin (theta )
167
- if not self .check_collision (tmp_node , self .obstacleList ):
168
- return False
169
-
170
- return True
171
-
172
185
173
186
def main ():
174
187
print ("Start " + __file__ )
@@ -184,11 +197,11 @@ def main():
184
197
] # [x,y,size(radius)]
185
198
186
199
# Set Initial parameters
187
- rrt = RRTStar (start = [0 , 0 ],
188
- goal = [10 , 10 ],
189
- rand_area = [- 2 , 15 ],
190
- obstacle_list = obstacle_list )
191
- path = rrt .planning (animation = show_animation , search_until_maxiter = False )
200
+ rrt_star = RRTStar (start = [0 , 0 ],
201
+ goal = [10 , 10 ],
202
+ rand_area = [- 2 , 15 ],
203
+ obstacle_list = obstacle_list )
204
+ path = rrt_star .planning (animation = show_animation )
192
205
193
206
if path is None :
194
207
print ("Cannot find path" )
@@ -197,7 +210,7 @@ def main():
197
210
198
211
# Draw final path
199
212
if show_animation :
200
- rrt .draw_graph ()
213
+ rrt_star .draw_graph ()
201
214
plt .plot ([x for (x , y ) in path ], [y for (x , y ) in path ], '-r' )
202
215
plt .grid (True )
203
216
plt .pause (0.01 ) # Need for Mac
0 commit comments