[Robotics_py] 路径规划算法 | 启发式函数 | A*算法

第五章:路径规划算法

欢迎回来,未来的机器人专家-=≡(・ω・)

在之前的章节中,我们已为机器人配备了核心知识:它能够跟踪自身的机器人状态/位姿,利用环境表示(栅格地图)理解周围环境,通过机器人运动模型预测运动轨迹,并借助定位滤波器精确定位。

现在,机器人已掌握"自身位置“和”环境信息"。但若要让其从A点移动到B点呢?

当存在墙壁或障碍物时,它无法直线行进。它需要一份"移动计划"。

这正是路径规划算法的用武之地!

什么是路径规划算法?

想象我们试图在一个陌生城市中从当前位置前往朋友家。

打开手机GPS导航,它不仅能显示直线距离,还会规划出避开建筑、湖泊和单行道的实际路线

路径规划算法就如同机器人的高级GPS系统

其核心任务是:基于地图(栅格地图)信息避开障碍物,为机器人找到从起点到目标点的安全高效移动序列(即"路径"),通常还需优化特定指标(如最短路径或最快路径)。

若无路径规划,机器人只会漫无目的游荡或直接撞上首个障碍物!这是指导机器人高层移动决策的"大脑"


路径规划的核心概念

理解机器人路径规划需掌握以下关键概念:

概念描述类比
起点机器人的初始位置和朝向(基于机器人状态/位姿)GPS上标注的当前位置
目标点机器人需要到达的最终位置和朝向朋友家的详细地址
障碍物机器人不可进入或穿过的区域,通常定义在栅格地图中地图上的建筑物、河流或禁行区
路径引导机器人从起点到目标点的中间点或状态序列,需避开障碍物GPS推荐的蓝色导航路线
代价表示路径"成本"的数值,可以是距离、时间、能耗或其组合GPS显示的预计行程时间或里程数
优化根据特定目标(如最短路径、最快路径)寻找最小化(或最大化)代价的路径在GPS中选择"最短路线"或"最快路线"选项

如何使用路径规划算法(A*算法示例)

PythonRobotics包含多种路径规划算法。

我们从A*(A-Star)搜索算法开始,这是一种广为人知且直观的算法,尤其适用于栅格地图。

假设我们需要机器人在存在障碍物的地图中从(10, 10)米移动到(50, 50)米。

以下是使用PathPlanning/AStar/a_star.pyAStarPlanner类设置并运行A*规划器的典型流程:

import matplotlib.pyplot as plt # 可视化工具
from PathPlanning.AStar.a_star import AStarPlanner# 1. 定义起点和目标点坐标(单位:米)
sx, sy = 10.0, 10.0  # 起点X,Y
gx, gy = 50.0, 50.0  # 目标点X,Y# 2. 定义地图属性及机器人尺寸
grid_size = 2.0      # 每个栅格单元为2.0m×2.0m
robot_radius = 1.0   # 机器人视为半径1.0m的圆形# 3. 定义障碍物(障碍物中心点坐标)
# 简单示例:创建墙状障碍物
ox, oy = [], []
for i in range(10, 40): # 在x=20处创建垂直墙(y从10到39)ox.append(20.0)oy.append(float(i))
for i in range(20, 50): # 在y=30处创建水平墙(x从20到49)ox.append(float(i))oy.append(30.0)# 4. 创建A*规划器对象
planner = AStarPlanner(ox, oy, grid_size, robot_radius)# 5. 执行路径规划!
print("开始路径规划...")
# rx, ry将存储规划路径的x,y坐标
rx, ry = planner.planning(sx, sy, gx, gy)if rx: # 找到路径时print(f"找到包含{len(rx)}个路径点的路径")# 可进行可视化:# plt.plot(ox, oy, ".k") # 绘制障碍物# plt.plot(sx, sy, "og") # 绘制起点# plt.plot(gx, gy, "xb") # 绘制目标点# plt.plot(rx, ry, "-r") # 绘制路径# plt.grid(True); plt.axis("equal"); plt.show()
else:print("未找到可行路径!")

