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

相关推荐
【心态好不摆烂】4 分钟前
数据结构基础精讲3
数据结构·算法
总要学点什么8 分钟前
第108篇:三维特效-图片轨迹线效果——把贴图滚成一串箭头,想用它的本色反而整条消失
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
漂流瓶jz1 小时前
UVA-1613 K度图的着色 题解答案代码 算法竞赛入门经典第二版
算法·深度优先·图论·贪心·aoapc·算法竞赛入门经典·uva
Pniubi2 小时前
动态规划入门 ( - 力扣509斐波那契数)
算法·动态规划
吴长建先生重名了3 小时前
GitHub Actions部署报表系统踩坑记:幂等性与限
算法
贝壳6903 小时前
一个2026年2月才上传的库,凭什么敢碰2009年就有人写烂的题目
算法
贝壳6904 小时前
同一道三亿位选型题,三个AI给了我三个答案,我把它们拉进同一台机器复跑
算法
starzy19905 小时前
深入理解Scala隐式值:编译期自动装配
开发语言·后端·scala
布莱克6055 小时前
Swift 条件语句详解:从 if 到 switch 的完整指南
开发语言·ssh·swift·switch·条件语句·guard·if
汉克老师5 小时前
《从C++小白到算法高手:GESP 1—8级成长地图》第一讲:认识GESP——从编程新手到算法探索者
c++·gesp·信息学竞赛·小学生学c++