ROS2 话题实例解析


ROS2 话题实例解析

一、ROS2 话题基础

在 ROS2 中,话题是一种发布/订阅(Pub/Sub)模式的消息传递机制。发布者(Publisher)节点向某个话题发送消息,而订阅者(Subscriber)节点则接收该话题上的消息。这种机制允许节点间在不直接连接的情况下进行通信,极大地提高了系统的灵活性和可扩展性。
话题具有以下特点:

异步性:

发布者发送消息与订阅者接收消息是异步进行的,互不干扰。

多对多关系:

一个发布者可以向多个订阅者发送消息,同时一个订阅者也可以接收多个发布者的消息。

消息类型:

每个话题都有明确的消息类型,发布者发送的消息类型必须与订阅者期望的消息类型一致。

二、ROS2 话题实例

为了更直观地理解 ROS2 话题,下面通过一个简单的实例进行说明。假设我们有一个机器人系统,其中一个节点负责检测环境中的障碍物(发布者),另一个节点则根据障碍物信息规划路径(订阅者)。

1. 消息类型定义

首先,我们需要定义一个用于传递障碍物信息的消息类型。在 ROS2 中,消息类型通常使用 IDL(接口描述语言)进行定义,并存储在 .msg 文件中。

# ObstacleMessage.msg
string id
float32 position_x
float32 position_y
float32 size

上述消息类型包含障碍物的 ID、位置(x、y 坐标)和大小。

2. 发布者节点实现

接下来,我们实现一个发布者节点,该节点定期发布障碍物信息。

#include <chrono>
#include <memory>
#include <rclcpp/rclcpp.hpp>
#include "obstacle_msgs/msg/obstacle_message.hpp"

class ObstaclePublisherNode : public rclcpp::Node
{
public:
    ObstaclePublisherNode()
    : Node("obstacle_publisher"), count_(0)
    {
        publisher_ = this->create_publisher<obstacle_msgs::msg::ObstacleMessage>(
            "obstacle_topic", 10);
        timer_ = this->create_wall_timer(
            std::chrono::seconds(1), std::bind(&ObstaclePublisherNode::timer_callback, this));
    }
private:
    void timer_callback()
    {
        auto message = obstacle_msgs::msg::ObstacleMessage();
        message.id = "obstacle_" + std::to_string(count_);
        message.position_x = 1.0f * count_;
        message.position_y = 2.0f * count_;
        message.size = 0.5f;
        RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.id.c_str());
        publisher_->publish(message);
        count_++;
    }
    rclcpp::TimerBase::SharedPtr timer_;
    rclcpp::Publisher<obstacle_msgs::msg::ObstacleMessage>::SharedPtr publisher_;
    size_t count_;
};
int main(int argc, char *argv[])
{
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ObstaclePublisherNode>());
    rclcpp::shutdown();
    return 0;
}

在上述代码中,我们创建了一个名为 obstacle_publisher 的节点,并定义了一个定时器,每秒发布一次障碍物信息。

3. 订阅者节点实现

最后,我们实现一个订阅者节点,该节点接收障碍物信息并进行处理。

#include <memory>
#include <rclcpp/rclcpp.hpp>
#include "obstacle_msgs/msg/obstacle_message.hpp"

class ObstacleSubscriberNode : public rclcpp::Node
{
public:
    ObstacleSubscriberNode()
    : Node("obstacle_subscriber")
    {
        subscription_ = this->create_subscription<obstacle_msgs::msg::ObstacleMessage>(
            "obstacle_topic", 10,
            std::bind(&ObstacleSubscriberNode::topic_callback, this, std::placeholders::_1));
    }
private:
    void topic_callback(const obstacle_msgs::msg::ObstacleMessage::SharedPtr msg) const
    {
        RCLCPP_INFO(this->get_logger(), "I heard: '%s' at (%f, %f) with size %f",
                    msg->id.c_str(), msg->position_x, msg->position_y, msg->size);
    }
    rclcpp::Subscription<obstacle_msgs::msg::ObstacleMessage>::SharedPtr subscription_;
};

int main(int argc, char *argv[])
{
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ObstacleSubscriberNode>());
    rclcpp::shutdown();
    return 0;
}

在上述代码中,我们创建了一个名为 obstacle_subscriber 的节点,并订阅了 obstacle_topic 话题。每当收到消息时,该节点会打印出障碍物的信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盼海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值