代码解析:

  • 创建AStarPlanner对象时需提供障碍物坐标(ox, oy)、栅格尺寸(grid_size,用于生成内部栅格地图)和机器人半径(robot_radius,确保与障碍物保持安全距离)。
  • planning()方法接收起点(sx, sy)和目标点(gx, gy)坐标,返回表示最优路径的rx, ry坐标列表。若目标点被阻塞则返回None

输出结果rx, ry即为机器人应遵循的详细路径坐标序列


路径规划算法内部原理(A*算法拆解)

🎢启发式函数

启发式函数是一种“经验法则”,用于估计从当前状态目标状态的近似距离,帮助算法更快找到最优路径。比如在地图导航中,启发式函数可以简单计算两点间的直线距离。

A*算法是一种智能路径搜索算法,通过结合当前路径成本和预估剩余距离(启发式函数)来高效找到最优路径,类似导航软件选择最快路线。

A*算法与BFS

A*算法可以看作BFS的智能升级版。

  • BFS会盲目扩展所有可能路径
  • 而A通过启发式函数优先探索更接近目标的路径。
    两者都用队列管理待探索节点,但A
    的队列按“实际成本+预估成本”排序,效率更高。
A*算法高层流程

在这里插入图片描述

A*代码核心组件

AStarPlanner类管理地图、障碍物及搜索过程,关键部分如下:

1. Node类:
A*算法中,"节点"代表算法正在考虑的栅格单元。其不仅包含x, y坐标,还存储搜索所需信息(详见第六章:路径规划搜索节点)。

PathPlanning/AStar/a_star.py中的简化实现:

class AStarPlanner:# ... (其他代码) ...class Node:def __init__(self, x, y, cost, parent_index):self.x = x            # 栅格单元X索引self.y = y            # 栅格单元Y索引self.cost = cost      # g_cost(从起点到本节点的累计代价)self.parent_index = parent_index # 到达本节点的父节点索引(用于路径重建)

解析:

  • x, y:栅格索引(非实际米制坐标),由AStarPlanner内部转换。
  • cost:即g_cost(从起点到当前节点的实际累计代价)。
  • parent_index:关键回溯信息,记录到达当前节点的前一节点。找到目标后,沿此索引逆向重建完整路径。

2. 运动模型(定义可行移动方向):
栅格化A*的"运动模型"定义了机器人可移动的相邻单元。
a_star.py中的get_motion_model()静态方法定义了8个可能方向(上下左右及对角线):

class AStarPlanner:# ... (其他代码) ...@staticmethoddef get_motion_model():# dx, dy, costmotion = [[1, 0, 1],      # 右移(X+1,Y+0),代价1[0, 1, 1],      # 上移(X+0,Y+1),代价1[-1, 0, 1],     # 左移(X-1,Y+0),代价1[0, -1, 1],     # 下移(X+0,Y-1),代价1[-1, -1, math.sqrt(2)], # 对角线(X-1,Y-1),代价√2[-1, 1, math.sqrt(2)],  # 对角线(X-1,Y+1),代价√2[1, -1, math.sqrt(2)],  # 对角线(X+1,Y-1),代价√2[1, 1, math.sqrt(2)]]   # 对角线(X+1,Y+1),代价√2return motion

解析:

  • 每个子列表[dx, dy, cost]描述一种移动方式,dxdy为栅格索引变化量。
  • cost为移动代价。水平/垂直移动代价为1,对角线移动为实际距离√2,确保算法找到真正最短路径。

3. 代价计算(f_cost = g_cost + h_cost):
A*算法通过"启发式函数"引导搜索方向,避免盲目探索。每个节点包含两种代价:

