49.在ROS中实现local planner(2)- 实现Purepersuit(纯跟踪)算法

2023-05-16

48.在ROS中实现local planner(1)- 实现一个可以用的模板实现了一个模板,接下来我们将实现一个简单的纯跟踪控制,也就是沿着固定的路径运动,全局规划已经规划出路径点,基于该路径输出相应的控制速度

1. Pure Pursuit

Pure Pursuit路径跟随便是基于受约束移动机器人圆周运动的特性所开发出来的运动控制方式。原理十分简单,如图所示,移动机器人有一个前视的搜索半径,与机器人规划的路径有一个焦点,假设机器人从当前位置到路径焦点的运动为圆周运动。其中的前视距离便是图1中的L。根据几何关系便可以计算机器人的运动半径。
在这里插入图片描述

受约束的机器人模型(不能横向运动)可由两个控制量组成,即运动参考点的线速度v与角速度w。在极短的运行周期中,机器人都是以固定的线速度与角速度运动。因此机器人的运动可以视为圆周运动(w=0时为直线运动)。

2. 运动半径推算

如图所示的机器人便是绕着一个旋转中心进行圆周运动,于是移动机器人的运动控制可视为求解其在运动过程中的实时旋转半径。图中,r为移动机器人的旋转半径。

我们以base坐标系为例,及当前机器人为坐标原点,x轴为前方,y轴为左方,即ROS的坐标系,(x,y)为目标点, L为距离目标点的距离(前视距离),如下计算,容易求得旋转半径r

由图可得 d = r − y d = {r - y} d=ry
d 2 + x 2 = r 2 d^2+x^2 = r^2 d2+x2=r2
即: r 2 − 2 r y + y 2 + x 2 = r 2 r^2-2ry+y^2+x^2 = r^2 r22ry+y2+x2=r2
即: x 2 + y 2 = 2 r y x^2+y^2 = 2ry x2+y2=2ry
即: L 2 = 2 r y L^2 = 2ry L2=2ry
即: r = L 2 / 2 y r = L^2/2y r=L2/2y

运动半径=前视距离的平方/两倍的y

我们知道r=v/w 即我们只需要给定v/w为固定的值即可

因v与L相关 我们取一次关系
v=aL a为长数项
可得w=v/r=a*2y/L

3. 坐标转换

我们知道setPlan下发的坐标一般使用的是map坐标系,我们计算的时候需要转换为base坐标系

我们可以使用init接口提供的tf::TransformListener即可完成, (1.14.0版本后接口更新,使用新的接口)


geometry_msgs::PoseStamped PurepursuitPlanner::goalToBaseFrame(const geometry_msgs::PoseStamped& goal_pose_msg) {

#if ROS_VERSION_GE(ROS_VERSION_MAJOR, ROS_VERSION_MINOR, ROS_VERSION_PATCH, 1, 14, 0)

  geometry_msgs::PoseStamped goal_pose, base_pose_msg;

  goal_pose = goal_pose_msg;

  goal_pose.header.stamp = ros::Time(0.0);

  try {

    base_pose_msg = tf_->transform(goal_pose, "base_link");

  } catch (tf2::TransformException& ex) {

    ROS_WARN("transform err");

    return base_pose_msg;

  }

#else

  geometry_msgs::PoseStamped base_pose_msg;

  tf::Stamped<tf::Pose> goal_pose, base_pose;

  poseStampedMsgToTF(goal_pose_msg, goal_pose);

  goal_pose.stamp_ = ros::Time();

  try {

    tf_->transformPose(costmap_ros_->getBaseFrameID(), goal_pose, base_pose);

  } catch (tf::TransformException& ex) {

    ROS_WARN("transform err");

    return base_pose_msg;

  }

  tf::poseStampedTFToMsg(base_pose, base_pose_msg);

#endif

  return base_pose_msg;

}

4. 前视距离

我们不断根据当前位置,更新前视距离,通过前面的接算,给定速度

4.1 前视距离大小设置

前世距离可以根据V我们预设速度相关

  • 如果前世距离较大,相当于路径采样间隔较大,跟踪路径与规划路径的偏差会大。

  • 如果前世距离较小,机器人容易抖动

4.2 前视距离更新策略

如果当前距离路径中前视距离的点后的n个点的距离小于前世距离,则更新前视距离
即如果当前前视距离的点在路径索引为n,则判断n+m索引距离当前点位置是否小于预设前视距离值

