ROS导航使用贝塞尔曲线对全局路径进行平滑处理

文章目录

  • 前言
  • 一、贝塞尔曲线的使用
  • 二、全局路经修改
  • 三、结果对比


前言

ROS原生的全局路径规划GlobalPlanner包含A*和Dijkstra,两者原理基本相同,能够规划出从起点到终点的路径,但是由于栅格地图存在锯齿形,得到的全局路径也会出现“折弯”,不够平滑的现象,虽然不影响导航的使用,但对于路径跟踪来讲,会存在运动不够平滑的情况,因此本文将会使用贝塞尔曲线对globalplanner规划的路径进行处理后给到局部路径,供导航使用。


一、贝塞尔曲线的使用

网上关于对贝塞尔曲线的介绍有很多,这里仅仅做一个简单的介绍。
贝塞尔曲线原理
贝塞尔曲线常用于绘制曲线,具有以下特征:

  1. 使用n个控制点{p1,p2,…,pn}来控制曲线的形状;
  2. 曲线通过起点平p1和终点pn,接近但不通过中间点

一阶贝塞尔曲线:给定点P0,P1,此时贝塞尔曲线只是两点之间的一条直线,描述为:
B ( t ) = P 0 + ( P 1 − P 0 ) t = ( 1 − t ) P 0 + t P 1 , t ∈ [ 0 , 1 ] B(t) = P0 + (P1-P0)t = (1-t)P0 + tP1, t ∈ [0,1] B(t)=P0+(P1P0)t=(1t)P0+tP1,t[0,1]
二阶贝塞尔曲线:给定点P0,P1,P2,贝塞尔曲线描述为:
B ( t ) = ( 1 − t ) 2 P 0 + 2 t ( 1 − t ) P 1 + t 2 P 2 , t ∈ [ 0 , 1 ] B(t) = (1-t)^2P0 + 2t(1-t)P1 + t^2P2, t ∈ [0,1] B(t)=(1t)2P0+2t(1t)P1+t2P2,t[0,1]

二、全局路经修改

ROS运动规划学习五介绍过全局路径的生成过程,是由planer_core文件中makePlan函数实现,因此在可以在makePlan函数中进行路径平滑。
步骤如下:

  1. 声明定义二阶和三阶贝塞尔曲线函数。
//二阶贝塞尔曲线
float GlobalPlanner::bezier2func(float uu,float* controlPoint){  float part0 = controlPoint[0] * (1-uu) * (1-uu);  float part1 = 2 * controlPoint[1] * uu * (1-uu);  float part2 = controlPoint[2] * uu * uu ;     return part0 + part1 + part2 ;   
}
//三阶贝塞尔曲线
float GlobalPlanner::bezier3func(float uu,float* controlPoint){  float part0 = controlPoint[0] * (1-uu) * (1-uu) * (1-uu);  float part1 = 3 * controlPoint[1] * uu * (1-uu) * (1 - uu);  float part2 = 3 * controlPoint[2] * uu * uu * (1 - uu);  float part3 = controlPoint[3] * uu * uu * uu;     return part0 + part1 + part2 + part3;   
}  
  1. 全局路径处理,获取要平滑的路径点。由于全局路径上的点太过密集,为减少计算量,这里每隔distance个点取一个点作为放入要平滑的路径,同时将路径终点也放入。
void GlobalPlanner::deal_path(const nav_msgs::Path& input,nav_msgs::Path& output,int distance){output.header.stamp = ros::Time::now();output.header.frame_id = "map";output.poses.clear();geometry_msgs::PoseStamped pathVehicle;int length = input.poses.size();for (int i = 0; i < (length / distance); i++) {pathVehicle.header.frame_id = "map";pathVehicle.header.stamp = ros::Time::now();pathVehicle.pose.position.x = input.poses[i*distance].pose.position.x;pathVehicle.pose.position.y = input.poses[i*distance].pose.position.y;pathVehicle.pose.position.z = 0;pathVehicle.pose.orientation.x = input.poses[i*distance].pose.orientation.x;pathVehicle.pose.orientation.y = input.poses[i*distance].pose.orientation.y;pathVehicle.pose.orientation.z = input.poses[i*distance].pose.orientation.z;pathVehicle.pose.orientation.w = input.poses[i*distance].pose.orientation.w;output.poses.push_back(pathVehicle);}pathVehicle.header.frame_id = "map";pathVehicle.header.stamp = ros::Time::now();pathVehicle.pose.position.x = input.poses[length-1].pose.position.x;pathVehicle.pose.position.y = input.poses[length-1].pose.position.y;pathVehicle.pose.position.z = 0;pathVehicle.pose.orientation.x = input.poses[length-1].pose.orientation.x;pathVehicle.pose.orientation.y = input.poses[length-1].pose.orientation.y;pathVehicle.pose.orientation.z = input.poses[length-1].pose.orientation.z;pathVehicle.pose.orientation.w = input.poses[length-1].pose.orientation.w;output.poses.push_back(pathVehicle);
}
  1. 使用贝塞尔曲线函数对2中得到的路径进行平滑,并创建新的全局路径。
