2. 使用rclcpp编写C++节点

任务目标

使用 rclcpp 编写一个 C++ ROS2 节点,该节点能够:

  • 正确初始化并优雅关闭(生命周期管理);
  • 以固定频率向 /chatter 话题发布字符串消息 "Hello ROS2 from C++"。

环境依赖

  • Ubuntu 22.04 + ROS2 Humble(或同等版本);
  • 已安装 ros-humble-rclcpp 与 ros-humble-std-msgs;
  • 已 source ROS2 环境:source /opt/ros/humble/setup.bash。

完整实现

创建文件 talker.cpp,内容如下:

#include <chrono>
#include <memory>
#include <string>

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

using namespace std::chrono_literals;

class Talker : public rclcpp::Node
{
public:
  Talker() : Node("cpp_talker")
  {
    publisher_ = this->create_publisher<std_msgs::msg::String>("chatter", 10);
    timer_ = this->create_wall_timer(
      500ms, std::bind(&Talker::timer_callback, this));
    RCLCPP_INFO(this->get_logger(), "节点已启动,开始发布消息");
  }

private:
  void timer_callback()
  {
    auto msg = std_msgs::msg::String();
    msg.data = "Hello ROS2 from C++";
    publisher_->publish(msg);
    RCLCPP_INFO(this->get_logger(), "发布: '%s'", msg.data.c_str());
  }

  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
  rclcpp::TimerBase::SharedPtr timer_;
};

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

编译与运行

在 CMakeLists.txt 中添加可执行目标(若使用 ament_cmake):

add_executable(talker src/talker.cpp)
ament_target_dependencies(talker rclcpp std_msgs)
install(TARGETS talker DESTINATION lib/${PROJECT_NAME})

编译并运行:

colcon build --packages-select your_package_name
source install/setup.bash
ros2 run your_package_name talker

验证方法

打开另一个终端,执行:

ros2 topic echo /chatter

通过条件:

  • talker 终端每 0.5 秒输出一条 发布: 'Hello ROS2 from C++' 日志;
  • echo 终端持续显示 data: Hello ROS2 from C++;
  • 按 Ctrl+C 终止 talker 时,进程正常退出且无内存错误提示。

生命周期说明

本节点采用最简生命周期模式:rclcpp::init() 初始化全局上下文,spin() 阻塞处理回调,shutdown() 在 spin 返回后清理资源。析构时智能指针自动释放发布器与定时器,无需手动干预。

rclcpp::init() 创建节点对象 spin() 回调循环 shutdown() Ctrl+C 触发中断 → spin 返回 → 自动清理资源