专栏名称: 新机器视觉
最前沿的机器视觉与计算机视觉技术
51好读  ›  专栏  ›  新机器视觉

手搓ROS应用 | 全局规划与局部避障系统

新机器视觉  · 公众号  · 机器人 科技自媒体  · 2024-11-16 21:36

正文

全局规划与局部避障系统



全局路径规划与局部动态避障是机器人导航领域中两个核心组成部分。全局路径规划确定了从起点到终点的最优路径,而局部动态避障负责在机器人执行全局路径时,实时避开障碍物。全局路径规划通常使用静态地图或环境模型来生成路径,而局部动态避障则在机器人移动过程中根据周围的动态环境进行实时调整。本文将深入探讨实现全局路径规划和局部动态避障的知识,分析其算法原理,并提供相应的代码示例。



一、全局路径规划


全局路径规划是指从地图上计算出机器人从起始点到目标点的最优路径。常见的全局路径规划算法有Dijkstra算法、A算法和D算法。


1. Dijkstra算法


Dijkstra算法是一种基于权重图的单源最短路径算法。它使用优先队列来遍历节点,通过记录每个节点的最小开销来找到到目标节点的最优路径。Dijkstra算法适合于静态地图中的全局路径规划,但由于其不考虑启发式信息,效率较低。


公式如下:



其中, d(u) 表示从起点到节点 u 的最小开销, w(v, u) 表示边 (v, u) 的权重。


2. A*算法


A算法是对Dijkstra算法的优化,引入了启发式函数 ( h(n) ),使得在搜索过程中优先探索距离目标点较近的节点。A算法通常用于网格地图的全局路径规划,启发式函数通常选用欧几里得距离或曼哈顿距离。


A*算法的代价函数公式如下:



其中, g(n) 表示从起点到节点 n 的实际开销, h(n) 表示从节点 n 到目标的启发式估计值。


3. D* Lite算法


D* Lite算法是D算法的简化版,适用于动态环境的全局路径规划。它允许在环境发生变化时动态调整路径,使得机器人能够重新规划最优路径。D Lite算法主要应用于未知环境和实时规划。



二、局部动态避障


局部动态避障主要通过机器人周围的传感器信息(如激光雷达、超声波传感器等)检测环境中的动态障碍物,然后根据当前的运动模型调整路径。常见的局部避障算法包括动态窗口法(DWA)、VFH(向量场直方图)以及人工势场法(APF)。


1. 动态窗口法(DWA)


动态窗口法基于速度空间进行避障。它在给定的时间窗内,根据机器人当前的速度和加速度限制,生成一系列可行的速度组合,并计算每种组合在障碍物间的安全性和目标距离。DWA通过对这些速度组合进行打分,选择得分最高的速度组合执行。


DWA的代价函数:




2. 向量场直方图(VFH)


VFH方法基于直方图对机器人周围环境进行分析,将环境划分为不同的扇区,判断障碍物所在位置,并生成避障路径。它能够快速适应动态障碍物变化,但在复杂环境下可能产生振荡问题。


3. 人工势场法(APF)


APF将目标点视为吸引力源,障碍物视为排斥力源。通过计算吸引力和排斥力的合力方向来引导机器人运动。其力学模型如下:



其中, q 表示机器人的当前位置, qgoal 表示目标位置, d(q) 表示当前点到障碍物的距离, dsafe 是安全距离。



三、全局路径规划与局部避障系统集成



在实际应用中,全局路径规划和局部避障通常是联合使用的。机器人首先通过全局路径规划算法计算出从起点到终点的路径,并在执行过程中依靠局部避障算法实时避开动态障碍物。



四、代码实现


以下代码实现了一个简单的全局路径规划与局部动态避障系统,结合A*算法进行全局路径规划,结合DWA进行局部避障。机器人在2D栅格地图上找到起点到终点的路径,并在遇到障碍物时进行避障调整。


import numpy as npimport heapq
# 全局路径规划 - A*算法def a_star(start, goal, grid):   rows, cols = grid.shape   open_list = []   heapq.heappush(open_list, (0, start))   came_from = {}   cost_so_far = {start: 0}   came_from[start] = None
  while open_list:       _, current = heapq.heappop(open_list)
      if current == goal:           break
      for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:           neighbor = (current[0] + dx, current[1] + dy)           if 0 <= neighbor[0] < rows and 0 <= neighbor[1] < cols and grid[neighbor] == 0:               new_cost = cost_so_far[current] + 1               if neighbor not in cost_so_far or new_cost < cost_so_far[neighbor]:                   cost_so_far[neighbor] = new_cost                   priority = new_cost + np.hypot(goal[0] - neighbor[0], goal[1] - neighbor[1])                   heapq.heappush(open_list, (priority, neighbor))                   came_from[neighbor] = current
  # 路径重建   path = []   if goal in came_from:       while goal:           path.append(goal)           goal = came_from[goal]       path.reverse()   return path
# 局部动态避障 - 简化版DWA算法def dwa(robot_pos, goal, obstacles, dt=0.1, max_speed=1.0, max_turn_rate=np.pi/4):   # 生成速度组合   v_samples = np.linspace(0, max_speed, 5)   w_samples = np.linspace(-max_turn_rate, max_turn_rate, 5)   best_v, best_w = 0, 0   min_cost = float('inf')
  for v in v_samples:       for w in w_samples:           new_pos = robot_pos + np.array([v * np.cos(robot_pos[2]) * dt, v * np.sin(robot_pos[2]) * dt, w * dt])           heading_cost = np.hypot(goal[0] - new_pos[0], goal[1] - new_pos[1])           obstacle_cost = min(np.hypot(new_pos[0] - obs[0], new_pos[1] - obs[1]) for obs in obstacles)
          if obstacle_cost > 0.5:  # 安全距离               total_cost = heading_cost + 1.0 / (obstacle_cost + 1e-5)               if total_cost < min_cost:                   min_cost, best_v, best_w = total_cost, v, w
  return best_v, best_w
# 示例环境设置grid = np.zeros((10, 10))grid[5, 3:7] = 1  # 障碍物start, goal = (0, 0), (9, 9)path = a_star(start, goal, grid)
# 机器人执行路径robot_pos = np.array([start[0], start[1], 0.0])  # 初始位置和角度obstacles =
[(5, y) for y in range(3, 7)]for target in path:   while np.hypot(robot_pos[0] - target[0], robot_pos[1] - target[1]) > 0.1:       v, w = dwa(robot_pos, target, obstacles)       robot_pos += np.array([v * np.cos(robot_pos[2]), v * np.sin(robot_pos[2]), w])       print("当前位置:", robot_pos[:2])



五、总结


本文系统介绍了全局路径规划与局部动态避障的相关知识,并给出了A*算法和DWA算法的代码实现。通过代码实现的例子,可以帮助理解如何结合两者构建一个自主导航系统。


转自:古月居


本文仅做学术分享,如有侵权,请联系删文。