Skip to content

Commit f3b4d05

Browse files
committed
first release potentialfieldplanning
1 parent 60aae7f commit f3b4d05

File tree

1 file changed

+79
-34
lines changed

1 file changed

+79
-34
lines changed

PathPlanning/PotentialFieldPlanning/potential_field_planning.py

Lines changed: 79 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,70 @@
22
33
Potential Field based path planner
44
5-
65
author: Atsushi Sakai (@Atsushi_twi)
76
87
"""
98

109
import numpy as np
1110
import 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+
4069
def 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

90126
def 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

111154
if __name__ == '__main__':
155+
print(__file__ + " start!!")
112156
main()
157+
print(__file__ + " Done!!")

0 commit comments

Comments
 (0)