(一) 路径规划算法---Astar与C++可视化在RVIZ的三维点云地图

2023-05-16

Astar与C++可视化在RVIZ的三维点云地图

文章目录

  • Astar与C++可视化在RVIZ的三维点云地图
    • 1.功能包介绍
    • 2.算法功能包的组成与介绍
      • 2.1文件系统组成
      • 2.2 头文件说明
      • 2.3 源文件说明
    • 3.相关坐标系说明
      • 3.1 坐标系
      • 3.2 点云数据存储
    • 4.重要代码说明
    • 5.代码运行情况

源代码下载链接: https://github.com/KailinTong/Motion-Planning-for-Mobile-Robots
本文代码下载链接: https://gitee.com/tanggujie/astar

1.功能包介绍

在这里插入图片描述

本文主要对上述工作空间中的grid_path_search、rviz_plugins、waypoint_generator进行介绍,其中rviz_pluginswaypoint_generator为RVIZ插件,为了更加方便的在rviz中提供指定的三维坐标点,并不是本文的研究重点。下面对三维点云地图中Astar算法的实现的功能包grid_path_search进行介绍。


2.算法功能包的组成与介绍

2.1文件系统组成

在这里插入图片描述
其中文件说明如下

include:存放Astar算法的头文件

launch:Astar算法的启动文件

pcd:存放点云地图的文件夹

rviz:RVIZ中的配置文件

src:Astar算法的头文件以及Astar对外的ros接口文件

2.2 头文件说明

在这里插入图片描述
其中红色框为本文基于原作者自己修改的头文件代码,包含自己所理解的中文注释。绿色框为源代码所拥有的头文件(源代码还提供了JPS算法,大家有兴趣可以将它和Astar进行比较。)

2.3 源文件说明

在这里插入图片描述
其中红色框为本文基于原作者自己修改的源文件代码,包含中文注释。绿色框为源代码所拥有的源文件

Astar.cpp:Astar算法的本体函数

astar_demo.cppAstar算法对外的ros接口函数

complex_map.cpp:提供的固定点云地图文件,点云地图以pcd的方式进行存储。其中pcd文件是通过源代码中的random_complex_generator.cpp进行产生(注意:该random_complex_generator.cpp并不会自己产生点云文件,需要自己添加保存点云的代码,并且random_complex_generator.cpp每次会随机产生点云地图,调试代码并不方便)

查看保存好的点云,指令如下,其中fc为背景颜色,ax为坐标轴的大小

pcl_viewer map.pcd -fc 255,255,255 -ax 1

在这里插入图片描述


3.相关坐标系说明

3.1 坐标系

世界坐标系:明确一点世界坐标系的原点就是点云地图的原点,且点云地图是反应真实世界的,默认单位为m。

栅格坐标系:名称自定义的,嘻嘻。目的是为了方便Astar算法搜索周围邻居,而在三维点云中,各个点之间并不会像图片那样可以方便的查找自己周围的邻居,它们是无序排列的。因此采用将点云空间进行栅格化,如果其中一个栅格有三维点,则在该栅格中置1,否则置0。

两大坐标系如下图所示,其中 O 1 X 1 Y 1 O_1X_1Y_1 O1X1Y1为世界坐标系, O 2 X 2 Y 2 O_2X_2Y_2 O2X2Y2为栅格坐标系,其中在程序代码中, O 1 O_1 O1处在整个栅格的中心位置, O 2 O_2 O2处在 O 1 O_1 O1的左上角位置。 O 2 A O_2A O2A为整个点云栅格的宽, O 2 B O_2B O2B为整个点云栅格的长, O 2 C O_2C O2C为整个点云栅格的高。
在这里插入图片描述

3.2 点云数据存储

该程序代码中,点云栅格地图数据的存储也是一维数据,按照先Z后Y再X的方向进行存储。例如栅格地图中某点坐标为 ( x , y , z ) (x,y,z) (x,y,z)(其中x,y,z均为整数),对应于一维点云数据为 d a t a [ x × L e n g t h × H i g h t + y × H i g h t + x ] data[x\times Length\times Hight+y\times Hight+x] data[x×Length×Hight+y×Hight+x]
在这里插入图片描述


4.重要代码说明

1.程序通过先读取点云地图进行Astar地图初始化,在程序设计中将该点的世界坐标系与栅格坐标系绑定起来,方便后续路径查找。

