快速体验ros2之发布者-订阅者模式

一、参考资料

编写一个简单的发布者和订阅者(C++) --- ROS 2 Documentation: Humble 文档

SLAM之ROS通信:发布者与话题(C++)(三) - 知乎

SLAM之ROS通信:订阅者与回调函数(C++)(四) - 知乎

二、发布者-订阅者模式

1. 创建ros2_ws工作空间

bash 复制代码
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src

2. 创建功能包

bash 复制代码
ros2 pkg create --build-type ament_cmake cpp_pubsub

输出示例

bash 复制代码
forlinx@okrk3588:/mnt/ros2_ws/src$ ros2 pkg create --build-type ament_cmake cpp_pubsub
going to create a new package
package name: cpp_pubsub
destination directory: /mnt/ros2_ws/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['forlinx <forlinx@todo.todo>']
licenses: ['TODO: License declaration']
build type: ament_cmake
dependencies: []
creating folder ./cpp_pubsub
creating ./cpp_pubsub/package.xml
creating source and include folder
creating folder ./cpp_pubsub/src
creating folder ./cpp_pubsub/include/cpp_pubsub
creating ./cpp_pubsub/CMakeLists.txt

[WARNING]: Unknown license 'TODO: License declaration'.  This has been set in the package.xml, but no LICENSE file has been created.
It is recommended to use one of the ament license identifiers:
Apache-2.0
BSL-1.0
BSD-2.0
BSD-2-Clause
BSD-3-Clause
GPL-3.0-only
LGPL-3.0-only
MIT
MIT-0

功能包创建成功后,构建信息会收集在两个文件中:package.xmlCMakeLists.txt,它们必须位于同一目录中。

功能包构建完成的目录结构:

bash 复制代码
.
├── build
├── install
├── log
└── src

3. 发布者

bash 复制代码
#include <memory>
#include <string>
#include <functional>
#include <chrono>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std::chrono_literals;

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(
            std::chrono::milliseconds(500), 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;
}

4. 订阅者

bash 复制代码
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

class MinimalSubscriber : public rclcpp::Node
{
public:
    MinimalSubscriber()
    : Node("minimal_subscriber")
    {
        subscription_ = this->create_subscription<std_msgs::msg::String>(
            "topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, std::placeholders::_1)
        );
    }

private:
    void topic_callback(const std_msgs::msg::String &msg) const
    {
        RCLCPP_INFO(this->get_logger(), "I head: '%s'", msg.data.c_str());
    }
    rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};

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

5. 修改 package.xml

xml 复制代码
  <build_depend>rclcpp</build_depend>
  <build_depend>std_msgs</build_depend>

  <exec_depend>rclcpp</exec_depend>
  <exec_depend>std_msgs</exec_depend>

6. 修改 CMakeLists.txt

CMakeLists.txt 中添加以下内容:

cmake 复制代码
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)

add_executable(talker src/publisher_member_function.cpp)
ament_target_dependencies(talker rclcpp std_msgs)

add_executable(listener src/subscriber_member_function.cpp)
ament_target_dependencies(listener rclcpp std_msgs)

install(TARGETS
  talker
  listener
  DESTINATION lib/${PROJECT_NAME}
)

7. 构建功能包

在构建之前,最好在工作空间的根目录ros2_ws 中运行 rosdep 检查是否缺少依赖项:

bash 复制代码
rosdep install -i --from-path src --rosdistro jazzy -y

构建功能包:

bash 复制代码
colcon build --packages-select cpp_pubsub

设置环境变量:

bash 复制代码
source install/setup.bash

发布sub订阅者节点:

bash 复制代码
ros2 run cpp_pubsub listener

启动pub发布者节点:

bash 复制代码
ros2 run cpp_pubsub talker

sub订阅者输出示例:

bash 复制代码
forlinx@okrk3588:/mnt/ros2_ws$ ros2 run cpp_pubsub listener
[INFO] [1765851862.727183300] [minimal_subscriber]: I head: 'Hello, world! 0'
[INFO] [1765851863.226124301] [minimal_subscriber]: I head: 'Hello, world! 1'
[INFO] [1765851863.726138208] [minimal_subscriber]: I head: 'Hello, world! 2'
[INFO] [1765851864.226031365] [minimal_subscriber]: I head: 'Hello, world! 3'
[INFO] [1765851864.726637431] [minimal_subscriber]: I head: 'Hello, world! 4'
[INFO] [1765851865.227187706] [minimal_subscriber]: I head: 'Hello, world! 5'
[INFO] [1765851865.726502618] [minimal_subscriber]: I head: 'Hello, world! 6'
[INFO] [1765851866.230778562] [minimal_subscriber]: I head: 'Hello, world! 7'
[INFO] [1765851866.727568708] [minimal_subscriber]: I head: 'Hello, world! 8'
[INFO] [1765851867.226840453] [minimal_subscriber]: I head: 'Hello, world! 9'

pub发布者输出示例:

bash 复制代码
forlinx@okrk3588:/mnt/ros2_ws$ ros2 run cpp_pubsub talker
[INFO] [1765851862.725834064] [minimal_publisher]: Publishing: 'Hello, world! 0'
[INFO] [1765851863.225641306] [minimal_publisher]: Publishing: 'Hello, world! 1'
[INFO] [1765851863.725631588] [minimal_publisher]: Publishing: 'Hello, world! 2'
[INFO] [1765851864.225584245] [minimal_publisher]: Publishing: 'Hello, world! 3'
[INFO] [1765851864.725695524] [minimal_publisher]: Publishing: 'Hello, world! 4'
[INFO] [1765851865.225820679] [minimal_publisher]: Publishing: 'Hello, world! 5'
[INFO] [1765851865.725987540] [minimal_publisher]: Publishing: 'Hello, world! 6'
[INFO] [1765851866.225913029] [minimal_publisher]: Publishing: 'Hello, world! 7'
[INFO] [1765851866.725899517] [minimal_publisher]: Publishing: 'Hello, world! 8'
[INFO] [1765851867.225956129] [minimal_publisher]: Publishing: 'Hello, world! 9'
相关推荐
某林21213 小时前
履带小车底盘stm32F103RCT6开发
人工智能·stm32·单片机·嵌入式硬件·架构·人机交互·ros2
qq_419203234 天前
[ROS2 学习指南4] --- 手写一个 TF2 监听器(python版)
ros2·监听器
CS_Zero5 天前
Gazebo仿真无人机接入物理遥控控制
无人机·飞控·ros2
zylyehuo5 天前
Ranger Mini V3 底盘运动性能测试与录包步骤
car·ros2
某林2125 天前
大模型边缘部署到底层硬件闭环
python·架构·机器人·硬件架构·ros2
某林2127 天前
构建高精度 6-DoF 灵巧手控制系统
人工智能·3d·机器人·ros2·技术复盘
zh路西法8 天前
【10天速通Navigation2】(九):LQR最优控制器的原理推导与Nav2插件实现
c++·ros2·最优控制·lqr·navigation2
视图猿人9 天前
ROS2 DDS 基础配置速查表及高级参数调优总结
ros2
视图猿人9 天前
ROS2中配置高带宽图像传输零拷贝文件
ros2
再遇当年11 天前
Ubuntu 22.04 + ROS 2 Humble 项目通过 TRAE 改成 Ubuntu 202.04 + ROS 1 Noetic 项目的SKLL技能
linux·运维·ubuntu·ros2·ros1·skll·sill