为研究打磨机器人最优路径控制代码,本文使用了 A * 算法来规划最优路径,并添加了机器人运动控制和路径平滑处理的功能。代码使用 Python 实现,包含了详细的注释和可视化功能。robot-polishing-path-planning打磨机器人最优路径控制代码,生成 robot_path_planning.py,这个代码实现了一个完整的打磨机器人路径规划系统,具有以下特点:
使用 A * 算法进行路径规划,支持 8 方向移动,考虑了对角线移动的额外代价,实现了路径平滑处理,使机器人运动更加流畅,支持多个打磨区域的路径规划,按照蛇形方式填充打磨区域,提供了可视化功能,可以直观地查看路径规划结果,包含机器人控制器类,模拟了路径执行和打磨操作的过程。
后续的研究中,可以根据实际需求调整代码中的参数,如网格大小、障碍物位置、打磨区域和机器人速度等。
如果需要适配特定的机器人平台,只需修改 RobotController 类中的相关方法即可。import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import heapq
from typing import List, Tuple, Dict, Optional
import random
class Node:
"""A*算法中的节点类"""
def __init__(self, x: int, y: int, g_cost: float = float('inf'), h_cost: float = float('inf'),
parent: Optional['Node'] = None):
self.x = x
self.y = y
self.g_cost = g_cost # 从起点到当前节点的实际代价
self.h_cost = h_cost # 从当前节点到目标节点的启发式估计代价
self.f_cost = g_cost + h_cost # 总代价
self.parent = parent # 父节点,用于回溯路径
def __lt__(self, other: 'Node') -> bool:
"""比较节点的总代价,用于优先队列"""
return self.f_cost < other.f_cost
def __eq__(self, other: 'Node') -> bool:
"""比较节点的坐标是否相同"""
return self.x == other.x and self.y == other.y
def __hash__(self) -> int:
"""节点的哈希值,用于集合操作"""
return hash((self.x, self.y))
class RobotPathPlanner:
"""打磨机器人路径规划器"""
def __init__(self, grid_size: Tuple[int, int], obstacles: List[Tuple[int, int]] = None):
self.grid_size = grid_size # 网格大小 (width, height)
self.obstacles = obstacles if obstacles else [] # 障碍物列表
self.grid = self._create_grid() # 创建网格地图
def _create_grid(self) -> np.ndarray:
"""创建网格地图,0表示可通行,1表示障碍物"""
grid = np.zeros(self.grid_size, dtype=int)
for obs in self.obstacles:
if 0 <= obs[0] < self.grid_size[0] and 0 <= obs[1] < self.grid_size[1]:
grid[obs[0], obs[1]] = 1
return grid
def is_valid(self, x: int, y: int) -> bool:
"""检查坐标是否在网格内且不是障碍物"""
return 0 <= x < self.grid_size[0] and 0 <= y < self.grid_size[1] and self.grid[x, y] == 0
def heuristic(self, current: Tuple[int, int], goal: Tuple[int, int]) -> float:
"""计算启发式函数值,使用曼哈顿距离"""
return abs(current[0] - goal[0]) + abs(current[1] - goal[1])
def a_star(self, start: Tuple[int, int], goal: Tuple[int, int]) -> List[Tuple[int, int]]:
"""A*算法实现"""
start_node = Node(start[0], start[1], 0, self.heuristic(start, goal))
goal_node = Node(goal[0], goal[1])
open_set: List[Node] = []
closed_set = set()
heapq.heappush(open_set, start_node)
while open_set:
current_node = heapq.heappop(open_set)
# 到达目标节点,回溯路径
if current_node.x == goal_node.x and current_node.y == goal_node.y:
path = []
while current_node:
path.append((current_node.x, current_node.y))
current_node = current_node.parent
return path[::-1] # 反转路径,从起点到终点
closed_set.add((current_node.x, current_node.y))
# 8个方向的移动
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
if dx == 0 and dy == 0:
continue
neighbor_x = current_node.x + dx
neighbor_y = current_node.y + dy
# 检查是否有效
if not self.is_valid(neighbor_x, neighbor_y):
continue
# 对角线移动的代价更高
movement_cost = 1.4 if dx != 0 and dy != 0 else 1.0
# 计算新的g值
new_g_cost = current_node.g_cost + movement_cost
# 如果邻居节点已经在关闭列表中,跳过
if (neighbor_x, neighbor_y) in closed_set:
continue
# 检查邻居节点是否在开放列表中
neighbor_node = None
for node in open_set:
if node.x == neighbor_x and node.y == neighbor_y:
neighbor_node = node
break
if not neighbor_node:
# 创建新节点
neighbor_node = Node(neighbor_x, neighbor_y, new_g_cost,
self.heuristic((neighbor_x, neighbor_y), goal))
neighbor_node.parent = current_node
heapq.heappush(open_set, neighbor_node)
elif new_g_cost < neighbor_node.g_cost:
# 更新已有节点
neighbor_node.g_cost = new_g_cost
neighbor_node.f_cost = new_g_cost + neighbor_node.h_cost
neighbor_node.parent = current_node
# 重新排序优先队列
open_set.sort()
# 没有找到路径
return []
def smooth_path(self, path: List[Tuple[int, int]], weight_data: float = 0.5,
weight_smooth: float = 0.1, tolerance: float = 0.00001) -> List[Tuple[float, float]]:
"""路径平滑处理"""
if not path or len(path) < 3:
return path
# 转换为浮点数列表以便进行平滑处理
smoothed_path = [[float(x), float(y)] for x, y in path]
change = tolerance
while change >= tolerance:
change = 0.0
for i in range(1, len(path) - 1):
for j in range(2): # x和y坐标
aux = smoothed_path[i][j]
# 数据项
smoothed_path[i][j] += weight_data * (path[i][j] - smoothed_path[i][j])
# 平滑项
smoothed_path[i][j] += weight_smooth * (smoothed_path[i-1][j] + smoothed_path[i+1][j] - 2.0 * smoothed_path[i][j])
# 检查边界条件
if j == 0: # x坐标
if smoothed_path[i][j] < 0:
smoothed_path[i][j] = 0.0
elif smoothed_path[i][j] > self.grid_size[0] - 1:
smoothed_path[i][j] = float(self.grid_size[0] - 1)
else: # y坐标
if smoothed_path[i][j] < 0:
smoothed_path[i][j] = 0.0
elif smoothed_path[i][j] > self.grid_size[1] - 1:
smoothed_path[i][j] = float(self.grid_size[1] - 1)
change += abs(aux - smoothed_path[i][j])
return [(x, y) for x, y in smoothed_path]
def generate_polishing_waypoints(self, area: Tuple[Tuple[int, int], Tuple[int, int]],
spacing: float = 1.0) -> List[Tuple[float, float]]:
"""生成打磨区域的路径点"""
(x_min, y_min), (x_max, y_max) = area
waypoints = []
direction = 1 # 1表示向右,-1表示向左
# 按行生成路径点,蛇形填充
for y in np.arange(y_min, y_max + spacing, spacing):
if direction == 1:
for x in np.arange(x_min, x_max + spacing, spacing):
waypoints.append((x, y))
else:
for x in np.arange(x_max, x_min - spacing, -spacing):
waypoints.append((x, y))
direction *= -1 # 切换方向
return waypoints
def plan_polishing_path(self, start: Tuple[int, int], polishing_areas: List[Tuple[Tuple[int, int], Tuple[int, int]]],
spacing: float = 1.0) -> List[Tuple[float, float]]:
"""规划完整的打磨路径"""
# 生成所有打磨区域的路径点
all_waypoints = []
for area in polishing_areas:
waypoints = self.generate_polishing_waypoints(area, spacing)
all_waypoints.extend(waypoints)
if not all_waypoints:
return []
# 规划从起点到第一个打磨点的路径
first_waypoint = (int(all_waypoints[0][0]), int(all_waypoints[0][1]))
path_to_first = self.a_star(start, first_waypoint)
# 连接所有打磨点形成完整路径
full_path = path_to_first[:-1] # 去掉第一个打磨点,避免重复
full_path.extend(all_waypoints)
# 平滑路径
smoothed_path = self.smooth_path(full_path)
return smoothed_path
def visualize_path(self, path: List[Tuple[float, float]], start: Tuple[int, int],
polishing_areas: List[Tuple[Tuple[int, int], Tuple[int, int]]]):
"""可视化路径规划结果"""
plt.figure(figsize=(10, 8))
# 绘制网格和障碍物
plt.imshow(self.grid.T, cmap='gray_r', origin='lower', alpha=0.5)
# 绘制障碍物
for obs in self.obstacles:
plt.gca().add_patch(Rectangle((obs[0]-0.5, obs[1]-0.5), 1, 1,
linewidth=1, edgecolor='r', facecolor='r'))
# 绘制打磨区域
for area in polishing_areas:
(x_min, y_min), (x_max, y_max) = area
plt.gca().add_patch(Rectangle((x_min-0.5, y_min-0.5), x_max-x_min+1, y_max-y_min+1,
linewidth=2, edgecolor='g', facecolor='none'))
# 绘制起点和终点
plt.plot(start[0], start[1], 'bo', markersize=10, label='Start')
# 绘制路径
if path:
x_vals = [p[0] for p in path]
y_vals = [p[1] for p in path]
plt.plot(x_vals, y_vals, 'b-', linewidth=2, label='Path')
# 绘制路径点
plt.plot(x_vals, y_vals, 'ro', markersize=4)
plt.grid(True)
plt.title('Robot Polishing Path Planning')
plt.xlabel('X Coordinate')
plt.ylabel('Y Coordinate')
plt.legend()
plt.axis('equal')
plt.tight_layout()
plt.show()
class RobotController:
"""打磨机器人控制器"""
def __init__(self, planner: RobotPathPlanner, speed: float = 1.0):
self.planner = planner
self.speed = speed # 机器人移动速度 (单位/秒)
self.current_position = None
def execute_path(self, path: List[Tuple[float, float]], start: Tuple[int, int]):
"""执行规划好的路径"""
self.current_position = start
print(f"机器人从位置 {start} 开始移动")
# 记录总执行时间
total_time = 0.0
for i, point in enumerate(path):
if i == 0 and point == start:
continue # 已经在起点
# 计算移动距离和时间
dx = point[0] - self.current_position[0]
dy = point[1] - self.current_position[1]
distance = np.sqrt(dx**2 + dy**2)
time = distance / self.speed
# 更新当前位置
self.current_position = point
# 输出移动信息
total_time += time
print(f"步骤 {i}: 移动到点 ({point[0]:.2f}, {point[1]:.2f}),耗时 {time:.2f} 秒")
# 模拟打磨操作
if i > 0: # 跳过起点
self._simulate_polishing(point)
print(f"路径执行完成,总耗时: {total_time:.2f} 秒")
def _simulate_polishing(self, position: Tuple[float, float]):
"""模拟打磨操作"""
# 这里可以添加实际的打磨控制代码
print(f" 在位置 ({position[0]:.2f}, {position[1]:.2f}) 执行打磨操作...")
# 示例使用
def main():
# 创建一个20x20的网格地图
grid_size = (20, 20)
# 添加一些随机障碍物
random.seed(42) # 设置随机种子,确保结果可重现
obstacles = []
for _ in range(15):
x = random.randint(2, 18)
y = random.randint(2, 18)
obstacles.append((x, y))
# 创建路径规划器
planner = RobotPathPlanner(grid_size, obstacles)
# 设置起点和打磨区域
start = (2, 2)
polishing_areas = [
((5, 5), (10, 8)), # 第一个打磨区域
((12, 10), (17, 15)) # 第二个打磨区域
]
# 规划打磨路径
path = planner.plan_polishing_path(start, polishing_areas, spacing=0.8)
# 可视化路径
planner.visualize_path(path, start, polishing_areas)
# 创建机器人控制器并执行路径
controller = RobotController(planner, speed=1.5)
controller.execute_path(path, start)
if __name__ == "__main__":
copyright © 2021 淄博市道路交通事故研究中心 版权所有 技术支持:网赢信息
地址:山东理工大学交通实验楼650房间 电话:13756699636 邮编:255000