How to create a simple Subscriber Node with C++ – ROS2

In this tutorial, we’ll create a simple ROS 2 node in C++ that subscribes to a topic and listens for messages published on it. If you haven’t checked out the simple publisher tutorial, I recommend starting there first.

🔍  What is a ROS Node and a Topic?

In ROS (Robot Operating System), software is organized into small, independent processes called nodes.
Nodes communicate by publishing and subscribing to topics — named channels that carry specific types of data.

For example:

  • A camera node might publish images on /camera/image_raw

  • A motor controller might subscribe to /cmd_vel to receive movement commands.

Nodes and topics decouple your software, so different parts of your robot can evolve independently and work together via message passing.

📦 Prerequisite: A ROS Workspace

If you haven’t created a ROS2 workspace yet, follow this clear tutorial first:
How to Create a ROS2 Workspace

Once your workspace is ready and sourced, continue from here.

📦 Create a New Package

If you haven’t already, create a new ROS 2 package:

				
					ros2 pkg create --build-type ament_cmake cpp_simple_subscriber --dependencies rclcpp std_msgs

				
			

This will generate a new package with the necessary CMakeLists.txt and package.xml files.

📄 Write the Publisher Node

Let’s create a new C++ file inside src/:

				
					cd ~/ros2_cpp_ws/src/tutorial_publisher/src
touch simple_subscriber.cpp

				
			

Open it in your text editor, and paste the following code:

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

using std::placeholders::_1;

class SimpleSubscriber : public rclcpp::Node
{
public:
  SimpleSubscriber() : Node("simple_subscriber")
  {
    subscription_ = this->create_subscription<std_msgs::msg::String>(
      "topic", 10, std::bind(&SimpleSubscriber::topic_callback, this, _1));
  }

private:
  void topic_callback(const std_msgs::msg::String::SharedPtr msg) const
  {
    RCLCPP_INFO(this->get_logger(), "I heard: '%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<SimpleSubscriber>());
  rclcpp::shutdown();
  return 0;
}

				
			

🔍 Code Explained Step by Step

Let’s carefully go through this code line by line.

Include Required Headers

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

				
			

We bring in ROS 2 C++ APIs, the standard string message type, and chrono utilities for timing.

Create a Node Class

				
					class SimpleSubscriber : public rclcpp::Node

				
			

We define a class SimpleSubscriber that inherits from rclcpp::Node.

Define the Subscription

				
					subscription_ = this->create_subscription<std_msgs::msg::String>(
  "topic", 10, std::bind(&SimpleSubscriber::topic_callback, this, _1));

				
			

Inside the constructor, we create a subscription to a topic named "topic".

  • The queue size is set to 10.

  • std::bind is used to associate the topic_callback method with the subscription’s callback.

Implement the Callback

				
					void topic_callback(const std_msgs::msg::String::SharedPtr msg) const
{
  RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str());
}

				
			

This function will be called each time a message is received on the subscribed topic. It simply logs the message content.

Main Function

				
					rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<SimpleSubscriber>());
rclcpp::shutdown();

				
			

The main function initializes ROS 2, spins the node (which keeps it alive to listen for messages), and then shuts down cleanly when done.

🏗️ Update CMakeLists.txt

Open CMakeLists.txt and add the subscriber source file:

Add executable and link libraries:

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

				
			

This tells CMake how to build your program and link it with ROS libraries.

🛠️ Build the Package

From your workspace root:

				
					cd ~/ros2_cpp_ws
colcon build --packages-select cpp_simple_subscriber
source install/setup.bash

				
			

🚀 Run the Publisher

In a new terminal:

				
					source install/setup.bash
ros2 run tutorial_publisher simple_cpp_publisher

				
			

📡 Monitor the Topic

In another terminal (after sourcing the workspace), run the ROS 2 CLI to publish a test message:

 
				
					ros2 topic pub /topic std_msgs/msg/String "{data: 'Hello from ROS 2!'}"

				
			

You should see the subscriber log the received message.

Want to learn more?

You can find a detailed explaination of the workspace in the "Robotics and ROS 2 - Learn by Doing! Manipulators" course
DISCOUNT
en_US