void GlobalPlanner::createCurve(const nav_msgs::Path& originPoint,nav_msgs::Path& output){}

三、结果对比

图中蓝色曲线为原始路径,红色曲线为平滑后的路径,能够看出,相比于原始路径存在折弯的部分,贝塞尔曲线处理后的路径更加平滑。
在这里插入图片描述


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

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

相关文章

解决uniapp H5页面限制输入框只能输数字问题

工作记录 最最近在做 uniapp 开发的移动端 H5 页面&#xff0c;有个需求是金额输入框只能输入数字&#xff0c;不能输入小数点和其他字符&#xff0c;经过各种尝试&#xff0c;发现其他字符可以通过正则过滤掉&#xff0c;但是输入小数点的话&#xff0c;因为没有触发 input 和…

DC-2 靶场渗透

目录 环境搭建 开始渗透 扫存活 扫端口 扫服务 看一下80端口 看一下指纹信息 使用wpscan扫描用户名 再使用cewl生成字典 使用wpscan爆破密码 登陆 使用7744端口 查看shell rbash绕过 切换到jerry用户 添加环境变量 现在可以使用su命令了 提权 使用git提权 环…

如何逐步操作vCenter修改DNS服务器?

在vSphere 7中有一个新功能&#xff0c;它允许管理员更改vCenter Server Appliance的FQDN和IP。因此本文将介绍如何轻松让vCenter修改DNS服务器。 vCenter修改DNS以及修改vCenter IP地址 与在部署 vCenter Server Appliance 后&#xff0c;您可以根据需要修改其 DNS 设置和 IP…

Qt qtcreator配置cmake

添加CMake 选择 Preferences > CMake > Tools. 可以将其设置为默认&#xff0c;如此新建的kit会自动选择默认cmake 完成CMake 代码&#xff08;自动补全&#xff09; Qt Creator 使用通用高亮为 CMake 命令提供代码完成的特定参数。例如&#xff0c;CMake: set_source_…

JeeSite 快速开发平台:全能企业级快速开发解决方案|GitCode 光引计划征文展示

投稿人GitCode ID&#xff1a;thinkgem 光引计划投稿项目介绍 JeeSite 快速开发平台&#xff0c;不仅仅是一个后台开发框架&#xff0c;它是一个企业级快速开发解决方案&#xff0c;后端基于经典组合 Spring Boot、Shiro、MyBatis&#xff0c;前端采用 Beetl、Bootstrap、Admi…

大模型系列17-RAGFlow搭建本地知识库

大模型系列17-RAGFlow搭建本地知识库 安装ollama安装open-wehui安装并运行ragflowRAG&#xff08;检索、增强、生成&#xff09;RAG是什么RAG三过程RAG问答系统构建步骤向量库构建检索模块生成模块 RAG解决LLM的痛点 使用ragflow访问ragflow配置ollama模型添加Embedding模型添加…

迟来的前端面试经验

最近也是在换工作&#xff0c;小公司和大厂&#xff08;虾皮、腾讯&#xff09;都有面试。几次面试收获还是比较大的&#xff0c;了解许多自己的短板&#xff0c;当然也拿到了合适的offer。本文主要整理下面试遇到的问题和知识点&#xff0c;希望对准备找工作的掘友有所帮助。 …

DepthLab: From Partial to Complete 论文解读

目录 一、概述 二、相关工作 1、深度补全 2、单目深度估计 3、已知部分深度的下游任务 三、DepthLab 1、总论 2、编码器和解码器 3、Estimation U-Net 4、Reference U-Net 四、训练操作 1、深度归一化 2、掩模策略 五、数据集 1、训练数据集 2、评估数据集 六、…

直播预告丨社区年度交流会 《RTE 和 AI 融合生态洞察报告 2024》发布

新的一年开始&#xff0c;是时候再深度交流一次了&#xff01;欢迎关注 1 月 4 日周六晚 社区年度交流会的 线上直播 。 这将是一群 实时多模态 AI 开发者 的聚会。 我们将一起探讨 Voice Agent 在 AI 陪伴助手、AI 硬件和 AI 企业服务等应用场景中的技术突破与产品创新。同时…

