ROS2之话题通信

话题通信操作

流程:

  • 创建并编辑接口文件:首先在一个专门子自定义接口的功能包中比如base_interfaces_demo中创建一个msg文件夹,然后创建Student.msg文件,在里面写入接口的定义

  • 编辑配置文件,具体来说,需要在packages.xmlCMakerList.txt中补充

packages.xml中,依赖包需要补充

1
2
3
4
5
6
7
<!-- 自定义接口 -->
<!-- 编译依赖 -->
<build_depend>rosidl_default_generators</build_depend>
<!-- 执行依赖 -->
<exec_depend>rosidl_default_runtime</exec_depend>
<!-- 声明当前包所属的功能包组 -->
<member_of_group>rosidl_interface_packages</member_of_group>

然后在CMakeList.txt中写入:

1
2
3
4
5
find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
"msg/Student.msg"
)
  • 编译: 进入(dpl39) tyfelix@tyfelix-B760M:~/zxz_ROS/ws01_plumbing$ 工作空间,编译colcon build --packages-select base interface_demo
  • 测试:编译完成之后,. install/setup.bash 然后ros2 interface show base_interface_demo/msg/Student 。输出内容为Student.msg的内容,那么说明编译成功。可以进行之后的操作。

下面展示了一个服务通信的例子(主要注意 1.话题名称需要保持一致性;2.接口的引入; 3. 函数不一样):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
----发布方----
from std_msgs.msg import String
import rclpy
from rclpy.node import Node
from base_interfaces_demo.msg import Student

class Talker(Node):
def __init__(self, node_name):
super().__init__(node_name=node_name)
# 创建定时器
self.count = 0
self.get_logger().info("发布方创建了(python)")
# 创建发布者
'''
参数:消息类型;话题名称;QoS队列长度
返回这个发布者对象
'''
self.publisher = self.create_publisher(Student,'chatter1',10)
# 创建定时器
'''
参数: 时间间隔;回调函数(函数作为参数传入)
'''
self.timer = self.create_timer(1.0,self.on_timer)
def on_timer(self):
# 组织并发布消息
stu = Student()
stu.name = "Felix Jackson"
stu.age = 20
stu.height = 175.0
self.publisher.publish(stu)
self.count += 1
# self.get_logger().info(f"发布的数据为:{message.data}")
def main():
# 初始化
rclpy.init()
# 创建node
node = Talker("talker_node_py3")
# 运行
rclpy.spin(node)
# 释放资源
rclpy.shutdown()

if __name__ == '__main__':
main()

----订阅方----
from std_msgs.msg import String
import rclpy
from rclpy.node import Node
from base_interfaces_demo.msg import Student

class Listener(Node):
def __init__(self, node_name):
super().__init__(node_name=node_name)
# 创建定时器
# self.count = 0
self.get_logger().info("订阅方创建了(python)")
# 创建订阅者
'''
参数:消息类型;话题名称(比如和发布者一致);回调函数;QoS队列长度
返回这个发布者对象
'''
self.subcriber = self.create_subscription(Student,'chatter1', self.do_cb, 10)
# # 创建定时器
# '''
# 参数: 时间间隔;回调函数(函数作为参数传入)
# '''
# self.timer = self.create_timer(1.0,self.on_timer)

def do_cb(self, stu):
# 解析并输出数据
self.get_logger().info(f"订阅的数据是:name:{stu.name}; age:{stu.age}; height:{stu.height}")

def main():
# 初始化
rclpy.init()
# 创建node
node = Listener("listener_node_py4")
# 运行
rclpy.spin(node)
# 释放资源
rclpy.shutdown()
if __name__ == '__main__':
main()