Skip to content

Commit 193ff61

Browse files
committed
fix coordinate bug and code clean up
1 parent f572359 commit 193ff61

File tree

1 file changed

+72
-54
lines changed

1 file changed

+72
-54
lines changed

PathPlanning/AStar/a_star.py

Lines changed: 72 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,46 @@
1414

1515
show_animation = True
1616

17-
1817
class Node:
1918

2019
def __init__(self, x, y, cost, pind):
21-
self.x = x
22-
self.y = y
20+
self.x = x # index of grid
21+
self.y = y # index of grid
2322
self.cost = cost
2423
self.pind = pind
2524

2625
def __str__(self):
2726
return str(self.x) + "," + str(self.y) + "," + str(self.cost) + "," + str(self.pind)
2827

29-
30-
def calc_final_path(ngoal, closedset, reso):
31-
# generate final course
32-
rx, ry = [ngoal.x * reso], [ngoal.y * reso]
33-
pind = ngoal.pind
34-
while pind != -1:
35-
n = closedset[pind]
36-
rx.append(n.x * reso)
37-
ry.append(n.y * reso)
38-
pind = n.pind
39-
40-
return rx, ry
41-
42-
4328
def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
4429
"""
45-
gx: goal x position [m]
46-
gx: goal x position [m]
47-
ox: x position list of Obstacles [m]
48-
oy: y position list of Obstacles [m]
49-
reso: grid resolution [m]
50-
rr: robot radius[m]
30+
A star path search
31+
32+
input:
33+
sx: start x position [m]
34+
sy: start y position [m]
35+
gx: goal x position [m]
36+
gx: goal x position [m]
37+
ox: x position list of Obstacles [m]
38+
oy: y position list of Obstacles [m]
39+
reso: grid resolution [m]
40+
rr: robot radius[m]
41+
42+
output:
43+
rx: x position list of the final path
44+
ry: y position list of the final path
5145
"""
5246

53-
nstart = Node(round(sx / reso), round(sy / reso), 0.0, -1)
54-
ngoal = Node(round(gx / reso), round(gy / reso), 0.0, -1)
5547
ox = [iox / reso for iox in ox]
5648
oy = [ioy / reso for ioy in oy]
5749

5850
obmap, minx, miny, maxx, maxy, xw, yw = calc_obstacle_map(ox, oy, reso, rr)
5951

6052
motion = get_motion_model()
6153

54+
nstart = Node(calc_xyindex(sx, minx, reso), calc_xyindex(sy, minx, reso), 0.0, -1)
55+
ngoal = Node(calc_xyindex(gx, minx, reso), calc_xyindex(gy, minx, reso), 0.0, -1)
56+
6257
openset, closedset = dict(), dict()
6358
openset[calc_index(nstart, xw, minx, miny)] = nstart
6459

@@ -69,7 +64,7 @@ def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
6964

7065
# show graph
7166
if show_animation: # pragma: no cover
72-
plt.plot(current.x * reso, current.y * reso, "xc")
67+
plt.plot(calc_position(current.x, minx, reso), calc_position(current.y, miny, reso), "xc")
7368
if len(closedset.keys()) % 10 == 0:
7469
plt.pause(0.001)
7570

@@ -81,6 +76,7 @@ def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
8176

8277
# Remove the item from the open set
8378
del openset[c_id]
79+
8480
# Add it to the closed set
8581
closedset[c_id] = current
8682

@@ -94,7 +90,7 @@ def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
9490
if n_id in closedset:
9591
continue
9692

97-
if not verify_node(node, obmap, minx, miny, maxx, maxy):
93+
if not verify_node(node, obmap, minx, miny, maxx, maxy, reso):
9894
continue
9995

10096
if n_id not in openset:
@@ -104,26 +100,49 @@ def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
104100
# This path is the best until now. record it!
105101
openset[n_id] = node
106102

107-
rx, ry = calc_final_path(ngoal, closedset, reso)
103+
rx, ry = calc_final_path(ngoal, closedset, reso, minx, miny)
108104

109105
return rx, ry
110106

111107

108+
109+
def calc_final_path(ngoal, closedset, reso, minx, miny):
110+
# generate final course
111+
rx, ry = [calc_position(ngoal.x, minx, reso)], [calc_position(ngoal.y, miny, reso)]
112+
pind = ngoal.pind
113+
while pind != -1:
114+
n = closedset[pind]
115+
rx.append(calc_position(n.x, minx, reso))
116+
ry.append(calc_position(n.y, miny, reso))
117+
pind = n.pind
118+
119+
return rx, ry
120+
121+
122+
112123
def calc_heuristic(n1, n2):
113124
w = 1.0 # weight of heuristic
114125
d = w * math.sqrt((n1.x - n2.x)**2 + (n1.y - n2.y)**2)
115126
return d
116127

