![ROS 2机器人开发:从入门到实践](https://wfqqreader-1252317822.image.myqcloud.com/cover/209/51975209/b_51975209.jpg)
2.1.1 Python示例
ROS 2提供了丰富的Python版本的客户端接口库,让你通过简单的调用即可完成节点的创建。
在主目录下创建chapt2/文件夹,并用VS Code打开该文件夹,接着创建ros2_python_node.py文件,在文件中编写代码清单2-1的内容。
代码清单2-1 一个最简单的Python节点
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/44_01.jpg?sign=1738961575-lUHklD8kgCMB7KOJ7YdhiesNUjtjjBoY-0-f411bcabf76944bd104db3010d152b3c)
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/45_01.jpg?sign=1738961575-qwfZuQt8M79fKWrAF89PyoQCSjxeZli8-0-88fc74c633320e74de2e64ef6e1548c4)
如代码清单2-1所示,首先导入ROS 2提供的Python版本客户端库rclpy,从rclpy库的node模块中导入Node类。然后定义了一个main函数,在函数里调用rclpy的init方法为接下来的通信分配资源,接着创建一个名为python_node的Node类实例,有了node实例,就可以通过它来订阅或者发布话题了,通信并不是本节的重点,所以这里没有进行任何操作。
创建完节点后,使用spin方法启动该节点,spin方法恰如其名,它会不断地循环检查被其运行的节点是否收到新的话题数据等事件,直到该节点被关闭为止。之后,rclpy.shutdown()方法用于清理分配的资源并确认节点是否被关闭。
在了解了每一行代码的作用后,运行代码,按Ctrl+Shift+~键可以快速地在VS Code内打开集成终端,输入代码清单2-2中的命令运行代码。
代码清单2-2 使用Python执行节点
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/45_02.jpg?sign=1738961575-RWEl3KGRZwd5I1Mk9OwvEqKwHI98E9QJ-0-ab4379070b0a87ee1ff62e3d828d79f5)
运行后会发现终端并没有任何输出和提示,此时不要怀疑代码有问题,节点其实已经运行起来了。按Ctrl+Shift+5键可以在VS Code原有的终端旁添加一个新的终端,在终端中输入代码清单2-3所示的命令。
代码清单2-3 使用命令行查询节点列表
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/45_03.jpg?sign=1738961575-Bs97RlJdbzm6jYRtihp8mtIgxq6Kqo11-0-1ad6ffc891b96b54aef5a7d6c5cd6fcd)
代码清单2-3中的ros2 node list是ROS 2命令行工具的节点模块下的命令之一,用于查看当前的节点列表,看到/python_node就代表我们的第一个ROS 2节点启动成功了。但启动后没有一点提示显然不太友好,所以修改代码清单2-1中的main函数,加一句输出,如代码清单2-4所示。
代码清单2-4 添加输出的节点代码
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/45_04.jpg?sign=1738961575-VFbasH82BqqGN9LhdfJ6mmL7ipnp1Jar-0-d12e48320864ed56e59910d215a6a92e)
这里我们加了一句输出指令,但并没有使用你所熟悉的print函数,而是先通过node实例调用get_logger()获取日志记录器,接着调用日志记录器的info方法输出了一句话。
接着来运行测试一下,在刚刚运行节点的终端里,按Ctrl+C键,该命令可以打断当前终端运行的程序,输入代码清单2-5所示的命令并运行。
代码清单2-5 运行带日志输出的Python节点
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/46_01.jpg?sign=1738961575-eSfQHN9eq9iVwFYACDwDDuSIsbF0wafN-0-71d339bbc0ab14cad8c47f2d1ffd23cc)
可以看到这里不仅输出了我们想要的内容,还输出了日志的级别、时间和节点信息。如果你想查看更多日志信息,可以通过环境变量RCUTILS_CONSOLE_OUTPUT_FORMAT修改输出的日志格式,使用如代码清单2-6所示的设置就可以在输出消息的同时输出代码所在的函数和行号。
代码清单2-6 使用环境变量输出更多的信息
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/46_02.jpg?sign=1738961575-hl52SPK5q9Unc14wEwTeKzJZETpvpZv6-0-19b767325f5d0157840c1440f04beee3)
使用{}包含特定单词就可以表示对应的消息,除了上面代码使用的三个外,还有表示日志级别的severity、表示日志记录器名的name、表示文件名字的file_name、表示时间戳的time以及表示纳秒时间戳的time_as_nanoseconds。
第一个Python节点到这里就算写完了,但在写代码的时候好像没有提示,这是因为没有安装Python插件。如图2-1所示,打开VS Code的扩展,搜索Python,安装第一个插件即可。
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/46_03.jpg?sign=1738961575-2PtkQT9BXOdhBIaQY9qM1o7VYnSfHxuv-0-c577f71f7b2993836d800374757923d4)
图2-1 安装插件
再次编辑代码时你会发现如图2-2所示的提示。把鼠标指针长时间悬停在某个函数上,函数注释就会随之跳出,如图2-3所示。
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/46_04.jpg?sign=1738961575-tA6Pit7wshSiKktaYzxKecsx0Ktqg2fi-0-e95e80ebf7a784e15ed47b9d6b548c6e)
图2-2 代码提示
![](https://epubservercos.yuewen.com/6232B7/30716170307984306/epubprivate/OEBPS/Images/46_05.jpg?sign=1738961575-NqOYsoJLKelaCV4Bqooh1rPxDcBDUqvQ-0-7919dc8fbd85e8f7f89901e23ff75841)
图2-3 函数注释