一起自学SLAM算法:1.6 ROS其他重要概念

 连载文章,长期更新,欢迎关注:


写在前面

第1章-ROS入门必备知识

        1.1 ROS简介

        1.2 ROS开发环境搭建

        1.3 ROS系统架构

        1.4 ROS调试工具

        1.5 ROS节点通信

        1.6 ROS其他重要概念

        1.7 ROS2.0展望

第2章-C++编程范式

第3章-OpenCV图像处理

第4章-机器人传感器

第5章-机器人主机

第6章-机器人底盘

第7章-SLAM中的数学基础

第8章-激光SLAM系统

第9章-视觉SLAM系统

第10章-其他SLAM系统

第11章-自主导航中的数学基础

第12章-典型自主导航系统

第13章-机器人SLAM导航综合实战


除了上面介绍的话题、服务和动作的核心概念,在做实际项目时还有一些重要的概念也会经常用到,这里给大家做一个简短的梳理,帮大家先建立起整体的概念。这样在具体使用过程中需要了解这些概念的细节时,就可以上网快速查找对应概念的知识点了。

1.6.1 parameter

参数可以看做是ROS中的一种全局变量,有静态参数和动态参数两种。静态参数一般在节点启动时用于设置节点工作模式;动态参数可以用在节点运行时动态配置节点或改变节点工作状态,比如电机控制节点里的PID控制参数。

静态参数的使用就比较简单了,在节点程序中使用getParam方法可以获取参数值,用setParam方法设置参数值,如下面的用法。也可以通过在launch文件启动节点时向节点传参的方式来设置参数值。

//获取参数的值
nh.getParam(“com_port”,com_port);
//设置参数的值
nh.setParam(“com_port”,“/dev/ttyUSB0”);

 动态参数的用法相对复杂一点,需要先在功能包中的cfg目录下新建*.cfg文件,在*.cfg文件里面添加需要的动态参数,*.cfg文件采用python脚本进行编写。然后还需要在功能包中的CMakeList.txt里面设置动态参数相关的编译配置,这个与前面讲过的自定义服务消息类型和动作类型有点类似。最后就可以在节点中引用动态参数头文件,然后启动动态参数的服务端,监听客户端发送的参数修改请求,并实时地维护动态参数的值。可以在其他节点中使用动态参数客户端来发起参数修改请求,或者直接使用rqt_reconfigure工具直接修改参数值。其实,动态参数机制与上面讲过的服务通信机制非常相似。具体实现代码就不展开了,有兴趣可以参考官方wiki教程。

1.6.2 tf

一个机器人系统中通常会有多个三维参考坐标系,机器人中的坐标系使用的是右手坐标系,而且这些坐标系之间的相对关系随时间推移会变化。这里举例来说明这种关系和变化,一个实际机器人应用场景的例子。假如该例子中激光slam构建出来的栅格地图的坐标系为map,机器人底盘的坐标系为base_footprint,激光雷达、imu等传感器自己的坐标系分别为base_laser_link、imu_link等,这些坐标系之间的关系有些是静态的、有些是动态的。比如在器人底盘移动的过程中,机器人底盘与世界的相对关系map->base_footprint就会随之变化;而安装在机器人底盘上的激光雷达、imu这些传感器与机器人底盘的相对关系base_footprint->base_laser_link、base_footprint->imu_link就不会随之变化。

由于坐标及坐标转换在机器人系统中非常重要,特别是机器人在环境地图中自主定位和导航、机械手臂对物体进行复杂的抓取任务时,都需要精确地知道机器人各部件之间的相对位置及机器人在工作环境中的相对位置。因此ROS专门提供了tf这个工具用于简化这些工作。tf可以让用户随时跟踪多个坐标系的关系,机器人各个坐标系之间的关系是通过一种树型数据结构来存储和维护的,即tf tree。借助这个tf tree,用户可以在任意时间将点、向量等数据的坐标在两个坐标系中完成坐标值变换。

在节点中使用tf分为两个部分,广播tf变换和监听tf变换。具体编程实例就不展开了,有兴趣可以参考官方wiki教程。

