创建 ROS 2 包

目标: 用 CMake 或者 Python 创建一个新的包,然后运行对应的可执行文件.

教程等级: 初级

预计时长: 15 分钟

背景

1 什么是 ROS 2 包?

包是 ROS 2 代码的组织单元. 如果你想安装你的代码或者与他人分享,那么你需要将它组织成一个包. 用包可以发布你的 ROS 2 工作,让其他人更容易构建和使用它.

ROS 2 中的包创建使用 ament 作为构建系统(build system),colcon 作为构建工具(build tool). 你可以使用 CMake 或者 Python 创建一个包,这两种方法都是官方支持的,当然也有其他构建类型.

2 ROS 2 包由哪些内容构成?

ROS 2 Python 和 CMake 包各自有自己的最低要求内容:

  • CMakeLists.txt 描述如何构建包内代码

  • include/<package_name> 目录包含包的公共头文件

  • package.xml 包含关于包的元信息

  • src 目录包含包的源代码

最简可运行的包应该有如下的文件结构:

my_package/
     CMakeLists.txt
     include/my_package/
     package.xml
     src/

3 工作空间中的包

每个工作空间可以包含任意多的包,每个包都在自己的文件夹中. 一个工作空间中可以有不同构建类型的包(CMake, Python 等). 但是一个包不能包含另一个包,也就是说包不能嵌套.

最佳实践:在工作空间中创建一个 src 文件夹,然后在里面放你的包. 这样可以保持工作空间顶层的“干净条理”.

一个简单的工作空间看起来是这样的:

workspace_folder/
    src/
      cpp_package_1/
          CMakeLists.txt
          include/cpp_package_1/
          package.xml
          src/

      py_package_1/
          package.xml
          resource/py_package_1
          setup.cfg
          setup.py
          py_package_1/
      ...
      cpp_package_n/
          CMakeLists.txt
          include/cpp_package_n/
          package.xml
          src/

前提条件

上一个教程 中按照指示操作,你应该已经有了 ROS 2 工作空间. 现在你可以在这个工作空间中创建你的包.

任务

1 创建包

首先,source 你的 ROS 2 安装环境.

让我们在 上一个教程 中创建的工作空间 ros2_ws 里创建新包.

确保你在运行包创建的命令之前已经在 src 文件夹里了.

cd ~/ros2_ws/src

下面这个命令能创建一个新的包:

ros2 pkg create --build-type ament_cmake --license Apache-2.0 <package_name>

在这个教程中,你将学习使用可选参数 --node-name 来创建一个简单的 Hello World 式的可执行文件.

在终端中输入以下命令:

ros2 pkg create --build-type ament_cmake --license Apache-2.0 --node-name my_node my_package

这个命令会在你的工作空间的 src 目录下创建一个新文件夹,名为 my_package.

运行完命令后,终端会返回以下信息:

going to create a new package
package name: my_package
destination directory: /home/user/ros2_ws/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['<name> <email>']
licenses: ['TODO: License declaration']
build type: ament_cmake
dependencies: []
node_name: my_node
creating folder ./my_package
creating ./my_package/package.xml
creating source and include folder
creating folder ./my_package/src
creating folder ./my_package/include/my_package
creating ./my_package/CMakeLists.txt
creating ./my_package/src/my_node.cpp

可以看到为新创建的包自动生成的文件.

2 构建包

把包都放在工作空间中就可以在工作空间根目录下运行 colcon build 来一次性构建所有包. 不然你还得单独构建每个包。

回到工作空间的根目录:

cd ~/ros2_ws

现在构建包:

colcon build

还记得上一个教程中你的 ros2_ws 中也放了 ros_tutorials 包吧. 你可能已经注意到运行 colcon build 时也构建了 turtlesim 包. 这在你的工作空间中只有几个包时没什么问题,但是包多了的话, colcon build 就会消耗很长时间.

下次如果只想构建 my_package 包,可以运行:

colcon build --packages-select my_package

3 Source 配置文件

想要运行新包里的可执行文件,首先要 source 你的 ROS 2 安装环境.

然后,在 ros2_ws 目录内运行以下命令来 source 你的工作空间:

source install/local_setup.bash

现在你的工作空间已经被添加到环境变量中,就可以使用新包的可执行文件了.

4 使用包

用以下指令运行在创建包的时候用 --node-name 指定生成的可执行文件:

ros2 run my_package my_node

终端会返回以下信息:

hello world my_package package

5 检查包的内容

ros2_ws/src/my_package 目录下可以看到 ros2 pkg create 自动创建了一些文件和文件夹:

CMakeLists.txt  include  package.xml  src

my_node.cpp is inside the src directory. This is where all your custom C++ nodes will go in the future.

6 自定义 package.xml

你应该已经注意到在创建包后返回的信息中 descriptionlicense 字段包含了一些 TODO 标记. 这是因为 package.xml 中的包描述和许可声明不是自动生成的,但是如果你想发布你的包,这两个字段则是是必需的. maintainer 字段也得根据需要填写.

ros2_ws/src/my_package 目录下用你喜欢的文本编辑器打开 package.xml 文件:

<?xml version="1.0"?>
<?xml-model
   href="http://download.ros.org/schema/package_format3.xsd"
   schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
 <name>my_package</name>
 <version>0.0.0</version>
 <description>TODO: Package description</description>
 <maintainer email="user@todo.todo">user</maintainer>
 <license>TODO: License declaration</license>

 <buildtool_depend>ament_cmake</buildtool_depend>

 <test_depend>ament_lint_auto</test_depend>
 <test_depend>ament_lint_common</test_depend>

 <export>
   <build_type>ament_cmake</build_type>
 </export>
</package>

如果 maintainer 字段没有自动填充,就在 maintainer 行输入你的名字和邮箱. 然后编辑 description 行来描述或概括一下包的内容或作用:

<description>Beginner client libraries tutorials practice package</description>

接下来更新 license 行. 在 这里 可以了解更多关于开源许可证的信息. 因为这个包只是练习用的,所以可以使用任何许可证. 我们使用 Apache License 2.0:

<license>Apache License 2.0</license>

编辑完成后别忘了保存.

license 标签(tag)下面,你会看到一些标签名字以 _depend 结尾. 这是你的 package.xml 列出了它对其他包的依赖,colcon 会搜索这些依赖. my_package 很简单,没有依赖,但是在后续教程中你会看到这个标签被用到.

你已经完成了全部任务!

总结

你已经创建了一个包来组织你的代码,以及让别人更容易使用它.

你的包已经自动填充了必要的文件,然后你用 colcon 构建它,这样你就可以在本地环境中使用它的可执行文件了.

下一步

接下来,让我们给包添加一些有意义的东西. 你将实现一个简单的发布/订阅系统,用 C++ 或者 Python 都可以.