徒手搓出来一个ROS2的Python节点
上节课,我们是利用模板的方式创建了一个ROS2的Python节点,今天我们来徒手搓出来一个ROS2的Python节点。
徒手搓出来的节点和模板创建的节点是一样的,只是我们手动创建了文件夹和文件(所以我们上节课要了解一下ROS2包的结构)。
利用Python手搓ament_python
节点的基本流程如下:
- 修改
package.xml
以添加任何额外的依赖项。 - 创建节点(node)。
- 修改
setup.py
文件。
让我们向我们的ament_python包中添加一个额外的节点,该节点实际上使用了 ROS2 功能。以下是通常需要采取的步骤,以添加一个新节点。
处理依赖项
package.xml
是由 ros2 pkg create 自动生成的,包含了关于包的基本信息。
package.xml
的一个重要作用是声明与其他 ROS2 包的依赖关系。新节点通常会有额外的依赖项,因此我们将在这里讨论这一点。对于任何 ROS2 包,我们必须修改 package.xml
以添加新的依赖项。
在这个简单的示例中,让我们添加rclpy
作为依赖项,因为它是RCL的 Python 实现。所有使用与 ROS2 相关的任何内容的节点都将直接或间接依赖于该库。并非巧合,package.xml
文件具有 .xml
扩展名,这意味着它是用 XML 编写的。
让我们在<license>
和<test_depend>
标签之间添加依赖关系。这不是一个严格的要求,但通常是标准包中的常见做法。
<?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>python_package_with_a_node</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="[email protected]">murilo</maintainer>
<license>TODO: License declaration</license>
<depend>rclpy</depend>
<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>
重新构建工作区
在将新依赖项添加到package.xml
后,除非执行新的构建,否则工作区中实际上没有任何变化。
cd ~/ros2_tutorial_workspace
colcon build
source install/setup.zsh
创建节点
在目录 src/python_package_with_a_node/python_package_with_a_node
中,创建一个名为python_node.py
的文件。我们将把节点的代码放在这里。
import rclpy
from rclpy.node import Node
def main():
rclpy.init()
node = Node("python_node")
node.get_logger().info("Hello from Python Node!")
rclpy.spin(node)
rclpy.shutdown()
修改setup.py
为了能让功能包python_package_with_a_node
找到这个节点,我们需要在setup.py
中添加一些入口信息。在src/python_package_with_a_node/setup.py
中,添加以下内容:
from setuptools import find_packages, setup
package_name = 'python_package_with_a_node'
setup(
name=package_name,
version='0.0.0',
packages=find_packages(exclude=['test']),
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='kyle',
maintainer_email='[email protected]',
description='TODO: Package description',
license='TODO: License declaration',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'sample_python_node = python_package_with_a_node.sample_python_node:main',
'python_node = python_package_with_a_node.python_node:main',
],
},
)
注意:上述代码的第24行,就是通知ROS2关于节点python_node
的程序启动入口。
运行节点
再次构建工作区,并加载环境变量:
cd ~/ros2_tutorial_workspace
colcon build
source install/setup.zsh
然后运行节点:
ros2 run python_package_with_a_node python_node
这将输出:
[INFO] [1742282609.323775524] [python_node]: Hello from Python Node!
课堂自学环节
本堂课大家照猫画虎地利用我们提供的Python代码,熟练了解了ROS2的Python节点的创建流程后,大家可以尝试自己创建一个ROS2的Python节点,完成以下任务:
- 利用我们的AI助手,解读
python_node.py
的代码含义。 - 创建一个新的节点,命名为
my_python_node
。 - 利用节点,循环打印从1到100的数字。
如果不借助我们的AI助手,嗯,估计您应该没法手搓出来这个功能,所以我们需要学习一些Python的基本编程知识。
我们以前提供了一个Python编程的学习路线图,大家可以参考一下: 02. 最低限度的Python知识技能
关于Python教材嘛?我认为这个系列教程是面向初学者的很好的参考: Python 基础教程
共性的问题我会在本堂自学环节统一解惑。
Action! Go Go Go!
总结
在本节中,我们学习了如何徒手搓出来一个ROS2的Python节点:
- 我们创建了一个新的节点,并将其添加到
python_package_with_a_node
包中。 - 我们还学习了如何修改
package.xml
以添加依赖项, - 以及如何在
setup.py
中添加节点的入口点。 - 我们还复习了如何使用
ros2 run
命令运行节点。 - 自学环节中,大家尝试创建了一个新的节点
my_python_node
,并利用节点循环打印从1到100的数字。
在下一节中,我们将学习如何使用rclpy
库中的其他功能来创建更复杂的节点。