Skip to content

Commit b06e42f

Browse files
committed
first release grid based_sweep_planner.py
1 parent 474ffef commit b06e42f

File tree

3 files changed

+92
-71
lines changed

3 files changed

+92
-71
lines changed

Mapping/grid_map_lib/grid_map_lib.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,13 @@ def set_value_from_xy_index(self, x_ind, y_ind, val):
9898
:param val: grid value
9999
"""
100100

101+
if (x_ind is None) or (y_ind is None):
102+
print(x_ind, y_ind)
103+
return False, False
104+
101105
grid_ind = int(y_ind * self.width + x_ind)
102106

103-
if 0 <= grid_ind <= self.ndata:
107+
if 0 <= grid_ind < self.ndata:
104108
self.data[grid_ind] = val
105109
return True # OK
106110
else:
@@ -164,6 +168,23 @@ def check_occupied_from_xy_index(self, xind, yind, occupied_val=1.0):
164168
else:
165169
return False
166170

171+
def expand_grid(self):
172+
xinds, yinds = [], []
173+
174+
for ix in range(self.width):
175+
for iy in range(self.height):
176+
if self.check_occupied_from_xy_index(ix, iy):
177+
xinds.append(ix)
178+
yinds.append(iy)
179+
180+
for (ix, iy) in zip(xinds, yinds):
181+
self.set_value_from_xy_index(ix + 1, iy, val=1.0)
182+
self.set_value_from_xy_index(ix, iy + 1, val=1.0)
183+
self.set_value_from_xy_index(ix + 1, iy + 1, val=1.0)
184+
self.set_value_from_xy_index(ix - 1, iy, val=1.0)
185+
self.set_value_from_xy_index(ix, iy - 1, val=1.0)
186+
self.set_value_from_xy_index(ix - 1, iy - 1, val=1.0)
187+
167188
@staticmethod
168189
def check_inside_polygon(iox, ioy, x, y):
169190

PathPlanning/AStar/a_star.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
1010
"""
1111

12-
import matplotlib.pyplot as plt
1312
import math
1413

14+
import matplotlib.pyplot as plt
15+
1516
show_animation = True
1617

1718

@@ -66,6 +67,10 @@ def planning(self, sx, sy, gx, gy):
6667
open_set[self.calc_grid_index(nstart)] = nstart
6768

6869
while 1:
70+
if len(open_set) == 0:
71+
print("Open set is empty..")
72+
break
73+
6974
c_id = min(
7075
open_set, key=lambda o: open_set[o].cost + self.calc_heuristic(ngoal, open_set[o]))
7176
current = open_set[c_id]
@@ -89,25 +94,25 @@ def planning(self, sx, sy, gx, gy):
8994
# Add it to the closed set
9095
closed_set[c_id] = current
9196

92-
# expand search grid based on motion model
97+
# expand_grid search grid based on motion model
9398
for i, _ in enumerate(self.motion):
9499
node = self.Node(current.x + self.motion[i][0],
95100
current.y + self.motion[i][1],
96101
current.cost + self.motion[i][2], c_id)
97102
n_id = self.calc_grid_index(node)
98103

99-
# If the node is in closed_set, do nothing
100-
if n_id in closed_set:
101-
continue
102104

103105
# If the node is not safe, do nothing
104106
if not self.verify_node(node):
105107
continue
106108

109+
if n_id in closed_set:
110+
continue
111+
107112
if n_id not in open_set:
108113
open_set[n_id] = node # discovered a new node
109114
else:
110-
if open_set[n_id].cost >= node.cost:
115+
if open_set[n_id].cost > node.cost:
111116
# This path is the best until now. record it
112117
open_set[n_id] = node
113118

PathPlanning/GridBasedSweepCCP/grid_based_sweep_planner.py

Lines changed: 59 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
import numpy as np
1313

1414
sys.path.append(os.path.relpath("../../Mapping/grid_map_lib/"))
15-
from grid_map_lib import GridMap
15+
try:
16+
from grid_map_lib import GridMap
17+
except ImportError:
18+
exit()
19+
20+
do_animation = True
1621

1722

