功能包:开发过程的大本营

在下载的教程代码中,大家可以看到有很多不同名称的文件夹,这些在ROS2并不是普通的文件夹,而是叫做功能包

每个机器人可能有很多功能,比如移动控制、视觉感知、自主导航等,如果我们把这些功能的源码都放到一起当然也是可以的,但是当我们想把其中某些功能分享给别人时,就会发现代码都混合到了一起,很难拆分出来。

image-20220606103223675

举个例子,我们手上有很多红豆、绿豆、黄豆,假设都放在一个袋子里,如果只想把黄豆都拿出来,是不是得在五颜六色的豆子里一颗一颗都找出来,数量越多,你就越头疼;如果我们把不同颜色的豆子放在不同的三个袋子里,需要拿出某种豆子的时候,不就立刻可以找出来了么。

功能包就是这个原理,我们把不同功能的代码划分到不同的功能包中,尽量降低他们之间的耦合关系,当需要在ROS社区中分享给别人的时候,只需要说明这个功能包该如何使用,别人很快就可以用起来了。

所以功能包的机制,是提高ROS中软件复用率的重要方法之一。

创建功能包

如何在ROS2中创建一个功能包呢?我们可以使用这个指令:

$ ros2 pkg create --build-type <build-type> <package_name>

ros2命令中:

  • pkg:表示功能包相关的功能;
  • create:表示创建功能包;
  • build-type:表示新创建的功能包是C++还是Python的,如果使用C++或者C,那这里就跟ament_cmake,如果使用Python,就跟ament_python;
  • package_name:新建功能包的名字。

比如在终端中分别创建C++和Python版本的功能包:

$ cd ~/dev_ws/src
$ ros2 pkg create --build-type ament_cmake learning_pkg_c               # C++
$ ros2 pkg create --build-type ament_python learning_pkg_python # Python

编译功能包

在创建好的功能包中,我们可以继续完成代码的编写,之后需要编译和配置环境变量,才能正常运行:

$ cd ~/dev_ws/src
$ colcon build   # 编译工作空间所有功能包
$ source install/local_setup.bash

功能包的结构

功能包并不是普通的文件夹,那如何判断一个文件夹是否是功能包呢?我们来分析下刚才新创建两个功能包的结构。

C++功能包

首先看下C++类型的功能包,其中必然存在两个文件:package.xmlCMakerLists.txt

image-20220524112122164

package.xml文件的主要内容如下,包含功能包的版权描述,和各种依赖的声明。

image-20220524112141298

CMakeLists.txt文件是编译规则,C++代码需要编译才能运行,所以必须要在该文件中设置如何编译,使用CMake语法。

image-20220524112132626

Python功能包

C++功能包需要将源码编译成可执行文件,但是Python语言是解析型的,不需要编译,所以会有一些不同,但也会有这两个文件:package.xmlsetup.py

image-20220524112228806

package.xml文件的主要内容和C++版本功能包一样,包含功能包的版权描述,和各种依赖的声明。

image-20220524112246102

setup.py文件里边也包含一些版权信息,除此之外,还有“entry_points”配置的程序入口,在后续编程讲解中,我们会给大家介绍如何使用。

image-20220524112235574

参考链接

https://docs.ros.org/en/humble/Tutorials/Workspace/Creating-A-Workspace.html

https://docs.ros.org/en/humble/Tutorials/Creating-Your-First-ROS2-Package.html

本系列视频公开课:https://class.guyuehome.com/detail/p_628f4288e4b01c509ab5bc7a/6