轨迹规划 | 图解纯追踪算法Pure Pursuit(附ROS C++/Python/Matlab仿真)

目录

  • 0 专栏介绍
  • 1 纯追踪算法原理推导
  • 2 自适应纯追踪算法(APP)
  • 3 规范化纯追踪算法(RPP)
  • 4 仿真实现
    • 4.1 ROS C++仿真
    • 4.2 Python仿真
    • 4.3 Matlab仿真

0 专栏介绍

🔥附C++/Python/Matlab全套代码🔥课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。

🚀详情:图解自动驾驶中的运动规划(Motion Planning),附几十种规划算法


1 纯追踪算法原理推导

纯追踪算法(Pure Pursuit, PP)参考了人类驾驶行为,其基本思想是:在待跟踪路径上设置预瞄点(goal-ahead),通过简单的几何方法驱动机器人跟踪预瞄点,随着机器人运动,预瞄点动态移动直至抵达目标位置。

给定路径点 P = { p 0 , p 1 , ⋯   , p g } \mathcal{P} =\left\{ \boldsymbol{p}_0,\boldsymbol{p}_1,\cdots ,\boldsymbol{p}_g \right\} P={p0,p1,,pg}。根据纯追踪算法设置的固定预瞄距离 L L L选择预瞄点

p l = p i ∈ P    s . t . ∥ p i − 1 − p r ∥ 2 2 < L    a n d ∥ p i − p r ∥ 2 2 ⩾ L \boldsymbol{p}_l=\boldsymbol{p}_i\in \mathcal{P} \,\,\mathrm{s}.\mathrm{t}. \left\| \boldsymbol{p}_{i-1}-\boldsymbol{p}_r \right\| _{2}^{2}<L\,\,\mathrm{and} \left\| \boldsymbol{p}_i-\boldsymbol{p}_r \right\| _{2}^{2}\geqslant L pl=piPs.t.pi1pr22<Landpipr22L

其中 p r \boldsymbol{p}_r pr是最接近机器人当前位置的路径点。

当规划时间间隔 Δ t → 0 \varDelta t\rightarrow 0 Δt0时,可认为机器人线速度 v v v和角速度 ω \omega ω不变,因此其转向半径 R = v / ω R={{v}/{\omega}} R=v/ω是定值,即机器人进行圆周运动。

在这里插入图片描述

如图所示,根据几何关系可得

L sin ⁡ 2 α = R sin ⁡ ( π / 2 − α ) ⇒ R = L 2 sin ⁡ α \frac{L}{\sin 2\alpha}=\frac{R}{\sin \left( {{\pi}/{2}}-\alpha \right)}\Rightarrow R=\frac{L}{2\sin \alpha} sin2αL=sin(π/2α)RR=2sinαL

确定曲率半径后,对于差速轮式移动机器人而言,可根据下式计算当前的控制指令

