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

相关推荐
无名猿1 小时前
shared_mutex 读写锁该不该用,以及 volatile 的三大误解
c++·性能优化·并发编程·现代c++
сокол1 小时前
【Python-基础-环境搭建】Ubuntu Python 开发环境搭建:编译、pipenv、pyenv、远程连接
开发语言·python·ubuntu
大侠归来3 小时前
C 语言 | 在函数中操作数组
c语言·c++·算法
liangshanbo12153 小时前
JavaScript 面试题:Object.keys() 的返回顺序是无序的吗?
开发语言·javascript·ecmascript
怕浪猫8 小时前
GEO 优化到底是什么?AI时代内容创作者必须懂的新技能
算法·面试·github
朝朝辞暮i9 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
Evand J9 小时前
【MATLAB例程】三维RRT+APF避障路径规划与到达角(AOA)定位算法|三维路径优化与定位仿真例程
算法·matlab·路径规划·代码·定位·rrt·aoa
小师兄吃牛肉10 小时前
C语言篇:宏
c语言·开发语言
郑同学的笔记10 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++