Nav2 and Autonomous NavigationJune 02, 20248 min read

How to Add Custom Libraries to a ROS 2 C++ Package

Learn to add custom libraries to your ROS 2 C++ packages. Enhance your robotics projects with reusable code and streamline your development process!

How to Add Custom Libraries to a ROS 2 C++ Package

Share :

Quick answer

Learn to add custom libraries to your ROS 2 C++ packages. Enhance your robotics projects with reusable code and streamline your development process!

Quick Answer

Learn to add custom libraries to your ROS 2 C++ packages. Enhance your robotics projects with reusable code and streamline your development process!

Who This Is For

  • ROS 2 Learner
  • Mobile Robotics Student
  • Robotics Career Shifter

What You Will Learn

Introduction

When developing projects in robotics, the need for additional features often arises, such as advanced motion planning or sensor fusion techniques. Implementing these functionalities from scratch can be time-consuming. In such cases, leveraging existing libraries that offer these features can significantly accelerate development. For example, in the domain of mobile robotics, utilizing libraries for path planning or simultaneous localization and mapping (SLAM) can greatly enhance the capabilities of autonomous robots. This article aims to clarify concepts around incorporating external libraries into ROS 2 C++ packages, facilitating faster development and expanding the capabilities of robotic applications.

Starting Point

No understanding of

  • ROS 2 C++ libraries and components
  • ROS 2 C++ Package Structure
  • Creating custom libraries

Learning outcomes

Easily able to

  • Creating Custom Modules into ROS 2 Packages
  • Install External Libraries to your ROS 2 Packages
  • Concept clearning of Python Package, Library and module

Understanding C++ Terminologies

You can find our very useful open source C++-based libraries, but to utilize them in your projects, you need to understand that C++ requires the step of getting compiled to run it. For that, we need to have a system like CmakeLists.txt to compile and produce an executable that we can run. Lets first understand difference between a library and simple code inclusion.

C++ Included Code

