ROS 2 LearningMay 12, 20246 min read

How to Write a C++ ROS 2 Node: A Beginner-Friendly Guide

Learn to create your first ROS 2 C++ node with our beginner friendly guide. Start your robotics journey and enhance your programming skills effectively!

How to Write a C++ ROS 2 Node: A Beginner-Friendly Guide

Share :

Quick answer

Learn to create your first ROS 2 C++ node with our beginner friendly guide. Start your robotics journey and enhance your programming skills effectively!

Quick Answer

Learn to create your first ROS 2 C++ node with our beginner friendly guide. Start your robotics journey and enhance your programming skills effectively!

Who This Is For

  • ROS 2 Learner
  • Robotics Student
  • Software Developer

What You Will Learn

Introduction

Robot Operating System 2 (ROS 2) represents a significant shift in the design and approach to robotic middleware. It's tailored for modern robotics applications, offering

  • improved security
  • Reliability
  • Scalability But this enhancement brought complexity to its structure for starters and introduced a steep learning curve. The key things you need are C++ basic syntax understanding.

Starting Point

No understanding of

  • ROS 2 C++ Node Structure
  • how to select a message type
  • Customise ROS 2 Node template

Learning outcomes

Easily able to

  • Publish data on different messages
  • Control Publishing messages speed
  • Single-Node Publishing and Subscribing

ROS 2 C++ Node High Level Strucutre

  1. Importing Libraries
#include <libraries>
#include <ros2msg_hpp>
  1. Minimal Publisher Class
class{ public :
publisher = (msgtype ,topic)
timer =
 run callback function
 every X ms (frequency)
 to publish data
 }
  1. Call-back function for Publishing
private:
void callback(){
 msg object create
 msg_data fill
 publish(msg)
  1. Main Function Call
int main(){
rclcpp spin (class)
}

c++ programming


Compiling and Running a ROS 2 node

I would recommend you get the publisher code and build it according to the wiki. It works in following order:

  1. Writing a C++ Node
#include <rclcpp>
int main(){
node=create.publisher()
publisher.publish(data)
}
  1. To compile, we add it into our package, CmakeLists.txt
find_pkg(rclcpp)
add_exe(node src/node.cpp)
  1. We link required libraries with the compiled executable and build
target_dependencies(node rclcpp)
colcon build
  1. We run using ros2 run command
ros2 run your_package_name node

ROS 2 C++ Publisher Node Understanding

Code Snippet requires an understanding of C++ concepts, but for utilising a basic template for your purpose, you need to just understand four points.

Defining a Message type for Communication

ROS 2 has a lot of buld in message that you can utilize , although you can create your own as well , below we will be using a sensor essage type for IMU data. Finding ROS 2 Message types

ros2 interface show <name>*( example : ros2 interface show sensor_msgs/msg/Imu )*

For adding message to C++ source file

find /opt/ros/<ros2-distro>/include -name "imu.hpp"*(example distro = humble )*

Including message headers in Nodes

For astring****data Message

#include "std_msgs/msg/string.hpp"

For Integer****data message

#include "std_msgs/msg/int32.hpp"

For IMU sensor data message

#include "sensor_msgs/msg/imu.hpp"

Defining Publisher Topic

## For a** string** message
 publisher_ = this->create_publisher**<std_msgs::msg::String>**("string_topic", 10);
 rclcpp::Publisher**<std_msgs::msg::String>**::SharedPtr publisher_;
## For a** int32** message
 publisher_ = this->create_publisher**<std_msgs::msg::Int32>**("int_topic", 10);
 rclcpp::Publisher**<std_msgs::msg::Int32>**::SharedPtr publisher_;
## For a** imu sensor** message
 publisher_ = this->create_publisher**<sensor_msgs::msg::Imu>**("imu_topic", 10);
 rclcpp::Publisher**<sensor_msgs::msg::Imu>**::SharedPtr publisher_;

Sending Data

Int32 Data

auto message = std_msgs::msg::Int32();
message.data = count_++;
publisher_->publish(message);

String Data

auto message = std_msgs::msg::String();
message.data = "Hi Robotisim";
publisher_->publish(message);

Imu Sensor data ( this is not general data like above; it is designed for real imu sensor data carriage )

auto message = sensor_msgs::msg::Imu();
message.header.stamp = this->get_clock()->now();
message.angular_velocity.x = 0.0;
message.angular_velocity.y = 0.0;
message.angular_velocity.z = 1.0;
message.linear_acceleration.x = 0.2;
message.linear_acceleration.y = 0.3;
message.linear_acceleration.z = 0.4;
publisher_->publish(message);

ROS 2 C++ Subscriber Node Understanding

Defining a Message type for Communication

This is important step for communication , message type should exactly be same as on publishing side. For a string data type

subscription_ = this->create_subscription
- **<std_msgs::msg::Int32>** ("
- **int_topic** ", 10, std::bind(&MinimalSubscriber::
- **topic_callback** , this,_1)); }
  1. We have here data type as**<std_msgs::msg::Int32>**
  2. topic name isstring_topic
  3. callback function on each message received istopic_callback
  4. We have here data type as**<sensor_msgs::msg::Imu>**
  5. topic name isimu_topic
  6. callback function on each message received istopic_callback For Imu data
