About ROS 2 client libraries
Table of Contents
Client libraries are the APIs that allow users to implement their ROS code. Using client libraries, users gain access to ROS concepts such as nodes, topics, services, etc. Client libraries come in a variety of programming languages so that users may write ROS code in the language that is best-suited for their application. For example, you might prefer to write visualization tools in Python because it makes prototyping iterations faster, while for parts of your system that are concerned with efficiency, the nodes might be better implemented in C++.
Nodes written using different client libraries are able to share messages with each other because all client libraries implement code generators that provide users with the capability to interact with ROS interface files in the respective language.
In addition to the language-specific communication tools, client libraries expose to users the core functionality that makes ROS “ROS”. For example, here is a list of functionality that can typically be accessed through a client library:
Names and namespaces
Time (real or simulated)
The C++ client library (
rclcpp) and the Python client library (
rclpy) are both client libraries which utilize common functionality in the RCL.
The ROS Client Library for C++ (
rclcpp) is the user facing, C++ idiomatic interface which provides all of the ROS client functionality like creating nodes, publisher, and subscribers.
rclcpp builds on top of
rcl and the
rosidl API, and it is designed to be used with the C++ messages generated by
rclcpp makes use of all the features of C++ and C++17 to make the interface as easy to use as possible, but since it reuses the implementation in
rcl it is able maintain a consistent behavior with the other client libraries that use the
The ROS Client Library for Python (
rclpy) is the Python counterpart to the C++ client library.
Like the C++ client library,
rclpy also builds on top of the
rcl C API for its implementation.
The interface provides an idiomatic Python experience which uses native Python types and patterns like lists and context objects, but by using the
rcl API in the implementation it stays consistent with the other client libraries in terms of feature parity and behavior.
In addition to providing Python idiomatic bindings around the
rcl API and Python classes for each message, the Python client library takes care of the execution model, using
threading.Thread or similar to run the functions in the
Like C++ it generates custom Python code for each ROS message that the user interacts with, but unlike C++ it eventually converts the native Python message object into the C version of the message.
All operations happen on the Python version of the messages until they need to be passed into the
rcl layer, at which point they are converted into the plain C version of the message so it can be passed into the
rcl C API.
This is avoided if possible when communicating between publishers and subscribers in the same process to cut down on the conversion into and out of Python.
While the C++ and Python client libraries are maintained by the core ROS 2 team, members of the ROS 2 community maintain additional client libraries:
Ada Ada binding and tools for ROS 2 - workspace overlay.
JVM and Android Java and Android bindings for ROS 2.
_.NET Core, UWP and C# This is a collection of projects (bindings, code generator, examples and more) for writing ROS 2 applications for .NET Core and .NET Standard.
Rust This is a set of projects (the rclrs client library, code generator, examples and more) that enables developers to write ROS 2 applications in Rust.
Older, unmaintained client libraries are:
Most of the functionality found in a client library is not specific to the programming language of the client library. For example, the behavior of parameters and the logic of namespaces should ideally be the same across all programming languages. Because of this, rather than implementing the common functionality from scratch, client libraries make use of a common core ROS Client Library (RCL) interface that implements logic and behavior of ROS concepts that is not language-specific. As a result, client libraries only need to wrap the common functionality in the RCL with foreign function interfaces. This keeps client libraries thinner and easier to develop. For this reason the common RCL functionality is exposed with C interfaces as the C language is typically the easiest language for client libraries to wrap.
In addition to making the client libraries light-weight, an advantage of having the common core is that the behavior between languages is more consistent. If any changes are made to the logic/behavior of the functionality in the core RCL – namespaces, for example – all client libraries that use the RCL will have these changes reflected. Furthermore, having the common core means that maintaining multiple client libraries becomes less work when it comes to bug fixes.
Client library concepts that require language-specific features/properties are not implemented in the RCL but instead are implemented in each client library. For example, threading models used by “spin” functions will have implementations that are specific to the language of the client library.
In ROS 1, all client libraries are developed “from the ground up”. This allows for the ROS 1 Python client library to be implemented purely in Python, for example, which brings benefits of such as not needing to compile code. However, naming conventions and behaviors are not always consistent between client libraries, bug fixes have to be done in multiple places, and there is a lot of functionality that has only ever been implemented in one client library (e.g. UDPROS).