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.mzph.cn/news/891626.shtml

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

相关文章

GIT 企业级开发学习 1

本节主要命令&#xff1a; git init ls 不能列出 .git ls -a 列出 .git 1. 初始化 Git 仓库 git init • 初始化一个新的 Git 仓库&#xff0c;在当前目录下生成一个 .git 隐藏文件夹&#xff0c;用于存储版本控制信息。 2. 查看隐藏文件 ls -a • 使用 ls -a 显示隐藏文件…

【从零开始入门unity游戏开发之——unity篇05】unity6基础入门——运行游戏按钮、Game游戏窗口和Project项目窗口介绍

文章目录 运行游戏按钮、Game游戏窗口和Project项目窗口一、运行游戏按钮二、Game游戏窗口1、右上角设置1.1 如果没有相机渲染则发出警告1.2 在”编程模式”下清除每一帧1.3 窗口最大化 2、上方工具&#xff08;1&#xff09;切换手机模拟器&#xff08;2&#xff09;切换不同显…

Java 定时任务发送邮件

163邮箱为例 1、添加依赖 <!-- mail-starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency> 2、编写配置&#xff0c;smtp默认端口25&#xff0c…

【深度学习进阶】基于CNN的10种物体识别项目

介绍 基于卷积神经网络&#xff08;CNN&#xff09;的猫狗图片分类项目是机器学习领域中的一种常见任务&#xff0c;它涉及图像处理和深度学习技术。以下是该项目的技术点和流程介绍&#xff1a; 技术点 卷积神经网络 (CNN): CNN 是一种专门用于处理具有类似网格结构的数据的…

开发培训-慧集通(iPaaS)集成平台脚本开发Groovy基础培训视频

‌Groovy‌是一种基于Java虚拟机&#xff08;JVM&#xff09;的敏捷开发语言&#xff0c;结合了Python、Ruby和Smalltalk的许多强大特性。它旨在提高开发者的生产力&#xff0c;通过简洁、熟悉且易于学习的语法&#xff0c;Groovy能够与Java代码无缝集成&#xff0c;并提供强大…

Flutter中添加全局防护水印的实现

随着版权意识的加强&#xff0c;越来越多的应用开始在应用内部增加各种各样的水印信息&#xff0c;防止核心信息泄露&#xff0c;便于朔源。 效果如下&#xff1a; 在Flutter中增加全局水印的方式&#xff0c;目前有两种实现。 方案一&#xff0c;在native层添加一个遮罩层&a…

华为ensp-BGP路由过滤

学习新思想&#xff0c;争做新青年&#xff0c;今天学习的是BGP路由过滤 实验目的&#xff1a; 掌握利用BGP路由属性AS_Path进行路由过滤的方法 掌握利用BGP路由属性Community进行路由过滤的方法 掌握利用BGP路由属性Next_Hop进行路由过滤的方法 实验内容&#xff1a; 本实…

鸿蒙应用开发搬砖经验之—使用DevTools工具调试前端页面

环境说明&#xff1a; 系统环境&#xff1a;Mac mini M2 14.5 (23F79) 开发IDE&#xff1a;DevEco Studio 5.0.1 Release 配置步骤&#xff1a; 按着官方的指引来慢慢一步一步来&#xff0c;但前提是要配置好SDK的路径&#xff08;没有配置的话&#xff0c;可能先看下面的配…

Linux(centos)安装 MySQL 8 数据库(图文详细教程)

前言 前几天写了个window系统下安装Mysql的博客&#xff0c;收到很多小伙伴私信需要Linux下安装Mysql的教程&#xff0c;今天这边和大家分享一下&#xff0c;话不多说&#xff0c;看教程。 一、删除以前安装的MySQL服务 一般安装程序第一步都需要清除之前的安装痕迹&#xff…

【HarmonyOS应用开发——ArkTS语言】欢迎界面(启动加载页)的实现【合集】

