├── .DS_Store
├── Project Report.pdf
├── README.md
├── dubins
├── dubin_1 .png
├── dubin_2.png
├── dubin_3.png
├── dubin_4.png
├── dubins.py
└── gazebo_dubin.py
├── rrt_dubins
├── Minkowski.py
├── gazebo_rrt_dubins.py
├── rrt_dubin.py
├── rrt_dubin_2.png
├── rrt_dubin_2_2.png
├── rrt_dubin_4.png
└── rrt_dubin_4_1.png
└── rrt_star_dubins
├── .DS_Store
├── Figure1.png
├── Figure2.png
├── rrt_star.png
├── rrt_star_dubins.py
├── rrt_star_dubins_minimized_euclidean.py
├── rrt_star_dubins_minimzed_dubins_paths.py
├── rrt_star_with_random_samplings.png
├── rrt_star_with_random_samplings2.png
├── rrtstar_minimized_dubins_paths.png
└── rrtstar_minimized_dubins_paths2.png
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/.DS_Store
--------------------------------------------------------------------------------
/Project Report.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/Project Report.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Mobile Robots Autonomous Navigation
2 |
3 | Implemented Dubins Curves and RRT(Rapidly Exploring Random Trees) along with the Optimal RRT version.
4 |
5 | Simulated an environment with obstacles with a Pioneer P3DX robot in Gazebo using ROS and applied these path planning algorithms.
6 |
7 | Refer the Project Report for more information.
8 |
9 | # Visuals
10 |
11 |
12 |
13 |
14 | RRT Star + Dubins (Sub-Optimal) with minimized Euclidean distance between nodes,
15 |
16 |
17 |
18 |
19 |
20 | RRT Star + Dubins with random samples,
21 |
22 |
23 |
24 |
25 |
26 | RRT Star + Dubins (Optimal) with minimized Dubins Paths between nodes,
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/dubins/dubin_1 .png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/dubins/dubin_1 .png
--------------------------------------------------------------------------------
/dubins/dubin_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/dubins/dubin_2.png
--------------------------------------------------------------------------------
/dubins/dubin_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/dubins/dubin_3.png
--------------------------------------------------------------------------------
/dubins/dubin_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/dubins/dubin_4.png
--------------------------------------------------------------------------------
/dubins/dubins.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | import math
4 | import matplotlib.patches as patches
5 | import sys
6 |
7 | current_x=0
8 | current_y=0
9 | current_th=0 #current angle in Degrees
10 |
11 | PI=3.14
12 | r_min=2
13 |
14 | goal_x=4
15 | goal_y=4
16 | goal_th=0 #goal angle in Degrees
17 |
18 | # fig, ax = plt.subplots()
19 |
20 |
21 |
22 |
23 | def LSL():
24 | plt.ylim(-5,15)
25 | plt.xlim(-5,15)
26 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
27 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
28 |
29 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
30 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
31 | #print c1_x,c1_y,c2_x,c2_y, c2_y-c1_y, c2_x-c1_x
32 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
33 |
34 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
35 | tan_pt1_y=c1_y-r_min*math.sin(theta)
36 |
37 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
38 | tan_pt2_y=c2_y-r_min*math.sin(theta)
39 |
40 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
41 | # print S,theta
42 | # print (tan_pt1_x,tan_pt1_y)
43 | # print (tan_pt2_x,tan_pt2_y)
44 | # print (c1_x,c1_y,c2_x,c2_y)
45 |
46 |
47 |
48 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
49 |
50 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
51 |
52 | if Ti<0:
53 | Ti+=2*np.pi
54 | if Tf<0:
55 | Tf+=2*np.pi
56 |
57 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
58 |
59 | Ti= Ti*180/np.pi
60 | if Ti<0:
61 | Ti+=360
62 | Tf= Tf*180/np.pi
63 | if Tf<0:
64 | Tf+=360
65 |
66 | # print Ti,Tf, total_dist,S
67 | ans=[Ti,Tf, total_dist,S]
68 |
69 | start_angle1 = np.arctan2(current_y - c1_y, current_x - c1_x) * 180 / np.pi
70 | end_angle1 = np.arctan2(tan_pt1_y - c1_y, tan_pt1_x - c1_x) * 180 / np.pi
71 |
72 | arc1 = patches.Arc((c1_x, c1_y), 2*r_min,2*r_min,theta1=start_angle1, theta2=end_angle1)
73 | plt.gca().add_patch(arc1)
74 |
75 | start_angle2 = np.arctan2(tan_pt2_y - c2_y, tan_pt2_x - c2_x) * 180 / np.pi
76 | end_angle2 = np.arctan2(goal_y - c2_y, goal_x - c2_x) * 180 / np.pi
77 |
78 | arc2 = patches.Arc((c2_x, c2_y), 2*r_min,2*r_min,theta1=start_angle2, theta2=end_angle2)
79 | plt.gca().add_patch(arc2)
80 |
81 |
82 | plt.scatter(current_x,current_y)
83 | plt.scatter(goal_x,goal_y)
84 | plt.scatter(c1_x,c1_y)
85 | plt.plot([tan_pt1_x,tan_pt2_x],[tan_pt1_y,tan_pt2_y],'ro-')
86 | plt.scatter(c2_x,c2_y)
87 | plt.scatter(tan_pt1_x,tan_pt1_y)
88 | plt.scatter(tan_pt2_x,tan_pt2_y)
89 |
90 | # x = np.linspace(-10, 20, 100)
91 | # y = np.linspace(-10, 20, 100)
92 | # X, Y = np.meshgrid(x,y)
93 | # F = (X-c1_x)**2 + (Y-c1_y)**2 - r_min**2
94 | # F1 = (X-c2_x)**2 + (Y-c2_y)**2 - r_min**2
95 | # # plt.contour(X,Y,F,[0])
96 | # plt.contour(X,Y,F1,[0])
97 | plt.gca().set_aspect('equal')
98 | plt.show()
99 | # ax.relim()
100 | return ans
101 |
102 | def RSR():
103 | plt.ylim(-5,15)
104 | plt.xlim(-5,15)
105 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
106 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
107 |
108 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
109 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
110 |
111 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
112 |
113 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
114 | tan_pt1_y=c1_y+r_min*math.sin(theta)
115 |
116 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
117 | tan_pt2_y=c2_y+r_min*math.sin(theta)
118 |
119 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
120 |
121 | # print (tan_pt1_x,tan_pt1_y)
122 | # print (tan_pt2_x,tan_pt2_y)
123 | # print (c2_x,c2_y)
124 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
125 |
126 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
127 |
128 | if Ti<0:
129 | Ti+=2*np.pi
130 | if Tf<0:
131 | Tf+=2*np.pi
132 |
133 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
134 |
135 | Ti= Ti*180/np.pi
136 | if Ti<0:
137 | Ti+=360
138 | Tf= Tf*180/np.pi
139 | if Tf<0:
140 | Tf+=360
141 |
142 | # print Ti,Tf,total_dist,S
143 |
144 | start_angle1 = np.arctan2(current_y - c1_y, current_x - c1_x) * 180 / np.pi
145 | end_angle1 = np.arctan2(tan_pt1_y - c1_y, tan_pt1_x - c1_x) * 180 / np.pi
146 |
147 | arc1 = patches.Arc((c1_x, c1_y), 2*r_min,2*r_min,theta1=end_angle1, theta2=start_angle1)
148 | plt.gca().add_patch(arc1)
149 |
150 | start_angle2 = np.arctan2(tan_pt2_y - c2_y, tan_pt2_x - c2_x) * 180 / np.pi
151 | end_angle2 = np.arctan2(goal_y - c2_y, goal_x - c2_x) * 180 / np.pi
152 |
153 | arc2 = patches.Arc((c2_x, c2_y), 2*r_min,2*r_min,theta1=end_angle2, theta2=start_angle2)
154 | plt.gca().add_patch(arc2)
155 |
156 | print start_angle1,end_angle1,start_angle2,end_angle2
157 |
158 | plt.scatter(current_x,current_y)
159 | plt.scatter(goal_x,goal_y)
160 | plt.scatter(c1_x,c1_y)
161 | plt.scatter(c2_x,c2_y)
162 | plt.scatter(tan_pt1_x,tan_pt1_y)
163 | plt.scatter(tan_pt2_x,tan_pt2_y)
164 | plt.plot([tan_pt1_x,tan_pt2_x],[tan_pt1_y,tan_pt2_y],'ro-')
165 |
166 | # x = np.linspace(-10, 20, 100)
167 | # y = np.linspace(-10, 20, 100)
168 | # X, Y = np.meshgrid(x,y)
169 | # F = (X-c1_x)**2 + (Y-c1_y)**2 - r_min**2
170 | # F1 = (X-c2_x)**2 + (Y-c2_y)**2 - r_min**2
171 | # plt.contour(X,Y,F,[0])
172 | # plt.contour(X,Y,F1,[0])
173 | plt.gca().set_aspect('equal')
174 | plt.show()
175 |
176 | ans=[Ti,Tf, total_dist,S]
177 | return ans
178 |
179 | def LSR():
180 | plt.ylim(-5,15)
181 | plt.xlim(-5,15)
182 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
183 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
184 |
185 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
186 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
187 |
188 | # if c2_x-c1_x<0:
189 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
190 | # elif c2_x-c1_x>0:
191 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
192 |
193 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
194 |
195 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
196 |
197 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y)) - np.arctan2(r_min,S/2.0)
198 |
199 |
200 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
201 | tan_pt1_y=c1_y-r_min*math.sin(theta)
202 |
203 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
204 | tan_pt2_y=c2_y+r_min*math.sin(theta)
205 |
206 | start_angle1 = np.arctan2(current_y - c1_y, current_x - c1_x) * 180 / np.pi
207 | end_angle1 = np.arctan2(tan_pt1_y - c1_y, tan_pt1_x - c1_x) * 180 / np.pi
208 |
209 | arc1 = patches.Arc((c1_x, c1_y), 2*r_min,2*r_min,theta1=start_angle1, theta2=end_angle1)
210 | plt.gca().add_patch(arc1)
211 |
212 | start_angle2 = np.arctan2(tan_pt2_y - c2_y, tan_pt2_x - c2_x) * 180 / np.pi
213 | end_angle2 = np.arctan2(goal_y - c2_y, goal_x - c2_x) * 180 / np.pi
214 |
215 | arc2 = patches.Arc((c2_x, c2_y), 2*r_min,2*r_min,theta1=end_angle2, theta2=start_angle2)
216 | plt.gca().add_patch(arc2)
217 |
218 | plt.scatter(current_x,current_y)
219 | plt.scatter(goal_x,goal_y)
220 | plt.scatter(c1_x,c1_y)
221 | plt.scatter(c2_x,c2_y)
222 | plt.scatter(tan_pt1_x,tan_pt1_y)
223 | plt.scatter(tan_pt2_x,tan_pt2_y)
224 | plt.plot([tan_pt1_x,tan_pt2_x],[tan_pt1_y,tan_pt2_y],'ro-')
225 |
226 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
227 |
228 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
229 | print (tan_pt1_x,tan_pt1_y)
230 | print (tan_pt2_x,tan_pt2_y)
231 | print (c1_x,c1_y,c2_x,c2_y)
232 |
233 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
234 |
235 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
236 |
237 | if Ti<0:
238 | Ti+=2*np.pi
239 | if Tf<0:
240 | Tf+=2*np.pi
241 |
242 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
243 |
244 | Ti= Ti*180/np.pi
245 | if Ti<0:
246 | Ti+=360
247 | Tf= Tf*180/np.pi
248 | if Tf<0:
249 | Tf+=360
250 |
251 | print Ti,Tf,total_dist,S,"yooo"
252 |
253 | # x = np.linspace(-10, 20, 100)
254 | # y = np.linspace(-10, 20, 100)
255 | # X, Y = np.meshgrid(x,y)
256 | # F = (X-c1_x)**2 + (Y-c1_y)**2 - r_min**2
257 | # F1 = (X-c2_x)**2 + (Y-c2_y)**2 - r_min**2
258 | # plt.contour(X,Y,F,[0])
259 | # plt.contour(X,Y,F1,[0])
260 | plt.gca().set_aspect('equal')
261 | plt.show()
262 |
263 | ans=[Ti,Tf, total_dist,S]
264 | return ans
265 |
266 | def RSL():
267 | plt.ylim(-5,15)
268 | plt.xlim(-5,15)
269 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
270 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
271 |
272 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
273 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
274 |
275 | # if c2_x-c1_x<0:
276 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
277 | # elif c2_x-c1_x>0:
278 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
279 |
280 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
281 |
282 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
283 |
284 | theta = + (np.arctan2((c2_x-c1_x), c2_y-c1_y)) + np.arctan2(r_min,S/2.0)
285 |
286 |
287 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
288 | tan_pt1_y=c1_y+r_min*math.sin(theta)
289 |
290 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
291 | tan_pt2_y=c2_y-r_min*math.sin(theta)
292 |
293 | plt.scatter(current_x,current_y)
294 | plt.scatter(goal_x,goal_y)
295 | plt.scatter(c1_x,c1_y)
296 | plt.scatter(c2_x,c2_y)
297 | plt.scatter(tan_pt1_x,tan_pt1_y)
298 | plt.scatter(tan_pt2_x,tan_pt2_y)
299 | plt.plot([tan_pt1_x,tan_pt2_x],[tan_pt1_y,tan_pt2_y],'ro-')
300 |
301 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
302 | print (tan_pt1_x,tan_pt1_y)
303 | print (tan_pt2_x,tan_pt2_y)
304 | print (c1_x,c1_y,c2_x,c2_y)
305 |
306 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
307 |
308 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
309 |
310 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
311 |
312 | if Ti<0:
313 | Ti+=2*np.pi
314 | if Tf<0:
315 | Tf+=2*np.pi
316 |
317 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
318 |
319 | Ti= Ti*180/np.pi
320 | if Ti<0:
321 | Ti+=360
322 | Tf= Tf*180/np.pi
323 | if Tf<0:
324 | Tf+=360
325 |
326 | # print Ti,Tf,total_dist,S
327 |
328 | start_angle1 = np.arctan2(current_y - c1_y, current_x - c1_x) * 180 / np.pi
329 | end_angle1 = np.arctan2(tan_pt1_y - c1_y, tan_pt1_x - c1_x) * 180 / np.pi
330 |
331 | arc1 = patches.Arc((c1_x, c1_y), 2*r_min,2*r_min,theta1=end_angle1, theta2=start_angle1)
332 | plt.gca().add_patch(arc1)
333 |
334 | start_angle2 = np.arctan2(tan_pt2_y - c2_y, tan_pt2_x - c2_x) * 180 / np.pi
335 | end_angle2 = np.arctan2(goal_y - c2_y, goal_x - c2_x) * 180 / np.pi
336 |
337 | arc2 = patches.Arc((c2_x, c2_y), 2*r_min,2*r_min,theta1=start_angle2, theta2=end_angle2)
338 | plt.gca().add_patch(arc2)
339 |
340 | # x = np.linspace(-10, 20, 100)
341 | # y = np.linspace(-10, 20, 100)
342 | # X, Y = np.meshgrid(x,y)
343 | # F = (X-c1_x)**2 + (Y-c1_y)**2 - r_min**2
344 | # F1 = (X-c2_x)**2 + (Y-c2_y)**2 - r_min**2
345 | # plt.contour(X,Y,F,[0])
346 | # plt.contour(X,Y,F1,[0])
347 | plt.gca().set_aspect('equal')
348 | plt.show()
349 |
350 | ans=[Ti,Tf, total_dist,S]
351 | return ans
352 |
353 |
354 | paths=[LSL,RSR,LSR,RSL]
355 | distance=sys.maxint
356 | ans=[]
357 | count=0
358 | ans_count=1
359 | path=""
360 | for i in paths:
361 | path_ans=i()
362 | count+=1
363 | if distance>path_ans[-2]:
364 | ans=path_ans
365 | distance=path_ans[-2]
366 | ans_count=count
367 |
368 | # print "Optimal Path: " ,paths[ans_count-1], "Total distance to cover: ",distance
369 | # LSL()
370 | # RSR()
371 | # LSR()
372 | # RSL()
373 |
374 |
--------------------------------------------------------------------------------
/dubins/gazebo_dubin.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import getch
3 | import roslib; roslib.load_manifest('p3dx_mover')
4 | import rospy
5 | import numpy as np
6 | import math
7 | import sys
8 |
9 | from nav_msgs.msg import Odometry
10 |
11 | from geometry_msgs.msg import Twist
12 |
13 | class A():
14 | def __init__(self):
15 | rospy.init_node('odometry')
16 | odom_sub=rospy.Subscriber('/odom',Odometry, self.callback)
17 | self.rate = rospy.Rate(10)
18 | self.PI=np.pi
19 |
20 | def callback(self, msg):
21 | self.current_x = round(msg.pose.pose.position.x, 4)
22 | self.current_y = round(msg.pose.pose.position.y, 4)
23 | self.q_w = round(msg.pose.pose.orientation.w ,4)
24 | self.q_x = round(msg.pose.pose.orientation.x ,4)
25 | self.q_y = round(msg.pose.pose.orientation.y ,4)
26 | self.q_z = round(msg.pose.pose.orientation.z ,4)
27 | siny = +2.0 * (self.q_w * self.q_z + self.q_x * self.q_y);
28 | cosy = +1.0 - 2.0 * (self.q_y * self.q_y + self.q_z * self.q_z);
29 | yaw = math.atan2(siny, cosy);
30 | self.current_th = yaw
31 |
32 | def LSL(self):
33 | c1_x=self.current_x-self.r_min*math.cos((self.current_th)-(self.PI/2)) #center of first circle of min_turning radius
34 | c1_y=self.current_y-self.r_min*math.sin((self.current_th)-(self.PI/2))
35 |
36 | c2_x=self.goal_x-self.r_min*math.cos(math.radians(self.goal_th)-(self.PI/2)) #center of second circle of min_turning radius
37 | c2_y=self.goal_y-self.r_min*math.sin(math.radians(self.goal_th)-(self.PI/2))
38 | #print c1_x,c1_y,c2_x,c2_y, c2_y-c1_y, c2_x-c1_x
39 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
40 |
41 | tan_pt1_x=c1_x+self.r_min*math.cos(theta) #tangent point in first circle of min_turning radius
42 | tan_pt1_y=c1_y-self.r_min*math.sin(theta)
43 |
44 | tan_pt2_x=c2_x+self.r_min*math.cos(theta) #tangent point in second circle of min_turning radius
45 | tan_pt2_y=c2_y-self.r_min*math.sin(theta)
46 |
47 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
48 |
49 | Ti = np.arctan2(self.current_x-c1_x,self.current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
50 |
51 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(self.goal_x - c2_x,self.goal_y- c2_y) #Final Turning angle
52 |
53 | if Ti<0:
54 | Ti+=2*np.pi
55 | if Tf<0:
56 | Tf+=2*np.pi
57 |
58 | total_dist = Ti*self.r_min + Tf*self.r_min + S #Total Distance from current to Goal
59 |
60 | #Ti= Ti*180/np.pi
61 | ans=[Ti,Tf, c1_x,c2_x,c1_y,c2_y,tan_pt1_x,tan_pt2_x,tan_pt1_y,tan_pt2_y,1,1,total_dist,S]
62 |
63 | return ans
64 |
65 | def RSR(self):
66 | c1_x=self.current_x+self.r_min*math.cos((self.current_th)-(self.PI/2)) #center of first circle of min_turning radius
67 | c1_y=self.current_y+self.r_min*math.sin((self.current_th)-(self.PI/2))
68 |
69 | c2_x=self.goal_x+self.r_min*math.cos(math.radians(self.goal_th)-(self.PI/2)) #center of second circle of min_turning radius
70 | c2_y=self.goal_y+self.r_min*math.sin(math.radians(self.goal_th)-(self.PI/2))
71 |
72 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
73 |
74 | tan_pt1_x=c1_x-self.r_min*math.cos(theta) #tangent point in first circle of min_turning radius
75 | tan_pt1_y=c1_y+self.r_min*math.sin(theta)
76 |
77 | tan_pt2_x=c2_x-self.r_min*math.cos(theta) #tangent point in second circle of min_turning radius
78 | tan_pt2_y=c2_y+self.r_min*math.sin(theta)
79 |
80 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
81 |
82 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(self.current_x-c1_x,self.current_y-c1_y) #Initial Turning angle
83 |
84 | Tf = np.arctan2(self.goal_x - c2_x,self.goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
85 |
86 | if Ti<0:
87 | Ti+=2*np.pi
88 | if Tf<0:
89 | Tf+=2*np.pi
90 |
91 | total_dist = Ti*self.r_min + Tf*self.r_min + S #Total Distance from current to Goal
92 |
93 | #Ti= Ti*180/np.pi
94 |
95 | ans=[Ti,Tf, c1_x,c2_x,c1_y,c2_y,tan_pt1_x,tan_pt2_x,tan_pt1_y,tan_pt2_y,-1,-1,total_dist,S]
96 | return ans
97 |
98 | def LSR(self):
99 | c1_x=self.current_x-self.r_min*math.cos((self.current_th)-(self.PI/2)) #center of first circle of min_turning radius
100 | c1_y=self.current_y-self.r_min*math.sin((self.current_th)-(self.PI/2))
101 |
102 | c2_x=self.goal_x+self.r_min*math.cos(math.radians(self.goal_th)-(self.PI/2)) #center of second circle of min_turning radius
103 | c2_y=self.goal_y+self.r_min*math.sin(math.radians(self.goal_th)-(self.PI/2))
104 |
105 | if c2_x-c1_x<0:
106 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*self.r_min))
107 | elif c2_x-c1_x>0:
108 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*self.r_min))
109 |
110 | tan_pt1_x=c1_x+self.r_min*math.cos(theta) #tangent point in first circle of min_turning radius
111 | tan_pt1_y=c1_y-self.r_min*math.sin(theta)
112 |
113 | tan_pt2_x=c2_x-self.r_min*math.cos(theta) #tangent point in second circle of min_turning radius
114 | tan_pt2_y=c2_y+self.r_min*math.sin(theta)
115 |
116 |
117 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
118 |
119 | S = 2*((-self.r_min**2 + (S1**2)/4.0 )**0.5)
120 |
121 | Ti = np.arctan2(self.current_x-c1_x,self.current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
122 |
123 | Tf = np.arctan2(self.goal_x - c2_x,self.goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
124 |
125 | if Ti<0:
126 | Ti+=2*np.pi
127 | if Tf<0:
128 | Tf+=2*np.pi
129 |
130 | total_dist = Ti*self.r_min + Tf*self.r_min + S #Total Distance from current to Goal
131 |
132 | #Ti= Ti*180/np.pi
133 |
134 | ans=[Ti,Tf, c1_x,c2_x,c1_y,c2_y,tan_pt1_x,tan_pt2_x,tan_pt1_y,tan_pt2_y,1,-1,total_dist,S]
135 | return ans
136 |
137 | def RSL(self):
138 | c1_x=self.current_x+self.r_min*math.cos((self.current_th)-(self.PI/2)) #center of first circle of min_turning radius
139 | c1_y=self.current_y+self.r_min*math.sin((self.current_th)-(self.PI/2))
140 |
141 | c2_x=self.goal_x-self.r_min*math.cos(math.radians(self.goal_th)-(self.PI/2)) #center of second circle of min_turning radius
142 | c2_y=self.goal_y-self.r_min*math.sin(math.radians(self.goal_th)-(self.PI/2))
143 |
144 | if c2_x-c1_x<0:
145 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*self.r_min))
146 | elif c2_x-c1_x>0:
147 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*self.r_min))
148 |
149 | tan_pt1_x=c1_x-self.r_min*math.cos(theta) #tangent point in first circle of min_turning radius
150 | tan_pt1_y=c1_y+self.r_min*math.sin(theta)
151 |
152 | tan_pt2_x=c2_x+self.r_min*math.cos(theta) #tangent point in second circle of min_turning radius
153 | tan_pt2_y=c2_y-self.r_min*math.sin(theta)
154 |
155 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
156 |
157 | S = 2*((-self.r_min**2 + (S1**2)/4.0 )**0.5)
158 |
159 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(self.current_x-c1_x,self.current_y-c1_y) #Initial Turning angle
160 |
161 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(self.goal_x - c2_x,self.goal_y- c2_y) #Final Turning angle
162 |
163 | if Ti<0:
164 | Ti+=2*np.pi
165 | if Tf<0:
166 | Tf+=2*np.pi
167 |
168 | total_dist = Ti*self.r_min + Tf*self.r_min + S #Total Distance from current to Goal
169 |
170 | #Ti= Ti*180/np.pi
171 |
172 | ans=[Ti,Tf, c1_x,c2_x,c1_y,c2_y,tan_pt1_x,tan_pt2_x,tan_pt1_y,tan_pt2_y,-1,1,total_dist,S]
173 | return ans
174 | def run(self):
175 | self.goal_x = input("x goal:")
176 | self.goal_y = input("y goal:")
177 | self.goal_th = input("theta goal: (Input in Degrees )")
178 |
179 | pub = rospy.Publisher('cmd_vel', Twist, queue_size=10)
180 | #rospy.init_node('p3dx_mover')
181 |
182 | twist = Twist()
183 |
184 | self.r_min = 2
185 |
186 | #samp=self.LSL()
187 |
188 |
189 |
190 | paths=[self.LSL,self.RSR,self.LSR,self.RSL]
191 | distance=sys.maxint
192 | ans=[]
193 | count=0
194 | ans_count=1
195 | path=""
196 | for i in paths:
197 | path_ans=i()
198 | count+=1
199 | if distance>path_ans[-2]:
200 | ans=path_ans
201 | distance=path_ans[-2]
202 | ans_count=count
203 |
204 | #print "Optimal Path: " ,paths[ans_count-1], "Total distance to cover: ",distance
205 | ans=self.LSL() #SELECT THE PATH HERE
206 | Ti=ans[0]
207 | Tf=ans[1]
208 | c1_x=ans[2]
209 | c2_x=ans[3]
210 | c1_y=ans[4]
211 | c2_y=ans[5]
212 | tan_pt1_x=ans[6]
213 | tan_pt2_x=ans[7]
214 | tan_pt1_y=ans[8]
215 | tan_pt2_y=ans[9]
216 | LoR1=ans[10]
217 | LoR2=ans[11]
218 | # c1_x=self.current_x-r_min*cos(self.current_th-self.PI/2)
219 | # c1_y=self.current_y-r_min*sin(self.current_th-self.PI/2)
220 |
221 | # c2_x=goal_x-r_min*cos(goal_th-self.PI/2)
222 | # c2_y=goal_y-r_min*sin(goal_th-self.PI/2)
223 |
224 | # theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
225 |
226 | # tan_pt1_x=c1_x+r_min*cos(theta)
227 | # tan_pt1_y=c1_y-r_min*sin(theta)
228 |
229 | # tan_pt2_x=c2_x+r_min*cos(theta)
230 | # tan_pt2_y=c2_y-r_min*sin(theta)
231 |
232 |
233 | # Ti = np.arctan2(self.current_x-c1_x,self.current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y)
234 |
235 | # Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y)
236 |
237 | # if Ti<0:
238 | # Ti+=2*np.pi
239 | # if Tf<0:
240 | # Tf+=2*np.pi
241 |
242 | # print c1_x,c1_y,tan_pt1_x,tan_pt1_y, tan_pt2_x,tan_pt2_y,Ti,Tf
243 | print ans
244 | dele=input("checkpoint (Enter any Number to continue)");
245 | print "initial configuration: ", self.current_x,self.current_y,self.current_th*180/self.PI
246 |
247 | linear_speed=0.2
248 | angular_speed=0.2/(self.r_min/0.808)
249 |
250 | twist.linear.x = 0
251 | twist.linear.y =0
252 | twist.linear.z =0
253 | twist.angular.x = 0
254 | twist.angular.y = 0
255 | twist.angular.z = 0
256 |
257 | twist.linear.x = abs(linear_speed)
258 | if LoR1==1:
259 | twist.angular.z = abs(angular_speed)
260 | elif LoR1==-1:
261 | twist.angular.z = -abs(angular_speed)
262 |
263 | # print ang_total
264 |
265 | err = math.sqrt( math.pow((tan_pt1_x-self.current_x),2) + math.pow((tan_pt1_y-self.current_y),2) )
266 |
267 | """while (err>0.01):
268 | pub.publish(twist)
269 | print self.current_x,",",self.current_y, "error", err
270 | err = sqrt( pow((tan_pt1_x-self.current_x),2) + pow((tan_pt1_y-self.current_y),2) )
271 | self.rate.sleep()"""
272 | errorf= math.sqrt( math.pow((tan_pt1_x-self.current_x),2) + math.pow((tan_pt1_y-self.current_y),2) )
273 | curr_x = self.current_x
274 | curr_y = self.current_y
275 | curr_yaw=self.current_th
276 | error_angle=(curr_yaw+Ti)*180/self.PI
277 | t1=rospy.get_time()
278 | while (errorf>0.1):
279 | pub.publish(twist)
280 | curr_x = self.current_x
281 | curr_y = self.current_y
282 | error_angle-=self.current_th
283 | print curr_x,",",curr_y, "error", errorf, error_angle
284 | errorf= math.sqrt( math.pow((tan_pt1_x-curr_x),2) + math.pow((tan_pt1_y-curr_y),2) )
285 | self.rate.sleep()
286 |
287 | twist.linear.x =0
288 | twist.angular.z = 0
289 | pub.publish(twist)
290 |
291 | print "configuration after first curve: ", self.current_x,self.current_y,self.current_th
292 | dele=input("checkpoint (Enter any Number to continue)");
293 | #exit()
294 |
295 | twist.linear.x = linear_speed
296 |
297 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
298 | distance=S*0.808#7.107#sqrt( pow((tan_pt2_x-tan_pt1_x),2) + pow((tan_pt2_y-tan_pt1_y),2) )
299 | distance_covered=0
300 | t1=rospy.get_time()
301 | while (distance_covered0.1):
330 | pub.publish(twist)
331 | err_goal = math.sqrt( math.pow((self.goal_x-self.current_x),2) + math.pow((self.goal_y-self.current_y),2) )
332 | if err_goal<0.5:
333 | break
334 | print self.current_x,",",self.current_y, "error", err_goal,errorf
335 | errorf= math.sqrt( math.pow((tan_pt2_x-self.current_x),2) + math.pow((tan_pt2_x-self.current_y),2) )
336 | self.rate.sleep()
337 |
338 | twist.linear.x =0
339 | twist.angular.z = 0
340 | pub.publish(twist)
341 |
342 | print "final configuration: ", self.current_x,self.current_y,self.current_th
343 |
344 |
345 | a=A()
346 | a.run()
--------------------------------------------------------------------------------
/rrt_dubins/Minkowski.py:
--------------------------------------------------------------------------------
1 | def minkowski_sum_circle(robot_radius,obstacle_radius):
2 | obstacle_radius+=2*robot_radius
3 | return obstacle_radius
4 |
5 |
6 | def minkowski_sum_square(robot_radius,obstacle_width):
7 | obstacle_width+=4*robot_radius
8 | return obstacle_width
--------------------------------------------------------------------------------
/rrt_dubins/gazebo_rrt_dubins.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import getch
3 | import roslib; roslib.load_manifest('p3dx_mover')
4 | import rospy
5 | import numpy as np
6 | import math
7 | import random
8 | import sys
9 | import copy
10 |
11 | from nav_msgs.msg import Odometry
12 |
13 | from geometry_msgs.msg import Twist
14 |
15 | class Node():
16 | def __init__(self,x,y):
17 | self.x=x
18 | self.y=y
19 | self.p=None
20 | self.tan_pt1_x=None
21 | self.tan_pt1_y=None
22 | self.tan_pt2_x=None
23 | self.tan_pt2_y=None
24 | self.Ti=None
25 | self.S=None
26 |
27 |
28 | class A():
29 | def __init__(self):
30 | rospy.init_node('odometry')
31 | odom_sub=rospy.Subscriber('/odom',Odometry, self.callback)
32 | self.rate = rospy.Rate(10)
33 | self.PI=np.pi
34 |
35 | def callback(self, msg):
36 | self.current_x = round(msg.pose.pose.position.x, 4)
37 | self.current_y = round(msg.pose.pose.position.y, 4)
38 | self.q_w = round(msg.pose.pose.orientation.w ,4)
39 | self.q_x = round(msg.pose.pose.orientation.x ,4)
40 | self.q_y = round(msg.pose.pose.orientation.y ,4)
41 | self.q_z = round(msg.pose.pose.orientation.z ,4)
42 | siny = +2.0 * (self.q_w * self.q_z + self.q_x * self.q_y);
43 | cosy = +1.0 - 2.0 * (self.q_y * self.q_y + self.q_z * self.q_z);
44 | yaw = math.atan2(siny, cosy);
45 | self.current_th = yaw
46 |
47 | def LSL(self,current_x,current_y,current_th,goal_x,goal_y,goal_th):
48 | c1_x=current_x-self.r_min*math.cos((current_th)-(self.PI/2)) #center of first circle of min_turning radius
49 | c1_y=current_y-self.r_min*math.sin((current_th)-(self.PI/2))
50 |
51 | c2_x=goal_x-self.r_min*math.cos(math.radians(goal_th)-(self.PI/2)) #center of second circle of min_turning radius
52 | c2_y=goal_y-self.r_min*math.sin(math.radians(goal_th)-(self.PI/2))
53 | #print c1_x,c1_y,c2_x,c2_y, c2_y-c1_y, c2_x-c1_x
54 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
55 |
56 | tan_pt1_x=c1_x+self.r_min*math.cos(theta) #tangent point in first circle of min_turning radius
57 | tan_pt1_y=c1_y-self.r_min*math.sin(theta)
58 |
59 | tan_pt2_x=c2_x+self.r_min*math.cos(theta) #tangent point in second circle of min_turning radius
60 | tan_pt2_y=c2_y-self.r_min*math.sin(theta)
61 |
62 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
63 |
64 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
65 |
66 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
67 |
68 | if Ti<0:
69 | Ti+=2*np.pi
70 | if Tf<0:
71 | Tf+=2*np.pi
72 |
73 | total_dist = Ti*self.r_min + Tf*self.r_min + S #Total Distance from current to Goal
74 |
75 | #Ti= Ti*180/np.pi
76 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LL"]
77 |
78 | return ans
79 |
80 | def RSR(self,current_x,current_y,current_th,goal_x,goal_y,goal_th):
81 | c1_x=current_x+self.r_min*math.cos((current_th)-(self.PI/2)) #center of first circle of min_turning radius
82 | c1_y=current_y+self.r_min*math.sin((current_th)-(self.PI/2))
83 |
84 | c2_x=goal_x+self.r_min*math.cos(math.radians(goal_th)-(self.PI/2)) #center of second circle of min_turning radius
85 | c2_y=goal_y+self.r_min*math.sin(math.radians(goal_th)-(self.PI/2))
86 |
87 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
88 |
89 | tan_pt1_x=c1_x-self.r_min*math.cos(theta) #tangent point in first circle of min_turning radius
90 | tan_pt1_y=c1_y+self.r_min*math.sin(theta)
91 |
92 | tan_pt2_x=c2_x-self.r_min*math.cos(theta) #tangent point in second circle of min_turning radius
93 | tan_pt2_y=c2_y+self.r_min*math.sin(theta)
94 |
95 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
96 |
97 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
98 |
99 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
100 |
101 | if Ti<0:
102 | Ti+=2*np.pi
103 | if Tf<0:
104 | Tf+=2*np.pi
105 |
106 | total_dist = Ti*self.r_min + Tf*self.r_min + S #Total Distance from current to Goal
107 |
108 | #Ti= Ti*180/np.pi
109 |
110 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RR"]
111 | return ans
112 |
113 | def LSR(self,current_x,current_y,current_th,goal_x,goal_y,goal_th):
114 | c1_x=current_x-self.r_min*math.cos((current_th)-(self.PI/2)) #center of first circle of min_turning radius
115 | c1_y=current_y-self.r_min*math.sin((current_th)-(self.PI/2))
116 |
117 | c2_x=goal_x+self.r_min*math.cos(math.radians(goal_th)-(self.PI/2)) #center of second circle of min_turning radius
118 | c2_y=goal_y+self.r_min*math.sin(math.radians(goal_th)-(self.PI/2))
119 |
120 | if c2_x-c1_x<0:
121 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*self.r_min))
122 | elif c2_x-c1_x>0:
123 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*self.r_min))
124 |
125 | tan_pt1_x=c1_x+self.r_min*math.cos(theta) #tangent point in first circle of min_turning radius
126 | tan_pt1_y=c1_y-self.r_min*math.sin(theta)
127 |
128 | tan_pt2_x=c2_x-self.r_min*math.cos(theta) #tangent point in second circle of min_turning radius
129 | tan_pt2_y=c2_y+self.r_min*math.sin(theta)
130 |
131 |
132 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
133 |
134 | if(-self.r_min**2 + (S1**2)/4.0 )<0:
135 | # print"Holaaaaaa"
136 | return None
137 |
138 | S = 2*((-self.r_min**2 + (S1**2)/4.0 )**0.5)
139 |
140 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
141 |
142 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
143 |
144 | if Ti<0:
145 | Ti+=2*np.pi
146 | if Tf<0:
147 | Tf+=2*np.pi
148 |
149 | total_dist = Ti*self.r_min + Tf*self.r_min + S #Total Distance from current to Goal
150 |
151 | #Ti= Ti*180/np.pi
152 |
153 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LR"]
154 | return ans
155 |
156 | def RSL(self,current_x,current_y,current_th,goal_x,goal_y,goal_th):
157 | c1_x=current_x+self.r_min*math.cos((current_th)-(self.PI/2)) #center of first circle of min_turning radius
158 | c1_y=current_y+self.r_min*math.sin((current_th)-(self.PI/2))
159 |
160 | c2_x=goal_x-self.r_min*math.cos(math.radians(goal_th)-(self.PI/2)) #center of second circle of min_turning radius
161 | c2_y=goal_y-self.r_min*math.sin(math.radians(goal_th)-(self.PI/2))
162 |
163 | if c2_x-c1_x<0:
164 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*self.r_min))
165 | elif c2_x-c1_x>0:
166 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*self.r_min))
167 |
168 | tan_pt1_x=c1_x-self.r_min*math.cos(theta) #tangent point in first circle of min_turning radius
169 | tan_pt1_y=c1_y+self.r_min*math.sin(theta)
170 |
171 | tan_pt2_x=c2_x+self.r_min*math.cos(theta) #tangent point in second circle of min_turning radius
172 | tan_pt2_y=c2_y-self.r_min*math.sin(theta)
173 |
174 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
175 |
176 | if(-self.r_min**2 + (S1**2)/4.0 )<0:
177 | # print"Holaaaaaa"
178 | return None
179 |
180 | S = 2*((-self.r_min**2 + (S1**2)/4.0 )**0.5)
181 |
182 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
183 |
184 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
185 |
186 | if Ti<0:
187 | Ti+=2*np.pi
188 | if Tf<0:
189 | Tf+=2*np.pi
190 |
191 | total_dist = Ti*self.r_min + Tf*self.r_min + S #Total Distance from current to Goal
192 |
193 | #Ti= Ti*180/np.pi
194 |
195 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RL"]
196 | # 0. 1. 2 3. 4. 5. 6. 7. 8. 9. 10. 11 12
197 | return ans
198 |
199 | def findNearest(self,sample,tree):
200 | min_d = sys.maxint
201 | ind=0
202 | min_node=tree[0]
203 | for indd,node in enumerate(tree):
204 | dis = ((node.x-sample.x)**2 + (node.y-sample.y)**2)**0.5
205 | if min_d>dis:
206 | min_d=dis
207 | min_node=node
208 | ind=indd
209 | return min_node,ind
210 |
211 | def run(self):
212 | self.goal_x = input("x goal:")
213 | self.goal_y = input("y goal:")
214 | self.goal_th = input("theta goal: (Input in Degrees )")
215 |
216 | current_x=0
217 | current_y=0
218 | current_th=0
219 |
220 | pub = rospy.Publisher('cmd_vel', Twist, queue_size=10)
221 | #rospy.init_node('p3dx_mover')
222 |
223 | step=5
224 |
225 | twist = Twist()
226 |
227 | self.r_min = 1
228 |
229 | #samp=self.LSL()
230 |
231 | tree = [Node(current_x,current_y)]
232 |
233 | initial=[]
234 |
235 | j=0
236 | while True:
237 | j+=1
238 | sample = Node(random.uniform(0,11),random.uniform(0,11))
239 | nearestNode,ind = self.findNearest(sample,tree)
240 | newNode = copy.deepcopy(nearestNode)
241 |
242 | theta = (np.arctan2(sample.y-nearestNode.y, sample.x-nearestNode.x))
243 | newNode.x+=step*math.cos(theta)
244 | newNode.y+=step*math.sin(theta)
245 |
246 | theta_start = theta
247 | theta_end = (np.arctan2(newNode.y-self.goal_y, newNode.x-self.goal_x))
248 |
249 |
250 | paths=[self.LSL,self.RSR,self.LSR,self.RSL]
251 | minS=sys.maxint
252 | ans=[]
253 | count=0
254 | curve=""
255 | ans_count=1
256 | for i in paths:
257 | path_ans=i(nearestNode.x,nearestNode.y,theta_start,newNode.x,newNode.y,theta_end)
258 | count+=1
259 | if path_ans:
260 | if minS>path_ans[3]:
261 | ans=path_ans
262 | minS=path_ans[3]
263 | ans_count=count
264 | curve=path_ans[12]
265 |
266 | newNode.p=ind
267 | nearestNode.tan_pt1_x=ans[4]
268 | nearestNode.tan_pt1_y=ans[5]
269 | nearestNode.tan_pt2_x=ans[6]
270 | nearestNode.tan_pt2_y=ans[7]
271 | nearestNode.S=ans[3]
272 | nearestNode.curve=curve
273 | nearestNode.Ti=ans[0]
274 |
275 | if j==1:
276 | initial.append([ans[4],ans[5],ans[6],ans[7],ans[3],curve])
277 |
278 | # if ((newNode.x-3)**2 + (newNode.y-3)**2)**0.5 < 1:
279 | # continue
280 | # if ((newNode.x-6)**2 + (newNode.y-5)**2)**0.5 < 1:
281 | # continue
282 | # if newNode.x>10 or newNode.y>10 or newNode.x<0 or newNode.y<0:
283 | # continue
284 | tree.append(newNode)
285 | if ((newNode.x-self.goal_x)**2 + (newNode.y-self.goal_y)**2)**0.5 < step:
286 | break
287 |
288 | paths=[self.LSL,self.RSR,self.LSR,self.RSL]
289 | minS=sys.maxint
290 | ans=[]
291 | count=0
292 | ans_count=1
293 | for i in paths:
294 | path_ans=i(newNode.x,newNode.y,0,self.goal_x,self.goal_y,self.goal_th)
295 | count+=1
296 | if path_ans:
297 | if minS>path_ans[3]:
298 | ans=path_ans
299 | minS=path_ans[3]
300 | ans_count=count
301 |
302 | newNode.tan_pt1_x=ans[4]
303 | newNode.tan_pt1_y=ans[5]
304 | newNode.tan_pt2_x=ans[6]
305 | newNode.tan_pt2_y=ans[7]
306 | newNode.S=ans[3]
307 | newNode.curve=curve
308 | newNode.Ti=ans[0]
309 |
310 |
311 | # path=[[newNode.x,newNode.y]]
312 | # while True:
313 | # if not newNode.p:
314 | # break
315 | # path.append([tree[newNode.p].x,tree[newNode.p].y])
316 | # newNode=tree[newNode.p]
317 |
318 | path_w_angles=[[newNode.tan_pt1_x,newNode.tan_pt1_y,newNode.tan_pt2_x,newNode.tan_pt2_y,newNode.S,newNode.curve,newNode.Ti]]
319 | while True:
320 | if not newNode.p:
321 | break
322 | path_w_angles.append([tree[newNode.p].tan_pt1_x,tree[newNode.p].tan_pt1_y,tree[newNode.p].tan_pt2_x,tree[newNode.p].tan_pt2_y,tree[newNode.p].S,tree[newNode.p].curve,tree[newNode.p].Ti])
323 | newNode=tree[newNode.p]
324 |
325 | path_w_angles.append(initial[0])
326 |
327 |
328 | # x=[self.goal_x]
329 | # y=[self.goal_y]
330 | # for i in path:
331 | # x.append(i[0])
332 | # y.append(i[1])
333 | # x.append(current_x)
334 | # y.append(current_y)
335 | # print x,y
336 |
337 |
338 | for ans in path_w_angles:
339 |
340 | tan_pt1_x=ans[0]
341 | tan_pt1_y=ans[1]
342 | tan_pt2_x=ans[2]
343 | tan_pt2_y=ans[3]
344 | S = ans[4]
345 | LoR1=ans[5][0]
346 | LoR2=ans[5][1]
347 |
348 | dele=input("checkpoint");
349 | print "initial configuration: ", self.current_x,self.current_y,self.current_th*180/self.PI
350 |
351 | linear_speed=0.2
352 | angular_speed=0.2/(self.r_min/0.808)
353 |
354 | twist.linear.x = 0
355 | twist.linear.y =0
356 | twist.linear.z =0
357 | twist.angular.x = 0
358 | twist.angular.y = 0
359 | twist.angular.z = 0
360 |
361 | twist.linear.x = abs(linear_speed)
362 | if LoR1=='L':
363 | twist.angular.z = abs(angular_speed)
364 | elif LoR1=='R':
365 | twist.angular.z = -abs(angular_speed)
366 |
367 |
368 | errorf= math.sqrt( math.pow((tan_pt1_x-self.current_x),2) + math.pow((tan_pt1_y-self.current_y),2) )
369 | curr_x = self.current_x
370 | curr_y = self.current_y
371 | curr_yaw=self.current_th
372 |
373 | t1=rospy.get_time()
374 | while (errorf>0.1):
375 | pub.publish(twist)
376 | curr_x = self.current_x
377 | curr_y = self.current_y
378 | print curr_x,",",curr_y, "error", errorf
379 | errorf= math.sqrt( math.pow((tan_pt1_x-curr_x),2) + math.pow((tan_pt1_y-curr_y),2) )
380 | self.rate.sleep()
381 |
382 | twist.linear.x =0
383 | twist.angular.z = 0
384 | pub.publish(twist)
385 |
386 | print "configuration after first curve: ", self.current_x,self.current_y,self.current_th
387 | dele=input("checkpoint");
388 |
389 | twist.linear.x = linear_speed
390 |
391 | distance=S*0.808#7.107#sqrt( pow((tan_pt2_x-tan_pt1_x),2) + pow((tan_pt2_y-tan_pt1_y),2) )
392 | distance_covered=0
393 | t1=rospy.get_time()
394 | while (distance_covered0.1):
423 | pub.publish(twist)
424 | err_goal = math.sqrt( math.pow((self.goal_x-self.current_x),2) + math.pow((self.goal_y-self.current_y),2) )
425 | if err_goal<0.5:
426 | break
427 | print self.current_x,",",self.current_y, "error", err_goal,errorf
428 | errorf= math.sqrt( math.pow((tan_pt2_x-self.current_x),2) + math.pow((tan_pt2_x-self.current_y),2) )
429 | self.rate.sleep()
430 |
431 | twist.linear.x =0
432 | twist.angular.z = 0
433 | pub.publish(twist)
434 |
435 | print "final configuration: ", self.current_x,self.current_y,self.current_th
436 |
437 |
438 | a=A()
439 | a.run()
--------------------------------------------------------------------------------
/rrt_dubins/rrt_dubin.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | import matplotlib.patches as patches
4 | import math
5 | import Minkowski
6 | import random
7 | from matplotlib.patches import Arc
8 | import sys
9 | # import dubins
10 | import copy
11 |
12 | class Node():
13 | def __init__(self,x,y):
14 | self.x=x
15 | self.y=y
16 | self.p=None
17 | self.tan_pt1_x=None
18 | self.tan_pt1_y=None
19 | self.tan_pt2_x=None
20 | self.tan_pt2_y=None
21 | self.Ti=None
22 | self.S=None
23 |
24 | plt.axis([-20, 20, -20, 20])
25 | # rectangle = plt.Rectangle((0.2, 0.2), 0.2, 0.2)
26 | # plt.gca().add_patch(rectangle)
27 |
28 | obs = plt.Circle((3, 3), radius=1, fc='r')
29 | plt.gca().add_patch(obs)
30 |
31 | obs = plt.Circle((6, 5), radius=1, fc='r')
32 | plt.gca().add_patch(obs)
33 |
34 | # obs = plt.Circle((7, 3), radius=1, fc='r')
35 | # plt.gca().add_patch(obs)
36 |
37 | # obs = plt.Circle((6, 5), radius=1, fc='r')
38 | # plt.gca().add_patch(obs)
39 |
40 | rectangle = plt.Rectangle((0, 0), 1, 1,fill=False)
41 | plt.gca().add_patch(rectangle)
42 |
43 |
44 | current_x=0
45 | current_y=0
46 | current_th=0 #current angle in Degrees
47 |
48 | PI=3.14
49 | r_min=0.2
50 | step=2
51 |
52 | goal_x=8
53 | goal_y=8
54 | goal_th=0 #goal angle in Degrees
55 |
56 | goal_circle = plt.Circle((8, 8), radius=1, fc='y')
57 | plt.gca().add_patch(goal_circle)
58 |
59 | plt.axis('scaled')
60 | # goal_circle =
61 | #plt.show()
62 |
63 | tree = [Node(current_x,current_y)]
64 |
65 | def check_obstacle(x,y,obs_x,obs_y):
66 | obstacle_radius = Minkowski.minkowski_sum_circle(0.2,0.6)
67 | if ((x-obs_x)**2 + (y-obs_y)**2)**0.5 < obstacle_radius+0.5:
68 | return True
69 | return False
70 | def LSL(current_x,current_y,current_th,goal_x,goal_y,goal_th):
71 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
72 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
73 |
74 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
75 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
76 | #print c1_x,c1_y,c2_x,c2_y, c2_y-c1_y, c2_x-c1_x
77 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
78 |
79 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
80 | tan_pt1_y=c1_y-r_min*math.sin(theta)
81 |
82 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
83 | tan_pt2_y=c2_y-r_min*math.sin(theta)
84 |
85 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
86 | # print S,theta
87 | # print (tan_pt1_x,tan_pt1_y)
88 | # print (tan_pt2_x,tan_pt2_y)
89 | # print (c1_x,c1_y,c2_x,c2_y)
90 |
91 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
92 |
93 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
94 |
95 | if Ti<0:
96 | Ti+=2*np.pi
97 | if Tf<0:
98 | Tf+=2*np.pi
99 |
100 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
101 |
102 | # Ti= Ti*180/np.pi
103 |
104 | # print Ti,Tf, total_dist,S
105 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LL"]
106 |
107 | return ans
108 |
109 | def RSR(current_x,current_y,current_th,goal_x,goal_y,goal_th):
110 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
111 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
112 |
113 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
114 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
115 |
116 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
117 |
118 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
119 | tan_pt1_y=c1_y+r_min*math.sin(theta)
120 |
121 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
122 | tan_pt2_y=c2_y+r_min*math.sin(theta)
123 |
124 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
125 |
126 | # print (tan_pt1_x,tan_pt1_y)
127 | # print (tan_pt2_x,tan_pt2_y)
128 | # print (c2_x,c2_y)
129 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
130 |
131 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
132 |
133 | if Ti<0:
134 | Ti+=2*np.pi
135 | if Tf<0:
136 | Tf+=2*np.pi
137 |
138 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
139 |
140 | Ti= Ti*180/np.pi
141 |
142 |
143 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RR"]
144 | return ans
145 |
146 | def LSR(current_x,current_y,current_th,goal_x,goal_y,goal_th):
147 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
148 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
149 |
150 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
151 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
152 |
153 | # if c2_x-c1_x<0:
154 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
155 | # elif c2_x-c1_x>0:
156 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
157 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
158 |
159 | if(-r_min**2 + (S1**2)/4.0 )<0:
160 | # print"Holaaaaaa"
161 | return None
162 |
163 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
164 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y)) - np.arctan2(r_min,S/2.0)
165 |
166 |
167 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
168 | tan_pt1_y=c1_y-r_min*math.sin(theta)
169 |
170 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
171 | tan_pt2_y=c2_y+r_min*math.sin(theta)
172 |
173 |
174 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
175 |
176 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
177 |
178 | if Ti<0:
179 | Ti+=2*np.pi
180 | if Tf<0:
181 | Tf+=2*np.pi
182 |
183 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
184 |
185 | Ti= Ti*180/np.pi
186 | print Ti, current_x,current_y,current_th,goal_x,goal_y,goal_th
187 |
188 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LR"]
189 | return ans
190 |
191 | def RSL(current_x,current_y,current_th,goal_x,goal_y,goal_th):
192 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
193 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
194 |
195 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
196 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
197 |
198 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
199 | # print (tan_pt1_x,tan_pt1_y)
200 | # print (tan_pt2_x,tan_pt2_y)
201 | if(-r_min**2 + (S1**2)/4.0 )<0:
202 | # print"Holaaaaaa"
203 | return None
204 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
205 |
206 | # if c2_x-c1_x<0:
207 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
208 | # elif c2_x-c1_x>0:
209 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
210 |
211 | theta = + (np.arctan2((c2_x-c1_x), c2_y-c1_y)) + np.arctan2(r_min,S/2.0)
212 |
213 | print "THETA ", theta, "c1_x =",c1_x, c1_y,c2_x,c2_y,"S=",S
214 |
215 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
216 | tan_pt1_y=c1_y+r_min*math.sin(theta)
217 |
218 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
219 | tan_pt2_y=c2_y-r_min*math.sin(theta)
220 |
221 |
222 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
223 |
224 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
225 |
226 | if Ti<0:
227 | Ti+=2*np.pi
228 | if Tf<0:
229 | Tf+=2*np.pi
230 |
231 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
232 |
233 | Ti= Ti*180/np.pi
234 | print Ti, current_x,current_y,current_th,goal_x,goal_y,goal_th
235 |
236 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RL"]
237 | # 0 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11
238 | return ans
239 |
240 |
241 | def findNearest(sample):
242 | min_d = sys.maxint
243 | ind=0
244 | min_node=tree[0]
245 | for indd,node in enumerate(tree):
246 | dis = ((node.x-sample.x)**2 + (node.y-sample.y)**2)**0.5
247 | if min_d>dis:
248 | min_d=dis
249 | min_node=node
250 | ind=indd
251 | return min_node,ind
252 |
253 | def RRT():
254 | j=0
255 | initial=[]
256 | theta_end=None
257 | while True:
258 | j+=1
259 | # if j>5:
260 | # break
261 | sample = Node(random.uniform(0,11),random.uniform(0,11))
262 | nearestNode,ind = findNearest(sample)
263 | newNode = copy.deepcopy(nearestNode)
264 |
265 | theta = (np.arctan2(sample.y-nearestNode.y, sample.x-nearestNode.x))
266 | newNode.x+=step*math.cos(theta)
267 | newNode.y+=step*math.sin(theta)
268 |
269 | # ansLSL=LSL(nearestNode.x,nearestNode.y,0,newNode.x,newNode.y,0)
270 | # if
271 |
272 | theta_start = theta
273 | theta_end = (np.arctan2(newNode.y-goal_y, newNode.x-goal_x))
274 |
275 |
276 | paths=[LSL,RSR,LSR,RSL]
277 | minS=sys.maxint
278 | ans=[]
279 | count=0
280 | curve=""
281 | ans_count=1
282 | for i in paths:
283 | path_ans=i(nearestNode.x,nearestNode.y,theta_start,newNode.x,newNode.y,theta_end)
284 | count+=1
285 | if path_ans:
286 | if minS>path_ans[3]:
287 | ans=path_ans
288 | minS=path_ans[3]
289 | ans_count=count
290 | curve=path_ans[12]
291 |
292 | plt.plot([ans[4],ans[6]],[ans[5],ans[7]])
293 |
294 | start_angle1 = np.arctan2(nearestNode.y - ans[9], nearestNode.x - ans[8]) * 180 / np.pi
295 | end_angle1 = np.arctan2(ans[5] - ans[9], ans[4] - ans[8]) * 180 / np.pi
296 |
297 | if curve[0]=="L":
298 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=start_angle1, theta2=end_angle1)
299 | else:
300 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=end_angle1, theta2=start_angle1)
301 | plt.gca().add_patch(arc1)
302 |
303 | start_angle2 = np.arctan2(ans[7] - ans[11], ans[6] - ans[10]) * 180 / np.pi
304 | end_angle2 = np.arctan2(newNode.y - ans[11], newNode.x - ans[10]) * 180 / np.pi
305 |
306 | if curve[1]=="L":
307 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=start_angle2, theta2=end_angle2)
308 | else:
309 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=end_angle2, theta2=start_angle2)
310 |
311 | plt.gca().add_patch(arc2)
312 |
313 | plt.gca().set_aspect('equal')
314 |
315 | # ans = LSL(nearestNode.x,nearestNode.y,0,newNode.x,newNode.y,0)
316 |
317 | newNode.p=ind
318 | nearestNode.tan_pt1_x=ans[4]
319 | nearestNode.tan_pt1_y=ans[5]
320 | nearestNode.tan_pt2_x=ans[6]
321 | nearestNode.tan_pt2_y=ans[7]
322 | nearestNode.S=ans[3]
323 | nearestNode.curve=curve
324 | nearestNode.Ti=ans[0]
325 | if j==1:
326 | initial.append([ans[4],ans[5],ans[6],ans[7],ans[3],curve,ans[0]])
327 |
328 | # if ((newNode.x-3)**2 + (newNode.y-3)**2)**0.5 < 1:
329 | # continue
330 | # if ((newNode.x-6)**2 + (newNode.y-5)**2)**0.5 < 1:
331 | # continue
332 | if check_obstacle(newNode.x,newNode.y,3,3):
333 | continue
334 | if check_obstacle(newNode.x,newNode.y,6,5):
335 | continue
336 | # if check_obstacle(newNode.x,newNode.y,3,6):
337 | # continue
338 | # if check_obstacle(newNode.x,newNode.y,6,5):
339 | # continue
340 | if newNode.x>10 or newNode.y>10 or newNode.x<0 or newNode.y<0:
341 | continue
342 | tree.append(newNode)
343 | if ((newNode.x-goal_x)**2 + (newNode.y-goal_y)**2)**0.5 < step:
344 | break
345 |
346 | # print tree[0].Ti
347 |
348 | paths=[LSL,RSR,LSR,RSL]
349 | minS=sys.maxint
350 | ans=[]
351 | count=0
352 | ans_count=1
353 | for i in paths:
354 | path_ans=i(newNode.x,newNode.y,theta_end,goal_x,goal_y,goal_th)
355 | count+=1
356 | if path_ans:
357 | if minS>path_ans[3]:
358 | ans=path_ans
359 | minS=path_ans[3]
360 | ans_count=count
361 | curve=path_ans[12]
362 |
363 | newNode.tan_pt1_x=ans[4]
364 | newNode.tan_pt1_y=ans[5]
365 | newNode.tan_pt2_x=ans[6]
366 | newNode.tan_pt2_y=ans[7]
367 | newNode.S=ans[3]
368 | newNode.curve=curve
369 | newNode.Ti=ans[0]
370 |
371 | plt.plot([ans[4],ans[6]],[ans[5],ans[7]])
372 |
373 | start_angle1 = np.arctan2(newNode.y - ans[9], newNode.x - ans[8]) * 180 / np.pi
374 | end_angle1 = np.arctan2(ans[5] - ans[9], ans[4] - ans[8]) * 180 / np.pi
375 |
376 | if curve[0]=="L":
377 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=start_angle1, theta2=end_angle1)
378 | else:
379 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=end_angle1, theta2=start_angle1)
380 | plt.gca().add_patch(arc1)
381 |
382 | start_angle2 = np.arctan2(ans[7] - ans[11], ans[6] - ans[10]) * 180 / np.pi
383 | end_angle2 = np.arctan2(goal_y - ans[11], goal_x - ans[10]) * 180 / np.pi
384 |
385 | if curve[1]=="L":
386 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=start_angle2, theta2=end_angle2)
387 | else:
388 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=end_angle2, theta2=start_angle2)
389 |
390 | plt.gca().add_patch(arc2)
391 |
392 | plt.gca().set_aspect('equal')
393 |
394 | newNode1 = copy.deepcopy(newNode)
395 |
396 | path=[[newNode.x,newNode.y]]
397 | while True:
398 | if not newNode.p:
399 | break
400 | #plt.plot([newNode.x,newNode.y],[tree[newNode.p].x,tree[newNode.p].y],'ro-')
401 | path.append([tree[newNode.p].x,tree[newNode.p].y])
402 | newNode=tree[newNode.p]
403 |
404 | path_w_angles=[[newNode1.tan_pt1_x,newNode1.tan_pt1_y,newNode1.tan_pt2_x,newNode1.tan_pt2_y,newNode1.S,newNode1.curve,newNode1.Ti]]
405 | while True:
406 | if not newNode1.p:
407 | break
408 | path_w_angles.append([tree[newNode1.p].tan_pt1_x,tree[newNode1.p].tan_pt1_y,tree[newNode1.p].tan_pt2_x,tree[newNode1.p].tan_pt2_y,tree[newNode1.p].S,tree[newNode1.p].curve,tree[newNode1.p].Ti])
409 | newNode1=tree[newNode1.p]
410 | path_w_angles.append(initial[0])
411 |
412 | path_w_angles=path_w_angles[::-1]
413 | #path_w_angles=[[0.11382975330055782, 0.03707606850741252, 1.550462272816677, 1.0601573107627982, 1.76369164662819, 'LR', 34.829836137384575], [1.8537386028505958, 1.3667442952423527, 1.3133630638948597, 2.820859157341914, 1.5512755252631716, 'LR', 108.68731498468217], [1.7125078645071232, 3.2591611478524074, 1.802594876855204, 3.8311177818676017, 0.579007824634343, 'LR', 83.07015853891144]]
414 |
415 | x=[goal_x]
416 | y=[goal_y]
417 | for i in path:
418 | x.append(i[0])
419 | y.append(i[1])
420 | x.append(current_x)
421 | y.append(current_y)
422 | # print x,y
423 | plt.plot(x, y, '-ro',alpha=0.2)
424 | print path_w_angles, len(path_w_angles), len(path)
425 | plt.show()
426 | RRT()
427 | # RSL(0.151237017246, 1.99427364336, 1.20720741966, 0.862498625581, 3.86352668255, -2.74749039623)
--------------------------------------------------------------------------------
/rrt_dubins/rrt_dubin_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_dubins/rrt_dubin_2.png
--------------------------------------------------------------------------------
/rrt_dubins/rrt_dubin_2_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_dubins/rrt_dubin_2_2.png
--------------------------------------------------------------------------------
/rrt_dubins/rrt_dubin_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_dubins/rrt_dubin_4.png
--------------------------------------------------------------------------------
/rrt_dubins/rrt_dubin_4_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_dubins/rrt_dubin_4_1.png
--------------------------------------------------------------------------------
/rrt_star_dubins/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_star_dubins/.DS_Store
--------------------------------------------------------------------------------
/rrt_star_dubins/Figure1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_star_dubins/Figure1.png
--------------------------------------------------------------------------------
/rrt_star_dubins/Figure2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_star_dubins/Figure2.png
--------------------------------------------------------------------------------
/rrt_star_dubins/rrt_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_star_dubins/rrt_star.png
--------------------------------------------------------------------------------
/rrt_star_dubins/rrt_star_dubins.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | import matplotlib.patches as patches
4 | import math
5 | import random
6 | import sys
7 | import copy
8 |
9 | class Node():
10 | def __init__(self,x,y):
11 | self.x=x
12 | self.y=y
13 | self.p=None
14 | self.cost=0
15 |
16 | plt.axis([-0.1, 1.1, -0.1, 1.1])
17 | # rectangle = plt.Rectangle((0.2, 0.2), 0.2, 0.2)
18 | # plt.gca().add_patch(rectangle)
19 |
20 | obs = plt.Circle((0.3, 0.3), radius=0.1, fc='r')
21 | plt.gca().add_patch(obs)
22 |
23 | obs = plt.Circle((0.6, 0.5), radius=0.2, fc='r')
24 | plt.gca().add_patch(obs)
25 |
26 | obs = plt.Circle((0.3, 0.5), radius=0.1, fc='r')
27 | plt.gca().add_patch(obs)
28 |
29 | obstacles = [(0.3,0.3,0.1),(0.6,0.5,0.2),(0.3,0.5,0.1)]
30 |
31 | rectangle = plt.Rectangle((0, 0), 1, 1,fill=False)
32 | plt.gca().add_patch(rectangle)
33 |
34 |
35 | current_x=0
36 | current_y=0
37 | current_th=0 #current angle in Degrees
38 |
39 | PI=3.14
40 | r_min=0.02
41 | step=0.3
42 |
43 | goal_x=0.8
44 | goal_y=0.8
45 | goal_th=0 #goal angle in Degrees
46 |
47 | goal_circle = plt.Circle((0.8, 0.8), radius=0.1, fc='b')
48 | plt.gca().add_patch(goal_circle)
49 |
50 | plt.axis('scaled')
51 | # goal_circle =
52 | #plt.show()
53 |
54 | def LSL(current_x,current_y,current_th,goal_x,goal_y,goal_th):
55 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
56 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
57 |
58 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
59 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
60 | #print c1_x,c1_y,c2_x,c2_y, c2_y-c1_y, c2_x-c1_x
61 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
62 |
63 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
64 | tan_pt1_y=c1_y-r_min*math.sin(theta)
65 |
66 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
67 | tan_pt2_y=c2_y-r_min*math.sin(theta)
68 |
69 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
70 | # print S,theta
71 | # print (tan_pt1_x,tan_pt1_y)
72 | # print (tan_pt2_x,tan_pt2_y)
73 | # print (c1_x,c1_y,c2_x,c2_y)
74 |
75 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
76 |
77 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
78 |
79 | if Ti<0:
80 | Ti+=2*np.pi
81 | if Tf<0:
82 | Tf+=2*np.pi
83 |
84 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
85 |
86 | # Ti= Ti*180/np.pi
87 |
88 | # print Ti,Tf, total_dist,S
89 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LL"]
90 |
91 | return ans
92 |
93 | def RSR(current_x,current_y,current_th,goal_x,goal_y,goal_th):
94 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
95 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
96 |
97 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
98 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
99 |
100 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
101 |
102 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
103 | tan_pt1_y=c1_y+r_min*math.sin(theta)
104 |
105 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
106 | tan_pt2_y=c2_y+r_min*math.sin(theta)
107 |
108 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
109 |
110 | # print (tan_pt1_x,tan_pt1_y)
111 | # print (tan_pt2_x,tan_pt2_y)
112 | # print (c2_x,c2_y)
113 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
114 |
115 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
116 |
117 | if Ti<0:
118 | Ti+=2*np.pi
119 | if Tf<0:
120 | Tf+=2*np.pi
121 |
122 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
123 |
124 | Ti= Ti*180/np.pi
125 |
126 |
127 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RR"]
128 | return ans
129 |
130 | def LSR(current_x,current_y,current_th,goal_x,goal_y,goal_th):
131 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
132 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
133 |
134 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
135 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
136 |
137 | # if c2_x-c1_x<0:
138 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
139 | # elif c2_x-c1_x>0:
140 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
141 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
142 |
143 | if(-r_min**2 + (S1**2)/4.0 )<0:
144 | # print"Holaaaaaa"
145 | return None
146 |
147 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
148 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y)) - np.arctan2(r_min,S/2.0)
149 |
150 |
151 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
152 | tan_pt1_y=c1_y-r_min*math.sin(theta)
153 |
154 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
155 | tan_pt2_y=c2_y+r_min*math.sin(theta)
156 |
157 |
158 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
159 |
160 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
161 |
162 | if Ti<0:
163 | Ti+=2*np.pi
164 | if Tf<0:
165 | Tf+=2*np.pi
166 |
167 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
168 |
169 | Ti= Ti*180/np.pi
170 | # print Ti, current_x,current_y,current_th,goal_x,goal_y,goal_th
171 |
172 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LR"]
173 | return ans
174 |
175 | def RSL(current_x,current_y,current_th,goal_x,goal_y,goal_th):
176 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
177 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
178 |
179 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
180 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
181 |
182 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
183 | # print (tan_pt1_x,tan_pt1_y)
184 | # print (tan_pt2_x,tan_pt2_y)
185 | if(-r_min**2 + (S1**2)/4.0 )<0:
186 | # print"Holaaaaaa"
187 | return None
188 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
189 |
190 | # if c2_x-c1_x<0:
191 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
192 | # elif c2_x-c1_x>0:
193 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
194 |
195 | theta = + (np.arctan2((c2_x-c1_x), c2_y-c1_y)) + np.arctan2(r_min,S/2.0)
196 |
197 | # print "THETA ", theta, "c1_x =",c1_x, c1_y,c2_x,c2_y,"S=",S
198 |
199 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
200 | tan_pt1_y=c1_y+r_min*math.sin(theta)
201 |
202 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
203 | tan_pt2_y=c2_y-r_min*math.sin(theta)
204 |
205 |
206 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
207 |
208 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
209 |
210 | if Ti<0:
211 | Ti+=2*np.pi
212 | if Tf<0:
213 | Tf+=2*np.pi
214 |
215 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
216 |
217 | Ti= Ti*180/np.pi
218 | # print Ti, current_x,current_y,current_th,goal_x,goal_y,goal_th
219 |
220 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RL"]
221 | # 0 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11
222 | return ans
223 |
224 | tree = [Node(current_x,current_y)]
225 |
226 | def check_for_obstacles(x,y):
227 | for ox,oy,orad in obstacles:
228 | if ((x-ox)**2 + (y-oy)**2)**0.5 < orad*2:
229 | return False
230 | return True
231 |
232 | def findNearest(sample):
233 | min_d = sys.maxint
234 | ind=0
235 | min_node=tree[0]
236 | for indd,node in enumerate(tree):
237 | dis = ((node.x-sample.x)**2 + (node.y-sample.y)**2)**0.5
238 | if min_d>dis:
239 | min_d=dis
240 | min_node=node
241 | ind=indd
242 | return min_node,ind
243 |
244 | def find_nearby_nodes(newNode):
245 | radius = step*2
246 | dist_list = [(node.x - newNode.x) ** 2 + (node.y - newNode.y) ** 2 for node in tree]
247 | nearinds = [dist_list.index(i) for i in dist_list if i <= (radius ** 2)]
248 | return nearinds
249 |
250 | def check_collision_extend(node, theta, d):
251 |
252 | temp_node = copy.deepcopy(node)
253 |
254 | for i in range(int(d / step)):
255 | temp_node.x += step * math.cos(theta)
256 | temp_node.y += step * math.sin(theta)
257 | if not check_for_obstacles(temp_node.x,temp_node.y):
258 | return False
259 | if temp_node.x>1 or temp_node.y>1 or temp_node.x<0 or temp_node.y<0:
260 | return False
261 | return True
262 |
263 | def rewire(node, nearinds):
264 | for i in nearinds:
265 | nearNode = tree[i]
266 | dx = node.x - nearNode.x
267 | dy = node.y - nearNode.y
268 | d = math.sqrt(dx ** 2 + dy ** 2)
269 |
270 | if nearNode.cost>node.cost+d:
271 | theta = np.arctan2(dy, dx)
272 | if check_collision_extend(tree[i], theta, d):
273 | nearNode.p=tree.index(node)
274 | nearNode.cost=node.cost+d
275 |
276 | def choose_parent(newNode, nearinds):
277 | if not nearinds:
278 | return newNode
279 | dist_list = []
280 | for i in nearinds:
281 | dx = newNode.x - tree[i].x
282 | dy = newNode.y - tree[i].y
283 | d = math.sqrt(dx ** 2 + dy ** 2)
284 | theta = np.arctan2(dy, dx)
285 | if check_collision_extend(tree[i], theta, d):
286 | dist_list.append(tree[i].cost + d)
287 |
288 | if not dist_list:
289 | return newNode
290 |
291 | mincost = min(dist_list)
292 | minind = nearinds[dist_list.index(mincost)]
293 |
294 | newNode.cost = mincost
295 | newNode.p = minind
296 |
297 | return newNode
298 |
299 | def RRT():
300 | while True:
301 | sample = Node(random.uniform(0,1),random.uniform(0,1))
302 |
303 | nearestNode,ind = findNearest(sample)
304 | newNode = copy.deepcopy(nearestNode)
305 | theta = (np.arctan2(sample.y-nearestNode.y, sample.x-nearestNode.x))
306 | newNode.x+=step*math.cos(theta)
307 | newNode.y+=step*math.sin(theta)
308 | newNode.p=ind
309 | newNode.cost+=step
310 | # plt.plot(newNode.x,newNode.y,'r+')
311 | # plt.plot(nearestNode.x,nearestNode.y,'bo')
312 | # plt.pause(2)
313 | # plt.plot(nearestNode.x,nearestNode.y,'wo')
314 | # plt.pause(2)
315 |
316 | # if ((newNode.x-0.3)**2 + (newNode.y-0.3)**2)**0.5 < 0.2:
317 | # # plt.plot(newNode.x,newNode.y,'w+')
318 | # # plt.pause(2)
319 | # continue
320 | # if ((newNode.x-0.6)**2 + (newNode.y-0.5)**2)**0.5 < 0.2:
321 | # # plt.plot(newNode.x,newNode.y,'w+')
322 | # # plt.pause(2)
323 | # continue
324 | # if ((newNode.x-0.3)**2 + (newNode.y-0.5)**2)**0.5 < 0.2:
325 | # # plt.plot(newNode.x,newNode.y,'w+')
326 | # # plt.pause(2)
327 | # continue
328 | if not check_for_obstacles(newNode.x,newNode.y):
329 | continue
330 | if newNode.x>1 or newNode.y>1 or newNode.x<0 or newNode.y<0:
331 | # plt.plot(newNode.x,newNode.y,'w+')
332 | # plt.pause(2)
333 | continue
334 | nearbyNodes = find_nearby_nodes(newNode)
335 | newNode = choose_parent(newNode, nearbyNodes)
336 | # plt.plot(newNode.x,newNode.y,'bo')
337 | # plt.pause(2)
338 | # plt.plot(newNode.x,newNode.y,'wo')
339 | # plt.pause(2)
340 | tree.append(newNode)
341 | rewire(newNode,nearbyNodes)
342 |
343 | if ((newNode.x-goal_x)**2 + (newNode.y-goal_y)**2)**0.5 < 0.1:
344 | break
345 | # DrawGraph(sample)
346 | path=[[newNode.x,newNode.y]]
347 | while True:
348 | if not newNode.p:
349 | break
350 | #plt.plot([newNode.x,newNode.y],[tree[newNode.p].x,tree[newNode.p].y],'ro-')
351 | path.append([tree[newNode.p].x,tree[newNode.p].y])
352 | newNode=tree[newNode.p]
353 | x=[goal_x]
354 | y=[goal_y]
355 | for i in path:
356 | x.append(i[0])
357 | y.append(i[1])
358 | # plt.plot(i[0],i[1],'o-')
359 | # plt.pause(0.5)
360 | x.append(current_x)
361 | y.append(current_y)
362 | # print x,y
363 | nx=x[::-1][1:]
364 | ny=y[::-1][1:]
365 |
366 | sx=0
367 | sy=0
368 | st=0
369 | for a,b in zip(nx,ny):
370 | ex,ey=a,b
371 | et=(np.arctan2(ey-goal_y, ex-goal_x))
372 |
373 | # dubins
374 | paths=[LSL,RSR,LSR,RSL]
375 | minS=float("inf")
376 | ans=[]
377 | count=0
378 | curve=""
379 | ans_count=1
380 | for i in paths:
381 | path_ans=i(sx,sy,st,ex,ey,et)
382 | count+=1
383 | if path_ans:
384 | if minS>path_ans[3]:
385 | ans=path_ans
386 | minS=path_ans[3]
387 | ans_count=count
388 | curve=path_ans[12]
389 |
390 | plt.plot([ans[4],ans[6]],[ans[5],ans[7]])
391 |
392 | start_angle1 = np.arctan2(sy - ans[9], sx - ans[8]) * 180 / np.pi
393 | end_angle1 = np.arctan2(ans[5] - ans[9], ans[4] - ans[8]) * 180 / np.pi
394 |
395 | if curve[0]=="L":
396 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=start_angle1, theta2=end_angle1)
397 | else:
398 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=end_angle1, theta2=start_angle1)
399 | plt.gca().add_patch(arc1)
400 |
401 | start_angle2 = np.arctan2(ans[7] - ans[11], ans[6] - ans[10]) * 180 / np.pi
402 | end_angle2 = np.arctan2(ey - ans[11], ex - ans[10]) * 180 / np.pi
403 |
404 | if curve[1]=="L":
405 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=start_angle2, theta2=end_angle2)
406 | else:
407 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=end_angle2, theta2=start_angle2)
408 |
409 | plt.gca().add_patch(arc2)
410 |
411 | plt.gca().set_aspect('equal')
412 |
413 | #
414 | sx,sy,st=ex,ey,et
415 | # plt.plot(x, y, 'o-')
416 | # plt.pause(0.05)
417 | plt.show()
418 | RRT()
--------------------------------------------------------------------------------
/rrt_star_dubins/rrt_star_dubins_minimized_euclidean.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | import matplotlib.patches as patches
4 | import math
5 | import random
6 | import sys
7 | import copy
8 |
9 | class Node():
10 | def __init__(self,x,y):
11 | self.x=x
12 | self.y=y
13 | self.p=None
14 | self.cost=0
15 |
16 | plt.axis([-0.1, 1.1, -0.1, 1.1])
17 | # rectangle = plt.Rectangle((0.2, 0.2), 0.2, 0.2)
18 | # plt.gca().add_patch(rectangle)
19 |
20 | obs = plt.Circle((0.3, 0.3), radius=0.1, fc='r')
21 | plt.gca().add_patch(obs)
22 |
23 | obs = plt.Circle((0.6, 0.5), radius=0.2, fc='r')
24 | plt.gca().add_patch(obs)
25 |
26 | obs = plt.Circle((0.3, 0.5), radius=0.1, fc='r')
27 | plt.gca().add_patch(obs)
28 |
29 | obstacles = [(0.3,0.3,0.1),(0.6,0.5,0.2),(0.3,0.5,0.1)]
30 |
31 | rectangle = plt.Rectangle((0, 0), 1, 1,fill=False)
32 | plt.gca().add_patch(rectangle)
33 |
34 |
35 | current_x=0
36 | current_y=0
37 | current_th=0 #current angle in Degrees
38 |
39 | PI=3.14
40 | r_min=0.02
41 | step=0.3
42 |
43 | goal_x=0.8
44 | goal_y=0.8
45 | goal_th=0 #goal angle in Degrees
46 |
47 | goal_circle = plt.Circle((0.8, 0.8), radius=0.1, fc='b')
48 | plt.gca().add_patch(goal_circle)
49 |
50 | plt.axis('scaled')
51 | # goal_circle =
52 | #plt.show()
53 |
54 | def LSL(current_x,current_y,current_th,goal_x,goal_y,goal_th):
55 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
56 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
57 |
58 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
59 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
60 | #print c1_x,c1_y,c2_x,c2_y, c2_y-c1_y, c2_x-c1_x
61 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
62 |
63 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
64 | tan_pt1_y=c1_y-r_min*math.sin(theta)
65 |
66 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
67 | tan_pt2_y=c2_y-r_min*math.sin(theta)
68 |
69 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
70 | # print S,theta
71 | # print (tan_pt1_x,tan_pt1_y)
72 | # print (tan_pt2_x,tan_pt2_y)
73 | # print (c1_x,c1_y,c2_x,c2_y)
74 |
75 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
76 |
77 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
78 |
79 | if Ti<0:
80 | Ti+=2*np.pi
81 | if Tf<0:
82 | Tf+=2*np.pi
83 |
84 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
85 |
86 | # Ti= Ti*180/np.pi
87 |
88 | # print Ti,Tf, total_dist,S
89 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LL"]
90 |
91 | return ans
92 |
93 | def RSR(current_x,current_y,current_th,goal_x,goal_y,goal_th):
94 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
95 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
96 |
97 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
98 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
99 |
100 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
101 |
102 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
103 | tan_pt1_y=c1_y+r_min*math.sin(theta)
104 |
105 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
106 | tan_pt2_y=c2_y+r_min*math.sin(theta)
107 |
108 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
109 |
110 | # print (tan_pt1_x,tan_pt1_y)
111 | # print (tan_pt2_x,tan_pt2_y)
112 | # print (c2_x,c2_y)
113 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
114 |
115 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
116 |
117 | if Ti<0:
118 | Ti+=2*np.pi
119 | if Tf<0:
120 | Tf+=2*np.pi
121 |
122 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
123 |
124 | Ti= Ti*180/np.pi
125 |
126 |
127 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RR"]
128 | return ans
129 |
130 | def LSR(current_x,current_y,current_th,goal_x,goal_y,goal_th):
131 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
132 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
133 |
134 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
135 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
136 |
137 | # if c2_x-c1_x<0:
138 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
139 | # elif c2_x-c1_x>0:
140 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
141 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
142 |
143 | if(-r_min**2 + (S1**2)/4.0 )<0:
144 | # print"Holaaaaaa"
145 | return None
146 |
147 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
148 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y)) - np.arctan2(r_min,S/2.0)
149 |
150 |
151 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
152 | tan_pt1_y=c1_y-r_min*math.sin(theta)
153 |
154 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
155 | tan_pt2_y=c2_y+r_min*math.sin(theta)
156 |
157 |
158 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
159 |
160 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
161 |
162 | if Ti<0:
163 | Ti+=2*np.pi
164 | if Tf<0:
165 | Tf+=2*np.pi
166 |
167 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
168 |
169 | Ti= Ti*180/np.pi
170 | # print Ti, current_x,current_y,current_th,goal_x,goal_y,goal_th
171 |
172 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LR"]
173 | return ans
174 |
175 | def RSL(current_x,current_y,current_th,goal_x,goal_y,goal_th):
176 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
177 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
178 |
179 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
180 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
181 |
182 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
183 | # print (tan_pt1_x,tan_pt1_y)
184 | # print (tan_pt2_x,tan_pt2_y)
185 | if(-r_min**2 + (S1**2)/4.0 )<0:
186 | # print"Holaaaaaa"
187 | return None
188 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
189 |
190 | # if c2_x-c1_x<0:
191 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
192 | # elif c2_x-c1_x>0:
193 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
194 |
195 | theta = + (np.arctan2((c2_x-c1_x), c2_y-c1_y)) + np.arctan2(r_min,S/2.0)
196 |
197 | # print "THETA ", theta, "c1_x =",c1_x, c1_y,c2_x,c2_y,"S=",S
198 |
199 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
200 | tan_pt1_y=c1_y+r_min*math.sin(theta)
201 |
202 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
203 | tan_pt2_y=c2_y-r_min*math.sin(theta)
204 |
205 |
206 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
207 |
208 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
209 |
210 | if Ti<0:
211 | Ti+=2*np.pi
212 | if Tf<0:
213 | Tf+=2*np.pi
214 |
215 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
216 |
217 | Ti= Ti*180/np.pi
218 | # print Ti, current_x,current_y,current_th,goal_x,goal_y,goal_th
219 |
220 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RL"]
221 | # 0 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11
222 | return ans
223 |
224 | tree = [Node(current_x,current_y)]
225 |
226 | def check_for_obstacles(x,y):
227 | for ox,oy,orad in obstacles:
228 | if ((x-ox)**2 + (y-oy)**2)**0.5 < orad*2:
229 | return False
230 | return True
231 |
232 | def findNearest(sample):
233 | min_d = sys.maxint
234 | ind=0
235 | min_node=tree[0]
236 | for indd,node in enumerate(tree):
237 | dis = ((node.x-sample.x)**2 + (node.y-sample.y)**2)**0.5
238 | if min_d>dis:
239 | min_d=dis
240 | min_node=node
241 | ind=indd
242 | return min_node,ind
243 |
244 | def find_nearby_nodes(newNode):
245 | radius = step*2
246 | dist_list = [(node.x - newNode.x) ** 2 + (node.y - newNode.y) ** 2 for node in tree]
247 | nearinds = [dist_list.index(i) for i in dist_list if i <= (radius ** 2)]
248 | return nearinds
249 |
250 | def check_collision_extend(node, theta, d):
251 |
252 | temp_node = copy.deepcopy(node)
253 |
254 | for i in range(int(d / step)):
255 | temp_node.x += step * math.cos(theta)
256 | temp_node.y += step * math.sin(theta)
257 | if not check_for_obstacles(temp_node.x,temp_node.y):
258 | return False
259 | if temp_node.x>1 or temp_node.y>1 or temp_node.x<0 or temp_node.y<0:
260 | return False
261 | return True
262 |
263 | def rewire(node, nearinds):
264 | for i in nearinds:
265 | nearNode = tree[i]
266 | dx = node.x - nearNode.x
267 | dy = node.y - nearNode.y
268 | d = math.sqrt(dx ** 2 + dy ** 2)
269 |
270 | if nearNode.cost>node.cost+d:
271 | theta = np.arctan2(dy, dx)
272 | if check_collision_extend(tree[i], theta, d):
273 | nearNode.p=tree.index(node)
274 | nearNode.cost=node.cost+d
275 |
276 | def choose_parent(newNode, nearinds):
277 | if not nearinds:
278 | return newNode
279 | dist_list = []
280 | for i in nearinds:
281 | dx = newNode.x - tree[i].x
282 | dy = newNode.y - tree[i].y
283 | d = math.sqrt(dx ** 2 + dy ** 2)
284 | theta = np.arctan2(dy, dx)
285 | if check_collision_extend(tree[i], theta, d):
286 | dist_list.append(tree[i].cost + d)
287 |
288 | if not dist_list:
289 | return newNode
290 |
291 | mincost = min(dist_list)
292 | minind = nearinds[dist_list.index(mincost)]
293 |
294 | newNode.cost = mincost
295 | newNode.p = minind
296 |
297 | return newNode
298 |
299 | def RRT():
300 | while True:
301 | sample = Node(random.uniform(0,1),random.uniform(0,1))
302 |
303 | nearestNode,ind = findNearest(sample)
304 | newNode = copy.deepcopy(nearestNode)
305 | theta = (np.arctan2(sample.y-nearestNode.y, sample.x-nearestNode.x))
306 | newNode.x+=step*math.cos(theta)
307 | newNode.y+=step*math.sin(theta)
308 | newNode.p=ind
309 | newNode.cost+=step
310 | # plt.plot(newNode.x,newNode.y,'r+')
311 | # plt.plot(nearestNode.x,nearestNode.y,'bo')
312 | # plt.pause(2)
313 | # plt.plot(nearestNode.x,nearestNode.y,'wo')
314 | # plt.pause(2)
315 |
316 | # if ((newNode.x-0.3)**2 + (newNode.y-0.3)**2)**0.5 < 0.2:
317 | # # plt.plot(newNode.x,newNode.y,'w+')
318 | # # plt.pause(2)
319 | # continue
320 | # if ((newNode.x-0.6)**2 + (newNode.y-0.5)**2)**0.5 < 0.2:
321 | # # plt.plot(newNode.x,newNode.y,'w+')
322 | # # plt.pause(2)
323 | # continue
324 | # if ((newNode.x-0.3)**2 + (newNode.y-0.5)**2)**0.5 < 0.2:
325 | # # plt.plot(newNode.x,newNode.y,'w+')
326 | # # plt.pause(2)
327 | # continue
328 | if not check_for_obstacles(newNode.x,newNode.y):
329 | continue
330 | if newNode.x>1 or newNode.y>1 or newNode.x<0 or newNode.y<0:
331 | # plt.plot(newNode.x,newNode.y,'w+')
332 | # plt.pause(2)
333 | continue
334 | nearbyNodes = find_nearby_nodes(newNode)
335 | newNode = choose_parent(newNode, nearbyNodes)
336 | # plt.plot(newNode.x,newNode.y,'bo')
337 | # plt.pause(2)
338 | # plt.plot(newNode.x,newNode.y,'wo')
339 | # plt.pause(2)
340 | tree.append(newNode)
341 | rewire(newNode,nearbyNodes)
342 |
343 | if ((newNode.x-goal_x)**2 + (newNode.y-goal_y)**2)**0.5 < 0.1:
344 | break
345 | # DrawGraph(sample)
346 | path=[[newNode.x,newNode.y]]
347 | while True:
348 | if not newNode.p:
349 | break
350 | #plt.plot([newNode.x,newNode.y],[tree[newNode.p].x,tree[newNode.p].y],'ro-')
351 | path.append([tree[newNode.p].x,tree[newNode.p].y])
352 | newNode=tree[newNode.p]
353 | x=[goal_x]
354 | y=[goal_y]
355 | for i in path:
356 | x.append(i[0])
357 | y.append(i[1])
358 | # plt.plot(i[0],i[1],'o-')
359 | # plt.pause(0.5)
360 | x.append(current_x)
361 | y.append(current_y)
362 | # print x,y
363 | nx=x[::-1][1:]
364 | ny=y[::-1][1:]
365 |
366 | sx=0
367 | sy=0
368 | st=0
369 | for a,b in zip(nx,ny):
370 | ex,ey=a,b
371 | et=(np.arctan2(ey-goal_y, ex-goal_x))
372 |
373 | # dubins
374 | paths=[LSL,RSR,LSR,RSL]
375 | minS=float("inf")
376 | ans=[]
377 | count=0
378 | curve=""
379 | ans_count=1
380 | for i in paths:
381 | path_ans=i(sx,sy,st,ex,ey,et)
382 | count+=1
383 | if path_ans:
384 | if minS>path_ans[3]:
385 | ans=path_ans
386 | minS=path_ans[3]
387 | ans_count=count
388 | curve=path_ans[12]
389 |
390 | plt.plot([ans[4],ans[6]],[ans[5],ans[7]])
391 |
392 | start_angle1 = np.arctan2(sy - ans[9], sx - ans[8]) * 180 / np.pi
393 | end_angle1 = np.arctan2(ans[5] - ans[9], ans[4] - ans[8]) * 180 / np.pi
394 |
395 | if curve[0]=="L":
396 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=start_angle1, theta2=end_angle1)
397 | else:
398 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=end_angle1, theta2=start_angle1)
399 | plt.gca().add_patch(arc1)
400 |
401 | start_angle2 = np.arctan2(ans[7] - ans[11], ans[6] - ans[10]) * 180 / np.pi
402 | end_angle2 = np.arctan2(ey - ans[11], ex - ans[10]) * 180 / np.pi
403 |
404 | if curve[1]=="L":
405 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=start_angle2, theta2=end_angle2)
406 | else:
407 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=end_angle2, theta2=start_angle2)
408 |
409 | plt.gca().add_patch(arc2)
410 |
411 | plt.gca().set_aspect('equal')
412 |
413 | #
414 | sx,sy,st=ex,ey,et
415 | # plt.plot(x, y, 'o-')
416 | # plt.pause(0.05)
417 | plt.show()
418 | RRT()
--------------------------------------------------------------------------------
/rrt_star_dubins/rrt_star_dubins_minimzed_dubins_paths.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | import matplotlib.patches as patches
4 | import math
5 | import random
6 | import sys
7 | import copy
8 |
9 | class Node():
10 | def __init__(self,x,y):
11 | self.x=x
12 | self.y=y
13 | self.p=None
14 | self.th=0
15 | self.cost=0
16 |
17 | plt.axis([-0.1, 1.1, -0.1, 1.1])
18 | # rectangle = plt.Rectangle((0.2, 0.2), 0.2, 0.2)
19 | # plt.gca().add_patch(rectangle)
20 |
21 | obs = plt.Circle((0.3, 0.3), radius=0.1, fc='r')
22 | plt.gca().add_patch(obs)
23 |
24 | obs = plt.Circle((0.6, 0.5), radius=0.2, fc='r')
25 | plt.gca().add_patch(obs)
26 |
27 | obs = plt.Circle((0.3, 0.5), radius=0.1, fc='r')
28 | plt.gca().add_patch(obs)
29 |
30 | obstacles = [(0.3,0.3,0.1),(0.6,0.5,0.2),(0.3,0.5,0.1)]
31 |
32 | rectangle = plt.Rectangle((0, 0), 1, 1,fill=False)
33 | plt.gca().add_patch(rectangle)
34 |
35 |
36 | current_x=0
37 | current_y=0
38 | current_th=0 #current angle in Degrees
39 |
40 | PI=3.14
41 | r_min=0.02
42 | step=0.3
43 |
44 | goal_x=0.8
45 | goal_y=0.8
46 | goal_th=0 #goal angle in Degrees
47 |
48 | pathDic={0:"LSL",1:"RSR",2:"LSR",3:"RSL"}
49 |
50 | goal_circle = plt.Circle((0.8, 0.8), radius=0.1, fc='b')
51 | plt.gca().add_patch(goal_circle)
52 |
53 | plt.axis('scaled')
54 | # goal_circle =
55 | #plt.show()
56 |
57 | def LSL(current_x,current_y,current_th,goal_x,goal_y,goal_th):
58 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
59 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
60 |
61 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
62 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
63 | #print c1_x,c1_y,c2_x,c2_y, c2_y-c1_y, c2_x-c1_x
64 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
65 |
66 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
67 | tan_pt1_y=c1_y-r_min*math.sin(theta)
68 |
69 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
70 | tan_pt2_y=c2_y-r_min*math.sin(theta)
71 |
72 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
73 | # print S,theta
74 | # print (tan_pt1_x,tan_pt1_y)
75 | # print (tan_pt2_x,tan_pt2_y)
76 | # print (c1_x,c1_y,c2_x,c2_y)
77 |
78 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
79 |
80 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
81 |
82 | if Ti<0:
83 | Ti+=2*np.pi
84 | if Tf<0:
85 | Tf+=2*np.pi
86 |
87 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
88 |
89 | # Ti= Ti*180/np.pi
90 |
91 | # print Ti,Tf, total_dist,S
92 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LL"]
93 |
94 | return ans
95 |
96 | def RSR(current_x,current_y,current_th,goal_x,goal_y,goal_th):
97 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
98 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
99 |
100 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
101 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
102 |
103 | theta = (np.arctan2(c2_x-c1_x, c2_y-c1_y))
104 |
105 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
106 | tan_pt1_y=c1_y+r_min*math.sin(theta)
107 |
108 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
109 | tan_pt2_y=c2_y+r_min*math.sin(theta)
110 |
111 | S = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5
112 |
113 | # print (tan_pt1_x,tan_pt1_y)
114 | # print (tan_pt2_x,tan_pt2_y)
115 | # print (c2_x,c2_y)
116 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
117 |
118 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
119 |
120 | if Ti<0:
121 | Ti+=2*np.pi
122 | if Tf<0:
123 | Tf+=2*np.pi
124 |
125 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
126 |
127 | Ti= Ti*180/np.pi
128 |
129 |
130 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RR"]
131 | return ans
132 |
133 | def LSR(current_x,current_y,current_th,goal_x,goal_y,goal_th):
134 | c1_x=current_x-r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
135 | c1_y=current_y-r_min*math.sin(math.radians(current_th)-(PI/2))
136 |
137 | c2_x=goal_x+r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
138 | c2_y=goal_y+r_min*math.sin(math.radians(goal_th)-(PI/2))
139 |
140 | # if c2_x-c1_x<0:
141 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
142 | # elif c2_x-c1_x>0:
143 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
144 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
145 |
146 | if(-r_min**2 + (S1**2)/4.0 )<0:
147 | # print"Holaaaaaa"
148 | return None
149 |
150 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
151 | theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y)) - np.arctan2(r_min,S/2.0)
152 |
153 |
154 | tan_pt1_x=c1_x+r_min*math.cos(theta) #tangent point in first circle of min_turning radius
155 | tan_pt1_y=c1_y-r_min*math.sin(theta)
156 |
157 | tan_pt2_x=c2_x-r_min*math.cos(theta) #tangent point in second circle of min_turning radius
158 | tan_pt2_y=c2_y+r_min*math.sin(theta)
159 |
160 |
161 | Ti = np.arctan2(current_x-c1_x,current_y-c1_y) - np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) #Initial Turning angle
162 |
163 | Tf = np.arctan2(goal_x - c2_x,goal_y- c2_y) - np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) #Final Turning angle
164 |
165 | if Ti<0:
166 | Ti+=2*np.pi
167 | if Tf<0:
168 | Tf+=2*np.pi
169 |
170 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
171 |
172 | Ti= Ti*180/np.pi
173 | # print Ti, current_x,current_y,current_th,goal_x,goal_y,goal_th
174 |
175 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"LR"]
176 | return ans
177 |
178 | def RSL(current_x,current_y,current_th,goal_x,goal_y,goal_th):
179 | c1_x=current_x+r_min*math.cos(math.radians(current_th)-(PI/2)) #center of first circle of min_turning radius
180 | c1_y=current_y+r_min*math.sin(math.radians(current_th)-(PI/2))
181 |
182 | c2_x=goal_x-r_min*math.cos(math.radians(goal_th)-(PI/2)) #center of second circle of min_turning radius
183 | c2_y=goal_y-r_min*math.sin(math.radians(goal_th)-(PI/2))
184 |
185 | S1 = ((c2_x-c1_x)**2 + (c2_y-c1_y)**2)**0.5 #Distance from (c1_x,c1_y) to (c2_x,c2_y)
186 | # print (tan_pt1_x,tan_pt1_y)
187 | # print (tan_pt2_x,tan_pt2_y)
188 | if(-r_min**2 + (S1**2)/4.0 )<0:
189 | # print"Holaaaaaa"
190 | return None
191 | S = 2*((-r_min**2 + (S1**2)/4.0 )**0.5)
192 |
193 | # if c2_x-c1_x<0:
194 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y+2*r_min))
195 | # elif c2_x-c1_x>0:
196 | # theta = (np.arctan2((c2_x-c1_x), c2_y-c1_y-2*r_min))
197 |
198 | theta = + (np.arctan2((c2_x-c1_x), c2_y-c1_y)) + np.arctan2(r_min,S/2.0)
199 |
200 | # print "THETA ", theta, "c1_x =",c1_x, c1_y,c2_x,c2_y,"S=",S
201 |
202 | tan_pt1_x=c1_x-r_min*math.cos(theta) #tangent point in first circle of min_turning radius
203 | tan_pt1_y=c1_y+r_min*math.sin(theta)
204 |
205 | tan_pt2_x=c2_x+r_min*math.cos(theta) #tangent point in second circle of min_turning radius
206 | tan_pt2_y=c2_y-r_min*math.sin(theta)
207 |
208 |
209 | Ti = np.arctan2(tan_pt1_x-c1_x,tan_pt1_y-c1_y) - np.arctan2(current_x-c1_x,current_y-c1_y) #Initial Turning angle
210 |
211 | Tf = np.arctan2(tan_pt2_x - c2_x,tan_pt2_y- c2_y) - np.arctan2(goal_x - c2_x,goal_y- c2_y) #Final Turning angle
212 |
213 | if Ti<0:
214 | Ti+=2*np.pi
215 | if Tf<0:
216 | Tf+=2*np.pi
217 |
218 | total_dist = Ti*r_min + Tf*r_min + S #Total Distance from current to Goal
219 |
220 | Ti= Ti*180/np.pi
221 | # print Ti, current_x,current_y,current_th,goal_x,goal_y,goal_th
222 |
223 | ans=[Ti,Tf, total_dist,S,tan_pt1_x,tan_pt1_y,tan_pt2_x,tan_pt2_y,c1_x,c1_y,c2_x,c2_y,"RL"]
224 | # 0 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11
225 | return ans
226 |
227 | tree = [Node(current_x,current_y)]
228 |
229 | def check_for_obstacles(x,y):
230 | for ox,oy,orad in obstacles:
231 | if ((x-ox)**2 + (y-oy)**2)**0.5 < orad*2:
232 | return False
233 | return True
234 |
235 | def findNearest(sample):
236 | min_d = sys.maxint
237 | ind=0
238 | min_node=tree[0]
239 | for indd,node in enumerate(tree):
240 | dis = ((node.x-sample.x)**2 + (node.y-sample.y)**2)**0.5
241 | if min_d>dis:
242 | min_d=dis
243 | min_node=node
244 | ind=indd
245 | return min_node,ind
246 |
247 | def find_nearby_nodes(newNode):
248 | radius = step*2
249 | dist_list=[]
250 | nearinds=[]
251 | for node in tree:
252 | minCost = float("inf")
253 | minPath = 0
254 | for i,path in enumerate([LSL,RSR,LSR,RSL]):
255 | path_ans = path(node.x,node.y,node.th,newNode.x,newNode.y,newNode.th)
256 | if path_ans:
257 | if minCost > path_ans[2]:
258 | minPath = i
259 | minCost = path_ans[2]
260 | dist_list.append(minCost)
261 | # dist_list = [(node.x - newNode.x) ** 2 + (node.y - newNode.y) ** 2 for node in tree]
262 | # for i,(c,p) in enumerate(dist_list):
263 | # if c<=(radius ** 2):
264 | # nearinds.append(i)
265 | nearinds = [dist_list.index(i) for i in dist_list if i <= (radius ** 2)]
266 | return nearinds
267 |
268 | def check_collision_extend(node, theta, d):
269 |
270 | temp_node = copy.deepcopy(node)
271 |
272 | for i in range(int(d / step)):
273 | temp_node.x += step * math.cos(theta)
274 | temp_node.y += step * math.sin(theta)
275 | if not check_for_obstacles(temp_node.x,temp_node.y):
276 | return False
277 | if temp_node.x>1 or temp_node.y>1 or temp_node.x<0 or temp_node.y<0:
278 | return False
279 | return True
280 |
281 | def rewire(node, nearinds):
282 | for i in nearinds:
283 | nearNode = tree[i]
284 | dx = node.x - nearNode.x
285 | dy = node.y - nearNode.y
286 | # d = math.sqrt(dx ** 2 + dy ** 2)
287 | # d = [LSL,RSR,LSR,RSL][p](node.x,node.y,node.th,nearNode.x,nearNode.y,nearNode.th)
288 |
289 | d = float("inf")
290 | for path in [LSL,RSR,LSR,RSL]:
291 | path_ans = path(node.x,node.y,node.th,nearNode.x,nearNode.y,nearNode.th)
292 | if path_ans:
293 | d = min(d,path_ans[2])
294 |
295 | if nearNode.cost>node.cost+d:
296 | theta = np.arctan2(dy, dx)
297 | if check_collision_extend(tree[i], theta, d):
298 | nearNode.p=tree.index(node)
299 | nearNode.cost=node.cost+d
300 |
301 | def choose_parent(newNode, nearinds):
302 | if not nearinds:
303 | return newNode
304 | dist_list = []
305 | for i in nearinds:
306 | dx = newNode.x - tree[i].x
307 | dy = newNode.y - tree[i].y
308 | # d = math.sqrt(dx ** 2 + dy ** 2)
309 | # d = [LSL,RSR,LSR,RSL](newNode.x,newNode.y,newNode.th,tree[i].x,tree[i].y,tree[i].th)
310 |
311 | d = float("inf")
312 | for path in [LSL,RSR,LSR,RSL]:
313 | path_ans = path(newNode.x,newNode.y,newNode.th,tree[i].x,tree[i].y,tree[i].th)
314 | if path_ans:
315 | d = min(d,path_ans[2])
316 |
317 |
318 |
319 | theta = np.arctan2(dy, dx)
320 | if check_collision_extend(tree[i], theta, d):
321 | dist_list.append(tree[i].cost + d)
322 |
323 | if not dist_list:
324 | return newNode
325 |
326 | mincost = min(dist_list)
327 | minind = nearinds[dist_list.index(mincost)]
328 |
329 | newNode.cost = mincost
330 | newNode.p = minind
331 |
332 | return newNode
333 |
334 | def RRT():
335 | while True:
336 | sample = Node(random.uniform(0,1),random.uniform(0,1))
337 |
338 | nearestNode,ind = findNearest(sample)
339 | newNode = copy.deepcopy(nearestNode)
340 | theta = (np.arctan2(sample.y-nearestNode.y, sample.x-nearestNode.x))
341 | newNode.x+=step*math.cos(theta)
342 | newNode.y+=step*math.sin(theta)
343 | newNode.p=ind
344 | newNode.cost+=step
345 | newNode.th = theta
346 | # plt.plot(newNode.x,newNode.y,'r+')
347 | # plt.plot(nearestNode.x,nearestNode.y,'bo')
348 | # plt.pause(2)
349 | # plt.plot(nearestNode.x,nearestNode.y,'wo')
350 | # plt.pause(2)
351 |
352 | # if ((newNode.x-0.3)**2 + (newNode.y-0.3)**2)**0.5 < 0.2:
353 | # # plt.plot(newNode.x,newNode.y,'w+')
354 | # # plt.pause(2)
355 | # continue
356 | # if ((newNode.x-0.6)**2 + (newNode.y-0.5)**2)**0.5 < 0.2:
357 | # # plt.plot(newNode.x,newNode.y,'w+')
358 | # # plt.pause(2)
359 | # continue
360 | # if ((newNode.x-0.3)**2 + (newNode.y-0.5)**2)**0.5 < 0.2:
361 | # # plt.plot(newNode.x,newNode.y,'w+')
362 | # # plt.pause(2)
363 | # continue
364 | if not check_for_obstacles(newNode.x,newNode.y):
365 | continue
366 | if newNode.x>1 or newNode.y>1 or newNode.x<0 or newNode.y<0:
367 | # plt.plot(newNode.x,newNode.y,'w+')
368 | # plt.pause(2)
369 | continue
370 | nearbyNodes = find_nearby_nodes(newNode)
371 | newNode = choose_parent(newNode, nearbyNodes)
372 | # plt.plot(newNode.x,newNode.y,'bo')
373 | # plt.pause(2)
374 | # plt.plot(newNode.x,newNode.y,'wo')
375 | # plt.pause(2)
376 | tree.append(newNode)
377 | rewire(newNode,nearbyNodes)
378 |
379 | if ((newNode.x-goal_x)**2 + (newNode.y-goal_y)**2)**0.5 < 0.1:
380 | break
381 | # DrawGraph(sample)
382 | path=[[newNode.x,newNode.y]]
383 | while True:
384 | if not newNode.p:
385 | break
386 | #plt.plot([newNode.x,newNode.y],[tree[newNode.p].x,tree[newNode.p].y],'ro-')
387 | path.append([tree[newNode.p].x,tree[newNode.p].y])
388 | newNode=tree[newNode.p]
389 | x=[goal_x]
390 | y=[goal_y]
391 | for i in path:
392 | x.append(i[0])
393 | y.append(i[1])
394 | # plt.plot(i[0],i[1],'o-')
395 | # plt.pause(0.5)
396 | x.append(current_x)
397 | y.append(current_y)
398 | # print x,y
399 | nx=x[::-1][1:]
400 | ny=y[::-1][1:]
401 |
402 | sx=0
403 | sy=0
404 | st=0
405 | for a,b in zip(nx,ny):
406 | ex,ey=a,b
407 | et=(np.arctan2(ey-goal_y, ex-goal_x))
408 |
409 | # dubins
410 | paths=[LSL,RSR,LSR,RSL]
411 | minS=float("inf")
412 | ans=[]
413 | count=0
414 | curve=""
415 | ans_count=1
416 | for i in paths:
417 | path_ans=i(sx,sy,st,ex,ey,et)
418 | count+=1
419 | if path_ans:
420 | if minS>path_ans[3]:
421 | ans=path_ans
422 | minS=path_ans[3]
423 | ans_count=count
424 | curve=path_ans[12]
425 |
426 | plt.plot([ans[4],ans[6]],[ans[5],ans[7]])
427 |
428 | start_angle1 = np.arctan2(sy - ans[9], sx - ans[8]) * 180 / np.pi
429 | end_angle1 = np.arctan2(ans[5] - ans[9], ans[4] - ans[8]) * 180 / np.pi
430 |
431 | if curve[0]=="L":
432 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=start_angle1, theta2=end_angle1)
433 | else:
434 | arc1 = patches.Arc((ans[8], ans[9]), 2*r_min,2*r_min,theta1=end_angle1, theta2=start_angle1)
435 | plt.gca().add_patch(arc1)
436 |
437 | start_angle2 = np.arctan2(ans[7] - ans[11], ans[6] - ans[10]) * 180 / np.pi
438 | end_angle2 = np.arctan2(ey - ans[11], ex - ans[10]) * 180 / np.pi
439 |
440 | if curve[1]=="L":
441 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=start_angle2, theta2=end_angle2)
442 | else:
443 | arc2 = patches.Arc((ans[10], ans[11]), 2*r_min,2*r_min,theta1=end_angle2, theta2=start_angle2)
444 |
445 | plt.gca().add_patch(arc2)
446 |
447 | plt.gca().set_aspect('equal')
448 |
449 | #
450 | sx,sy,st=ex,ey,et
451 | # plt.plot(x, y, 'o-')
452 | # plt.pause(0.05)
453 | plt.show()
454 | RRT()
--------------------------------------------------------------------------------
/rrt_star_dubins/rrt_star_with_random_samplings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_star_dubins/rrt_star_with_random_samplings.png
--------------------------------------------------------------------------------
/rrt_star_dubins/rrt_star_with_random_samplings2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_star_dubins/rrt_star_with_random_samplings2.png
--------------------------------------------------------------------------------
/rrt_star_dubins/rrtstar_minimized_dubins_paths.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_star_dubins/rrtstar_minimized_dubins_paths.png
--------------------------------------------------------------------------------
/rrt_star_dubins/rrtstar_minimized_dubins_paths2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/srnand/Mobile-Robots-Autonomous-Navigation/988336e40d4259a817912025b95a35135367f7a1/rrt_star_dubins/rrtstar_minimized_dubins_paths2.png
--------------------------------------------------------------------------------