What’s Middleware
Middleware abstracts the complexity of managing communication, serialization, discovery, and other low-level functionalities, allowing developers to focus on application-level logic.
-
ROS1’s middleware is TCPROS: it’s a custom serialization format, a custom transport protocol as well as a custom central discovery mechanism
-
ROS2 uses an existing middleware interface, DDS. There are multiple DDS implementations. ROS has a unified interface for these implementations
- In DDS, each ROS 2 node is equivalent to a DDS “participant”. There could be multiple ROS nodes in the same process. Each node is still a DDS participant
- Under the hood, there are DDS datareader, datawriter, and DDS topics. They are not exposed to ROS users
1
2
3
4
5
6
7
8
9
10
11
+-----------------------------------------------+
| user land | No middleware implementation specific code
+-----------------------------------------------+
| ROS client library |
+-----------------------------------------------+
| middleware interface | No DDS specifics
+-----------------------------------------------+
| DDS adapter 1 | DDS adapter 2 | DDS adapter 3 |
+---------------+---------------+---------------+
| RTI DDS impl 1 | PrimsTech DDS impl | DDS impl 3 |
+---------------+---------------+---------------+
Why DDS (Summary)
When trying to develop ROS 2 communication systems, Open Robotics faced two choices: 1. improving on the existing ROS1 infrastructure 2. Use ZeroMQ, Protocol Buffers, and Zeroconf (see below). Both choices need a middleware.
Some Salient Features of DDS:
- The default implementation of DDS is over UDP, and only requires that level of functionality from the transport.
- Because it’s based on UDP, Quality of Service (QoS) needs to be introduced (unlike TCP)
- for soft real-time, you can basically tune DDS to be just a UDP blaster.
- DDS would completely replace the ROS master based discovery system.
- DDS has publisher and subscriber. However, they are implemented by
DataWriter
andDataReader
, which hides the implementations of communication - Shared Memory Support
- In ROS 1, nodelets were used. Nodelets allow publishers and subscribers to share data by passing around
boost::shared_ptrs
to messages
- In ROS 1, nodelets were used. Nodelets allow publishers and subscribers to share data by passing around
Disadvantages of DDS:
- ROS must work within that existing design. If the design did not target a relevant use case or is not flexible, it might be necessary to work around the design.
[1] DDS Implementations
There are multiple middlewares because you might have considerations such as license, platform availability, or computation footprint:
Fast DDS
(by eProsima) whose wire protocol isFast RTPS
. Package:rmw_fastrtps_cpp
- ROS2 Humble’s default
Cyclone DDS
(Eclipse): slightly lighter weight, but less configurable than Fast RTPS. Can be explicitly installed by:sudo apt install ros-humble-rmw-cyclonedds-cpp
. Package:rmw_cyclonedds_cpp
- ROS2 Galactic’s default
ConnextDDS
(RTI). Package:rmw_connext_cpp
DDS is controlled by:
1
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
rmw
stands forROS Middleware
. It’ a package that implements the abstract ROS middleware interface using DDS or RTPS’s API and tools.
Some RMW implementations can communicate:
Fast DDS <-> Cyclone DDS
Fast DDS <-> Connext
[2] Zeroconf
ROS 2 and many other IoT devices heavily relies on Zeroconf. Zero Configuration Networking (Zeroconf
) allow devices on local network to discover and communicate with each other without requiring manual configuation. It does:
- Automated Addressing:
- Devices assign themselves a unique IP address without requiring a DHCP server. This is usually in the
link-local
address range(169.254.x.x in IPv4)
- It tries to use DHCP first. If no DHCP server is found, the device assigns itself a link-local IP address.
- Devices assign themselves a unique IP address without requiring a DHCP server. This is usually in the
- Service Discovery
- Each device broadcasts and discovers services (printers, file shares, media servers) on the local network
- Often uses Multicast DNS, DNS Service Discovery (DNS-SD)
- Name resolution
- Based on the discovered devices,
names <-> IP
mapping can be broadcasted
- Based on the discovered devices,
Common protocols used inZeroconf :
Apple Bonjour
: A popular Zeroconf implementation used in macOS and iOS.Avahi
: A Linux-based Zeroconf implementation, commonly used for service discovery.DNS-SD (Service Discovery)
: Advertises and discovers services (e.g., “_http._tcp.local” for a web server).Multicast DNS (mDNS)
: Resolves hostnames to IP addresses in the absence of a DNS server.
Advantages:
- No network configuration needed. It uses dynamic and flexible local networking
- Reduces dependency on network infrastructure like DHCP and DNS servers
Disadvantages:
- Scalability. In larger network, multicast could be noisy
- Security: open broadcasting could be intercepted
- Network scope: limited to a single subnet and does not cross routers
Reference: ROS2 Design Documentation
Backgrounds of DDS
DDS comes out of a set of companies which are decades old, was laid out by the OMG which is an old-school software engineering organization, and is used largely by government and military users.
- They have limited forum support
- They do not have extensive user-contributed wikis or an active Github repository.
[1] What is Fast RTPS
Fast RTPS
was designed by Object Management Group (OMG). While DDS defines overall framework and API, Fast RTPS
defines the nitty-gritty of the publisher-subscriber model used by DDS
:
- Serialization, deserialization
- publishers, subscribers, topics
- QoS policies: reliability, durability, and liveliness
- Automatic Discovery
- Transport Independence uses UDP and shared_memory
How does RTPS work?
First, RTPS has Participants
, which represent applications or nodes in the distributed system. They correspond to DDS participants.
Each participant has Writers
and Readers
:
- Writers: Publish data (similar to DDS DataWriters).
- Readers: Subscribe to data (similar to DDS DataReaders).
Each writer and reader has topics
: Logical channels through which writers and readers exchange data.
RTPS Communication Workflow
-
discovery
process: RTPS uses Simple Endpoint Discovery Protocol (SEDP) to discover participants, topics, and endpoints (readers/writers). -
Data Exchange
phase:
- Writers publish serialized data to the network.
- Readers listen for data on the corresponding topic and deserialize it upon reception.
- QoS Enforcement
[2] What is IDL
DDS uses the “Interface Description Language (IDL)” as defined by the Object Management Group (OMG) for message definition and serialization. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module RobotSystem {
struct Pose {
float x; // Position in X-axis
float y; // Position in Y-axis
float z; // Position in Z-axis
float roll; // Rotation around X-axis
float pitch; // Rotation around Y-axis
float yaw; // Rotation around Z-axis
};
struct RobotState {
string<255> name; // Robot name (max 255 characters)
Pose pose; // Pose of the robot
bool is_active; // Is the robot active?
};
};
DDS implementations (e.g., Fast DDS, Cyclone DDS, or RTI Connext) provide tools to generate code from the IDL file. The generated code includes:
1
2
Serialization and deserialization functions.
Definitions for the corresponding data types in the target programming language (e.g., C++, Python, etc.).
Messages, Services and Actions
[1] Message Conversions Base Mechanism
.msg
files still keep its format and in-memory representation because it’s proven to be functional in ROS1..msg
file are converted into.idl
files so that they could be used with the DDS transport.- Language specific files, conversion functions are generated as well.
- Conversion functions convert ROS <-> DDS in memory instances
ROS2
API only converts a message field-by-field into anidl
object. DDS in-memory instances are not generated and consumed except only in.publish()
and topic callbacks.- This is because serialization is at least
10x
longer than field-to-field copy. - ROS2 build can do
msg -> idl
outsidepublish()
and receiver callbacks instead of doing a zero-copy msg conversion.
- This is because serialization is at least
- Language specific files, conversion functions are generated as well.
.idl
files are published
So during c++ compilation, msg
file Pose.msg
:
1
2
3
4
5
6
float32 x
float32 y
float32 z
float32 roll
float32 pitch
float32 yaw
will be converted to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Generated C++ code
namespace custom_msgs {
struct Pose {
float x;
float y;
float z;
float roll;
float pitch;
float yaw;
// Constructor
Pose() : x(0.0), y(0.0), z(0.0), roll(0.0), pitch(0.0), yaw(0.0) {}
// Comparison operators, serialization methods, etc., are also included
};
}
So you can create:
1
2
3
custom_msgs::Pose pose;
pose.x = 1.0;
...
In Python, similar thing happens during build
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Generated Python code
class Pose:
def __init__(self):
self.x = 0.0
self.y = 0.0
self.z = 0.0
self.roll = 0.0
self.pitch = 0.0
self.yaw = 0.0
# User code
from custom_msgs.msg import Pose
pose = Pose()
pose.x = 1.0
- In
ROS2
terms, each C++/Python variable is an in-memory representation - The in-memory representation includes methods for serialization (converting to a binary format for transmission) and deserialization (reconstructing the object from the binary format).
[2] Service and Actions
A service in ROS 2 is a mechanism for synchronous communication between a client and a server. It allows a node to send a request and receive a response. E.g,
1
2
3
4
5
# AddTwoInts.srv
int64 a
int64 b
---
int64 sum
An action is a mechanism for asynchronous, long-running tasks that provides periodic feedback and the ability to cancel the task. It uses Goal-Feedback-Result
model:
1
2
3
4
5
6
# Fibonacci.action
int32 order # Goal
---
int32[] sequence # Feedback
---
int32[] sequence # Result
Both Service and Actions are built on top of the publish-subscribe
model.
- Service uses two topics:
/service_name_request
and/service_name_response
- Action has:
Goal
service: send the goal to the action serverCancel
service: cancel the current goal- Feedback and status are communicated using topics:
- A feedback topic for periodic updates.
- A status topic to inform about the state of the goal (e.g., “active,” “canceled,” “succeeded”).
Result
service: retrieve the final result