本文最后更新于:2024年7月16日 上午
ROS2 支持 Python 语言,本文记录 Python 创建 ROS2 节点的流程以及运行方式。
环境配置
-
安装好 ROS2 环境
-
安装好 Python 环境 (python 3.10)
我安装的 ros2 humbel 自带了 python 3.10, 使用其他版本的 python 会报错
-
安装 colcon
1
pip install -U colcon-common-extensions
ROS2 创建单个节点
-
建立文件夹
ros2-python-test
,后续将在这里创建一系列子文件夹以用作不同的ROS2案例的工作空间。 -
然后创建我们的第一个文件夹(也即我们的第一个工作空间):
1 |
|
- 接下来,切换到该工作空间下,本次ROS2的所有操作都将在该目录下操作。
1 |
|
确定了工作空间,就像盖房子已经选好了地址,打好了地基。
然后在这个地基上,就要开始搭建房子了,并且对房子进行各种定义。
ROS2是怎么搭建这个房子的呢?它是要先创建一个统一的固定名字的文件夹“src”,然后在这个文件夹下面再去具体定义各个房间。
- 因此,要先创建一个src文件夹,并切换到这个目录下。
1 |
|
在src文件夹下面定义各个房间早已经工程化了,直接在命令行属于ros2相关命令就能快速搭建好一个基础框架出来。
- 使用如下命令就可以创建包,这个包就是功能包。
1 |
|
ros2 会创建一系列 py 框架文件,当前文件结构如下:
1 |
|
虽然一下多了很多文件夹和文件,但是这些都是一个功能包的标配。
我们只需要在 package_001
中定义好一个节点,然后再在 setup.py
文件中配置好我们要调用这个节点就可以了。
- 在
package_001
中创建node_001.py
文件,写入如下内容:
1 |
|
- 保存文件后,再更改下配置文件
setup.py
。
console_scripts的值原本为空,这里需要将console_scripts的值添加上我们新建的节点,如下所示:
1 |
|
保存之后退出 setup.py
文件。
到这里终于把源码部分定义好了(相当与定义好了房间的框架),接下来,只需要编译一下这个工作空间(相当于快速填充墙体),一个最简单的房子就搭建好了。
- 因此我们回到工作空间目录
ros2_ws_demo001
下,执行如下命令进行编译就行了。
1 |
|
终端输出:
1 |
|
编译完成后,我们发现工作空间下又多出了几个文件夹。分别是build、install、和log。而在这几个文件夹下面又很多其他文件夹和文件生成。
- 执行 python 节点程序:
1 |
|
可以看到屏幕上打印了“hello,I am node_001”,这个正是我们在自定义节点里做的事。
1 |
|
- 新开一个终端,输入如下指令,可以检查下我们正在运行的节点列表(虽然目前只有一个节点在运行):
1 |
|
小结
我们来稍微总结下使用python创建一个ros2节点并运行的整个过程:
1、创建一个独立的工作空间(其实就是创建了一个文件夹);
2、在工作空间下创建src文件夹(源码文件夹),并在src下创建功能包(非常简单,使用ros2命令行工具直接就生成了);
3、在功能包里面编辑一个节点python程序,唯一需要你动动脑子写的东西,但我们这个例子也才区区8行代码,已经简单到了极致;
4、在功能包里面配置setup.py文件,将我们上一步创建的节点程序调用起来;
5、回到工作空间,使用colcon工具编译(build)整个代码;
6、运行编译后的代码;
非官方方式
事实上 Python 使用 ROS2 总线相对灵活,不一定需要上述 ros2 run
的方法,直接 Python 运行某个 py 文件也是一样的。
1 |
|
你可以自己试一下。
ROS2 创建两个节点
稍微扩展下上面的代码,做两个ROS2节点,然后运行起来。
- 将上一节的工作空间复制出一个新的工作空间,接下来我将在这个新的工作空间里完成我新的测试。
1 |
|
- 现在我们在新的工作空间里面了。接下来要做的事情也是非常简单,将第一个节点文件复制生成第二个节点文件,并稍作编辑以作区分。
1 |
|
-
修改
node_002.py
1
2
3
4
5
6
7
8
9import rclpy
from rclpy.node import Node
def main(args=None):
rclpy.init(args=args) # init rclpy
my_node = Node("node_002") # to create a Node object
my_node.get_logger().info("hello,I am node_002") # to print a message.
rclpy.spin(my_node) # to keep Node running
rclpy.shutdown() # to close Node -
把它配置到setup.py文件中:
1
2
3
4'console_scripts': [
"node_001 = package_001.node_001:main",
"node_002 = package_001.node_002:main"
], -
然后,退回到新的工作空间下,删除之前的编译结果,重新进行编译。
1
2
3
4
5cd ~/ROS2_study/ros2_ws_demo002_2_nodes
rm -rf build
rm -rf install
rm -rf log
colcon build -
编译完成后,在当前终端直接启动第一个节点:
1
2source install/setup.zsh
ros2 run package_001 node_001 -
然后新打开一个终端,运行第二个节点:
1
2source install/setup.zsh
ros2 run package_001 node_002 -
两个终端页面显示了我们输出的字符串:
1
2
3
4
5
6
7# terminal 1
> ros2 run package_001 node_001
[INFO] [1720690420.025982182] [node_001]: hello, I am node_001
# terminal 2
> ros2 run package_001 node_002
[INFO] [1720690454.321045447] [node_002]: hello, I am node_002 -
然后再来打开一个终端确认下目前正在运行的节点有哪些:
1
ros2 node list
可以看到两个节点在线
1
2
3> ros2 node list
/node_001
/node_002至此,我们实现了两个ROS2节点的创建并完成了调用。
ROS2 使用 launch 文件启动多个节点
规范
launch 文件默认 调用的 py 文件中存在 main() 函数,他会自动调用 main 函数,并将其中生成的节点命名为 launch 文件中配置的名称
1 |
|
该配置会在 package_001
文件夹中,调用 node_001.py
文件, 调用其中的 main()
函数,将生成的节点命名为 node_001_launch
,调用的 Python 为当前终端环境中的默认 python 程序路径,也就是说, 通过 conda activate
的环境可以作用于 ros2
通过 launch 启动的节点在launch 程序结束时会调用 shutdown 关闭这些节点,直接运行 py 文件创建的节点如果没有及时运行 shutdown 可能会导致节点残留,即程序已经退出但是仍然可以被 ros2 发现的节点。
实操
ROS2 可以通过配置 launch
文件,一次性将所有节点都设置好,然后统一启动。
- 备份上一节的工作空间,复制生成新的工作空间并进入。
1 |
|
- 然后在功能包下面手动创建一个launch文件夹:
1 |
|
- 在launch文件夹下新建一个python文件用作启动文件,这里我随意命令为了
my_multi_nodes_launch.py
, 内容如下:
1 |
|
- 然后,依然需要在setup.py文件中引入该launch文件以保证编译的时候能找到它。setup.py更改后内容如下:
1 |
|
实这里只添加了一句话:
1 |
|
最后,回到工作空间编译一下:
1 |
|
- 运行这个launch文件(注意这次的运行方式有些不同了):
1 |
|
终端输出:
1 |
|
- 用ros2 node list确认下正在运行的节点:
1 |
|
至此我们通过launch方法实现了一次性启动多个节点。
直接启动多个节点
可以在 一个 py 文件中直接启动多个 ros2 节点
1 |
|
这样在运行这个 py 程序后可以看到 Test_node1
Test_node2
两个节点在线.
但是如果将该文件替换上文的 node_001.py 文件,则会报错:
1 |
|
这时查看 ros2 的节点列表看到的是:
1 |
|
也就是说通过 ros2 launch 启动方式启动和 运行 py 文件启动的ros 节点结果可能是不同的, 关键在于launch 配置, 将过程中创建的节点都命名为配置的名称.
CTL 工具
这里记录官方文档的一些工具细节
Remapping
重新映射允许您将节点名称、主题名称、服务名称等默认节点属性重新指定为自定义值。
终端中运行以下命令可以重新指定 turtlesim
节点的名称。
1 |
|
ros2 node info
如果已经知道了节点的名称,可以使用以下命令获取更多节点信息:
1 |
|
ros2 node info 返回订阅者、发布者、服务和操作的列表,即与该节点交互的 ROS 图连接。输出结果应该是这样的:
1 |
|
参考资料
- https://docs.ros.org/en/humble/index.html
- https://colcon.readthedocs.io/en/released/user/installation.html
- https://mp.weixin.qq.com/s?__biz=Mzg3NzU4NDE0OA==&mid=2247491345&idx=1&sn=9368fb3baa572445113ff0df91b6addb&chksm=cf21956af8561c7cfb4e05f6e8ffe29ab1cb529c2698658a3d780f8e5ab7ab6aa88820e98810&scene=178&cur_album_id=3205491925185806338#rd
- https://blog.51cto.com/u_16213308/9024548
- https://blog.csdn.net/guanjing_dream/article/details/139090792
文章链接:
https://www.zywvvd.com/notes/tools/ros2/ros2-python/ros2-python/
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”
微信支付
支付宝支付