5. 速度限制

一般机器人小车,线速度是>0的即,只能前进,无法后退。这就需要我们新增当前前视点角度判断, 如果角度超过90,即在车的后方。可以对速度修正强制旋转

  auto target_yaw_diff = atan2(goal.pose.position.y, goal.pose.position.x);  // 当前目标点相对机器人的角度
  
.... // 计算半径 速度

    // 当前目标点相对机器人的角度 相差较大(即目标点在机器人后面), 需要直发角速度(即原地旋转), 转向目标点
    if (target_yaw_diff > PI*0.5) {
      cmd_vel.linear.x = 0;
      cmd_vel.angular.z = 0.8;
    } else if (target_yaw_diff < -PI*0.5) {
      cmd_vel.linear.x = 0;
      cmd_vel.angular.z = -0.8;
    }

6. 完成判断

我们在前视点到达规划路径的最后一个时,且当前点与该最后一点距离差小于预设的容忍差,强制输出0速度

  if (got && l < GOAL_TOERANCE_XY) {
    goal_reached_ = true;
    cmd_vel.angular.z = 0;
    cmd_vel.linear.x = 0;
  }

7. 测试

  • 修改move_base配置文件move_base_params.yaml
# base_local_planner: "dwa_local_planner/DWAPlannerROS"
base_local_planner: pure_pursuit_local_planner/PurepursuitPlanner

dwa_local_planner/DWAPlannerROS—>pure_pursuit_local_planner/PurepursuitPlanner

  • 启动模拟器
pibot_simulator
  • 启动rviz
pibot_view

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

