ROS2 Topic 介绍及应用
概述
ROS2(Robot Operating System 2)的 Topic 是节点(Node)之间进行异步通信的核心机制。通过 Topic,节点可以发布(Publish)或订阅(Subscribe)特定类型的消息(Message),实现一对多、多对一或多对多的通信模式。与 ROS1 相比,ROS2 的 Topic 机制基于 DDS(Data Distribution Service) 中间件,支持更灵活的实时性和服务质量(QoS)策略。
核心概念
1. 核心组件
- Publisher(发布者):向 Topic 发布消息的节点。
- Subscriber(订阅者):从 Topic 订阅并接收消息的节点。
- Topic(主题):由名称和消息类型定义的逻辑通道,用于标识消息的传输路径。
- QoS Policy(服务质量策略):控制数据传输的可靠性、持久性、历史深度等行为(如
RELIABLE
、BEST_EFFORT
、HISTORY_KEEP_LAST
)。
2. 通信模型
ROS2 的 Topic 采用 发布/订阅(Publish-Subscribe)模型:
- 异步通信:发布者与订阅者无需直接关联,发布消息后不等待确认。
- 多对多支持:一个 Topic 可以有多个发布者和订阅者。
- DDS 中间件:通过 RTPS(Real-Time Publish-Subscribe)协议实现跨供应商的互操作性。
Topic 通信机制
1. 核心流程
- 发布者:创建 Publisher 对象,绑定 Topic 名称和消息类型,并配置 QoS 策略。
- 订阅者:创建 Subscriber 对象,订阅同一 Topic 名称和消息类型,并定义回调函数处理消息。
- DDS 中间件:自动匹配发布者和订阅者,通过 RTPS 协议传输数据。
2. 关键特性
- 无耦合性:发布者和订阅者无需知道彼此的存在,仅需通过 Topic 名称和消息类型通信。
- 实时性:通过 QoS 策略(如
Deadline
、Liveliness
)保障实时性要求。
- 灵活性:支持自定义消息类型(如定义
.msg
文件)。
代码示例
1. 创建 Publisher 节点(C++)
C++ |
---|
| #include <chrono>
#include <memory>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
class MinimalPublisher : public rclcpp::Node {
public:
MinimalPublisher() : Node("minimal_publisher"), count_(0) {
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
timer_ = this->create_wall_timer(
500ms, std::bind(&MinimalPublisher::timer_callback, this));
}
private:
void timer_callback() {
auto message = std_msgs::msg::String();
message.data = "Hello, world! " + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
publisher_->publish(message);
}
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
size_t count_;
};
int main(int argc, char *argv[]) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalPublisher>());
rclcpp::shutdown();
return 0;
}
|
2. 创建 Subscriber 节点(Python)
Python |
---|
| import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class MinimalSubscriber(Node):
def __init__(self):
super().__init__('minimal_subscriber')
self.subscription = self.create_subscription(
String,
'topic',
self.listener_callback,
10)
self.subscription # 避免被静态分析工具警告
def listener_callback(self, msg):
self.get_logger().info('Received: "%s"' % msg.data)
def main(args=None):
rclpy.init(args=args)
minimal_subscriber = MinimalSubscriber()
rclpy.spin(minimal_subscriber)
minimal_subscriber.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
|
常用命令
ROS2 提供了一系列命令行工具用于调试和监控 Topic:
1. 查看 Topic 列表
Bash |
---|
| ros2 topic list # 列出所有 Topic
ros2 topic list -t # 显示 Topic 及其消息类型
|
2. 查看 Topic 详细信息
Bash |
---|
| ros2 topic info /topic_name # 显示 Topic 的发布者、订阅者及 QoS 策略
ros2 topic info -v /topic_name # 显示详细信息(包括 DDS 实现细节)
|
3. 发布与接收消息
Bash |
---|
| ros2 topic pub /topic_name std_msgs/msg/String "data: 'Hello ROS2'" # 手动发布消息
ros2 topic echo /topic_name # 实时显示 Topic 的消息内容
|
4. 监控 Topic 性能
Bash |
---|
| ros2 topic hz /topic_name # 显示 Topic 的发布频率(Hz)
ros2 topic bw /topic_name # 显示 Topic 的带宽(Byte/s)
|
应用场景
- 传感器数据传输:如相机、激光雷达的实时数据通过 Topic 分发。
- 控制指令传递:发送机器人运动指令(如 Twist 消息控制小车)。
- 状态监控:发布机器人状态(如电池电量、关节角度)供其他节点订阅。
- 分布式系统协调:多个节点通过 Topic 协同完成复杂任务(如多机协作)。
ROS2 与 ROS1 的区别
总结
ROS2 的 Topic 机制通过 DDS 中间件提供了高效、灵活的异步通信能力,适用于机器人系统的传感器数据传输、控制指令分发等场景。结合 QoS 策略和丰富的命令工具,开发者可以快速构建高可靠性和实时性的机器人应用。