RP2K:一个面向细粒度图像的大规模零售商品数据集

这是一种用于细粒度图像分类的新的大规模零售产品数据集。与以往专注于相对较少产品的数据集不同&#xff0c;我们收集了2000多种不同零售产品的35万张图像&#xff0c;这些图像直接在真实的零售商店的货架上拍摄。我们的数据集旨在推进零售对象识别的研究&#xff0c;该研究具…

实战设计模式之建造者模式

概述 在实际项目中&#xff0c;我们有时会遇到需要创建复杂对象的情况。这些对象可能包含多个组件或属性&#xff0c;而且每个组件都有自己的配置选项。如果直接使用构造函数或前面介绍的工厂方法来创建这样的对象&#xff0c;可能会导致以下两个严重问题。 1、参数过多。当一个…

我的博客年度之旅:感恩、成长与展望

目录 感恩有你 技能满点 新年新征程 嘿&#xff0c;各位技术大佬、数码潮咖还有屏幕前超爱学习的小伙伴们&#xff01;当新年的钟声即将敲响&#xff0c;我们站在时光的交汇点上&#xff0c;回首过往&#xff0c;满心感慨&#xff1b;展望未来&#xff0c;豪情满怀。过去的这…

聆听音乐 1.5.9 | 畅听全网音乐,支持无损音质下载

聆听音乐手机版是面向广大音乐爱好者的移动应用程序&#xff0c;用户可以随时随地通过手机享受丰富的音乐资源。它提供了多种魅力功能&#xff0c;让用户在手机上畅享更舒适的音乐体验&#xff0c;每位用户都能享受精彩纷呈的收听体验。此外&#xff0c;软件还支持无损音质音乐…

GRU-PFG:利用图神经网络从股票因子中提取股票间相关性

“MCI-GRU: Stock Prediction Model Based on Multi-Head Cross-Attention and Improved GRU” 论文地址&#xff1a;https://arxiv.org/pdf/2410.20679 摘要 金融市场因复杂性及大数据时代的来临&#xff0c;使得准确预测股票走势变得尤为重要。传统的时序分析模型&#xff0…

Leetcode 第426场周赛分析总结

3370. 仅含置位位的最小整数 AC代码 class Solution { public:int smallestNumber(int n) {int x 1;while (x - 1 < n) {x << 1;}return x - 1;} };分析总结 也可以先直接获取n的长度&#xff0c;然后计算得到&#xff0c;这样时间复杂度由O(logn)优化为O(1) 在C…

在 SQL 中,区分 聚合列 和 非聚合列(nonaggregated column)

文章目录 1. 什么是聚合列&#xff1f;2. 什么是非聚合列&#xff1f;3. 在 GROUP BY 查询中的非聚合列问题示例解决方案 4. 为什么 only_full_group_by 要求非聚合列出现在 GROUP BY 中&#xff1f;5. 如何判断一个列是聚合列还是非聚合列&#xff1f;6. 总结 在 SQL 中&#…

C++ —— 智能指针

内存泄漏 什么是内存泄漏&#xff0c;内存泄漏的危害 什么是内存泄漏&#xff1a;内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内 存泄漏并不是指内存在物理上的消失&#xff0c;而是应用程序分配某段内存后&#xff0c;因为设计错误&#xff0c;失去…

Ethernet 系列(12)-- 基础学习::SOME/IP

目录 1. SOME/IP简介&#xff1a; 1.1 什么是SOME/IP&#xff1a; 1.2 什么时候使用SOME/IP&#xff1a; 2. SOME/IP的特点&#xff1a; 2.1 序列化&#xff1a; 2.2 远程过程调用&#xff08;RPC&#xff09;: 2.3 服务发现&#xff1a; 2.4 发布/订阅&#xff1a; 2.5 UDP消息…

UE5.3 虚幻引擎 Windows插件开发打包(带源码插件打包、无源码插件打包)

0 引言 随着项目体量的增大&#xff0c;所有代码功能都放一起很难管理。所以有什么办法可以将大模块划分成一个个小模块吗。当然有&#xff0c;因为虚幻引擎本身就遇到过这个问题&#xff0c;他的解决办法就是使用插件的形式开发。 例如&#xff0c;一个团队开发了文件I/O模块插…

自学记录鸿蒙API 13:实现多目标识别Object Detection

起步&#xff1a;什么叫多目标识别&#xff1f; 无论是生活中的动物识别、智能相册中的场景分类&#xff0c;还是工业领域的检测任务&#xff0c;都能看到多目标识别的身影。这次&#xff0c;我决定通过学习HarmonyOS最新的Object Detection API&#xff08;API 13&#xff09…