subscription_ = this->create_subscription
- **<sensor_msgs::msg::Imu>** ( "
- **imu_topic** ", 10, std::bind(&IMUSubscriber::
- **topic_callback** , this, std::placeholders::_1)); }

Processing Received Data

This message type only contains a single entry For Int32

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

For Imu data

void topic_callback(const sensor_msgs::msg::Imu::SharedPtr msg)
 {
 RCLCPP_INFO(this->get_logger(), "Received IMU data: Angular velocity Z:
 '%f'", msg->angular_velocity.z);
 }

There are other fields that you can find through ros2 interface command


Single-Node Publishing and Subscribing

There are many cases where we have to subscribe a data as well as publish data within a single node. For that scenario, we apply our programming concepts to ROS 2 C++ node.Below is the code that shows the implementation of the concept.you will observe that the additions are in public initialization and private functions We recommend you apply the four-step ROS 2 C++ node structure explained initially to the below-listed node.

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/int32.hpp"
#include "sensor_msgs/msg/imu.hpp"
using namespace std::chrono_literals;
class IntAndIMUPublisherSubscriber : public rclcpp::Node
{
public:
 IntAndIMUPublisherSubscriber()
 : Node("int_and_imu_publisher_subscriber"), count_(0)
 {
 int_publisher_ = this->create_publisher<std_msgs::msg::Int32>("int_topic", 10);
 imu_subscription_ = this->create_subscription<sensor_msgs::msg::Imu>(
 "imu_topic", 10, std::bind(&IntAndIMUPublisherSubscriber::imu_callback, this, std::placeholders::_1));
 // Timer to periodically publish Int32 data
 timer_ = this->create_wall_timer(
 1000ms, std::bind(&IntAndIMUPublisherSubscriber::timer_callback, this));
 }
private:
 void timer_callback()
 {
 auto message = std_msgs::msg::Int32();
 message.data = count_++;
 RCLCPP_INFO(this->get_logger(), "Publishing: %d", message.data);
 int_publisher_->publish(message);
 }
 void imu_callback(const sensor_msgs::msg::Imu::SharedPtr msg)
 {
 RCLCPP_INFO(this->get_logger(), "Received IMU data: Angular velocity Z: '%f'", msg->angular_velocity.z);
 }
 rclcpp::TimerBase::SharedPtr timer_;
 rclcpp::Publisher<std_msgs::msg::Int32>::SharedPtr int_publisher_;
 rclcpp::Subscription<sensor_msgs::msg::Imu>::SharedPtr imu_subscription_;
 int count_;
};
int main(int argc, char*argv [])
{
 rclcpp::init(argc, argv);
 auto node = std::make_shared<IntAndIMUPublisherSubscriber>();
 rclcpp::spin(node);
 rclcpp::shutdown();
 return 0;
}

Video Demonstration on ROS 2 C++ Nodes

https://www.youtube.com/watch?v=cjckvOHo8B4&t=182s


FAQs for ROS 2 C++ Nodes

  • If we have Python-based code as well, then why should we go with C++?
  • Choosing C++ over Python for ROS 2 development depends on several factors, including performance requirements, real-time capabilities, and system complexity. C++ offers more control over system resources and execution speed, which is critical in many robotics applications that require real-time performance. While Python might be easier to use and faster for development, C++ provides better efficiency and is more suitable for lower-level system interactions.
  • How do I determine when to use a publisher or a subscriber in ROS 2? - The decision to use a publisher or a subscriber in ROS 2 depends on the role your node needs to play in the communication ecosystem. Use a publisher when your node needs to send information, such as sensor data or status updates. Use a subscriber when your node needs to receive and react to information from other nodes, such as commands or sensor data from different parts of the system.
  • Can ROS 2 nodes written in C++ interact with nodes written in Python? - Yes, ROS 2 nodes written in C++ can interact seamlessly with nodes written in Python. By utilising a middleware to manage node-to-node communication, ROS 2 offers an abstraction layer on top of the programming language. This implies that no extra configuration is needed for a Python node to subscribe to messages from a C++ node and vice versa.

ROS 2 C++ Quiz

Practical Example

A practical way to use this article is to connect the concept to a small robot workflow: identify the input, the processing step, and the output you expect from the robot. If the article involves ROS 2, test the idea in a small workspace or simulation before applying it to a larger robot project.

Common Mistakes

  • Trying to memorize the term without connecting it to a robot behavior.
  • Skipping the prerequisite concepts that make the workflow easier to debug.
  • Copying commands or code without checking what each node, topic, file, or parameter is responsible for.
  • Treating one tutorial as a complete roadmap instead of linking it to the next concept.

How This Connects to Other Topics

  • 3D Printing Robotics Hardware for an Autonomous Robot Build
  • How to Collect Raw Sensor Data for Robotics with ROS 2
  • How to Add Custom Libraries to a ROS 2 Python Package
  • How to Start Developing in ROS 2: A Beginner-Friendly Guide
  • How to Finish Your First ROS Robotics Project

Learn Next

  • 3D Printing Robotics Hardware for an Autonomous Robot Build
  • How to Collect Raw Sensor Data for Robotics with ROS 2
  • How to Add Custom Libraries to a ROS 2 Python Package
  • How to Start Developing in ROS 2: A Beginner-Friendly Guide
  • How to Finish Your First ROS Robotics Project
  • ROS 2 Foundation Path

FAQ

Is How to Write a C++ ROS 2 Node: A Beginner-Friendly Guide suitable for beginners?

Yes. The article is written to make the concept easier to understand, while still connecting it to practical robotics work.

What should I learn before this topic?

Start with the prerequisite ideas listed in the article, then connect them to a small project or simulation so the concept becomes concrete.

How does this topic connect to real robots?

It helps you understand how software, sensors, control, simulation, or career decisions show up in practical robot development.

What should I do after reading this article?

Pick one related concept from the Learn Next section and build a small example that uses it.

Can I learn this through Robotisim?

Yes. Robotisim connects these concepts to structured learning paths and project-based robotics practice.

Final Summary

How to Write a C++ ROS 2 Node: A Beginner-Friendly Guide is part of the broader ROS 2 Learning learning path. The key is to understand the concept, connect it to a real robot workflow, and then practice it through a focused project instead of learning it in isolation.

Connected learning path

This article supports ROS 2 Foundation Path, especially ROS 2.

Learn with Robotisim

Start learning ROS 2 step by step inside Robotisim.

Explore the academy

Learn next

3D Printing Robotics Hardware for an Autonomous Robot Build
Jun 03, 2025|7 min read

3D Printing Robotics Hardware for an Autonomous Robot Build

Discover how to 3D print robotics hardware for building autonomous robots. Learn key steps from assembly to motion control with ROS 2

Read more
How to Collect Raw Sensor Data for Robotics with ROS 2
Jun 05, 2025|7 min read

How to Collect Raw Sensor Data for Robotics with ROS 2

Learn to integrate sensors with ROS 2 and collect raw sensor data for robotics. Guide on real time data processing and sensor fusion for autonomous robots.

Read more
How to Add Custom Libraries to a ROS 2 Python Package
Jun 02, 2024|6 min read

How to Add Custom Libraries to a ROS 2 Python Package

Learn to create custom libraries for ROS 2 Python packages. Enhance your robotics projects with reusable code and improve your development workflow!

Read more
How to Start Developing in ROS 2: A Beginner-Friendly Guide
Jun 02, 2024|8 min read

How to Start Developing in ROS 2: A Beginner-Friendly Guide

Begin your ROS 2 development journey with our guide. Learn key concepts and setup for creating effective robotics applications in no time!

Read more