全覆盖路径规划开源项目Clean-robot-turtlebot3原理及流程概括总结

本文主要是介绍全覆盖路径规划开源项目Clean-robot-turtlebot3原理及流程概括总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本系列文章主要介绍全覆盖路径规划开源项目Clean-robot-turtlebot3的相关内容,包含如下四篇文章,分别介绍了开源项目Clean-robot-turtlebot3流程的概括总结、ROS坐标系常用坐标及其变换、Clean-robot-turtlebot3关键函数解析等内容。

1、全覆盖路径规划开源项目Clean-robot-turtlebot3原理及流程概括总结

https://blog.csdn.net/qq_44339029/article/details/136880603

2、ROS坐标系常用坐标及其变换详细梳理

https://blog.csdn.net/qq_44339029/article/details/136671867

3、全覆盖路径规划开源项目Clean-robot-turtlebot3关键函数解析(上)

https://blog.csdn.net/qq_44339029/article/details/136879605

4、全覆盖路径规划开源项目Clean-robot-turtlebot3关键函数解析(下)

https://blog.csdn.net/qq_44339029/article/details/136660766


一、相关介绍


Clean-robot-turtlebot3项目源码链接如下:

https://github.com/li-haojia/Clean-robot-turtlebot3

Clean-robot-turtlebot3效果演示如下:【图片来源于项目介绍】

Clean-robot-turtlebot3系统结构如下:【图片来源于项目介绍】


二、Clean-robot-turtlebot3原理及实现流程概括总结


总的来说,Clean-robot-turtlebot3实现全覆盖清扫的流程可以分为初始化阶段、全覆盖路径规划阶段、执行覆盖阶段,这三个阶段,各个阶段的主要流程如下所示:

1、初始化阶段

在初始化阶段,通过类的构造函数CleaningPathPlanning(),及其调用或间接调用的initializeMats()、getCellMatAndFreeSpace()、initializeNeuralMat()、initializeCoveredGrid()等函数完成算法各项参数和数据结构的初始化。

在初始化阶段有几个变量需要重点注意一下,首先是使用costmap栅格地图来初始化的新地图变量srcMap_,这里的转换仅仅是进行格式的转换(srcMap_的数据类型是OpenCV常用的Mat类型),其尺寸、分辨率和代价值均与costmap栅格地图相同。

紧接着进一步按照设定的覆盖直径SIZE_OF_CELL,对srcMap_地图变量进行划分成一个个SIZE_OF_CELL x SIZE_OF_CELL个栅格大小的正方形区域。每个正方形区域将变成新地图cellMat_中的一个栅格,且若原地图中这个SIZE_OF_CELL x SIZE_OF_CELL个栅格的正方形区域中每个栅格均不存在障碍物,则认为转换后得到的新地图cellMat_中的这个栅格处没有障碍物,否则认为新地图中的这个栅格处有障碍物。

上述转换将原有地图稀疏化,即认为机器人每走过原地图中一个栅格就完成了对其周围SIZE_OF_CELL个栅格的覆盖,所以按照SIZE_OF_CELL对地图进行稀疏化后得到的新地图,可以更简便的进行后续的全覆盖路径的规划。此外,得到了新地图cellMat_后,进一步标记了出新地图的自由空间(无障碍物)的栅格,并将其坐标存储到freeSpaceVec_中,方便后续覆盖规划时查找是否还存在没有覆盖的无障碍区域。

最后,使用稀疏后的新地图cellMat_来初始化活力值地图neuralizedMat_,如果新地图中某个栅格处有障碍物,则其对应的活力值地图中存储一个较大的负数-100000,如果没有障碍物,则活力值地图中对应的位置存储的活力值为50/j,其中j是其所在的列数,这种活力值设置模式使得同一列无障碍物点的初始活力值相同,而随着所在列编号的增加,活力值依次降低,在后续的步骤中,机器人会倾向于向活力值高的区域移动,这样初始化活力值,将引导机器人按列形成从弓字型的覆盖路径,且避开障碍物。


2、全覆盖路径规划阶段

全覆盖路径规划阶段,核心程序在mainPlanningLoop()函数中,首先将机器人的当前位置作为全覆盖路径规划的起点,然后进行循环迭代,核心流程是,在每次迭代中,先计算机器人在当前点周围八个方向上相邻栅格(新地图中)的活动值,然后选择活动值最大的方向作为下一步的移动方向。然后按照该方向移动一个栅格,得到全覆盖路径中下一个点的位置,将其加入存储全覆盖路径的队列pathVec_中,并将该点坐标更新为新的当前点坐标,方便进行下一轮循环迭代信息。在特定条件下,还要处理距离关系,防止自锁现象,在当前点周围没有合适的点作为下一个路径点时,前往下一个区域继续规划。循环执行以上步骤,直到达到规划循环的最大次数或出现自锁现象(全覆盖路径规划完成)。

