49.在ROS中实现local planner(2)- 实现Purepersuit(纯跟踪)算法
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−yd = {r - y} d=r−y
d2+x2=r2d^2+x^2 = r^2 d2+x2=r2
即:r2−2ry+y2+x2=r2r^2-2ry+y^2+x^2 = r^2 r2−2ry+y2+x2=r2
即:x2+y2=2ryx^2+y^2 = 2ry x2+y2=2ry
即:L2=2ryL^2 = 2ry L2=2ry
即:r=L2/2yr = 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;}#elsegeometry_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);#endifreturn 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

相关文章:
49.在ROS中实现local planner(2)- 实现Purepersuit(纯跟踪)算法
48.在ROS中实现local planner(1)- 实现一个可以用的模板实现了一个模板,接下来我们将实现一个简单的纯跟踪控制,也就是沿着固定的路径运动,全局规划已经规划出路径点,基于该路径输出相应的控制速度 1. Pur…...
Allegro如何设通孔Pin和Via的消盘操作指导
Allegro如何设通孔Pin和Via的消盘操作指导 用Allegro做PCB设计的时候,除了可以在光绘设置里面设置内层通孔Pin和Via的消盘,在设计过程中,同样也可以设置消盘效果,以便实时显示,如下图 如何设置,具体操作如下 点击Setup点击Unused Pads Suppression...
Android工厂模式
工厂模式分为三种 :简单工厂模式 、工厂方法模式 、抽象工厂模式 。 目录 简单工厂模式 UML图 实现 使用场景: 优点 : 缺点: 工厂方法模式 UML图 实现 使用场景: 优点: 缺点: 抽象工厂模式 UM…...
神经网络硬件加速器-架构篇
架构设计 常规架构通常包括两种: 1、全流水线架构,顾名思义,将整个神经网络进行平铺,并对每一层进行优化设计,优点:实现高吞吐率和低延时。缺点:消耗大量硬件资源,通常无法跨网络或…...
Python raise用法(超级详细,看了无师自通)
是否可以在程序的指定位置手动抛出一个异常?答案是肯定的,Python 允许我们在程序中手动设置异常,使用 raise 语句即可。 大家可能会感到疑惑,即我们从来都是想方设法地让程序正常运行,为什么还要手动设置异常呢&#…...
1.SpringSecurity快速入门
*SpringScurity的核心功能: 认证:验证当前访问系统的是不是本系统的用户,并且要确认具体是哪个用户 授权:经过认证后判断当前用户是否有权限进行某个操作 *第一步:创建springboot工程 *第二步:引入SpringSecurity依赖 *第三步:写controller,访问对应的url:localhos…...
Graph Partition: Edge cut and Vertex cut
Graph PartitionEdge cut and Vertex cutEdge cutVertex cut实际如何进行点分割和边分割的呢?Graph store format情况1:按照边列表存储:情况2:按照邻接表存储:Edge cut and Vertex cut 图结构描述了数据流动ÿ…...
Javascript周学习小结(初识,变量,数据类型)
JS的三大书写方式行内式如图所示:几点说明:JS的行内式写在HTML的标签内部,(常以on开头),如onclick行内式常常使用单引号括住字符串以区分HTML的双引号可读性差,不建议使用引号易出错,不建议使用特殊情况下使…...
C语言-基础了解-10-C函数
C函数 一、C函数 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。 您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上&…...
【LeetCode】剑指 Offer(16)
目录 题目:剑指 Offer 33. 二叉搜索树的后序遍历序列 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 题目:剑指 Offer …...
第三十九章 linux-并发解决方法二(互斥锁mutex)
第三十九章 linux-并发解决方法二(互斥锁mutex) 文章目录第三十九章 linux-并发解决方法二(互斥锁mutex)互斥锁的定义与初始化互斥锁的DOWN操作互斥锁的UP操作用count1的信号量实现的互斥方法还不是Linux下经典的用法,…...
脚本方式本地仓库jar包批量导入maven私服
脚本内容,将以下内容保存为mavenimport.sh,放置于需要上传的目录下,可以是顶层目录,或者某个分包的目录,若私服已有待上传的包,则执行会被替换 #!/bin/bash # copy and run this script to the root of th…...
【c++】引用的学习
引用的定义和声明 引用是一种别名,它允许使用与原变量相同的内存位置。在C中,引用是使用&符号来定义的。引用必须在定义时初始化,并且可以与原变量分别使用。 int a 10; int& b a; // 定义了一个引用b,它指向a引用的作用…...
linux 软件安装及卸载
1.联网在线安装及卸载ubuntu环境下:使用apt-get 工具apt-get install - 安装软件包apt-get remove - 移除(卸载)软件包CentOS环境下:使用yum工具 (银河麒麟系统属于centos)yum install - 安装软件包yum rem…...
XShell连接ubuntu20.04.LTS
1 下载XshellXShell官方下载地址打开XSHELL官方下载地址,我们可以选择【家庭和学校用户的免费许可证】,输入邮箱之后即可获得下载链接安装非常简单,跟着提示进行即可。2 连接ubuntu2.1 查看ubuntu的ip地址输入命令查看ip地址ifconfig刚开始可…...
【FPGA】Verilog:MSI/LSI 组合电路之解码器 | 多路分解器
写在前面:本章将理解编码器与解码器、多路复用器与多路分解器的概念,通过使用 Verilog 实现多样的解码器与多路分解器,通过 FPGA 并使用 Verilog 实现。 Ⅰ. 前置知识 0x00 解码器与编码器(Decoder / Encoder) 解码器…...
深入理解JDK动态代理原理,使用javassist动手写一个动态代理框架
文章目录一、动手实现一个动态代理框架1、初识javassist2、使用javassist实现一个动态代理框架二、JDK动态代理1、编码实现2、基本原理(1)getProxyClass0方法(2)总结写在后面一、动手实现一个动态代理框架 1、初识javassist Jav…...
一、策略模式的使用
1、策略模式定义: 策略模式(Strategy Pattern)定义了一组策略,分别在不同类中封装起来,每种策略都可以根据当前场景相互替换,从而使策略的变化可以独立于操作者。比如我们要去某个地方,会根据距…...
Verilog使用always块实现时序逻辑
这篇文章将讨论 verilog 中一个重要的结构---- always 块(always block)。verilog 中可以实现的数字电路主要分为两类----组合逻辑电路和时序逻辑电路。与组合逻辑电路相反,时序电路电路使用时钟并一定需要触发器等存储元件。因此,…...
面向对象设计模式:行为型模式之迭代器模式
一、迭代器模式,Iterator Pattern aka:Cursor Pattern 1.1 Intent 意图 Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. 提供一种按顺序访问聚合对象的元素而不公开其基…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
