一、场景
完成ROS中一个系统性的功能,可能涉及到多个功能包,比如实现了机器人导航模块,该模块下有地图、定位、路径规划...等不同的子级功能包。那么调用者安装该模块时,需要逐一的安装每一个功能包吗?
显而易见的,逐一安装功能包的效率低下,在ROS中,提供了一种方式可以将不同的功能包打包成一个功能包,当安装某个功能模块时,直接调用打包后的功能包即可,该包又称之为元功能包(metapackage)。
在一些ROS的教学资料和博客里,你可能还会看到一个Stack(功能包集)的概念,它指的是将多个功能接近、甚至相互依赖的软件包的放到一个集合中去。但Stack这个概念在Hydro之后就取消了,取而代之的就是Metapackage。尽管换了个马甲,但它的作用没变,都是把一些相近的功能模块、软件包放到一起。
二、概念
MetaPackage是Linux的一个文件管理系统的概念。是ROS中的一个虚包,里面没有实质性的内容,但是它依赖了其他的软件包,通过这种方法可以把其他包组合起来,我们可以认为它是一本书的目录索引,告诉我们这个包集合中有哪些子包,并且该去哪里下载。
例如:
sudo apt install ros-melodic-desktop-full
命令安装ros时就使用了元功能包,该元功能包依赖于ROS中的其他一些功能包,安装该包时会一并安装依赖。
还有一些常见的MetaPackage
:navigation
moveit!
turtlebot3
Metapacakge | 描述 | 链接 |
---|---|---|
navigation | 导航相关的功能包集 | https://github.com/ros-planning/navigation |
moveit | 运动规划相关的(主要是机械臂)功能包集 | https://github.com/ros-planning/moveit |
image_pipeline | 图像获取、处理相关的功能包集 | https://github.com/ros-perception/image_common |
vision_opencv | ROS与OpenCV交互的功能包集 | https://github.com/ros-perception/vision_opencv |
turtlebot | Turtlebot机器人相关的功能包集 | https://github.com/turtlebot/turtlebot |
pr2_robot | pr2机器人驱动功能包集 | https://github.com/PR2/pr2_robot |
三、作用:安装与编译
- 安装
方便用户的安装,我们只需要这一个包就可以把其他相关的软件包组织到一起安装了,比如sudo apt install ros-melodic-desktop-full
。
-
catkin_make
编译
catkin_make -DCATKIN_WHITELIST_PACKAGES="navigation"
catkin_make
无法根据metapackage编译其依赖的相应包,只会编译metapackage
-
catkin build
编译
catkin build navigation
catkin build
可以根据metapackage
编译其依赖的相应包
四、实现
首先:新建一个功能包
- 修改
package.xml
,内容如下:
<exec_depend>被集成的功能包</exec_depend>
.....
<export>
<metapackage />
</export>
这里需要有export
和metapacakge
标签,注意这种固定写法
- 修改
CMakeLists.txt
,内容如下:
cmake_minimum_required(VERSION 3.0.2)
project(demo)
find_package(catkin REQUIRED)
catkin_metapackage()
PS:CMakeLists.txt
中不可以有换行。
五、例子:navigation的metapackage写法
- 1 文件组织形式
navigation
├── CHANGELOG.rst
├── CMakeLists.txt
├── package.xml
└── README.rst
其中CHANGELOG.rst
和README.rst
不是必须的
- 2
CMakeLists.txt
-
3
package.xml
4 分析
可以看到package.xml中包含build tools,和构建和依赖的包。
Format1中的构建依赖项 <build_depend>运行依赖项 <run_depend>:等价于 Format 2 中的 <exec_depend>
<buildtool_depend>catkin</buildtool_depend>
<exec_depend>amcl</exec_depend>
<exec_depend>base_local_planner</exec_depend>
<exec_depend>carrot_planner</exec_depend>
<exec_depend>clear_costmap_recovery</exec_depend>
<exec_depend>costmap_2d</exec_depend>
<exec_depend>dwa_local_planner</exec_depend>
<exec_depend>fake_localization</exec_depend>
<exec_depend>global_planner</exec_depend>
<exec_depend>map_server</exec_depend>
<exec_depend>move_base</exec_depend>
<exec_depend>move_base_msgs</exec_depend>
<exec_depend>move_slow_and_clear</exec_depend>
<exec_depend>navfn</exec_depend>
<exec_depend>nav_core</exec_depend>
<exec_depend>rotate_recovery</exec_depend>
<exec_depend>voxel_grid</exec_depend>
最后设置该包为metapackage
<export>
<metapackage/>
</export>
总结
metapacakge
中的以上两个文件和普通pacakge不同点是:
CMakeLists.txt
:加入了catkin_metapackage()
宏,指定本软件包为一个metapacakge
。package.xml
:标签将所有软件包列为依赖项,标签中添加metapackage
标签声明。