Including a C++ source file (#include "my_functions.cpp") directly into another fileis more like copying and pastingthe contents of that file. It's not a standard way to distribute reusable code and this is not a library.


// my_functions.cpp
#include <iostream>
void sayHello() {
 std::cout << "Hello, Robotisim!" << std::endl;
}
// main.cpp
#include "my_functions.cpp"
int main() {
 sayHello();
 return 0;
}

c++ programming

C++** Libraries**

A library is aprecompiled set of functions and codethat can be reused by other programs. It is typically distributed as a binary file (**libexample.a** for static libraries or **libexample.so** for dynamic/shared libraries) that can be linked to an executable. Lets understand through a popular example

  • Header only library but no compiled .a or .so file
  • In this example, **#include <iostream>**includes the iostream header file, which provides functionality for input and output operations
#include <iostream>
int main() {
 std::cout << "Hello, World!" << std::endl;
 return 0;
}

Creating Custom C++ Library

Lets look at an example of static library creation , to build our understanding about the process and get rid of copy pasting of source codes.

Header File

#ifndef BOT_MOVE_H
#define BOT_MOVE_H
enum DIR { FORWARD, BACKWARD};
bool botMove(DIR direction);
void botStop();
#endif

Source File

#include "bot_move.h"
bool botMove(Dir direction)
{std::cout << "Moving robot";
return true;}
void botStop() {
std::cout << "Stop";}

Compile Library

g++ -c bot_move.cpp
ar rcs libbot_move.a bot_move.o

Library Files Understanding

After compiling, you will obtain a static library file**libbot_move.a**that contains the compiled code for the botMove and botStop functions. This library can be linked to other programs that need to control a robot's movement.

Utilising our custom Library

Once these library files are created then you can utilize them or link them into your C++ ROS 2 Code

Main Code

#include "bot_move.h"
int main() {
 moveRobot(FORWARD); // Move the robot forward at speed 50
 stopRobot(); // Stop the robot
 return 0;
}

This code is inlcuding the header file but when we will compile we will mention that do not take definitions of header files from .cpp instead take from .a compile library

Linking Command

g++ main.cpp -L. -lbot_move -o robot_movement

Explanation

  • main.cpp is your main C++ file that uses the functions from the bot_move library.
  • **-L**. tells the compiler to look for libraries in the current directory.
  • **-lbot_move** specifies the name of the library to link**(libbot_move.a).**
  • **-o robot_movement** specifies the output executable name.

ROS 2 C++ Package Strucutre

When we create a python package using ROS 2 command, we have couple of things to understand

  • **ros2 pkg create** : This is the command used to create a new ROS 2 package.
  • **--build-type ament_cmake** : This option specifies the build system to use for the package. In this case, ament_cmake is selected.
  • **--node-name sensor_fusion_node** : This option specifies that a node named
  • **sensor_fusion_pkg** : This is the name of the package that will be created.
ros2 pkg create --build-type ament_cmake --node-name sensor_fusion_node sensor_fusion_pkg

When we execute this command, we see a package with a node automatically created with a fixed structure. This below structure is produced mainly for keeping standards fixed for compatibility between tools and ease of maintenance. Lets look at its structure and important files

Node

**sensor_fusion_pkg**/
|-- include/
| `-- sensor_fusion_pkg/
| `-- sensor_fusion_node.hpp
|-- src/
| |-- sensor_fusion_node.cpp
| `-- CMakeLists.txt
|-- CMakeLists.txt
|-- package.xml
`-- README.md

Node

#include <rclcpp>
#include libraries
class Node{
 publishers.create();
 subscriber.create();
}
void main (){
Node.spin();
}

CmakeLists.txt

include_directories(include)
add_executable(sensor_fusion_node src/sensor_fusion_node.cpp)
ament_target_dependencies(sensor_fusion_node rclcpp)

Including OpenCV and Eigen Library into ROS 2 C++ Package

Lets bring in some popular libraries to be included into our ROS 2 C++ node afterinstallation , just to understand the process.

sensor_fusion_node.cpp

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include <opencv2/core.hpp>
#include <Eigen/Dense>
class SensorFusion : public rclcpp::Node
{
public:
 SensorFusion()
 : Node("sensor_fusion_node")
 {
 // Use OpenCV
 cv::Mat image(100, 100, CV_8UC3, cv::Scalar(0, 255, 0));
 cv::imshow("Image", image);
 cv::waitKey(0);
 // Use Eigen
 Eigen::MatrixXd matrix(3, 3);
 matrix << 1, 2, 3, 4, 5, 6, 7, 8, 9;
 std::cout << "Eigen Matrix:\n" << matrix << std::endl;
 }
};
int main(int argc, char*argv [])
{
 rclcpp::init(argc, argv);
 auto node = std::make_shared<SensorFusion>();
 rclcpp::spin(node);
 rclcpp::shutdown();
 return 0;
}

CmakeList.txt

cmake_minimum_required(VERSION 3.5)
project(**sensor_fusion_pkg**)
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
 set(CMAKE_CXX_STANDARD 14)
endif()
# Find OpenCV package
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
# Find Eigen package
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
# Find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
# Create an executable
add_executable(SensorFusion_node src/SensorFusion.cpp)
# Link the OpenCV and Eigen libraries
target_link_libraries(SensorFusion_node ${OpenCV_LIBRARIES} ${EIGEN3_LIBRARIES})
ament_target_dependencies(my_node rclcpp std_msgs)
# Install the executable
install(TARGETS my_node
 DESTINATION lib/${PROJECT_NAME})
ament_package()

Utilising Custom Library in ROS 2 C++ Package

  • Includes necessary headers: rclcpp for ROS 2 functionality, std_msgs/msg/string.hpp for standard message types, and **bot_move**.h for your custom library.
  • Defines a class BotMove that inherits from rclcpp::Node, providing a constructor that initializes the node with the name "bot_move".
  • Inside the constructor, it calls a function (moveRobot()) from your custom library bot_move and logs the result using RCLCPP_INFO.

sensor_fusion_node.cpp

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
## #include "bot_move.h"
class BotMove : public rclcpp::Node
{
public:
 BotMove()
 : Node("bot_move")
 {
 int result = moveRobot();
 RCLCPP_INFO(this->get_logger(), "Result: %d", result);
 }
};
int main(int argc, char*argv [])
{
 rclcpp::init(argc, argv);
 auto node = std::make_shared<BotMove>();
 rclcpp::spin(node);
 rclcpp::shutdown();
 return 0;
}

CmakeLists

cmake_minimum_required(VERSION 3.5)
project(sensor_fusion_pkg)
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
include_directories(
 include
 ${CMAKE_CURRENT_SOURCE_DIR}/lib
)
# create an executable
add_executable(bot_move_node src/bot_move.cpp)
# link your custom library
target_link_libraries(bot_move_node ${CMAKE_CURRENT_SOURCE_DIR}/lib/libmove_bot.a)
ament_target_dependencies(sensor_fusion_node rclcpp)
# install the executable
install(TARGETS bot_move_node
 DESTINATION lib/${PROJECT_NAME})
ament_package()
  • Includes directories for the headers of your custom library (${CMAKE_CURRENT_SOURCE_DIR}/lib).
  • Creates an executable named BotMove from bot_move.cpp and links it with your custom library (target_link_libraries).
  • Specifies the dependencies (ament_target_dependencies).

FAQ

Q: What is the standard structure of a ROS 2 C++ package?

A: A standard ROS 2 C++ package structure includes directories for include files, source files, a CMakeLists.txt file, a package.xml file, and other necessary files for building and running the package.

Q: How do you create a ROS 2 C++ package?

A: You can create a ROS 2 C++ package using the command:

bashCopy coderos2 pkg create --build-type ament_cmake --node-name sensor_fusion_node sensor_fusion_pkg

Q: How do you include OpenCV and Eigen libraries in a ROS 2 C++ package?

A: To include OpenCV and Eigen libraries, you need to find these packages and include their directories in your CMakeLists.txt file:

cmakeCopy codefind_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})

