For an A* implementation (to generate a path for a 'car' robot), I need to adapt my model to take into account the car's 'width' and hence avoid obstacles.
One idea I got is to expand all obstacles by the car's width, that way all the cells that are too close to an obstacle will be also marked as obstacles.
I tried using two naive algorithms to do this, but it's still too slow (especially on big grids) because it goes through the same cells many times:
unreachable = set()
# I first add all the unreachables to a set to avoid 'propagation'
for line in self.grid:
for cell in line:
if not cell.reachable:
unreachable.add(cell)
for cell in unreachable:
# I set as unreachable all the cell's neighbours in a certain radius
for nCell in self.neighbours( cell, int(radius/division) ):
nCell.reachable = False
Here's the definition of neighbours:
def neighbours(self, cell, radius = 1, unreachables = False):
neighbours = set()
for i in xrange(-radius, radius + 1):
for j in xrange(-radius, radius + 1):
x = cell.x + j
y = cell.y + i
if 0 <= y < self.height and 0 <= x < self.width and (self.grid[y][x].reachable or unreachables )) :
neighbours.add(self.grid[y][x])
return neighbours
Is there any sequential algorithm (or O(n.log(n))) that could do the same thing ?
您要寻找的是所谓的Minkowski sum ,并且如果您的障碍物和汽车是凸的,则有一个线性算法可以对其进行计算。
I ended up using convolution product, with my 'map' (a matrix where '1' is an obstacle and '0' is a free cell) as the first operand and a matrix of the car's size and all filled with '1's as the second operand.
The convolution product of those two matrices gives a matrix where the cells that weren't in reach of any obstacle (that is: didn't have any obstacle in the neighberhood) have a value of '0', and those who had at least one obstacle in their neighberhood (that is a cell equal to '1') have a value != 0.
Here's the Python implementation (using scipy for the convolution product) :
# r: car's radius; 1 : Unreachable ; 0 : Reachable
car = scipy.array( [[1 for i in xrange(r)] for j in xrange(r)] )
# Converting my map to a binary matrix
grid = scipy.array( [[0 if self.grid[i][j].reachable else 1 for j in xrange(self.width)] for i in xrange(self.height)] )
result = scipy.signal.fftconvolve( grid, car, 'same' )
# Updating the map with the result
for i in xrange(self.height):
for j in xrange(self.width):
self.grid[i][j].reachable = int(result[i][j]) == 0
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.