1823
class SweepSearcher:
@@ -35,14 +40,16 @@ def move_target_grid(self, cxind, cyind, gmap):
3540
return nxind, nyind
3641
else: # occupided
3742
ncxind, ncyind = self.find_safe_turning_grid(cxind, cyind, gmap)
38-
if not ncxind and not ncyind:
43+
if (ncxind is None) and (ncyind is None):
3944
# moving backward
4045
ncxind = -self.moving_direction + cxind
4146
ncyind = cyind
4247
if gmap.check_occupied_from_xy_index(ncxind, ncyind):
4348
# moved backward, but the grid is occupied by obstacle
4449
return None, None
4550
else:
51+
while not gmap.check_occupied_from_xy_index(ncxind + self.moving_direction, ncyind, occupied_val=0.5):
52+
ncxind += self.moving_direction
4653
self.swap_moving_direction()
4754
return ncxind, ncyind
4855

@@ -55,7 +62,6 @@ def find_safe_turning_grid(self, cxind, cyind, gmap):
5562

5663
# found safe grid
5764
if not gmap.check_occupied_from_xy_index(nxind, nyind, occupied_val=0.5):
58-
print(dxind, dyind)
5965
return nxind, nyind
6066

6167
return None, None
@@ -81,34 +87,22 @@ def swap_moving_direction(self):
8187
self.update_turning_window()
8288

8389

84-
def find_sweep_direction_and_start_posi(ox, oy, start_posi):
90+
def find_sweep_direction_and_start_posi(ox, oy):
8591
# find sweep_direction
86-
maxd_id = None
8792
maxd = 0.0
8893
vec = [0.0, 0.0]
94+
sweep_start_pos = [0.0, 0.0]
8995
for i in range(len(ox) - 1):
9096
dx = ox[i + 1] - ox[i]
9197
dy = oy[i + 1] - oy[i]
9298
d = np.sqrt(dx ** 2 + dy ** 2)
9399

94100
if d > maxd:
95-
maxd_id = i
96101
maxd = d
97102
vec = [dx, dy]
103+
sweep_start_pos = [ox[i], oy[i]]
98104

99-
# find sweep start posi
100-
d1 = np.sqrt((ox[maxd_id] - start_posi[0]) ** 2 +
101-
(oy[maxd_id] - start_posi[1]) ** 2)
102-
d2 = np.sqrt((ox[maxd_id + 1] - start_posi[0]) ** 2 +
103-
(oy[maxd_id + 1] - start_posi[1]) ** 2)
104-
105-
if d2 >= d1: # first point is near
106-
sweep_start_posi = [ox[maxd_id], oy[maxd_id]]
107-
else:
108-
sweep_start_posi = [ox[maxd_id + 1], oy[maxd_id + 1]]
109-
vec = [-1.0 * iv for iv in vec] # reverse direction
110-
111-
return vec, sweep_start_posi
105+
return vec, sweep_start_pos
112106

113107

114108
def convert_grid_coordinate(ox, oy, sweep_vec, sweep_start_posi):
@@ -140,19 +134,26 @@ def convert_global_coordinate(x, y, sweep_vec, sweep_start_posi):
140134
return rx, ry
141135

142136

143-
def search_free_lower_y_grid_index(grid_map):
144-
miny = None
137+
def search_free_grid_index_at_edge_y(grid_map, from_upper=False):
138+
yind = None
145139
xinds = []
146140

147-
for iy in range(grid_map.height):
148-
for ix in range(grid_map.width):
141+
if from_upper:
142+
xrange = range(grid_map.height)[::-1]
143+
yrange = range(grid_map.width)[::-1]
144+
else:
145+
xrange = range(grid_map.height)
146+
yrange = range(grid_map.width)
147+
148+
for iy in xrange:
149+
for ix in yrange:
149150
if not grid_map.check_occupied_from_xy_index(ix, iy):
150-
miny = iy
151+
yind = iy
151152
xinds.append(ix)
152-
if miny:
153+
if yind:
153154
break
154155

155-
return xinds, miny
156+
return xinds, yind
156157

157158

158159
def setup_grid_map(ox, oy, reso):
@@ -167,47 +168,33 @@ def setup_grid_map(ox, oy, reso):
167168

168169
grid_map.set_value_from_polygon(ox, oy, 1.0, inside=False)
169170

170-
# fill grid
171-
# for i in range(len(ox) - 1):
172-
# grid_map.set_value_from_xy_pos(ox[i], oy[i], 1.0)
173-
#
174-
# x, y = ox[i], oy[i]
175-
# th = math.atan2(oy[i + 1] - oy[i], ox[i + 1] - ox[i])
176-
# d = np.sqrt((x - ox[i + 1])**2 + (y - oy[i + 1])**2)
177-
#
178-
# while d > reso:
179-
# x += np.cos(th) * reso
180-
# y += np.sin(th) * reso
181-
# d = np.sqrt((x - ox[i + 1])**2 + (y - oy[i + 1])**2)
182-
#
183-
# grid_map.set_value_from_xy_pos(x, y, 1.0)
184-
185-
xinds, miny = search_free_lower_y_grid_index(grid_map)
186-
187-
# grid_map.plot_gridmap()
171+
grid_map.expand_grid()
172+
173+
xinds, miny = search_free_grid_index_at_edge_y(grid_map)
188174

