快速体验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'
相关推荐
飘忽不定的bug1 天前
ubuntu22.04部署ROS2-humble
linux·ubuntu·ros2
zylyehuo1 天前
Ubuntu22.04 外接显示屏显示异常
ros2·夯实基础
滴啦嘟啦哒2 天前
【机械臂】【总览】基于VLA结构的指令驱动式机械臂
python·ros2·vla
kyle~2 天前
导航---Nav2导航框架概览
c++·机器人·ros2·导航
米有哥3 天前
[Embodied AI] Mac上安装ROS2
人工智能·macos·ros2
叠叠乐6 天前
ros2 找功能包的get_package_share_directory
ros2
漫漫求10 天前
ros2常用命令
ros2
奔跑的花短裤13 天前
ROS2安装
ros·ros2·ros1
敬往事一杯酒哈13 天前
1.3 Ros2快速体验
python·ros2