ROS2笔记-节点
节点
学习资料参考ROS2入门21讲图文教程.
机器人是各种功能的综合体,每一项功能就像机器人的一个工作细胞,众多细胞通过一些机制连接到一起,成为了一个机器人整体。
在ROS中,我们给这些 “细胞”取了一个名字,那就是节点。
通信模型
完整的机器人系统可能并不是一个物理上的整体,比如这样一个的机器人:
在机器人身体里搭载了一台计算机A,它可以通过机器人的眼睛——摄像头,获取外界环境的信息,也可以控制机器人的腿——轮子,让机器人移动到想要去的地方。除此之外,可能还会有另外一台计算机B,放在你的桌子上,它可以远程监控机器人看到的信息,也可以远程配置机器人的速度和某些参数,还可以连接一个摇杆,人为控制机器人前后左右运动。
这些功能虽然位于不同的计算机中,但都是这款机器人的工作细胞,也就是节点,他们共同组成了一个完整的机器人系统。
节点在机器人系统中的职责就是执行某些具体的任务,从计算机操作系统的角度来看,也叫做进程;
每个节点都是一个可以独立运行的可执行文件,比如执行某一个python程序,或者执行C++编译生成的结果,都算是运行了一个节点;
既然每个节点都是独立的执行文件,那自然就可以想到,得到这个执行文件的编程语言可以是不同的,比如C++、Python,乃至Java、Ruby等更多语言。
这些节点是功能各不相同的细胞,根据系统设计的不同,可能位于计算机A,也可能位于计算机B,还有可能运行在云端,这叫做分布式,也就是可以分布在不同的硬件载体上;
每一个节点都需要有唯一的命名,当我们想要去找到某一个节点的时候,或者想要查询某一个节点的状态时,可以通过节点的名称来做查询。
节点也可以比喻是一个一个的工人,分别完成不同的任务,他们有的在一线厂房工作,有的在后勤部门提供保障,他们互相可能并不认识,但却一起推动机器人这座“工厂”,完成更为复杂的任务。
接下来,我们就来看看, 节点这个工作细胞,到底该如何实现。
背景
ROS2图
ROS图是一个ROS 2元素网络,同时处理数据。它包含所有可执行文件以及它们之间的连接,如果要将它们全部映射并可视化。
ROS中的每个节点应负责单个模块用途(例如一个节点用于控制车轮电机,一个节点用来控制激光测距仪等)。每个节点都可以通过主题、服务、操作或参数向其他节点发送和接收数据。
ROS2的节点
ROS中的每个节点应负责单个模块用途(例如一个节点用于控制车轮电机,一个节点用来控制激光测距仪等)。每个节点都可以通过主题、服务、操作或参数向其他节点发送和接收数据。
一个完整的机器人系统由许多协同工作的节点组成。在ROS 2中,单个可执行文件(C++程序、Python程序等)可以包含一个或多个节点。
案例一:Hello World节点(面向过程)
ROS2中节点的实现当然是需要编写程序了,我们从Hello World例程开始,先来实现一个最为简单的节点,功能并不复杂,就是循环打印一个“Hello World”字符串到终端中。
创建节点流程
所以总体而言,节点的实现方式依然是这四个步骤,只不过编码方式做了一些改变而已。
- 编程接口初始化
- 创建节点并初始化
- 实现节点功能
- 销毁节点并关闭接口
通过如下命令创建功能包learning_node,并实现helloworld节点
$ cd ~/dev_ws/src
$ ros2 pkg create --build-type ament_python learning_node
$ cd learning_node/learning_node
$ gedit node_helloworld.py
node_helloworld.py内容如下
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@作者: 古月居(www.guyuehome.com)
@说明: ROS2节点示例-发布“Hello World”日志信息, 使用面向过程的实现方式
"""
import rclpy # ROS2 Python接口库
from rclpy.node import Node # ROS2 节点类
import time
def main(args=None): # ROS2节点主入口main函数
rclpy.init(args=args) # ROS2 Python接口初始化
node = Node("node_helloworld") # 创建ROS2节点对象并进行初始化
while rclpy.ok(): # ROS2系统是否正常运行
node.get_logger().info("Hello World") # ROS2日志输出
time.sleep(0.5) # 休眠控制循环时间
node.destroy_node() # 销毁节点对象
rclpy.shutdown() # 关闭ROS2 Python接口
完成代码的编写后需要设置功能包的编译选项,让系统知道Python程序的入口,打开功能包的setup.py文件,加入如下入口点的配置:
entry_points={
'console_scripts': [
'node_helloworld = learning_node.node_helloworld:main',
],
},
编译执行
$ cd ~/dev_ws/src
$ colcon build
$ ros2 run learning_node node_helloworld
[INFO] [1663995000.408755490] [node_helloworld]: Hello World
[INFO] [1663995000.909924309] [node_helloworld]: Hello World
[INFO] [1663995001.411069528] [node_helloworld]: Hello World
[INFO] [1663995001.912105173] [node_helloworld]: Hello World
[INFO] [1663995002.413409973] [node_helloworld]: Hello World
[INFO] [1663995002.914844265] [node_helloworld]: Hello World
[INFO] [1663995003.416305538] [node_helloworld]: Hello World
[INFO] [1663995003.917357029] [node_helloworld]: Hello World
节点命令行操作
节点命令的常用操作如下:
$ ros2 node list # 查看节点列表
$ ros2 node info <node_name> # 查看节点信息