私はロボット プロジェクト (SVG ファイルから生成されたいくつかのセンサーとマップを使用して自分自身をローカライズする「自律型」車) のフロント エンドに取り組んでいます。
ロボットを制御可能にするには、現在の位置と目標の間のパスを生成する必要があります。そのために最も簡単なアルゴリズムを使用しました:A *。
これを行うと、奇妙な結果が得られました。車は 45 度の倍数で進む傾向があり、特に厄介な問題が 1 つあります。
この場合、オレンジ色の四角形の近くにノイズの多いパスが表示されます。
これらの奇妙な/ノイズの多い結果を回避する方法はありますか? 最終的には、方向角の変更が最小限のパスを作成する必要があります。(車は移動せずに曲がることができるため、パスの「平滑化」は必要ありません)。
これが私の A* 実装です:
def search(self, begin, goal):
if goal.x not in range(self.width) or goal.y not in range(self.height):
print "Goal is out of bound"
return []
elif not self.grid[begin.y][begin.x].reachable:
print "Beginning is unreachable"
return []
elif not self.grid[goal.y][goal.x].reachable:
print "Goal is unreachable"
return []
else:
self.cl = set()
self.ol = set()
curCell = begin
self.ol.add(curCell)
while len(self.ol) > 0:
# We choose the cell in the open list having the minimum score as our current cell
curCell = min(self.ol, key = lambda x : x.f)
# We add the current cell to the closed list
self.ol.remove(curCell)
self.cl.add(curCell)
# We check the cell's (reachable) neighbours :
neighbours = self.neighbours(curCell)
for cell in neighbours:
# If the goal is a neighbour cell :
if cell == goal:
cell.parent = curCell
self.path = cell.path()
self.display()
self.clear()
return self.path
elif cell not in self.cl:
# We process the cells that are not in the closed list
# (processing <-> calculating the "F" score)
cell.process(curCell, goal)
self.ol.add(cell)
EDIT 1:一般的な要求により、スコア計算関数 (プロセス) は次のとおりです。
def process(self, parent, goal):
self.parent = parent
self.g = parent.distance(self)
self.h = self.manhattanDistance(goal)
self.f = self.g + self.h
編集これが隣人の方法です(user1884905の回答に従って更新されました):
def neighbours(self, cell, radius = 1, unreachables = False, diagonal = True):
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 ) and (diagonal or (x == cell.x or y == cell.y)) :
neighbours.add(self.grid[y][x])
return neighbours
(これは複雑に見えますが、セルの 8 つの隣接要素 (対角線の隣接要素を含む) を提供するだけです。他の機能に使用されるため、1 以外の半径を取ることもできます)
および距離の計算 (対角線を使用するかどうかに応じて:)
def manhattanDistance(self, cell):
return abs(self.x - cell.x) + abs(self.y - cell.y)
def diagonalDistance(self, cell):
xDist = abs(self.x - cell.x)
yDist = abs(self.y - cell.y)
if xDist > yDist:
return 1.4 * yDist + (xDist - yDist)
else:
return 1.4 * xDist + (yDist - xDist)