上述流程有两个关键地方,即如何计算活力值,以及当前点周围没有合适的点进行移动时,如何前往下一个区域继续规划。

先来看如何计算活力值,基于当前点的位置(这里的当前点是指当前规划中的当前点,不是机器人的当前位置)在姿态角分别为0, 45, 90, 135, 180, 225, 270, 315这八个方向上计算这八个相邻栅格的活动值,具体而言,计算每个方向上活动值时,先计算当前方向角度与上一步的角度lasttheta之间的角度差deltaTheta,如果差值超过180度,进行调整,确保差值在0到180度之间。然后将其转换为当前方向的角度与上一步的角度的偏离程度e。e的值在0到1之间,极端的0表示方向相同,1表示方向相反。若沿当前方向移动一步后,会超出地图边界,则当前方向需要给一个很小的活力值,如程序中的v = -100000,来使机器人不要向该方向移动。若不会超出地图边界则采活力值的计算分为两种情况,对于0,90,180,270这四个横平竖直的移动方向,活力值由两部分构成,第一部分是从活力值地图neuralizedMat_中查询的沿当前方向移动一步后的位置的活力值,第二部分是c_0 * e,其中c_0 是常系数50。附加项 c_0 * e的作用是更倾向于选取与上一次移动方向相同或者相近的方向。对于所有对角方向,即45, 135, 225, 315这四个方向计算活力值时,后面还有一个附加项-200,这个-200的附加项的作用可能是尽量选取上下左右这四个方向,所以对对角的四个方向施加了额外的代价。沿着0度和45度方向的计算表达式如下所示

v = neuralizedMat_.at<float>(currentPoint.row, currentPoint.col + 1) + c_0 * e;
 v = neuralizedMat_.at<float>(currentPoint.row - 1, currentPoint.col + 1) + c_0 * e - 200;

接下来介绍当前点周围没有合适的点进行移动时,如何前往下一个区域继续规划。在计算完当前点周围八个相邻点的活力值后,会进行判断,若他们这的最大活力值依然小于0,说明周围上下左右四个移动方向上的点要么是障碍物,要么已经在覆盖路径里面了,在该区域已经不能继续维持弓字形继续规划覆盖路径了,则考虑跳到另一个区域进行规划。

此时,需要依次遍历存储新地图无障碍点坐标的变量freeSpaceVec_中的点,查询该点的活力值,若活力值大于0,则找到了一个新的活跃的点,则进一步判断该点周围相邻的位置是否存在活力值为-250的点(即已经在覆盖路径中的点),若存在,则计算当前点与找到的这个活跃点之间的距离,如果这个距离小于当前的最小距离(初始化为一个较大值100000000),则更新最小距离及其索引,也就是在freeSpaceVec_中的位置,遍历完freeSpaceVec_中的点后,判断最小距离是否为初始化的100000000,若不是,则找到了距离当前点最近的活跃点,进行跳转,即更新当前点位置为该活跃点位置,并将其添加到路径点队列pathVec_中,继续在新的区域进行全覆盖路径的规划。若没有找到,则说明产生了自锁现象,已经完成对地图可行区域的全覆盖路径的规划,退出循环,结束规划。mainPlanningLoop()函数结束后,就得到了规划的全覆盖路径点存放在pathVec_中,然后赋值给GetPathInROS()中的变量cellvec,转换成合适的格式后以话题/path_planning_node /cleaning_plan_nodehandle/cleaning_path发布出去。

3、执行覆盖阶段

next_goal节点会接收上面发布的规划完成的全覆盖路径,然后依次发布这个全覆盖路径中的点作为目标点发送出去,当机器人当前位置与当前目标点位置小于阈值时,发送下一个。发送出去的目标点通过点对点的全局和局部规划算法进行跟踪来完成对地图的覆盖的,项目里面全局规划算法用的ROS提供的NavfnROS包中的Dijkstra算法。局部算法用的ROS提供的DWA算法。


三、换地图测试效果

我使用自己的地图对该开源程序进行测试,发现算法存在一些缺陷,并不能完成对地图中所以可行区域的探索,有很大的空白区域,如下所示:



这篇关于全覆盖路径规划开源项目Clean-robot-turtlebot3原理及流程概括总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/832358

相关文章

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

怎么用idea创建一个SpringBoot项目

《怎么用idea创建一个SpringBoot项目》本文介绍了在IDEA中创建SpringBoot项目的步骤,包括环境准备(JDK1.8+、Maven3.2.5+)、使用SpringInitializr... 目录如何在idea中创建一个SpringBoot项目环境准备1.1打开IDEA,点击New新建一个项

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建