目录
ROS 元功能包
1、新建launch文件
launch文件标签之node
launch文件标签之include
launch文件标签之param
launch文件标签之rosparam
launch文件标签之group
launch文件标签之arg
ROS工作空间覆盖
ROS是多进程(节点)的分布式框架,一个完整的ROS系统实现:
可能包含多台主机
每台主机又有多个工作空间(workspace)
每个的工作空间又包含多个功能包(package)
每个功能包又包含多个节点(Node),不同节点都有自己的节点名称
每个节点可能还会设置一个或者多个话题(topic)
场景:完成ROS中的一个系统性功能、可能涉及到多个功能包,比如实现了机器人导航模块,该模块下有地图、定位、路径规划...等不同的子集功能包。那么调用者安装该模块时,需要逐一的安装每一个功能包吗?
显而易见,逐一安装功能包的效率低下,在ROS中,提供了一种方式可以将不同的功能包打包成一个功能包,当安装某个功能模块时,直接调用了打包后的功能包即可,该包又称之为元功能包。
概念
MetaPackage是Linux的一个文件管理系统的概念。是ROS中的一个虚包,里面没有实质性的内容,但是它依赖了其他的软件包,通过这种方法可以把其他包组合起来,我们可以认为它是一本书的目录索引,告诉我们这个包集合中有哪些子包,并且该去哪里下载,
例如
还有一些常见的MetaPackage:navigation moveit!turtlebot3
作用:方便用户的安装,我们只需要这一个包就可以把其他相关的软件包组织到一起安装了
实现
首先:新建一个安装包
然后,修改package.xml,内容如下:
被集成的功能包 .....
最后修改:CMakeLists.txt,内容如下;
cmake_minimum_required(VERISON 3.0.2)
project(demo)
find_package(catkin REQUIRED)
catkin_metapackage()
PS:CMakeLists.txt中部可以有换行
另请参考官网的ROS WIKI:http://wiki.ros.org/catkin/package.xml#Metapackages
ROS节点运行管理launch文件
关于launch文件之前已经提过了,一个程序中可能需要启动多个节点,比如:ROS内置的小乌龟案例,如果要控制乌龟运动,要启动多个窗口,分别启动roscore、乌龟节点、键盘控制节点。如果每次都调用rosrun逐一启动,显然效率低下,如何优化?
采用的优化策略就是使用launch命令集合launch文件启动管理节点,并且在后续教程中,也使用到了launch文件
概念
launch文件是一个xml格式的文件,可以启动本地和远程的多个节点,还可以在参数服务器中设置参数
作用
简化节点的配置与启动,提高ROS程序的启动效率。
使用
以turtlesim为例演示
在功能包下添加launch目录,目录下新建launch文件,编辑launch文件
调用launch文件
roslaunch 包名 xxx.launch
注意:roslaunch命令执行launch文件时,首先会判断是否启动了roscore,如果启动了,则不在启动,否则,会自动调用roscore
launch文件标签之launch
属性
告知当前用户当前的launch文件已经启用, 不建议使用
子集标签
所有其他标签都是launch的子级
属性
子级标签
include标签用于将另一个xml格式的launch文件导入到当前文件
属性
子级标签
launch文件标签之remap
用于话题重命名
属性
子级标签
无
标签主要用于在参数服务器上设置参数,参数源可以在标签中通过value指定,特可以通过外部文件加载,在
属性
参数名称,可以包含命名空间
value="xxx"(可选)
定义参数值,如果此处省略,必须指定外部文件作为参数源
type=“str|int|double|bool|yaml”(可选)
指定参数类型,如果未指定,roslaunch会尝试确定参数类型,规则如下:
如果包含‘.’的数字解析为浮点型,否则为整型
”true“和”false”是bool值(不区分大小写)
其他是字符串
子级标签
无
属性
command=“load | dump | delete”(可选,默认为load)
加载、导出或删除参数
file="$(find xxxxx)/xxx/yyy..."
加载或导出到yaml文件
param=“参数名称”
ns=“命名空间(可选)”
子级标签
无
属性
ns=“名称空间”(可选)
clear_params="true | false"(可选)
启动前,是否删除组名称空间的所有参数(慎用,此功能危险)
子级标签
除了launch标签外的其他标签
属性
name=“参数名称”
default=“默认值”(可选)
value=“数值”(可选)
不可以与default并存
doc=“描述”
参数说明
子级标签
无
示例
launch文件传参语法实现
命令行调用launch传参
roslaunch hello.launch xxx:=值
所谓工作空间覆盖,是指不同工作空间中,存在同名的功能包的情形
ROS 开发中,会自定义工作空间且自定义工作空间可以同时存在多个,可能会出现一种情况: 虽然特定工作空间内的功能包不能重名,但是自定义工作空间的功能包与内置的功能包可以重名或者不同的自定义的工作空间中也可以出现重名的功能包,那么调用该名称功能包时,会调用哪一个呢?比如:自定义工作空间A存在功能包 turtlesim,自定义工作空间B也存在功能包 turtlesim,当然系统内置空间也存在turtlesim,如果调用turtlesim包,会调用哪个工作空间中的呢?
实现
0.新建工作空间A与工作空间B,两个工作空间都创建功能包:turtlesim
1.在~/.bashrc文件下追加当前工作空间的bash格式如下:
source /home/用户/路径/工作空间A/devel/setup.bash
source /home/用户/路径/工作空间B/devel/setup.bash
2.新开命令行source.bashrc加载环境变量
3.查看ROS环境变量echo $ROS_PACKAGE_PATH
结果:自定义工作空间B:自定义工作空间A:系统内置空间
4.调用命令:roscd turtlesim会进入自定义工作空间B
原因
ROS 会解析 .bashrc 文件,并生成 ROS_PACKAGE_PATH ROS包路径,该变量中按照 .bashrc 中配置设置工作空间优先级,在设置时需要遵循一定的原则:ROS_PACKAGE_PATH 中的值,和 .bashrc 的配置顺序相反--->后配置的优先级更高,如果更改自定义空间A与自定义空间B的source顺序,那么调用时,将进入工作空间A。
结论
功能包重名时,会按照 ROS_PACKAGE_PATH 查找,配置在前的会优先执行。
隐患
存在安全隐患,比如当前工作空间B优先级更高,意味着当程序调用 turtlesim 时,不会调用工作空间A也不会调用系统内置的 turtlesim,如果工作空间A在实现时有其他功能包依赖于自身的 turtlesim,而按照ROS工作空间覆盖的涉及原则,那么实际执行时将会调用工作空间B的turtlesim,从而导致执行异常,出现安全隐患。
BUG 说明:
当在 .bashrc 文件中 source 多个工作空间后,可能出现的情况,在 ROS PACKAGE PATH 中只包含两个工作空间,可以删除自定义工作空间的 build 与 devel 目录,重新 catkin_make,然后重新载入 .bashrc 文件,问题解决。