189175
return grid_map, xinds, miny
190176

191177

192-
def sweep_path_search(sweep_searcher, gmap, start_posi):
193-
sx, sy = start_posi[0], start_posi[1]
194-
# print(sx, sy)
178+
def search_start_grid(grid_map):
179+
xinds, y_ind = search_free_grid_index_at_edge_y(grid_map, from_upper=True)
180+
181+
return min(xinds), y_ind
195182

196-
# search start grid
197-
cxind, cyind = gmap.get_xy_index_from_xy_pos(sx, sy)
198-
if gmap.check_occupied_from_xy_index(cxind, cyind):
199-
cxind, cyind = sweep_searcher.find_safe_turning_grid(cxind, cyind, gmap)
200-
gmap.set_value_from_xy_index(cxind, cyind, 0.5)
201183

184+
def sweep_path_search(sweep_searcher, gmap):
202185
px, py = [], []
203186

204-
# fig, ax = plt.subplots()
187+
# search start grid
188+
cxind, cyind = search_start_grid(gmap)
189+
if not gmap.set_value_from_xy_index(cxind, cyind, 0.5):
190+
print("Cannot find start grid")
191+
return px, py
205192

193+
# fig, ax = plt.subplots()
206194
while True:
207-
208195
cxind, cyind = sweep_searcher.move_target_grid(cxind, cyind, gmap)
209196

210-
if sweep_searcher.is_search_done(gmap) or (not cxind and not cyind):
197+
if sweep_searcher.is_search_done(gmap) or (cxind is None or cyind is None):
211198
print("Done")
212199
break
213200

@@ -220,16 +207,15 @@ def sweep_path_search(sweep_searcher, gmap, start_posi):
220207
gmap.set_value_from_xy_index(cxind, cyind, 0.5)
221208

222209
# gmap.plot_grid_map(ax=ax)
223-
# plt.pause(0.1)
210+
# plt.pause(1.0)
224211

225212
gmap.plot_grid_map()
226213

227214
return px, py
228215

229216

230-
def planning(ox, oy, reso, start_posi):
231-
sweep_vec, sweep_start_posi = find_sweep_direction_and_start_posi(
232-
ox, oy, start_posi)
217+
def planning(ox, oy, reso):
218+
sweep_vec, sweep_start_posi = find_sweep_direction_and_start_posi(ox, oy)
233219

234220
rox, roy = convert_grid_coordinate(ox, oy, sweep_vec, sweep_start_posi)
235221

@@ -240,7 +226,7 @@ def planning(ox, oy, reso, start_posi):
240226

241227
sweep_searcher = SweepSearcher(moving_direction, sweeping_direction, xinds_miny, miny)
242228

243-
px, py = sweep_path_search(sweep_searcher, gmap, start_posi)
229+
px, py = sweep_path_search(sweep_searcher, gmap)
244230

245231
rx, ry = convert_global_coordinate(px, py, sweep_vec, sweep_start_posi)
246232

@@ -250,17 +236,26 @@ def planning(ox, oy, reso, start_posi):
250236
def main():
251237
print("start!!")
252238

253-
start_posi = [0.0, 0.0]
254-
255239
ox = [0.0, 20.0, 50.0, 100.0, 130.0, 40.0, 0.0]
256240
oy = [0.0, -20.0, 0.0, 30.0, 60.0, 80.0, 0.0]
257241
reso = 5.0
258242

259-
px, py = planning(ox, oy, reso, start_posi)
243+
px, py = planning(ox, oy, reso)
260244

261245
plt.subplots()
262246

263-
plt.plot(start_posi[0], start_posi[1], "or")
247+
# animation
248+
if do_animation:
249+
for ipx, ipy in zip(px, py):
250+
plt.cla()
251+
plt.plot(ox, oy, "-xb")
252+
plt.plot(px, py, "-r")
253+
plt.plot(ipx, ipy, "or")
254+
plt.axis("equal")
255+
plt.grid(True)
256+
plt.pause(0.1)
257+
258+
plt.cla()
264259
plt.plot(ox, oy, "-xb")
265260
plt.plot(px, py, "-r")
266261
plt.axis("equal")

0 commit comments

Comments
 (0)