for (int i=0;i<GLX_SIZE;i++)
    {
        GridNodeMap[i].resize(GLY_SIZE);
        for (int j=0;j<GLY_SIZE;j++)
        {
            GridNodeMap[i][j].resize(GLZ_SIZE);
            for (int k=0;k<GLZ_SIZE;k++)
            {
                Vector3i tmpIdx(i,j,k);     //栅格索引 
                Vector3d pos = gridIndex2coord(tmpIdx);  //该栅格对应的世界坐标系下的点云位置坐标
                GridNodeMap[i][j][k] = new GridNode(tmpIdx, pos);
            }
        }
    }

栅格转世界坐标系函数gridIndex2coord()
W x = M x × r e s o l u t i o n + o r i g i n _ x W y = M y × r e s o l u t i o n + o r i g i n _ y W z = M z × r e s o l u t i o n + o r i g i n _ z W_x=M_x\times resolution+origin\_x \\ W_y=M_y\times resolution+origin\_y \\ W_z=M_z\times resolution+origin\_z Wx=Mx×resolution+origin_xWy=My×resolution+origin_yWz=Mz×resolution+origin_z

Vector3d AstarPathFinder::gridIndex2coord(const Vector3i & index) 
{
    Vector3d pt;

    pt(0) = ((double)index(0) + 0.5) * resolution + gl_xl;
    pt(1) = ((double)index(1) + 0.5) * resolution + gl_yl;
    pt(2) = ((double)index(2) + 0.5) * resolution + gl_zl;

    return pt;
}

世界转栅格坐标系函数coord2gridIndex()

