当前位置:网站首页>ROS2——topic话题(八)
ROS2——topic话题(八)
2022-07-05 06:35:00 【我与nano】
ROS2机器人操作系统
文章目录
前言
节点实现了机器人各种各样的功能,但这些功能并不是独立的,之间会有千丝万缕的联系,其中最重要的一种联系方式就是话题,它是节点间传递数据的桥梁。
一、topic话题
1.通信模型
以两个机器人节点为例。A节点的功能是驱动相机这个硬件设备,获取得到相机拍摄的图像信息,B节点的功能是视频监控,将相机拍摄到的图像实时显示给用户查看。此时从节点A到节点B传递图像数据的方式,在ROS中,我们就称之为话题,它作为一个桥梁,实现了节点之间某一个方向上的数据传输。
2.发布订阅模型
从话题本身的实现角度来看,使用了基于DDS的发布/订阅模型,什么叫发布和订阅呢?
话题数据传输的特性是从一个节点到另外一个节点,发送数据的对象称之为发布者,接收数据的对象称之为订阅者,每一个话题都需要有一个名字,传输的数据也需要有固定的数据类型。
怎么说呢,发布和订阅的关系就类似于,我创建了一个发布者,我把消息发布了出去,你什么订阅我不管,我反正是把消息发送到了一个频道,你订阅了变可以查看我发布的消息,同样也可以很多个人订阅。你没有订阅当然是看不到的
3.多对多通信
大家再仔细想下这些可以订阅的东西,是不是并不是唯一的,我们每个人可以订阅很多公众号、报纸、杂志,这些公众号、报纸、杂志也可以被很多人订阅,没错,ROS里的话题也是一样,发布者和订阅者的数量并不是唯一的,可以称之为是多对多的通信模型。
因为话题是多对多的模型,发布控制指令的摇杆可以有一个,也可以有2个、3个,订阅控制指令的机器人可以有1个,也可以有2个、3个,大家可以想象一下这个画面,似乎还是挺魔性的,如果存在多个发送指令的节点,建议大家要注意区分优先级,不然机器人可能不知道该听谁的了。
4.异步通信
话题通信还有一个特性,那就是异步,这个词可能有同学是第一次听说?所谓异步,只要是指发布者发出数据后,并不知道订阅者什么时候可以收到,这就叫做异步。
异步的特性也让话题更适合用于一些周期发布的数据,比如传感器的数据,运动控制的指令等等,如果某些逻辑性较强的指令,比如修改某一个参数,用话题传输就不太合适了。
5.消息结构
最后,既然是数据传输,发布者和订阅者就得统一数据的描述格式,不能一个说英文,一个理解成了中文。在ROS中,话题通信数据的描述格式称之为消息,对应编程语言中数据结构的概念。比如这里的一个图像数据,就会包含图像的长宽像素值、每个像素的RGB等等,在ROS中都有标准定义。
消息是ROS中的一种接口定义方式,与编程语言无关,我们也可以通过.msg后缀的文件自行定义,有了这样的接口,各种节点就像积木块一样,通过各种各样的接口进行拼接,组成复杂的机器人系统。
二、话题实例
1.Hello World话题通信
启动第一个终端,运行话题的发布者节点:
ros2 run learning_topic topic_helloworld_pub
启动第二个终端,运行话题的订阅者节点:
ros2 run learning_topic topic_helloworld_sub
发布者代码解析
import rclpy # ROS2 Python接口库
from rclpy.node import Node # ROS2 节点类
from std_msgs.msg import String # **字符串消息类型**
"""
创建一个发布者节点
"""
class PublisherNode(Node):
def __init__(self, name):
super().__init__(name) # ROS2节点父类初始化
self.pub = self.create_publisher(String, "chatter", 10) # **创建发布者对象(消息类型、话题名、队列长度)**
self.timer = self.create_timer(0.5, self.timer_callback) # 创建一个定时器(单位为秒的周期,定时执行的回调函数)
def timer_callback(self): # 创建定时器周期执行的回调函数
msg = String() # **创建一个String类型的消息对象**
msg.data = 'Hello World' # **填充消息对象中的消息数据**
self.pub.publish(msg) # 发布话题消息
self.get_logger().info('Publishing: "%s"' % msg.data) # 输出日志信息,提示已经完成话题发布
def main(args=None): # ROS2节点主入口main函数
rclpy.init(args=args) # ROS2 Python接口初始化
node = PublisherNode("topic_helloworld_pub") # 创建ROS2节点对象并进行初始化
rclpy.spin(node) # 循环等待ROS2退出
node.destroy_node() # 销毁节点对象
rclpy.shutdown() # 关闭ROS2 Python接口
完成代码的编写后需要设置功能包的编译选项,让系统知道Python程序的入口,打开功能包的setup.py文件,加入如下入口点的配置:
entry_points={
'console_scripts': [
'topic_helloworld_pub = learning_topic.topic_helloworld_pub:main',
],
},
流程总结
对以上程序进行分析,如果我们想要实现一个发布者,流程如下:
编程接口初始化
创建节点并初始化
创建发布者对象
创建并填充话题消息
发布话题消息
销毁节点并关闭接口
订阅者代码解析
import rclpy # ROS2 Python接口库
from rclpy.node import Node # ROS2 节点类
from std_msgs.msg import String # ROS2标准定义的String消息
"""
创建一个订阅者节点
"""
class SubscriberNode(Node):
def __init__(self, name):
super().__init__(name) # ROS2节点父类初始化
self.sub = self.create_subscription(\
String, "chatter", self.listener_callback, 10) # 创建订阅者对象(消息类型、话题名、订阅者回调函数、队列长度)
def listener_callback(self, msg): # 创建回调函数,执行收到话题消息后对数据的处理
self.get_logger().info('I heard: "%s"' % msg.data) # 输出日志信息,提示订阅收到的话题消息
def main(args=None): # ROS2节点主入口main函数
rclpy.init(args=args) # ROS2 Python接口初始化
node = SubscriberNode("topic_helloworld_sub") # 创建ROS2节点对象并进行初始化
rclpy.spin(node) # 循环等待ROS2退出
node.destroy_node() # 销毁节点对象
rclpy.shutdown() # 关闭ROS2 Python接口
完成代码的编写后需要设置功能包的编译选项,让系统知道Python程序的入口,打开功能包的setup.py文件,加入如下入口点的配置:
entry_points={
'console_scripts': [
'topic_helloworld_pub = learning_topic.topic_helloworld_pub:main',
'topic_helloworld_sub = learning_topic.topic_helloworld_sub:main',
],
},
流程总结
对以上程序进行分析,如果我们想要实现一个订阅者,流程如下:
编程接口初始化
创建节点并初始化
创建订阅者对象
回调函数处理话题数据
销毁节点并关闭接口
同样也可以用机器视觉来解释,这里就不过多赘述了,可以去看古月的视频。
2.话题命令行操作
ros2 topic list # 查看话题列表
ros2 topic info <topic_name> # 查看话题信息
ros2 topic hz <topic_name> # 查看话题发布频率
ros2 topic bw <topic_name> # 查看话题传输带宽
ros2 topic echo <topic_name> # 查看话题数据
ros2 topic pub <topic_name> <msg_type> <msg_data> # 发布话题消息
总结
话题通信的特性是单向传输、异步通信,适合周期性的数据传递,对于一个复杂的机器人系统来讲,这种特性肯定无法满足所有数据传输的需求.
边栏推荐
- Relevant information of National Natural Science Foundation of China
- Package webapp or H5 pages into apps
- Chinese remainder theorem acwing 204 Strange way of expressing integers
- Some classic recursion problems
- Vant Weapp SwipeCell设置多个按钮
- Install opencv -- CONDA to establish a virtual environment and add the kernel of this environment in jupyter
- Time is fast, please do more meaningful things
- Vant Weapp SwipeCell設置多個按鈕
- 7. Oracle table structure
- Rehabilitation type force deduction brush question notes D2
猜你喜欢
‘mongoexport‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
PHY驱动调试之 --- MDIO/MDC接口22号和45号条款(一)
Some classic recursion problems
Vant weapp swippecell set multiple buttons
ollvm编译出现的问题纪录
Skywalking全部
Client use of Argo CD installation
The problem of Chinese garbled code in the vscode output box can be solved once for life
Adg5412fbruz-rl7 applies dual power analog switch and multiplexer IC
Find the combination number acwing 889 01 sequence meeting conditions
随机推荐
Relevant information of National Natural Science Foundation of China
2022-5-the fourth week daily
代码中的英语全部
Game theory acwing 893 Set Nim game
NVM Downloading npm version 6.7.0... Error
Skywalking全部
Database mysql all
ADG5412FBRUZ-RL7应用 双电源模拟开关和多路复用器IC
Dataframe (1): introduction and creation of dataframe
Vant Weapp SwipeCell設置多個按鈕
Inclusion exclusion principle acwing 890 Divisible number
Instruction execution time
扫盲-以太网MII接口类型大全-MII、RMII、SMII、GMII、RGMII、SGMII、XGMII、XAUI、RXAUI
[Chongqing Guangdong education] 1185t administrative leadership reference test of National Open University in autumn 2018
Adg5412fbruz-rl7 applies dual power analog switch and multiplexer IC
2048 project realization
Configuration method and configuration file of SolidWorks GB profile library
Use the Paping tool to detect TCP port connectivity
'mongoexport 'is not an internal or external command, nor is it a runnable program or batch file.
Log4qt usage of logbase in QT project