自动驾驶算法详解(6):Astar算法原理以及路径规划应用在python与ros平台实现

一、算法原理

Astar算法流程图如下:

 Astar算法是一种图形搜索算法,常用于路径规划。它是个以广度优先搜索为基础,集Dijkstra算法与最佳优先(best fit)算法特点于一身的一种算法。

Astar算法从起点开始向周围扩张,通过估计函数不断计算周围相邻点的cost,并选择cost最小的节点作为下一次进行扩张的节点,按此规则一直循环直到搜索到终点。

其中每个扩展节点对应的估值函数记为:

f(n) = g(n) + h(n)

g(n) 表示当前节点的实际代价函数;

h(n) 表示当前节点至目标节点的估值函数,常用的估值方法有欧式距离、曼哈顿距离等;

二、代码实现及注释

# init astar plannet
resolution = grid_size 
rr = robot_radius
min_x, min_y = 0, 0
max_x, max_y = 0, 0
obstacle_map = None
x_width, y_width = 0, 0
motion = get_motion_model()

### calc_obstacle_map
min_x = round(min(ox))
min_y = round(min(oy))
max_x = round(max(ox))
max_y = round(max(oy))
# cal map width
x_width = round((max_x - min_x) / resolution)
y_width = round((max_y - min_y) / resolution)
# generate map with obstacle
obstacle_map = [[False for _ in range(y_width)]
 for _ in range(x_width)]
for ix in range(x_width):
    x = calc_grid_position(ix, min_x)
 for iy in range(y_width):
        y = calc_grid_position(iy, min_y)
 for iox, ioy in zip(ox, oy):
            d = math.hypot(iox - x, ioy - y)
 if d <= rr:
                obstacle_map[ix][iy] = True
 break 

### start planning                
# define node
start_node = Node(calc_xy_index(sx, min_x),
                       calc_xy_index(sy, min_y), 0.0, -1)
goal_node = Node(calc_xy_index(gx, min_x),
                      calc_xy_index(gy, min_y), 0.0, -1)
# define 
open_set, closed_set = dict(), dict()
open_set[calc_grid_index(start_node)] = start_node

search_index = 0
while 1 :
 if len(open_set) == 0:
 print("Open set is empty..")
 break

    c_id = min(
        open_set,
        key=lambda o: open_set[o].cost + calc_heuristic(goal_node,open_set[o]))
    current = open_set[c_id]

 if current.x == goal_node.x and current.y == goal_node.y:
 print("Find goal")
        goal_node.parent_index = current.parent_index
        goal_node.cost = current.cost
 break

 # Remove the item from the open set
 del open_set[c_id]

 # Add it to the closed set
    closed_set[c_id] = current

 # expand_grid search grid based on motion model
 for i, _ in enumerate(motion):
        node = Node(current.x + motion[i][0],
                         current.y + motion[i][1],
                         current.cost + motion[i][2], c_id)
        n_id = calc_grid_index(node)

 # If the node is not safe, do nothing
 if not verify_node(node):
 continue

 if n_id in closed_set:
 continue

 if n_id not in open_set:
            open_set[n_id] = node  # discovered a new node
 else:
 if open_set[n_id].cost > node.cost:
 # This path is the best until now. record it
                open_set[n_id] = node
 
    search_index = search_index + 1

rx, ry = calc_final_path(goal_node, closed_set)

三、结果分析

在代码中可以设置启发函数的权重w,可以看到不同的w对搜索的速度与结果有直接影响

1、w = 10 的搜索结果,可以看到最终的搜索步数为43

2、 w = 0 的搜索结果,可以看到最终的搜索步数为146

3、 w = 2 的搜索结果,可以看到最终的搜索步数为88

 

 

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是Python实现A*算法的代码。首先,需要定义一个`Node`类来表示节点,包括节点的坐标、f、g、h值和父节点。 ```python class Node: def __init__(self, x, y, f=0, g=0, h=0, parent=None): self.x = x self.y = y self.f = f self.g = g self.h = h self.parent = parent ``` 接下来,定义A*算法主函数`astar_search()`,其中包括启发式函数`heuristic()`和计算节点花费函数`cost()`。 ```python import heapq def heuristic(node, goal): return abs(node.x - goal.x) + abs(node.y - goal.y) def cost(current, next): return 1 def astar_search(map, start, goal): start_node = Node(start[0], start[1]) goal_node = Node(goal[0], goal[1]) open_list = [] closed_list = [] heapq.heappush(open_list, (start_node.f, start_node)) while open_list: current_node = heapq.heappop(open_list)[1] if current_node.x == goal_node.x and current_node.y == goal_node.y: path = [] while current_node.parent: path.append((current_node.x, current_node.y)) current_node = current_node.parent path.append((start_node.x, start_node.y)) return path[::-1] closed_list.append(current_node) for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]: next_node = Node(current_node.x + dx, current_node.y + dy) if next_node.x < 0 or next_node.x >= len(map) or next_node.y < 0 or next_node.y >= len(map[0]): continue if map[next_node.x][next_node.y] == 1: continue if next_node in closed_list: continue next_node.g = current_node.g + cost(current_node, next_node) next_node.h = heuristic(next_node, goal_node) next_node.f = next_node.g + next_node.h next_node.parent = current_node if any((next_node.f, node) in open_list for node in open_list): continue heapq.heappush(open_list, (next_node.f, next_node)) return None ``` 最后,定义一个地图并调用`astar_search()`函数进行路径规划。 ```python map = [[0, 0, 0, 0, 0], [0, 1, 0, 1, 0], [0, 1, 0, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 1, 0]] start = (0, 0) goal = (4, 4) path = astar_search(map, start, goal) print(path) ``` 输出结果为`[(0, 0), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (4, 2), (4, 3), (4, 4)]`,表示从起点(0,0)到终点(4,4)的路径

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自动驾驶Player

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值