其中 m i n ( m a x ( X , a ) , b ) min(max(X,a),b) min(max(X,a),b)表示
f ( X ) = { X X ∈ [ a , b ] a X < a b X > b f(X) = \left\{ \begin{array}{l} X &\text X \in [a,b]\\ a &\text X < a\\ b &\text X > b \end{array} \right. f(X)=XabX[a,b]X<aX>b

Vector3i AstarPathFinder::coord2gridIndex(const Vector3d & pt) 
{
    Vector3i idx;
    /*
        0<=(pt(0) - gl_xl) * inv_resolution)<=GLX_SIZE - 1
        0<=(pt(1) - gl_yl) * inv_resolution)<=GLY_SIZE - 1
        0<=(pt(2) - gl_zl) * inv_resolution)<=GLZ_SIZE - 1
    */
    idx <<  min( max( int( (pt(0) - gl_xl) * inv_resolution), 0), GLX_SIZE - 1),
            min( max( int( (pt(1) - gl_yl) * inv_resolution), 0), GLY_SIZE - 1),
            min( max( int( (pt(2) - gl_zl) * inv_resolution), 0), GLZ_SIZE - 1);                  
  
    return idx;
}

2.Astar算法的障碍物判断为isOccupied()函数,三维栅格点云数据以一维数组data进行存储,数组大小为 W i d t h × L e n g t h × H i g h t Width \times Length \times Hight Width×Length×Hight具体栅格坐标系下某点坐标转化到一维数组中的位置,见3.2节点云数据的存储。

inline bool AstarPathFinder::isOccupied(const int & idx_x, const int & idx_y, const int & idx_z) const 
{
    return  (idx_x >= 0 && idx_x < GLX_SIZE && idx_y >= 0 && idx_y < GLY_SIZE && idx_z >= 0 && idx_z < GLZ_SIZE && 
            (data[idx_x * GLYZ_SIZE + idx_y * GLZ_SIZE + idx_z] == 1));
}

3.其他均是一些Astar算法的本体函数,与一些接口函数的调用,本文就不赘述了。具体可参考代码中的注释。

3.1 Astar算法中的启发式函数 h h h的计算是对真实距离的估计,因此 h h h的计算基于世界坐标系。

3.2 Astar邻居的索引是在栅格坐标系中的,因为三维点云数据无序,需要进行栅格化。

3.3 Astar路径的生成是通过rviz中的Marker功能实现的,而Marker所需的坐标点是基于世界坐标系的,因此,Astar路径的生成也是基于世界坐标系的。


5.代码运行情况

启动

roslaunch grid_path_search my_demo.launch 

稍等片刻,就会显示rviz信息,如下图所示。可以改变AllMap下的Spheres进行点云数据不同风格的显示。点击3D Nav Goal(或者点击键盘中的"g"键) 进行目标点的设置,首先通过鼠标左键进行XY平面位置的确定,此时按住鼠标左键不要松,在点击鼠标右键进行上下拖动,进行Z位置的确定,同时松开鼠标左键和鼠标右键,即可显示Astar的三维路径。
在这里插入图片描述
注意:

  1. 在该算法演示中,并没有设置Astar的起点,若想改变Astar的起点位置,需要在my_demo.launch中
<arg name="start_x" default=" 0.0"/>
<arg name="start_y" default=" 0.0"/>
<arg name="start_z" default=" 1.0"/>

进行起始点 X 、 Y 、 Z X、Y、Z XYZ的设置。其实也可以利用3D Nav Goal进行起始点的设置,不过为了偷懒,并没有写,感兴趣的可以尝试一下。

  1. 该显示函数提供了更新功能,即不需要关闭程序,在此指定一个新的坐标点,算法会重新生成一条新的Astar路径点。

此外,非常感谢源代码对我的帮助,从中学到了很多有用的知识。

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

(一) 路径规划算法---Astar与C++可视化在RVIZ的三维点云地图 的相关文章

  • c++ vscode 环境一键配置

    致谢 首先感谢原作者为我等初学者所做的软件 xff0c 其他文章讲了一堆的东西都没解决 xff0c 作者一个软件一步到位 xff0c 如果觉得不错的话可以star一下 xff0c 原作者视频地址 xff1a https www bilibi
  • 使用ESP8266实现单片机与上位机之间的wifi通信。

    使用ESP8266实现单片机与上位机之间的wifi通信 首先弄清楚8266的工作模式 xff0c 分别是 模式1 xff1a station xff0c 模式2 xff1a ap xff0c 模式3 xff1a station 43 ap
  • 【C 陷阱与缺陷】(四)连接

    码字不易 xff0c 对你有帮助 点赞 转发 关注 支持一下作者 微信搜公众号 xff1a 不会编程的程序圆 看更多干货 xff0c 获取第一时间更新 代码 xff0c 练习上传至 xff1a https github com hairrr
  • DIY无人机(匿名拓控者P2+F330机架)

    今年三月份的时候DIY过一个大疆NAZA 43 F450机架的无人机 xff0c 第一次体验DIY多旋翼无人机的全流程 xff0c 目的其实是为了后面更深入了解做准备 不然的话 xff0c 这钱买个大疆MINI3不香吗 xff1f DIY无
  • 在lammps模拟过程中的常用势函数设置

    文章目录 1 lj cut1 1 lj cut在in文件中使用方法1 2 lj cut在data文件中使用方法1 3 lj cut参数查询方法1 4 lj cut参数单位转换方法1 5 lj cut不同原子之间的参数1 6 lj cut参数
  • C语言十进制转16进制

    int DEC HEX uint32 t Dec int ram 61 0 整 int ray 61 0 余 uint32 t Hex 61 0x0 int i 61 0 do ram 61 Dec 16 ray 61 Dec 16 Dec
  • Windows系统下的Visual studio2019 安装 opencv4.5.1的安装

    OpenCV文档 xff1a https docs opencv org 4 5 1 examples html 安装OpenCV 4 5 1 xff0c 下载地址 https opencv org releases 下载完成后得到open
  • STM32串口初始化与使用详解(基于HAL库编程)

    STM32串口初始化与使用详解 串口简介串口初始化具体步骤串口收发理论代码执行 串口简介 USART Universal Synchronous Asynchronous Receiver Transmitter 通用同步 异步串行接收发送
  • STM32F103C8T6+OV7670(有FIFO和无FIFO版本)入门教程/使用总结(待续写,有问题可发在评论区中)

    前言 xff1a 本文为第一遍草稿 xff0c 错误会有点多 xff08 指技术性的东西会叫错等等 xff0c 欢迎纠正 xff09 xff0c 有需要可以先看看 OV7670还没有完全弄清楚 xff0c 目前已成功出图 xff08 指测试
  • 串口DMA实现接收--不定长度接收

    1 DMA接收配置 1 direction xff1a 数据传输的方向是外设 xff08 串口 xff09 gt 内存 xff08 DMA Buff xff09 xff1b 2 memory inc xff1a 内存自增 xff0c 内存指
  • ROS信息的收发

    图像信息的收发 图像信息发送 include lt ros ros h gt include lt image transport image transport h gt 用于image的订阅和发布 xff0c 并为压缩模式compres
  • 标定工具Kalibr安装、使用及标定结果评估方法

    单目相机标定 安装和配置 cd kalibr workspace source devel setup bash 如果使用april tag标定板 xff0c 设置aprilgrid yaml配置文件 标定数据bag采集 采集单目标定数据时
  • 2.什么是机械设计?

    机械设计是研究如何创造机械 以使其安全 可靠地工作等的内容 机械的定义是 一个组装的零件系统 可以以预定和受控的方式传递运动和能量 或更简单地说 一个控制力和运动的系统 那么 设计是又是什么呢 设计 设 计 设就是设想 从无到有的想象 想象
  • 手把手教你实现一个单链表

    目录 一 节点声明二 尾插三 链表打印四 头插五 尾删六 头删七 查找值八 指定插入九 指定删除十 销毁链表 一 节点声明 链表是一种数据结构 xff0c 用于数据的存储 如图 xff0c 每一个链表节点所在的内存空间是不延续的 xff0c
  • 使用多线程以及RandomAccessfile来实现多线程复制文件

    Class RandomAccessFile 介绍 该类的实例支持读取和写入随机访问文件 随机访问文件的行为类似于存储在文件系统中的大量字节 有一种游标 xff0c 或索引到隐含的数组 xff0c 称为文件指针 输入操作读取从文件指针开始的
  • 线程池中线程抛了异常如何处理?

    文章目录 1 模拟线程池抛异常2 如何获取和处理异常方案一 xff1a 使用 try catch方案二 xff1a 使用Thread setDefaultUncaughtExceptionHandler方法捕获异常方案三 xff1a 重写a
  • ROS放弃指南2:ROS创建工作空间及五种设置环境变量的方法

    参考链接 xff1a 中国大学MOOC中的机器人操作系统入门 https www icourse163 org course ISCAS 1002580008 古月居博客 www guyuehome com 运行环境 xff1a Ubunt
  • 百科不全书之ROS函数解析

    1 ROS的回调函数 span class token comment 单线程 span ros span class token operator span span class token operator span span clas
  • VsCode 运行后终端没有结果

    最近入手了VsCode很多都还不太清楚 xff0c 稍微记录一下碰到的一点问题 也是第一次写博客 VsCode 运行后终端没有结果 一 运行后终端没有结果二 终端中文乱码问题 一 运行后终端没有结果 在网上试了好多好多解决方法都没有用 xf
  • STM32CubeMX(05) 移植陀螺仪MPU6050的DMP库读取三轴角度,加速度

    文章目录 前言一 MPU6050是什么 xff1f 二 STM32CubeMX配置2 1 IIC配置2 2 开启中断2 3 硬件连接2 4 软件编写 三 导入DMP库3 1 keil配置3 2 添加头文件路径3 3 添加头文件3 4 添加初

随机推荐

  • 基于STM32的智能GPS定位系统(云平台、小程序)

    如需源码或成品可以私我 背景及目标 前阵子 xff0c 准确的说是好几个月前买了一辆电瓶车 xff0c 当时呢因为车停得很随意 xff0c 所以想给小电驴装一个GPS xff0c 一方面是防盗 xff0c 另一方面是为了测速和绘制骑行轨迹
  • 蓝桥杯大赛

    第十一届蓝桥杯单片机比赛心得 前期的准备十月份省赛十一月份国赛错过结果发布 想要做一点事情 xff0c 传承 前期的准备 本次蓝桥杯大赛由于疫情原因延迟了将近7个月举行 xff0c 原先是3月份举行 xff0c 拖到了10月份 xff0c
  • 蓝桥杯模块练习之关闭外设

    蓝桥杯单片机比赛系列1初探关闭外设 关闭LED关闭继电器和蜂鸣器 关闭LED 本节将会介绍板子上的最简单最基础的部分 比赛一般上来需要关闭无关外设 xff0c 蓝桥杯的板子比较特殊 xff0c 51上电默认P0 O1 P2 P3都是高电平
  • 蓝桥杯模块练习之温度传感器DS18B20

    蓝桥杯单片机比赛系列4温度传感器DS18B20 温度传感器DS18B20原理相关电路onewire总线几个需要知道的暂存器和命令 代码解释修改代码自写代码 实现代码 温度传感器DS18B20原理 相关电路 DS18B20遵循onewire总
  • 被锡膏坑了一把

    锡膏 61 锡珠 43 助焊剂 把锡膏放大来看如下图 我是去年买的一罐锡膏 xff0c 138度的 xff0c 用了一两次 xff0c 然后就放在哪里没动它 xff0c 盖子也盖好了 xff0c 没有放冰箱 今年又拿出来用 xff0c 用钢
  • 蓝桥杯模块练习之AD/DA

    蓝桥杯单片机比赛系列6AD DA转换 AD DA原理相关电路pcf8591器件地址 代码解释修改代码AD自写代码ADDA AD DA原理 相关电路 通过pcf8591芯片实现ad转换 板子上ad采集主要采集滑动变阻器的电压值和与光敏电阻串联
  • 蓝桥杯模块练习之EEPROM

    蓝桥杯单片机比赛系列7EEPROM EEPROM原理相关电路AT24C02器件地址 EEPROM自写代码 EEPROM原理 相关电路 有了系列6的基础 xff0c 上手eeprom就简单多了 xff0c 板子上对应的器件是AT24C02 A
  • Openmv学习day1——色块识别

    find blobs函数 image find blobs thresholds roi 61 Auto x stride 61 2 y stride 61 1 invert 61 False area threshold 61 10 pi
  • 蓝桥杯嵌入式模块练习之扩展版MEME

    三轴传感器 PA4 7都不能作为其他用处 xff0c 三周传感器需要使用到这四个引脚资源 当然 xff0c 如果不用中断 xff0c 也可以只结PA4 5 xff0c PA6 7可接到温度传感器和温湿度传感器 这个外设的通信协议也是I2C跟
  • Github Pages 搭建网站

    个人站点 访问 https 用户名 gitub io 搭建步骤 1 创建个人站点 gt 新建仓库 xff08 仓库名必须是 用户名 github io xff09 2 在仓库下新建index heml文件即可 3 Github pages仅
  • 普通io口模拟串口通信

    之前公司在做项目的时候需要用到多串口 xff0c 板载串口资源不足 xff0c 就在网上找相关内容 xff0c 结合自己的理解做出虚拟串口 模拟串口需要用到两个普通io引脚 xff0c 一个定时器 软件串口的实现 IO模拟串口 波特率 xf
  • UART,SPI,IIC,RS232通信时序和规则

    一 UART 1 串口通信方式 2 串口通信步骤 注意 xff1a 串口协议规定 xff0c 闲置时必须是高电平 校验位 xff1a 是使用奇偶校验 停止位必须高电平 一个0和多个0区分是靠掐时间 异步通信 xff1a 时钟各不一样 二 I
  • kvaser pcie can 在ros中使用socketcan开发

    kvaser pcie can 在ros中使用socketcan开发 0 系统配置 Ubuntu 16 04 6 LTS Linux version 4 15 0 45 generic 1 官网下载地址 https www kvaser c
  • 算法训练 - 连接字符串 编程将两个字符串连接起来。例如country与side相连接成为countryside。   输入两行,每行一个字符串(只包含小写字母,长度不超过100);输出一行一个字符

    问题描述 编程将两个字符串连接起来 例如country与side相连接成为countryside 输入两行 xff0c 每行一个字符串 xff08 只包含小写字母 xff0c 长度不超过100 xff09 xff1b 输出一行一个字符串 例
  • 笔记 FreeRtos任务创建失败原因

    问题 使用NXP的S32芯片开发 xff0c 环境是S32DS 2018 xff0c 创建了三个任务 xff0c 最后发现只有一个任务在运行 找问题 S32DS自带了Freertos的分析调试工具 xff0c 打开后可以显示任务的状态 xf
  • 3.提升不同专业能力的差别?

    有段时间没写博客了 今天来谈谈最近工作的一些感悟 首先 我觉得工资和个人能力是成正相关的 这应该是是所有人都认同的吧 如果工资是一个函数的话 也可以说 工资 Y 是一个与个人能力 X 有关的一次函数Y aX b 方然我们不能忽略行业之间的差
  • 网络通讯学习(1)---TCP通讯

    TCP IP四层模型 UDP TCP协议 TCP xff08 The Transmission Control Protocol xff09 xff1a 传输控制协议 UDP TCP协议都属于传输层协议 xff0c 都位于IP协议以上 xf
  • 网络通讯学习(3)-----UDP通讯(仅了解)

    理论 UDP xff08 用户数据报协议 xff09 是一个无连接 xff0c 不可靠的数据传输 xff0c 其特点是简单 xff0c 快捷 相比与TCP xff0c UDP不需要建立连接 xff08 不需connect accept函数
  • WIFI模块不支持MQTT协议,可通过MCU实现

    1 话题原因 我们使用某款WIFI模块 xff0c 在物联网开发时 xff0c 平台端的开发者想要使用MQTT协议 xff0c 但是我们当前使用的模块不支持MQTT协议 xff08 好像ESP8266可以通过重新烧录固件的方式支持 xff0
  • (一) 路径规划算法---Astar与C++可视化在RVIZ的三维点云地图

    Astar与C 43 43 可视化在RVIZ的三维点云地图 文章目录 Astar与C 43 43 可视化在RVIZ的三维点云地图1 功能包介绍2 算法功能包的组成与介绍2 1文件系统组成2 2 头文件说明2 3 源文件说明 3 相关坐标系说