Q: How do you use a custom library in a ROS 2 C++ package?

A: You include the header of your custom library in your node's source file and link the compiled library in your CMakeLists.txt file. For example, include the header in your .cpp file:

#include "bot_move.h"

And link the library in CMakeLists.txt:

cmakeCopy codetarget_link_libraries(bot_move_node ${CMAKE_CURRENT_SOURCE_DIR}/lib/libmove_bot.a)

Q: Why is EIGEN3 not included in the target_link_libraries?

A: Eigen is a header-only library, which means its functionality is included directly through headers, and there are no compiled binaries to link against.

A: The naming conventions for linking libraries in CMakeLists.txt can differ based on how the CMake configuration files for those libraries are set up. OpenCV_LIBS and Boost_LIBRARIES are the variables defined in their respective CMake configurations to hold the library linking information.

Lets take a 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

  • Robot Localization Guide: Indoor Pose Estimation with Encoder Odometry
  • Robot Starter Kit Guide: Choose the Right Beginner Robot Parts
  • ROS 2 SLAM Beginner Guide: Help Your Robot Draw Its First Floorplan
  • From STL to Autonomy: Building an Indoor Self-Driving Robot
  • ROS 2 Dataset Guide: Foxglove, RViz, and TurtleBot3 SLAM

Learn Next

  • Robot Localization Guide: Indoor Pose Estimation with Encoder Odometry
  • Robot Starter Kit Guide: Choose the Right Beginner Robot Parts
  • ROS 2 SLAM Beginner Guide: Help Your Robot Draw Its First Floorplan
  • From STL to Autonomy: Building an Indoor Self-Driving Robot
  • ROS 2 Dataset Guide: Foxglove, RViz, and TurtleBot3 SLAM
  • Mobile Robotics Engineer Path

FAQ

Is How to Add Custom Libraries to a ROS 2 C++ Package 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 Add Custom Libraries to a ROS 2 C++ Package is part of the broader Nav2 and Autonomous Navigation 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 Mobile Robotics Engineer Path, especially Nav2.

Learn with Robotisim

Build a complete Nav2 robot inside Robotisim.

Explore the academy

Learn next

Robot Localization Guide: Indoor Pose Estimation with Encoder Odometry
Oct 07, 2025|6 min read

Robot Localization Guide: Indoor Pose Estimation with Encoder Odometry

Understand robot localization using encoder odometry in C++. Learn how robots estimate pose indoors with equations, examples, and real world insights.

Read more
Robot Starter Kit Guide: Choose the Right Beginner Robot Parts
Jul 29, 2025|9 min read

Robot Starter Kit Guide: Choose the Right Beginner Robot Parts

Avoid overspending on the wrong parts. This guide walks you through building your first robot with a smart, affordable robot starter kit and key upgrade paths.

Read more
ROS 2 SLAM Beginner Guide: Help Your Robot Draw Its First Floorplan
Jun 07, 2025|8 min read

ROS 2 SLAM Beginner Guide: Help Your Robot Draw Its First Floorplan

Learn how to set up ROS 2 SLAM and map your robot's environment. A beginner friendly guide to launching SLAM with LiDAR, odometry, and ROS 2 navigation stack.

Read more
From STL to Autonomy: Building an Indoor Self-Driving Robot
Jun 13, 2025|7 min read

From STL to Autonomy: Building an Indoor Self-Driving Robot

Learn how to build a ROS 2 autonomous robot from 3D printed STL parts to indoor navigation. A complete DIY guide for robotics and ROS 2 beginners.

Read more