ROS 2 包的Python开发与构建基础
创建Workspace
类似于 ROS2 文件安装在 /opt/ros/{ROS_DISTRO}
中以便我们可以同时安装多个发行版的方式,我们也可以在系统中拥有许多单独的工作区(workspace)。在 ROS2 中,工作区只不过是一个包含所有包的文件夹。
我们只需要创建一个文件夹,例如我们将在这些教程中使用的文件夹。
cd ~
mkdir -p ros2_tutorial_workspace/src
通常的做法是将所有源文件都放在 src
文件夹中,因此对于这些教程,我们也会这样做——尽管这并不是一个严格的要求。
无论它当前是否是一个空的项目,我们都会运行一次 colcon 来设置环境并说明一些事情。(程序 colcon 是 ROS2 的构建系统,稍后将更详细地描述。)
cd ~/ros2_tutorial_workspace
colcon build
上述命令的输出将类似于:
Summary: 0 packages finished [0.09s]
由于我们的工作区中没有包,因此 colcon 什么也没有构建,这是正常的。
文件夹 build
、install
和 log
已由 colcon 自动生成。项目结构如下所示:
~/ros2_tutorial_workspace/
└── src/
└── build/
└── install/
└── log/
install
文件夹内包含项目生成的所有程序等,用户可以访问。
我们需要通过source
命令加载工作区的环境变量,以便我们可以使用工作区中的程序。
source ~/ros2_tutorial_workspace/install/setup.zsh
目前,由于我们的工作区目前是空的,因此我们不能对它做太多事情。让我们添加一些内容。
创建ROS2包的脚手架命令
ROS2 有一个工具可以帮助创建包模板。我们可以通过运行:
ros2 pkg create -h
上述命令将显示所有可用选项。我们一般重点关注四个命令选项及其使用方法:
--build-type {cmake,ament_cmake,ament_python}
--dependencies DEPENDENCIES [DEPENDENCIES ...]
--node-name NODE_NAME
--library-name LIBRARY_NAME
创建ROS2的Python包
ROS2 中的包可以依赖 CMake 或直接使用 Python 中提供的设置工具。对于纯 Python 项目,使用 ament_python 可能更容易,因此我们从它开始本教程。
让我们构建最简单的 Python 包并从那里开始。
cd ~/ros2_tutorial_workspace/src
ros2 pkg create the_simplest_python_package \
--build-type ament_python
这将导致以下输出,表示包已成功生成:
going to create a new package
package name: the_simplest_python_package
destination directory: /home/kyle/ros2_tutorial_workspace/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['kyle <s***********[email protected]>']
licenses: ['TODO: License declaration']
build type: ament_python
dependencies: []
creating folder ./the_simplest_python_package
creating ./the_simplest_python_package/package.xml
creating source folder
creating folder ./the_simplest_python_package/the_simplest_python_package
creating ./the_simplest_python_package/setup.py
creating ./the_simplest_python_package/setup.cfg
creating folder ./the_simplest_python_package/resource
creating ./the_simplest_python_package/resource/the_simplest_python_package
creating ./the_simplest_python_package/the_simplest_python_package/__init__.py
creating folder ./the_simplest_python_package/test
creating ./the_simplest_python_package/test/test_copyright.py
creating ./the_simplest_python_package/test/test_flake8.py
creating ./the_simplest_python_package/test/test_pep257.py
[WARNING]: Unknown license 'TODO: License declaration'. This has been set in the package.xml, but no LICENSE file has been created.
It is recommended to use one of the ament license identifiers:
Apache-2.0
BSL-1.0
BSD-2.0
BSD-2-Clause
BSD-3-Clause
GPL-3.0-only
LGPL-3.0-only
MIT
MIT-0
我们可以使用 colcon 构建现在包含此空包的工作空间:
cd ~/ros2_tutorial_workspace
colcon build
这将现在输出:
Starting >>> the_simplest_python_package
Finished <<< the_simplest_python_package [1.55s]
Summary: 1 package finished [1.68s]
这意味着 colcon 成功构建了包the_simplest_python_package
。
利用模板创建Python 节点
注意:我们依然是基于 ament_python 脚手架工具进行构建。
始终依赖ros2 pkg create中提供的模板是一个好习惯,主要是因为打包的最佳实践可能会在 ROS2 版本之间发生变化。
让我们使用模板创建一个包含节点的包,如下所示:
cd ~/ros2_tutorial_workspace/src
ros2 pkg create python_package_with_a_node \
--build-type ament_python \
--node-name sample_python_node
这将输出与之前示例中许多相同的内容,但有两个主要区别:
- 它生成一个 Node 模板,而不是一个空包。
setup.py
包含了有关节点的信息。
going to create a new package
package name: python_package_with_a_node
destination directory: /home/kyle/ros2_tutorial_workspace/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['kyle <[email protected]>']
licenses: ['TODO: License declaration']
build type: ament_python
dependencies: []
node_name: sample_python_node
creating folder ./python_package_with_a_node
creating ./python_package_with_a_node/package.xml
creating source folder
creating folder ./python_package_with_a_node/python_package_with_a_node
creating ./python_package_with_a_node/setup.py
creating ./python_package_with_a_node/setup.cfg
creating folder ./python_package_with_a_node/resource
creating ./python_package_with_a_node/resource/python_package_with_a_node
creating ./python_package_with_a_node/python_package_with_a_node/__init__.py
creating folder ./python_package_with_a_node/test
creating ./python_package_with_a_node/test/test_copyright.py
creating ./python_package_with_a_node/test/test_flake8.py
creating ./python_package_with_a_node/test/test_pep257.py
creating ./python_package_with_a_node/python_package_with_a_node/sample_python_node.py
[WARNING]: Unknown license 'TODO: License declaration'. This has been set in the package.xml, but no LICENSE file has been created.
It is recommended to use one of the ament license identifiers:
Apache-2.0
BSL-1.0
BSD-2.0
BSD-2-Clause
BSD-3-Clause
GPL-3.0-only
LGPL-3.0-only
MIT
MIT-0
然后,我们可以像往常一样构建工作空间,以便也将新包考虑在内。
cd ~/ros2_tutorial_workspace
colcon build
上述命令将使我们遍历在前一个示例和当前示例中创建的包,并构建它们。输出应该类似于:
Starting >>> python_package_with_a_node
Starting >>> the_simplest_python_package
Finished <<< python_package_with_a_node [1.59s]
Finished <<< the_simplest_python_package [1.68s]
Summary: 2 packages finished [1.83s]
当我们利用colcon build
命令构建工作空间后,我们需要使用source
命令加载工作空间的环境变量,以便我们可以使用工作空间中的程序。
思考:如果我们不用source
命令加载工作空间的环境变量,我们将无法使用工作空间中的程序。这是因为我们的 shell 不知道工作空间中的程序在哪里。 尝试在没有运行source
命令的情况下运行如下命令:
ros2 run python_package_with_a_node sample_python_node
看看会发生什么?
Tips: 所以我们最好每次运行完colcon build
命令后,都要运行source
命令。
cd ~/ros2_tutorial_workspace
source install/setup.zsh
然后,我们可以通过以下命令执行示例节点和包功能:
ros2 run python_package_with_a_node sample_python_node
现在将正确输出:
Hi from python_package_with_a_node.
总结
- 在本节中,我们学习了如何创建一个 ROS2 工作空间。
- 我们学习了如何使用 ros2 pkg create 命令创建一个空的 Python 包。
- 我们学习了如何使用 ros2 pkg create 命令创建一个包含节点的 Python 包。
- 我们学习了如何构建工作空间并使用
source
命令加载工作空间的环境变量。 - 我们学习了如何运行包中的节点。(课程回顾:请回到课程ROS2的基石:节点Node, 比较与本节内容的异同)
课后作业
- 总结通过
ament_python
创建包的步骤和流程; - 并观察执行完主要步骤之后,文件夹发生了哪些变化。
- 解谜:程序输出
Hi from python_package_with_a_node.
,请找到这个输出的源代码在哪个文件。
作业执行人: 所有同学。
友情提示:
- 本节的课后作业每个同学都要做。
- 因为下节课我们要开始动手裸写Python代码。
- 没有本次课后作业的经验,下节课你会感觉很酸爽。