22
33Potential Field based path planner
44
5-
65author: Atsushi Sakai (@Atsushi_twi)
76
87"""
98
109import numpy as np
1110import matplotlib .pyplot as plt
1211
12+ # Parameters
13+ KP = 5.0 # attractive potential gain
14+ ETA = 100.0 # repulsive potential gain
15+ AREA_WIDTH = 70.0 # potential area width [m]
16+
17+ show_animation = True
18+
1319
14- def calc_potential_field (gx , gy , reso ):
15- minx = - 10 .0
16- miny = - 10 .0
17- maxx = 50 .0
18- maxy = 50 .0
19- xw = round (maxx - minx )
20- yw = round (maxy - miny )
20+ def calc_potential_field (gx , gy , ox , oy , reso , rr ):
21+ minx = min ( ox ) - AREA_WIDTH / 2 .0
22+ miny = min ( oy ) - AREA_WIDTH / 2 .0
23+ maxx = max ( ox ) + AREA_WIDTH / 2 .0
24+ maxy = max ( oy ) + AREA_WIDTH / 2 .0
25+ xw = round (( maxx - minx ) / reso )
26+ yw = round (( maxy - miny ) / reso )
2127
22- pmap = [[0.0 for i in range (xw )] for i in range (yw )]
28+ # calc each potential
29+ pmap = [[0.0 for i in range (yw )] for i in range (xw )]
2330
2431 for ix in range (xw ):
2532 x = ix * reso + minx
2633 for iy in range (yw ):
2734 y = iy * reso + miny
28-
29- ug = np .hypot (x - gx , y - gy )
30- uo = 0.0
35+ ug = calc_attractive_potential (x , y , gx , gy )
36+ uo = calc_repulsive_potential (x , y , ox , oy , rr )
3137 uf = ug + uo
32-
3338 pmap [ix ][iy ] = uf
3439
35- # print(pmap)
36-
3740 return pmap , minx , miny
3841
3942
43+ def calc_attractive_potential (x , y , gx , gy ):
44+ return 0.5 * KP * np .hypot (x - gx , y - gy )
45+
46+
47+ def calc_repulsive_potential (x , y , ox , oy , rr ):
48+ # search nearest obstacle
49+ minid = - 1
50+ dmin = float ("inf" )
51+ for i in range (len (ox )):
52+ d = np .hypot (x - ox [i ], y - oy [i ])
53+ if dmin >= d :
54+ dmin = d
55+ minid = i
56+
57+ # calc repulsive potential
58+ dq = np .hypot (x - ox [minid ], y - oy [minid ])
59+
60+ if dq <= rr :
61+ if dq <= 0.1 :
62+ dq = 0.1
63+
64+ return 0.5 * ETA * (1.0 / dq - 1.0 / rr ) ** 2
65+ else :
66+ return 0.0
67+
68+
4069def get_motion_model ():
4170 # dx, dy
4271 motion = [[1 , 0 ],
@@ -51,10 +80,10 @@ def get_motion_model():
5180 return motion
5281
5382
54- def potential_field_planning (sx , sy , gx , gy , reso ):
83+ def potential_field_planning (sx , sy , gx , gy , ox , oy , reso , rr ):
5584
5685 # calc potential field
57- pmap , minx , miny = calc_potential_field (gx , gy , reso )
86+ pmap , minx , miny = calc_potential_field (gx , gy , ox , oy , reso , rr )
5887
5988 # search path
6089 d = np .hypot (sx - gx , sy - gy )
@@ -63,14 +92,15 @@ def potential_field_planning(sx, sy, gx, gy, reso):
6392 rx , ry = [sx ], [sy ]
6493 motion = get_motion_model ()
6594 while d >= reso :
66- # print(ix, iy)
67- # input()
6895 minp = float ("inf" )
6996 minix , miniy = - 1 , - 1
7097 for i in range (len (motion )):
7198 inx = ix + motion [i ][0 ]
7299 iny = iy + motion [i ][1 ]
73- p = pmap [inx ][iny ]
100+ if inx >= len (pmap ) or iny >= len (pmap [0 ]):
101+ p = float ("inf" ) # outside area
102+ else :
103+ p = pmap [inx ][iny ]
74104 if minp > p :
75105 minp = p
76106 minix = inx
@@ -80,33 +110,48 @@ def potential_field_planning(sx, sy, gx, gy, reso):
80110 xp = ix * reso + minx
81111 yp = iy * reso + miny
82112 d = np .hypot (gx - xp , gy - yp )
83- # print(d, xp, yp)
113+
114+ if show_animation :
115+ plt .plot (rx , ry , "-r" )
116+ plt .pause (0.01 )
117+
84118 rx .append (xp )
85119 ry .append (yp )
86120
121+ print ("Goal!!" )
122+
87123 return rx , ry
88124
89125
90126def main ():
91127
92- sx = 0.0
93- sy = 10.0
94- gx = 30.0
95- gy = 30.0
96- grid_size = 2.0 # [m]
128+ sx = 0.0 # start x position [m]
129+ sy = 10.0 # start y positon [m]
130+ gx = 30.0 # goal x position [m]
131+ gy = 30.0 # goal y position [m]
132+ grid_size = 0.5 # potential grid size [m]
133+ robot_radius = 5.0 # robot radius [m]
97134
98- rx , ry = potential_field_planning (sx , sy , gx , gy , grid_size )
135+ ox = [15.0 , 5.0 , 20.0 , 25.0 ] # obstacle x position list [m]
136+ oy = [25.0 , 15.0 , 26.0 , 25.0 ] # obstacle y position list [m]
99137
100- plt .plot (rx , ry , "-r" )
138+ if show_animation :
139+ plt .plot (ox , oy , "ok" )
140+ plt .plot (sx , sy , "*c" )
141+ plt .plot (gx , gy , "*c" )
142+ plt .grid (True )
143+ plt .axis ("equal" )
101144
102- plt .plot (sx , sy , "*r" )
103- plt .plot (gx , gy , "*r" )
104- plt .grid (True )
105- plt .axis ("equal" )
106- plt .show ()
145+ # path generation
146+ rx , ry = potential_field_planning (
147+ sx , sy , gx , gy , ox , oy , grid_size , robot_radius )
107148
108- print (__file__ + " start!!" )
149+ if show_animation :
150+ plt .plot (rx , ry , "-r" )
151+ plt .show ()
109152
110153
111154if __name__ == '__main__' :
155+ print (__file__ + " start!!" )
112156 main ()
157+ print (__file__ + " Done!!" )
0 commit comments