128+
def calc_position(index, minp, reso):
129+
return index*reso+minp
117130

118-
def verify_node(node, obmap, minx, miny, maxx, maxy):
131+
def calc_xyindex(position, minp, reso):
132+
return round((position - minp)/reso)
119133

120-
if node.x < minx:
134+
def verify_node(node, obmap, minx, miny, maxx, maxy, reso):
135+
136+
px = calc_position(node.x, minx, reso)
137+
py = calc_position(node.y, miny, reso)
138+
139+
if px < minx:
121140
return False
122-
elif node.y < miny:
141+
elif py < miny:
123142
return False
124-
elif node.x >= maxx:
143+
elif px >= maxx:
125144
return False
126-
elif node.y >= maxy:
145+
elif py >= maxy:
127146
return False
128147

129148
if obmap[node.x][node.y]:
@@ -132,32 +151,31 @@ def verify_node(node, obmap, minx, miny, maxx, maxy):
132151
return True
133152

134153

135-
def calc_obstacle_map(ox, oy, reso, vr):
154+
def calc_obstacle_map(ox, oy, reso, rr):
136155

137156
minx = round(min(ox))
138157
miny = round(min(oy))
139158
maxx = round(max(ox))
140159
maxy = round(max(oy))
141-
# print("minx:", minx)
142-
# print("miny:", miny)
143-
# print("maxx:", maxx)
144-
# print("maxy:", maxy)
160+
print("minx:", minx)
161+
print("miny:", miny)
162+
print("maxx:", maxx)
163+
print("maxy:", maxy)
145164

146165
xwidth = round(maxx - minx)
147166
ywidth = round(maxy - miny)
148-
# print("xwidth:", xwidth)
149-
# print("ywidth:", ywidth)
167+
print("xwidth:", xwidth)
168+
print("ywidth:", ywidth)
150169

151170
# obstacle map generation
152171
obmap = [[False for i in range(ywidth)] for i in range(xwidth)]
153172
for ix in range(xwidth):
154173
x = ix + minx
155174
for iy in range(ywidth):
156175
y = iy + miny
157-
# print(x, y)
158176
for iox, ioy in zip(ox, oy):
159177
d = math.sqrt((iox - x)**2 + (ioy - y)**2)
160-
if d <= vr / reso:
178+
if d <= rr:
161179
obmap[ix][iy] = True
162180
break
163181

@@ -191,37 +209,37 @@ def main():
191209
gx = 50.0 # [m]
192210
gy = 50.0 # [m]
193211
grid_size = 1.0 # [m]
194-
robot_size = 1.0 # [m]
212+
robot_radius = 1.0 # [m]
195213

214+
# set obstable positions
196215
ox, oy = [], []
197-
198-
for i in range(60):
216+
for i in range(-10, 60):
199217
ox.append(i)
200-
oy.append(0.0)
201-
for i in range(60):
218+
oy.append(-10.0)
219+
for i in range(-10, 60):
202220
ox.append(60.0)
203221
oy.append(i)
204-
for i in range(61):
222+
for i in range(-10, 61):
205223
ox.append(i)
206224
oy.append(60.0)
207-
for i in range(61):
208-
ox.append(0.0)
225+
for i in range(-10, 61):
226+
ox.append(-10.0)
209227
oy.append(i)
210-
for i in range(40):
228+
for i in range(-10, 40):
211229
ox.append(20.0)
212230
oy.append(i)
213-
for i in range(40):
231+
for i in range(0, 40):
214232
ox.append(40.0)
215233
oy.append(60.0 - i)
216234

217235
if show_animation: # pragma: no cover
218236
plt.plot(ox, oy, ".k")
219-
plt.plot(sx, sy, "xr")
237+
plt.plot(sx, sy, "og")
220238
plt.plot(gx, gy, "xb")
221239
plt.grid(True)
222240
plt.axis("equal")
223241

224-
rx, ry = a_star_planning(sx, sy, gx, gy, ox, oy, grid_size, robot_size)
242+
rx, ry = a_star_planning(sx, sy, gx, gy, ox, oy, grid_size, robot_radius)
225243

226244
if show_animation: # pragma: no cover
227245
plt.plot(rx, ry, "-r")

0 commit comments

Comments
 (0)