代价类型描述类比
g_cost从起点到当前节点的实际代价已从起点行走的实际距离
h_cost当前节点到目标的预估代价(启发式)预估剩余距离(如直线距离猜测)
f_cost总预估代价(g_cost + h_cost路径总长度的综合预估

A*算法始终选择开放集合中f_cost最低的节点扩展

a_star.py中的calc_heuristic方法通过欧氏距离计算h_cost

import mathclass AStarPlanner:# ... (其他代码) ...@staticmethoddef calc_heuristic(n1, n2):# n1: 当前节点, n2: 目标节点# 计算两栅格点间的直线距离d = math.hypot(n1.x - n2.x, n1.y - n2.y)return d

解析:

  • n1.x - n2.xn1.y - n2.y为坐标差。
  • math.hypot()计算直角三角形斜边长度,作为引导A*高效搜索的"启发式估计"。

4. 碰撞检测(verify_node):
规划器需确认新栅格单元的安全性,包括检查地图边界及障碍物(基于栅格地图生成的obstacle_map),并考虑机器人半径的安全距离。

class AStarPlanner:# ... (其他代码) ...def verify_node(self, node):# 将栅格索引转换为实际坐标px = self.calc_grid_position(node.x, self.min_x)py = self.calc_grid_position(node.y, self.min_y)# 1. 检查是否超出地图边界if not (self.min_x <= px < self.max_x and self.min_y <= py < self.max_y):return False# 2. 检查障碍物碰撞# self.obstacle_map为二维数组(类似栅格地图)# True表示占据/碰撞,False表示空闲if self.obstacle_map[node.x][node.y]: # 简化检测return Falsereturn True # 节点安全

解析:

  • calc_grid_position将栅格索引转换为实际坐标以进行边界检查。
  • self.obstacle_map为预先生成的障碍物栅格图,若obstacle_map[node.x][node.y]True,表示该单元存在碰撞风险。

PythonRobotics中的其他路径规划算法

尽管A*在栅格地图中表现优异,PythonRobotics还提供多种适应不同场景的规划算法:

  • 动态窗口法(DWA)(PathPlanning/DynamicWindowApproach/dynamic_window_approach.py):一种局部路径规划算法。DWA不预先规划全局路径,而是在实时窗口中评估可行的速度与转向指令,结合机器人动力学障碍物规避目标趋近进行决策。常用于实时避障
  • 快速扩展随机树(RRT)(PathPlanning/RRT/rrt.py):基于采样的算法,通过随机生成节点构建树状结构连接起点与目标。适用于复杂高维空间或狭窄通道环境,克服栅格方法的局限性
  • Frenet最优轨迹(FOT)(PathPlanning/FrenetOptimalTrajectory/frenet_optimal_trajectory.py):常用于自动驾驶的高级算法。在"Frenet坐标系"(与参考路径如道路中线对齐)中生成多项式轨迹,通过优化速度、舒适度及避障等代价选择最优路径

这些算法展示了路径规划技术的多样性,但均以实现安全高效移动为核心目标。


小结

本章深入探讨了路径规划算法的关键作用。作为机器人的"智能导航系统",该算法通过结合栅格地图信息与启发式搜索,在避开障碍物的同时优化路径成本。

我们以A*算法为例,解析了节点扩展代价计算碰撞检测的核心机制,并简介了DWA、RRT和Frenet等高级算法

搜索节点作为多数规划算法的核心组件,将在下一章详细剖析其结构与应用逻辑。

下一章:路径规划搜索节点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/95274.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/95274.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决 HTTP 请求 RequestBody 只能被读取一次的问题

简介 HTTP 请求 RequestBody 只能被读取一次&#xff1a;HttpServletRequest 的输入流 (InputStream) 在被读取后会被关闭&#xff0c;导致后续无法再次读取。本文将介绍如何通过 请求包装类 (RequestWrapper) 来解决这个问题。问题背景 当我们需要在以下场景中多次读取 Reques…

(LeetCode 面试经典 150 题) 226. 翻转二叉树 (深度优先搜索dfs )

题目&#xff1a;226. 翻转二叉树 思路:深度优先搜索dfs&#xff0c;时间复杂度0(n)。 C版本&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr)…

2025牛客暑期多校训练营3(FDJAEHB)

题目链接&#xff1a;牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ F Flower 思路 可知当n<a时无论怎么操作她都会离开 n%(ab&#xff09;是指进行完若干轮之后剩下的不足ab个&#xff0c;如果是>a的话那么最后一轮必然不在a中&#xff0c;否则就…

【KO】 Android基础

以下是对这些 Android 相关问题的解答: 1. Activity 与 Fragment 之间常见的几种通信方式 接口回调:Fragment 定义接口,Activity 实现该接口,Fragment 通过接口实例调用方法传递数据 。 使用 Bundle:Fragment 可通过 setArguments(Bundle) 传数据给自身,Activity 可在创…

Gradle构建工具教程:由来与发展史(版本演进与未来优势)

一、Gradle简介Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具&#xff0c;使用基于Groovy的领域特定语言&#xff08;DSL&#xff09;声明项目设置。相较于传统XML配置&#xff0c;这种DSL使构建脚本更简洁易读。Gradle支持Java、Groovy、Kotlin、Sca…

@Rancher简介部署使用 - Docker Compose

Rancher 安装和使用介绍 - Docker Compose 文章目录Rancher 安装和使用介绍 - Docker Compose1. Rancher 简介1.1 什么是 Rancher1.2 Rancher 核心功能1.3 Rancher 架构2. 安装前准备2.1 系统要求2.2 环境准备3. 使用 Docker Compose 安装 Rancher3.1 创建 Docker Compose 文件…

程序员接私活的一些平台和建议,千万要注意,别掉坑里!

关于程序员接私活&#xff0c;社会各界说法不一&#xff0c;如果你确实急用钱&#xff0c;价格又合适&#xff0c;那就去做。 不过&#xff0c;私活也没有那么好做&#xff0c;一般私活的性价比远比上班拿工资的低。但是作为一个额外的收益渠道&#xff0c;一部分生活窘迫的程序…

多轮问答与指代消解

目录引言一、LangChain是怎么实现的多轮问答1、记忆模块&#xff08;Memory&#xff09;管理对话历史‌2、对话链&#xff08;Conversational Chain&#xff09;架构‌3、智能体&#xff08;Agent&#xff09;决策机制‌4、上下文感知的Prompt工程‌5、RAG&#xff08;检索增强…

文件IO、文件IO与标准IO的区别

一、文件IO --->fd&#xff08;文件描述符&#xff09;打开文件open读、写文件read/write关闭文件close#include <sys/types.h>#include <sys/stat.h>#include<fcntl.h>文件描述符&#xff1a;操作系统中已打开文件的标识符。小的、非负的整形数据范围&am…

【模型剪枝2】不同剪枝方法实现对 yolov5n 剪枝测试及对比

目录 一、背景 二、剪枝 1. Network Slimming 1.0 代码准备 1.1 稀疏化训练 1.2 剪枝 1.3 微调 1.4 测试总结 2. Torch Pruning&#xff08;TP&#xff09; 2.1 MagnitudePruner 2.1.1 剪枝 2.1.2 retrain 2.1.3 测试总结 2.2 SlimmingPruner 2.2.1 定义重要性评…

AI入门学习--AI模型评测

一、AI模型评测目标传统质量主要关注功能、性能、安全、兼容性等。 AI模型评测在此基础上,引入了全新的、更复杂的评估维度: 1.性能/准确性:这是基础,在一系列复杂的评测基准上评价个性能指标。 2.安全性:模型是否可能被用于恶意目的?是否会生成有害、违法或有毒的内容?是否容…

nt!MmCreatePeb函数分析之peb中OSMajorVersion的由来

第一部分&#xff1a;NTSTATUS MmCreatePeb (IN PEPROCESS TargetProcess,IN PINITIAL_PEB InitialPeb,OUT PPEB *Base) {PPEB PebBase;PebBase->OSMajorVersion NtMajorVersion;PebBase->OSMinorVersion NtMinorVersion;PebBase->OSBuildNumber (USHORT)(NtBuildN…

Unity TimeLine使用教程

1.概述 Timeline 是一个基于时间轴的序列化编辑工具&#xff0c;主要用于控制游戏或动画中的 过场动画&#xff08;Cutscenes&#xff09;、剧情事件、角色动画混合、音频控制 等。它类似于视频编辑软件&#xff08;如 Adobe Premiere&#xff09;的时间线&#xff0c;但专门针…

数据分析基本内容(第二十节课内容总结)

1.pd.read_csv(一个文件.csv)&#xff1a;从本地文件加载数据&#xff0c;返回一个 DataFrame 对象&#xff0c;这是 pandas 中用于存储表格数据的主要数据结构2.df.head()&#xff1a;查看数据的前五行&#xff0c;帮助快速了解数据的基本结构和内容3.df.info()&#xff1a;查…

2025年最新原创多目标算法:多目标酶作用优化算法(MOEAO)求解MaF1-MaF15及工程应用---盘式制动器设计,提供完整MATLAB代码

一、酶作用优化算法 酶作用优化&#xff08;Enzyme Action Optimizer, EAO&#xff09;算法是一种2025年提出的新型仿生优化算法&#xff0c;灵感源于生物系统中酶的催化机制&#xff0c;发表于JCR 2区期刊《The Journal of Supercomputing》。其核心思想是模拟酶与底物的特异性…

用 COLMAP GUI 在 Windows 下一步步完成 相机位姿估计(SfM) 和 稀疏点云重建的详细步骤:

使用 COLMAP GUI 进行 SfM 和稀疏点云重建的步骤1. 打开 COLMAP GUI运行 colmap.bat&#xff0c;会弹出图形界面。2. 新建项目&#xff08;或打开已有项目&#xff09;点击菜单栏的 File > New Project&#xff0c;选择一个空文件夹作为项目目录&#xff08;建议新建一个空目…

天线设计 介质材料PEC和FR4有什么区别吗

在电磁仿真&#xff08;包括 CST 中&#xff09;&#xff0c;PEC 和 FR4 是两种完全不同的材料类型&#xff0c;主要区别如下&#xff1a;材料性质&#xff1a;PEC&#xff08;Perfect Electric Conductor&#xff0c;理想电导体&#xff09;&#xff1a;是一种理论上的理想材料…

mysql锁+索引

mysql锁按锁的粒度分类表级锁&#xff08;Table - level locks&#xff09;特点&#xff1a;对整张表进行锁定&#xff0c;实现简单&#xff0c;加锁和释放锁的速度快&#xff0c;但并发度较低。当一个事务对表加表级锁后&#xff0c;其他事务对该表的读写操作都可能被阻塞。应…

计算机视觉CS231n学习(7)

可视化和理解 这里主要是对CNN中间的层的结果可视化滤波器可视化 直接可视化网络各层的滤波器权重&#xff0c;高层滤波器的可视化结果趣味性较低&#xff0c;而底层滤波器通常对应边缘、纹理等基础视觉特征 &#xff08;“高层滤波器” 通常指的是网络中靠后的卷积层所包含的滤…

OpenBMC中工厂模式的简明工作流程解析

本文将以最简单直接的方式&#xff0c;从零开始讲解OpenBMC中工厂模式的完整工作流程&#xff0c;包括从设计到使用的全生命周期。 1. 工厂模式最简示例 我们先从一个最基础的工厂模式实现开始&#xff1a; // 产品接口 class GpioPin { public:virtual void setValue(bool val…