{ v t = v d ω t = v t / R \begin{cases} v_t=v_d\\ \omega _t={{v_t}/{R}}\\\end{cases} {vt=vdωt=vt/R

在机器人局部坐标系中,设机器人与预瞄点的纵向误差为 e y e_y ey,则

R = L 2 2 e y ⇔ κ = 2 L 2 ⋅ e y R=\frac{L^2}{2e_y}\Leftrightarrow \kappa =\frac{2}{L^2}\cdot e_y R=2eyL2κ=L22ey

相当于一个以横向跟踪误差为系统误差的比例控制器,如图所示。增大 L L L有利于降低超调,但会产生稳态误差;减小 L L L能够加快动态响应速度,但容易引起振荡。

在这里插入图片描述

2 自适应纯追踪算法(APP)

为了在跟踪振荡和较慢收敛间取得可接受的权衡,自适应纯追踪算法(Adaptive Pure Pursuit, APP)根据运动速度自适应调整预瞄距离

L t = l t v t + L 0 L_t=l_tv_t+L_0 Lt=ltvt+L0

其中 l t l_t lt是前瞻增益,表示将 v t v_t vt向前投影的时间增量; L 0 L_0 L0是最小预瞄距离。

3 规范化纯追踪算法(RPP)

考虑到机器人始终以期望速度 运动并不合理,尤其是在狭窄区域、急转弯等不完全可见工作空间,动态调整机器人速度有利于提供更高质量的行为表现。规范化纯追踪算法(Regulated Pure Pursuit, RPP)引入了修正启发式等进行自适应调整。举例而言,曲率启发式,目的是放慢机器人在部分可观察环境的速度,以提高盲转弯时的安全性。其中最大曲率阈值 提供了急转弯位置的速度缩放。

v t ′ = { v t    , κ ⩽ κ max ⁡ κ max ⁡ κ v t    , κ > κ max ⁡ v_{t}^{'}=\begin{cases} v_t\,\, , \kappa \leqslant \kappa _{\max}\\ \frac{\kappa _{\max}}{\kappa}v_t\,\, , \kappa >\kappa _{\max}\\\end{cases} vt={vt,κκmaxκκmaxvt,κ>κmax

可以根据应用需求设计更多启发式

4 仿真实现

4.1 ROS C++仿真

核心代码如下所示

bool RPPPlanner::computeVelocityCommands(geometry_msgs::Twist& cmd_vel)
{
  ...
  
  double vt = std::hypot(base_odom.twist.twist.linear.x, base_odom.twist.twist.linear.y);
  double L = getLookAheadDistance(vt);

  getLookAheadPoint(L, robot_pose_map, prune_plan, lookahead_pt, theta, kappa);
  double lookahead_k = 2 * sin(_dphi(lookahead_pt, robot_pose_map)) / L;

  // calculate commands
  if (shouldRotateToGoal(robot_pose_map, global_plan_.back()))
  {
    ...
  }
  else
  {
    double e_theta = regularizeAngle(_dphi(lookahead_pt, robot_pose_map));

    // large angle, turn first
    if (shouldRotateToPath(std::fabs(e_theta), M_PI_2))
    {
      cmd_vel.linear.x = 0.0;
      cmd_vel.angular.z = angularRegularization(base_odom, e_theta / d_t_);
    }

    // apply constraints
    else
    {
      double curv_vel = _applyCurvatureConstraint(max_v_, lookahead_k);
      double cost_vel = _applyObstacleConstraint(max_v_);
      double v_d = std::min(curv_vel, cost_vel);
      v_d = _applyApproachConstraint(v_d, robot_pose_map, prune_plan);

      cmd_vel.linear.x = linearRegularization(base_odom, v_d);
      cmd_vel.angular.z = angularRegularization(base_odom, v_d * lookahead_k);
    }
  }

  return true;
}

在这里插入图片描述

4.2 Python仿真

核心代码如下所示

def plan(self):
    lookahead_pts = []
    dt = self.params["TIME_STEP"]
    for _ in range(self.params["MAX_ITERATION"]):
        # break until goal reached
        if self.shouldRotateToGoal(self.robot.position, self.goal):
            return True, self.robot.history_pose, lookahead_pts

        # get the particular point on the path at the lookahead distance
        lookahead_pt, _, _ = self.getLookaheadPoint()

        # get the tracking curvature with goalahead point
        lookahead_k = 2 * math.sin(
            self.angle(self.robot.position, lookahead_pt) - self.robot.theta
        ) / self.lookahead_dist

        # calculate velocity command
        e_theta = self.regularizeAngle(self.robot.theta - self.goal[2]) / 10
        if self.shouldRotateToGoal(self.robot.position, self.goal):
            if not self.shouldRotateToPath(abs(e_theta)):
                u = np.array([[0], [0]])
            else:
                u = np.array([[0], [self.angularRegularization(e_theta / dt)]])
        else:
            e_theta = self.regularizeAngle(
                self.angle(self.robot.position, lookahead_pt) - self.robot.theta
            ) / 10
            if self.shouldRotateToPath(abs(e_theta), np.pi / 4):
                u = np.array([[0], [self.angularRegularization(e_theta / dt)]])
            else:
                # apply constraints
                curv_vel = self.applyCurvatureConstraint(self.params["MAX_V"], lookahead_k)
                cost_vel = self.applyObstacleConstraint(self.params["MAX_V"])
                v_d = min(curv_vel, cost_vel)
                u = np.array([[self.linearRegularization(v_d)], [self.angularRegularization(v_d * lookahead_k)]])
        
        # update lookahead points
        lookahead_pts.append(lookahead_pt)

        # feed into robotic kinematic
        self.robot.kinematic(u, dt)
    
    return False, None, None

在这里插入图片描述

4.3 Matlab仿真

核心代码如下所示

while iter < param.max_iteration
	iter = iter + 1;
	
	% break until goal reached
	if shouldRotateToGoal([robot.x, robot.y], goal, param)
	    flag = true;
	    break;
	end
	
	% get the particular point on the path at the lookahead distance
	[lookahead_pt, ~, ~] = getLookaheadPoint(robot, path, param);
	
	% get the tracking curvature with goalahead point
	lookahead_k = 2 * sin( ...
	    atan2(lookahead_pt(2) - robot.y, lookahead_pt(1) - robot.x) - robot.theta ...
	) / getLookaheadDistance(robot, param);
	
	% calculate velocity command
	e_theta = regularizeAngle(robot.theta - goal(3)) / 10;
	if shouldRotateToGoal([robot.x, robot.y], goal, param)
	    if ~shouldRotateToPath(abs(e_theta), 0.0, param)
	        u = [0, 0];
	    else
	        u = [0, angularRegularization(robot, e_theta / param.dt, param)];
	    end
	else
	    e_theta = regularizeAngle( ...
	        atan2(lookahead_pt(2) - robot.y, lookahead_pt(1) - robot.x) - robot.theta ...
	    ) / 10;
	    if shouldRotateToPath(abs(e_theta), pi / 4, param)
	        u = [0, angularRegularization(robot, e_theta / param.dt, param)];
	    else
	        % apply constraints
	        curv_vel = applyCurvatureConstraint(param.max_v, lookahead_k, param);
	        cost_vel = applyObstacleConstraint(param.max_v, map, robot, param);
	        v_d = min(curv_vel, cost_vel);
	        u = [
	                linearRegularization(robot, v_d, param), ...
	                angularRegularization(robot, v_d * lookahead_k, param) ...
	        ];
	    end
	end
	
	% input into robotic kinematic
	robot = f(robot, u, param.dt);
	pose = [pose; robot.x, robot.y, robot.theta];
end

在这里插入图片描述

完整工程代码请联系下方博主名片获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android面试题之Kotlin和Java之间互操作

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 互操作性和可空性 要注意Java中所有类型都是可空的String!表示平台数据类型 public class JavaTest {public String generateName() {return …

瞬息全宇宙——平行宇宙终极教程,手把手教你做出百万点赞视频

最近一种叫“瞬息全宇宙”的视频火了&#xff0c;抖音一期视频百万赞&#xff0c;各个博主视频都在带瞬息全宇宙这个标签&#xff0c;于是就有很多朋友催我出教程了&#xff0c;在琢磨了几天之后&#xff0c;终于整出来了 教程包含了插件的安装&#xff0c;界面的讲解&#xff…

for 双重循环

一.双循环&#xff1a; 可以使用嵌套循环来实现脚本的双层循环&#xff0c;示例代码如下 1.显示外循环是$a 内循环$b encho -e \t 是制表符 2.9 9乘法表 for 循环&#xff1a; echo -n是不换行输出 while循环: 3.输出长度宽度都为9个星的矩形 for循环 while循环 …

开发者出海时都在用哪些组件库?

❝ 哈喽&#x1f44b;&#xff0c;我是树酱。今天我要介绍的是在开发者出海时经常使用的组件库。这些组件库大多采用Tailwind CSS作为基础&#xff0c;它们不仅风格独树一帜&#xff0c;而且外观也非常吸引人&#xff01; 1.Shadcn-ui shadcn的风格跟Notion风格很像&#xff0c…

博客互动革命:如何打造活跃读者社区并提升参与度

CSDN 的朋友你们好&#xff0c;我是未来&#xff0c;今天给大家带来专栏【程序员博主教程&#xff08;完全指南&#xff09;】的第 10 篇文章“与读者互动”。本文揭示了提升技术博客参与度的秘诀。从评论互动到社交媒体策略&#xff0c;本文将指导你如何建立强大的读者社区。掌…

编程技巧:什么是JavaScript递归

什么是递归 程序调用自身的编程技巧称为递归&#xff08;recursion&#xff09; 递归的基本思想是将一个复杂的问题分解成更小、更易于管理的子问题&#xff0c;这些子问题与原始问题相似&#xff0c;但规模更小。 递归的要素 基本情况&#xff08;Base Case&#xff09;&…

【C语言 | 数据结构】栈

文章目录 前言1、栈1.1栈的概念和定义1.1.2栈的基本概念&#xff1a; 1.2栈的方法(接口)1.3栈的实现方法1.4栈的性质1.5栈的应用1.6栈的结构 2、栈的实现2.1 顺序栈2.1.1 顺序栈的结构体2.1.2 顺序栈的初始化2.1.3 顺序栈的销毁2.1.4 顺序栈的入栈2.1.5 顺序栈的出栈2.1.5 顺序…

聚观早报 | 比亚迪海狮07 EV上市;苹果将升级Siri

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 5月13日消息 比亚迪海狮07 EV上市 苹果将升级Siri OpenAI开发全新技术 沃尔沃EX30车型将上市 SpaceX计划新建发…

template——模板进阶(C++)

在之前的文章中&#xff0c;介绍了模板初阶&#xff1a;Cpp_桀桀桀桀桀桀的博客-CSDN博客 在本篇中将会对模板进一步的讲解。本篇中的主要内容为&#xff1a;非类型模板参数、函数模板的特化、类模板的特化&#xff08;其中包含全特化和偏特化&#xff09;&#xff0c;最后讲解…

【计算机网络篇】数据链路层(9)使用集线器的共享式以太网

文章目录 &#x1f6f8;使用同轴电缆的共享总线以太网 &#x1f386;使用集线器的共享式以太网&#x1f95a;集线器的特点 &#x1f354;10BASE-T星型以太网 &#x1f6f8;使用同轴电缆的共享总线以太网 若总线上的某个机械连接点接触不良或断开&#xff0c;则整个网络通信就不…

【前端工程化指南】Git常见操作之忽略文件

默认情况下&#xff0c;Git管理代码版本时会对所有文件进行跟踪&#xff0c;但有些时候我们并不希望项目中的一些文件上传到远程仓库或公共仓库中&#xff0c;例如密钥&#xff0c;个人隐私文件等。因此Git提供了两种忽略跟踪文件的方式.gitignore文本文件与git rm命令&#xf…

亿级流量下通用的高并发架构设计

既然是亿级用户应用&#xff0c;那么高并发必然是其架构设计的核心要素。 本文我们将介绍高并发架构设计的一些通用设计方案。 关键词&#xff1a;读/写分离、数据缓存、缓存更新、CQRS、数据分片、异步写 本文节选自电子工业出版社博文视点刚刚出版的《亿级流量系统架构设计…

Java随笔1

1.编程中组件的概念&#xff1a; 在编程中&#xff0c;组件&#xff08;Component&#xff09;通常指的是一种可重用的、模块化的代码单元&#xff0c;它封装了特定的功能或用户界面元素&#xff0c;并提供了与其他代码进行交互的接口。组件可以看作是对数据和方法的简单封装&…

ADS基础操作篇2

上篇文章《ADS基础介绍篇1》,对ADS界面,常用小工具及自带设计模板进行了介绍。ADS使用非常方便,含大量的控件和仿真模板。这篇文章我们主要讲解ADS的基础操作,包含Workspace、原理图、symbol的创建,仿真结果查看及优化。 1. 新建Workspace 添加名称及路径后,点击create…

共享充电宝语音芯片ic方案支持远程4g无线更新语音

一、简介 共享充电宝语音芯片ic方案支持远程4g无线wifi蓝牙更新语音 共享充电宝已经是遍布在大街小巷的好产品&#xff0c;解决了携带充电宝麻烦的痛点 但是很多的共享充电宝在人机交互方便&#xff0c;还做得不够好&#xff0c;比如&#xff1a;借、还设备没有语音提示&…

基于SSM的计算机课程实验管理系统的设计与实现(源码)

| 博主介绍&#xff1a;✌程序员徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f44…

AI视频教程下载:用ChatGPT制作 YouTube视频的指南

课程大纲&#xff1a; 面向 YouTuber 的 ChatGPT YouTube关键词研究 YouTube标题 YouTube缩略图 YouTube社区帖子 组织您的 YouTube 视频 本课程将通过两个不同领域的YouTube视频&#xff0c;展示如何使用Chat GPT来创建关键词、标题、缩略图、描述和社区帖子。 关键词研…

【Linux网络】Https【下】{CA认证/证书的签发与认证/安全性/总结}

文章目录 1.引入证书【为方案五铺垫】1.1再谈https1.2SSL/TLS1.3CA机构1.4理解数字签名1.4继续铺垫1.5方案五服务端申请证书回顾一二三回顾方案四方案五过程寻找方案五的漏洞客⼾端对证书进⾏认证 2.查看证书2.1查看浏览器的受信任证书发布机构2.2中间⼈有没有可能篡改该证书2.…

Postman工具介绍与安装

一、Postman介绍 Postman 乃是一款对 HTTP 协议予以支持的接口调试及测试工具&#xff0c;其突出特性在于功能强大&#xff0c;并且使用简便、易用性良好。不管是开发人员开展接口调试工作&#xff0c;还是测试人员进行接口测试任务&#xff0c;Postman 均属于首选工具之一。 接…

会声会影2024中文旗舰免费版(Corel VideoStudio)下载安装包附带会声会影软件注册机

一、软件背景及版本概述 会声会影&#xff08;Corel VideoStudio&#xff09;是由加拿大Corel公司发布的一款视频编辑软件&#xff0c;该软件以其功能丰富、操作简便而广受好评。2024年版本在继承之前版本优点的基础上&#xff0c;进行了诸多创新和改进&#xff0c;为用户提供…