1.6.3 urdf

机器人中的机械模型用urdf来描述,机器人机械模型在导航避障、机械臂抓取、建图等应用中非常重要。一般是专门新建一个功能包,在里面编写urdf文件,并利用模型发布工具将urdf文件描述的内容进行发布。urdf文件中可以描述各种几何物体的形状,还可以描述部件之间的tf关系。因此除了在launch文件中设置静态tf关系外,还可以直接在urdf文件中设置静态tf关系,但是要注意两种设置方法不要重复。关于urdf的使用与编程,可以参考官方wiki教程。

1.6.4 launch

在一个大型的机器人项目中,经常涉及到多个node协同工作,并且每个node都有很多可设置的parameter。比如本书综合实战部分讨论的xiihoo机器人导航项目,涉及到地图服务节点、定位算法节点、运动控制节点、底盘控制节点、激光雷达数据获取节点等众多节点,和几百个影响着这些node行为模式的parameter。如果全部手动rosrun逐个启动node并传入parameter,工程的复杂程度将难以想象。所以这个时候就需要用roslaunch来解决问题,将需要启动的节点和需要设置的parameter全部写入一个*.launch文件,然后用roslaunch一次性地启动*.launch文件,这样所有的节点就轻而易举地启动了。launch文件采用xml文本标记语言进行编写,本书综合实战部分讨论的xiihoo机器人导航项目的launch文件如代码清单1-26所示。

代码清单1-26  xiihoo机器人导航项目的launch文件xiihoo_nav.launch


  
  
  

  
  
  
  
  
    
    
    
  

  
  
    

    
    
    
    
    
    
  

可以发现launch能够嵌套使用,也就是在一个luanch中嵌套调用另一个launch。另外launch文件中设置参数的形式也有很种,比如通过param 标签为某个参数指定固定值,也可以通过arg标签从外部载入参数的设置值,还可以通过rosparam标签从外部文件批量载入参数的设置值。

关于launch文件的使用很简单,首先在相应功能包目录下新建一个launch文件夹。然后在launch文件夹中新建*.launch文件,并按照launch标签规则编写好launch文件的内容,关于launch标签规则,有兴趣可以参考官方wiki教程。最后在终端中用roslaunch命令启动launch文件,启动xiihoo_nav.launch的命令如下。

roslaunch  xiihoo_nav  xiihoo_nav.launch

1.6.5 plugin

ROS支持功能包的动态加载和卸载,这个功能由一个C++的pluginlib库来实现。比如导航功能包move_base来说,我们可以在move_base运行的过程中,动态加载Class类对象、动态函数库等,像代价地图、路径规划这些功能包都是通过plugin机制动态加载到move_base中的。使用plugin来扩展和升级程序的功能很方便,不用改动原有程序的源码也不用重编译,就能动态加载和卸载功能。关于plugin的用法,有兴趣可以参考官方wiki教程。

1.6.6 nodelet

通常情况下我们使用的ROS节点都是独立的可执行文件,每个节点启动后在系统里都是以一个独立的进程存在的,也就是说节点之间的通信就是进程间的通信,并且通信过程需要消耗网络的带宽。为了提高通信的效率和减少网络带宽的占用,ROS中有一类特殊的节点nodelet,这类节点可以在单个进程下以多个线程的形式运行,这样节点间的通信就是线程间的通信了。比如摄像头这类数据量大的传感器,可以使用nodelet方式与其他节点通信,能大大提高传输效率。关于nodelet的用法,有兴趣可以参考官方wiki教程。

源码仓库

  • Github下载:github.com/xiihoo/Books_Robot_SLAM_Navigation

  • Gitee下载(国内访问速度快):gitee.com/xiihoo-robot/Books_Robot_SLAM_Navigation

参考文献

【1】 张虎,机器人SLAM导航核心技术与实战[M]. 机械工业出版社,2022.

你可能感兴趣的:(一起自学SLAM算法,算法,人工智能,c++,自动驾驶,计算机视觉)