1,话题
话题:故事其实就是讲了一下ROS2中Topic通信方式,Topic通信模型是一种发布订阅模型。
需要满足以下规则:
- 话题名字是关键,发布订阅接口类型要相同,发布的是字符串,接受也要用字符串来接收;
- 同一个人(节点)可以订阅多个话题,同时也可以发布多个话题,就像一本书的作者也可以是另外一本书的读者;
- 同一个小说不能有多个作者(版权问题),但跟小说不一样,同一个话题可以有多个发布者。
1,相关的工具
ros2 run demo_nodes_py listener
ros2 run demo_nodes_cpp talker
rqt_graph
2,ROS2话题相关命令行界面(CLI)工具
ros2也支持很多强大的topic指令。可以使用下面的指令查看。
ros2 topic -h
ros2 topic list 返回系统中当前活动的所有主题的列表
命令
ros2 topic list
ros2 topic list -t 增加消息类型
命令
2ros2 topic list -t
ros2 topic echo 打印实时话题内容
命令
ros2 topic echo /c)hatter
ros2 topic info 查看主题信息
命令
ros2 topic info /chatter
ros2 interface show 查看消息类型
上面一个指令告诉大家这个消息是std_msgs/msg/String,那String里面有什么呢?
命令
ros2 interface show std_msgs/msg/String
topic pub arg 手动发布命令
关闭发布者,我们受到来发布
命令
ros2 topic pub /chatter std_msgs/msg/String 'data: "123"'
参考链接:Understanding ROS 2 topics — ROS 2 Documentation: Foxy documentation
话题编程
1.发布话题(sexy_girl)
下面这样:
class WriterNode(Node):
那代码里的WriterNode继承Node之后,会具备什么能力呢?在本节中用到了以下四个能力:
- 创建一个话题发布者的能力
- 创建一个定时器的能力
- 创建一个话题订阅者的能力
- 获取日志打印器的能力
除了上述四种能力之外,Node节点所具备的详细的能力可以查看API:https://docs.ros2.org/foxy/api/rclpy/index.html
编写一个话题发布者一流程:
- 导入消息类型
- 声明并创建发布者
- 编写发布逻辑发布数据
用VsCode打开上一章中town_ws工作空间,并打开li4.py。我们在其中添加代码即可。
添加完成后WriterNode类中代码如下:
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
# 1. 导入消息类型
from std_msgs.msg import String
class WriterNode(Node):
"""
创建一个李四节点,并在初始化时输出一个话
"""
def __init__(self,name):
super().__init__(name)
self.get_logger().info("大家好,我是%s,我是一名作家!" % name)
# 2.创建并初始化发布者成员属性pubnovel
self.pub_novel = self.create_publisher(String,"sexy_girl", 10)
#3. 编写发布逻辑
# 创建定时器成员属性timer
self.i = 0 # i 是个计数器,用来算章节编号的
timer_period = 5 #每5s写一章节话
self.timer = self.create_timer(timer_period, self.timer_callback) #启动一个定时装置,每 1 s,调用一次time_callback函数
def timer_callback(self):
"""
定时器回调函数
"""
msg = String()
msg.data = '第%d回:潋滟湖 %d 次偶遇胡艳娘' % (self.i,self.i)
self.pub_novel.publish(msg) #将小说内容发布出去
self.get_logger().info('李四:我发布了艳娘传奇:"%s"' % msg.data) #打印一下发布的数据,供我们看
self.i += 1 #章节编号+1
def main(args=None):
rclpy.init(args = args)
li4_node = WriterNode("li4")
rclpy.spin(li4_node)
rclpy.shutdown()
1.3 代码讲解
1.3.1 创建发布者
self.create_publisher(String,"sexy_girl", 10)
小鱼这里使用create_publisher方法来创建的发布者,该方法一共有三个参数,第一个是方法类型,第二个是话题名称,第三个是消息队列长度,第一个参数我们这里添了String,需要注意的是,这里的String并非Python自带的字符串类型,我们使用
from std_msgs.msg import String
从std_msgs.msg
中导入了String类,那std_msgs是什么呢?
std_msgs
是ROS2自带的接口类型,其中规定了我们常用的大多数消息类型,可以使用下面的指令来查看std_msgs
中所有的消息类型。
ros2 interface package std_msgs
比如我们接下来想让李四收钱,我们将消息类型设置为UInt32,无符号整型,毕竟收钱没有收成负数的。
还可以使用 ros2 interface list查看所有ros2自带的消息类型。
需要注意的是,ros2中自带的类型基本上能够满足我们日常做机器人时的使用,但如果ros2中的消息类型不能满足我们的需求时,也可以选择自己定义消息类型。
1.3.2 编写发布 逻辑发布数据
使用了一个方法来创建一个定时器
self.create_timer(timer_period, self.timer_callback)
这个定时器的作用就是根据传入的timer_period
时间周期,每隔一个timer_period
秒,调用一次self.timer_callback
函数。
在self.timer_callback
函数里,我们使用publish方法将数据(小说内容)发送出去。也就是说每1s中发送一次小说内容。
self.write.publish(msg) #将小说内容发布出去
2.测试是否发布成功
完成上面的代码后,我们就可以编译运行节点了。
在VsCode中可以使用下面的命令打开和拆分终端:
单独编译李家村,可以使用下面的指令来单独编译某一个功能包。
colcon build --packages-select village_li