ROS 2 C++(rclcpp)版本,实现话题订阅、话题发布,以及完整编译运行流程

1. 节点代码

保存为:~/ros2_ws/src/demo_pkg/src/demo_node.cpp

cpp 复制代码
#include <chrono>
#include <memory>

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

using namespace std::chrono_literals;

class DemoNode : public rclcpp::Node
{
public:
  DemoNode() : Node("demo_node")
  {
    // 发布者:向 chatter_out 发布 std_msgs/msg/String
    pub_ = this->create_publisher<std_msgs::msg::String>("chatter_out", 10);

    // 订阅者:订阅 chatter_in
    sub_ = this->create_subscription<std_msgs::msg::String>(
      "chatter_in", 10,
      [this](const std_msgs::msg::String::SharedPtr msg) {
        chatterCallback(msg);
      });

    // 定时器:每 1 秒发布一次心跳
    timer_ = this->create_wall_timer(
      1s, [this]() { timerCallback(); });

    RCLCPP_INFO(this->get_logger(),
                "DemoNode started: sub='chatter_in', pub='chatter_out'");
  }

private:
  void chatterCallback(const std_msgs::msg::String::SharedPtr msg)
  {
    RCLCPP_INFO(this->get_logger(), "I heard: [%s]", msg->data.c_str());

    auto out = std_msgs::msg::String();
    out.data = "echo: " + msg->data;
    pub_->publish(out);
  }

  void timerCallback()
  {
    auto out = std_msgs::msg::String();
    out.data = "heartbeat from demo_node";
    pub_->publish(out);

    RCLCPP_INFO(this->get_logger(), "Published heartbeat");
  }

  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_;
  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_;
  rclcpp::TimerBase::SharedPtr timer_;
};

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

2. 创建包

bash 复制代码
source /opt/ros/humble/setup.bash

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src

ros2 pkg create --build-type ament_cmake demo_pkg \
  --dependencies rclcpp std_msgs

然后把上面的代码写入:~/ros2_ws/src/demo_pkg/src/demo_node.cpp

3. 修改 CMakeLists.txt

文件:~/ros2_ws/src/demo_pkg/CMakeLists.txt

cpp 复制代码
cmake_minimum_required(VERSION 3.8)
project(demo_pkg)

if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 17)
  set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)

add_executable(demo_node src/demo_node.cpp)
ament_target_dependencies(demo_node rclcpp std_msgs)

install(TARGETS demo_node
  DESTINATION lib/${PROJECT_NAME}
)

ament_package()

4. 修改 /核对 package.xml

XML 复制代码
<buildtool_depend>ament_cmake</buildtool_depend>

<depend>rclcpp</depend>
<depend>std_msgs</depend>

<export>
  <build_type>ament_cmake</build_type>
</export>

如果使用 ros2 pkg create --dependencies rclcpp std_msgs,依赖通常已经自动加好,核对一下即可。

5. 编译

bash 复制代码
cd ~/ros2_ws
colcon build --packages-select demo_pkg
source install/setup.bash

6. 运行

ros2 run demo_pkg demo_node

7. 测试订阅和发布

另外打开一个终端,运行(测试订阅)

bash 复制代码
source ~/ros2_ws/install/setup.bash
ros2 topic echo /chatter_out

再开一个终端:

bash 复制代码
source ~/ros2_ws/install/setup.bash
ros2 topic pub --once /chatter_in std_msgs/msg/String "{data: 'hello'}"

预期结果:

  • demo_node 打印:I heard: [hello]

  • /chatter_out 收到:echo: hello

  • 同时每 1 秒还会收到一次:heartbeat from demo_node

相关推荐
星夜离尘566 小时前
MATLAB 工程实验:不等间隔流量积分,先把缺口与覆盖率说清楚
开发语言·matlab·时间戳·数据质量·数值积分
Ai-_Man7 小时前
Meta Muse还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·c#·1024程序员节
梓豪csd7 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
会编程的小孩7 小时前
C++ qt的安装
c++
学逆向的7 小时前
C 枚举变量
c语言·开发语言·网络安全
Sakura_j_h_7 小时前
Python 在定时任务里输出 emoji,UnicodeEncodeError 从哪来
开发语言·字符编码·windows·python·定时任务
企业数字化笔记9 小时前
视频人体姿态怎么做三维可视化?2D关键点、深度局限与技术选型
人工智能·算法·音视频
?abc!10 小时前
(数组)581. 最短无序连续子数组
数据结构·算法·leetcode
小成2023032026513 小时前
C++~07补充
开发语言·c++
小郎君65813 小时前
MPTT树复选框的半选状态:一棵百万节点树从递归到计数器,再到区间覆盖
算法