49.在ROS中实现local planner(2)- 实现Purepersuit(纯跟踪)算法 的相关文章

  • java基础知识——16.多态

    这篇文章 xff0c 我们来介绍一下java的多态 目录 1 多态概述 2 多态调用成员的特点 3 多态的优势与弊端 4 instanceof 关键字 5 小结 1 多态概述 我们先来回顾一下前面的知识 利用封装 xff0c 我们可以将一些
  • java基础知识——23.正则表达式

    这篇文章我们简略的讲一下java的正则表达式 目录 1 正则表达式概述 2 正则表达式的简单匹配规则 3 正则表达式的复杂匹配规则 4 正则表达式的分组匹配规则 5 正则表达式的非贪婪匹配 6 使用正则表达式进行搜索和替换 1 正则表达式概
  • java基础知识——26.反射

    这篇文章我们来讲一下java的代理与反射 xff0c 这是很重要的一部分内容 目录 1 什么是反射 2 获取class对象的三种方式 3 反射获取构造方法 4 利用反射来获取成员变量 5 利用反射来获取成员方法 6 反射的作用 7 反射小结
  • java基础知识——27.动态代理

    这篇文章 xff0c 我们来学一下java的动态代理 目录 1 动态代理的介绍 2 具体的代码实现 1 动态代理的介绍 动态代理 xff1a 无侵入式的额外给代码增加功能 很不好理解 xff0c 下面 xff0c 我们通过两个例子来说明一下
  • JavaWeb——1.JavaWeb概述

    这是我们javaweb的第一篇文章 xff0c 首先我们来介绍一下什么是Javaweb JavaWeb xff1a 使用java语言完成服务器端程序开发 如下面这张图所示 xff1a 可能不太好理解 xff0c 那么就用通俗的语言来解释一下
  • 关于创建spring boot项目时的报错(java: 无法访问org.springframework.boot.SpringApplication 错误的类文件:xxx类文件具有错误的版本 61)

    最近使用idea创建一个新的spring boot项目时出现了一个错误 xff0c 完成项目创建后直接运行项目出现了以下错误 当然在出现了这个问题前 xff0c 项目还出现明明已经选了Java8的版本 xff0c 项目构建完成后Java版本
  • 【公网映射——让私人电脑成为一台公网服务器】

    一 前言 自己有台电脑一直空着 xff0c 想着如果能把这台电脑布成一个服务器 xff0c 做测试用 xff0c 就能发挥它的余热了 二 步骤概述 2 1 把电脑的8080端口映射到公网 xff0c 使得外网可以访问到这台电脑的web工程
  • 数据结构-指针和结构体

    1 指针 首先看变量在内存中的存储 有时候需要获取并使用程序运行中某个变量的内存地址 xff0c 如何获取这个地址 如何存储这个地址 xff1f amp 取地址符 xff0c amp a就是获得了a的地址 可以存储地址的变量称为指针变量 指
  • mysqldump+binlog+gtid 实现数据库的增量备份

    文章目录 mysqldump备份数据库高级备份参数 xff1a binlog日志的GTID新特性示例 xff1a 演示跨binlog文件截取日志 mysqldump备份数据库 完全备份 43 增加备份 xff0c 速度相对较慢 xff0c
  • python爬取豆瓣电影排行前250获取电影名称和网络链接[静态网页]————爬虫实例(1)

    目录 1 算法原理 xff1a 2 程序流程 xff1a 3 程序代码 xff1a 4 运行结果 部分结果展示 xff1a 5 结果分析 xff1a 1 算法原理 xff1a xff08 1 xff09 利用import命令导入模块或者导入
  • 上、下拉电阻(定义、强弱上拉、常见作用、吸电流、拉电流、灌电流)

    目录 1 上 下拉电阻定义 2 强上拉 弱上拉 3 上 下拉电阻的作用 3 1 维持输入管脚是一个稳态 3 2 三极管实现电平转换电路的外围电路 3 3 OC OD电路 3 4 总线I O接口上 下拉电阻 3 5 增加输出管脚的驱动能力 3
  • Python——contains方法

    1 contains 方法用途 contains 方法可以判断子串是否在原字符串中 2 contains 来源 contains 方法在 operator 模块中 xff0c operator模块是 Python 中内置的操作符接口 xff
  • 下载3D元件模型导入Altium Designer并制作PCB元件库

    大家好 xff0c 一个新手菜鸟前来报到 xff01 好久没更新文章了 xff0c 前几天出去了 xff0c 不在家 xff0c 昨天有小伙伴疑惑 xff0c 从某平台导出的PCB并没有3D元件模型 xff0c 只有一个空空的焊盘 xff0
  • 贪心算法——背包问题

    14天阅读挑战赛 目录 1 题目描述 nbsp nbsp nbsp 2 问题分析 3 算法设计 4 C 程序 5 算法复杂度及优化
  • 【01】FreeRTOS基础知识

    目录 1 任务调度器简介 1 1抢占式调度举例 1 2时间片调度举例 2 任务状态 3 总结 1 任务调度器简介 调度器就是使用相关的调度算法来决定当前需要执行哪个任务 FreeRTOS一共支持以下三种任务调度方式 xff1a FreeRT
  • 【03】FreeRTOS的任务创建(静态和动态)和删除

    目录 1 任务创建和删除的API函数 1 1动态创建任务函数 1 1 1实现动态创建任务流程 1 1 2任务控制块结构成员介绍 1 2静态创建任务函数 1 2 1实现静态创建任务流程 1 3任务删除函数 1 3 1删除任务流程 2 任务创建
  • 【05】FreeRTOS的中断管理

    目录 1 什么是中断 2 中断优先级分组 2 1中断优先级分组 介绍 2 2中断优先级分组 配置 2 3中断优先级分组 特点 3 中断相关寄存器 3 1寄存器地址 3 2在FreeRTOS中配置PendSV和Systick中断优先级 3 3
  • PyQt - 使用多线程避免界面卡顿

    1 问题 在使用pyqt开发界面时 xff0c 遇到了一种情况 xff0c 就是在点击按钮之后 xff0c 响应函数中会启动一个循环 xff0c 该循环会一直执行 xff0c 然后就造成界面无响应 xff0c 如下所示 xff0c 由于我是
  • 【06】FreeRTOS临界段代码保护及调度器挂起与恢复

    目录 1 临界段代码保护简介 2 临界段代码保护函数介绍 2 1任务级临界区调用格式示例 2 2中断级临界区调用格式示例 2 3函数调用特点 2 4任务级进入和退出临界段函数 2 5中断级进入和退出临界段函数 3 任务调度器的挂起和恢复 3
  • 【08】FreeRTOS的任务调度

    目录 1 开启任务调度器 2 启动第一个任务 2 1prvStartFirstTask 2 1 1什么是MSP指针 2 1 2为什么是 0xE000ED08 xff1f 2 2 vPortSVCHandler 2 2 1出栈 压栈汇编指令详

随机推荐