目录 &#x1f60b;环境配置&#xff1a;华为HarmonyOS开发者 &#x1f4fa;演示效果&#xff1a; &#x1f4d6;实验步骤及方法&#xff1a; 一、在media文件夹中添加想要使用的图片素材​ 二、在entry/src/main/ets/page目录下创建Welcome.ets文件 1. 整体结构与组件声…

查看打开的端口

对一个大范围的网络或活跃的主机进行渗透测试&#xff0c;需要了解这些主机上所打开的端口号。 使用Nmap工具扫描主机上开放的端口号&#xff1a; 输出的信息显示了主机www.yiai.xyz上开放的所有端口 指定扫描端口范围 如果目标主机上打开的端口较多时&#xff0c;用户查看起…

运动控制探针功能详细介绍(CODESYS+SV63N伺服)

汇川AM400PLC和禾川X3E伺服EtherCAT通信 汇川AM400PLC和禾川X3E伺服EtherCAT通信_汇川ethercat通信-CSDN博客文章浏览阅读1.2k次。本文详细介绍了如何使用汇川AM400PLC通过EtherCAT总线与禾川X3E伺服进行通信。包括XML硬件描述文件的下载与安装,EtherCAT总线的启用,从站添加…

大模型 LangChain 开发框架:Runable 与 LCEL 初探

大模型 LangChain 开发框架&#xff1a;Runable 与 LCEL 初探 一、引言 在大模型开发领域&#xff0c;LangChain 作为一款强大的开发框架&#xff0c;为开发者提供了丰富的工具和功能。其中&#xff0c;Runnable 接口和 LangChain 表达式语言&#xff08;LCEL&#xff09;是构…

力扣28找出字符串中第一个匹配项的下标

class Solution:def strStr(self, haystack: str, needle: str) -> int:# 特殊情况处理if not needle:return 0# 获取 haystack 和 needle 的长度a len(needle)b len(haystack)# 遍历 haystack&#xff0c;检查每个子字符串是否与 needle 匹配for i in range(b - a 1):if…

基于微信小程序的自修室预约系统

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 在知识爆炸的时代&#xff0c;自修室成为了众多学习者…

计算机网络期末复习(含选择题、判断题、简答题、判断题)

&#x1f4e2;&#x1f4e2;&#x1f4e2;传送门 一、选择题二、判断题三、简答题目1.问&#xff1a;常用的信道复用技术包括哪几种?简述它们的基本工作原理2.问&#xff1a;请分别列举OSI参考模型和TCP/IP参考模型的层次结构3.问&#xff1a;请描述交换机的基本功能。用它怎样…

MySQL - 函数

一 . 函数定义&#xff1a; 函数 是指一段可以直接被另一段程序调用的程序或代码。 ---> 说明这些函数已经被mysql内置了 MySQL中的函数主要分为以下四类&#xff1a; 字符串函数、数值函数、日期函数、流程函数。 二 . 字符串函数 MySQL中内置了很多字符串函数&#xff0c…

UniApp 原生插件开发指南

一、UniApp 原生插件开发引言 在当今的移动应用开发领域&#xff0c;跨平台开发已成为主流趋势&#xff0c;而 UniApp 作为一款强大的跨平台开发框架&#xff0c;备受开发者青睐。它凭借 “一套代码&#xff0c;多端运行” 的特性&#xff0c;极大地提高了开发效率&#xff0c…

Java高频面试之SE-08

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本牛马baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; 成员变量和局部变量的区别有哪些&#xff1f; 在 Java 中&#xff0c;成员变量和局部变量是两种不同类型的变量&#xff0c;它们在作用域…

计算机网络 (15)宽带接入技术

前言 计算机网络宽带接入技术是指通过高速、大容量的通信信道或网络&#xff0c;实现用户与互联网或其他通信网络之间的高速连接。 一、宽带接入技术的定义与特点 定义&#xff1a;宽带接入技术是指能够传输大量数据的通信信道或网络&#xff0c;其传输速度通常较高&#xff0c…