Introducing ROS2 Wrapper for ZED
It’s a little more than a year since the first official release of ROS2 has been released. While the new version of the Robotic Operating System was promising, many features were still under development.
With the release of ROS2 Crystal Clemmys in December 2018, ROS2 has gained a lot of maturity and we felt it was time to add support in ROS2 for the ZED and its 3D computer vision software stack.
What’s new in ROS2
ROS2 introduces a lot of changes with respect to the ten-year-old ROS1. The official ROS2 design post presents these changes in detail.
The biggest step forward is in the development languages. ROS2 supports Python v3.5, C++11, C++14 and C++17. The “Boost” library is not a dependency anymore.
Also, while ROS1 was created with the PR2 robot in mind, ROS2’s design targets every kind of robot, with an emphasis on robot security, real-time control and distributed control.
Multiple nodes in one process
In ROS1, you can write your code either as a ROS node or as a ROS nodelet. ROS1 nodes are being compiled into executables. ROS1 nodelets on the other hand are being compiled into a shared library which is then being loaded at runtime by a container process.
In ROS2 the concepts of node and nodelet has been unified and each not is now a
Component, very similar to the nodelet in ROS1. In ROS2 a single process can execute more than one node, using Composition, exploiting the intra-process communication feature.
ROS1 communication infrastructure is based on a custom serialization format, a custom transport protocol and a custom central discovery mechanism. ROS1 needs a “master node” running on one of the machines of the robot infrastructure to relay all messages between the different nodes..This means that that if the communication with the “master” node fails, the whole system collapses.
ROS2 has an abstract middleware interface that provides serialization, transport, and discovery. Currently, all implementations of this interface are based on the DDS standard. This enables ROS2 to provide various Quality of Service policies (QoS) which improve communication over different networks. Playing with QoS parameters gives direct control over the reliability, latency and lifespan of each published message. You can reduce the latency of a sensor message that does not need reliability, but guarantee that a message will remain available until it does not reach its destination.
Yuya Maruyama’s “Exploring the Performance of ROS2” provides an excellent analysis about the communication improvements in ROS2.
Components with life cycle
In ROS1, most nodes have their own main functions. In ROS2, components can be subclassed from a life cycle component. The life cycle can be used by tools like roslaunch to start a system composed of many components in a deterministic way, knowing the real state of each node in every moment of its “life”.
Python-based launch system
ROS1 launch files are based on XML tags with very limited capabilities. In ROS2, the launch files are written in Python, which enables more complex logic like conditionals. The Python launch system gives complete control over life cycle components. Users can start each node when a well-defined situation occurs. For example, the file could start the motor control node only when all the sensor nodes are ready to provide information.
Decentralized parameter system
In ROS1, a single global server takes care of all the parameters available in the whole system. Users must instantiate a node-specific dynamic reconfigure server for each node in order to handle real-time changes.
ROS2 eliminates the concept of global parameters. Each node has its own parameter set. When a parameter changes, it notifies the node about the event, which can handle the new value.
Users can’t define the parameters in the launch file like in ROS1. But as they need to provide one or more YAML files, parameter management is still simple and organized.
Future support for real-time
ROS1 does not support writing real-time code, instead relying on external frameworks like Orocos. In ROS2, it will eventually be possible to write real-time nodes when using a proper RTOS.
ROS2 ZED wrapper features
The new ZED wrapper for ROS2 (beta) exploits many of the new functionalities offered by ROS2. The primary features include:
- New Lifecycle node design: It is important for a robotic system to be able to know and control the state of each module for its entire working life. That’s why we decided to use the new Lifecycle design, and the ZED wrapper node is now a state machine.
- Configuration using YAML files: There are three different YAML files that define the node parameters: a common file, a file for the ZED camera and a file for the ZED-M camera.
- Managed and unmanaged Python launch scripts: you can control a Lifecycle node directly with a launch file, or manually using Command Line Instructions. See this tutorial for more information.
- RGB streams publishing: The plugin publishes left and right RGB streams on their own topics using the
- Depth streams publishing: The plugin publishes the depth map, confidence map and disparity map on their own topics.
- Pointcloud publishing: The plugin now provides a colored point cloud.
- Positional tracking: The plugin publishes the position of the camera in real-time, relative to its own center.
- 3D Camera models for RVIZ2
- RVIZ2 launch Python scripts: We provide pre-configured Python launch files to launch the ZED node, and the RVIZ2 GUI to easily get access to all visual information.
- Dynamically reconfiguring runtime parameters: Users can now change runtime parameters (e.g. gain, exposure, white balance) during node execution using Command Line Instructions.
The online documentation details how to monitor and control the node state machine using the new tools available in ROS2, via the new launch Python scripting and by writing your own control node in C++.
The wrapper comes with a complete guide describing all available features, plus three C++ tutorials about how to retrieve the main information from a ZED camera connected to the ROS2 network:
- Installation guide
- Video subscribing using global callback function
- Depth subscribing using node composition and node callback
- Lifecycle status monitoring using Lambda expressions
It is important to recognize that this is a beta version. Not all features may work as expected, mainly due to ROS2 still being under development.
For example, two very important modules,
transformBroadcaster, do not yet support the Lifecycle interface (see this issue, this issue and this issue). This problem forced us to develop a workaround to take advantage of their functionalities. We added two sub-nodes of the main ZED process, they subscribe to the topics of the main life cycle node and re-publish them as TF and image transport structures. This workaround introduces a little latency in image publishing and TF broadcasting.
RVIZ2 also has a big limitation: The
message_filter support, introduced with Crystal Clemmys, is not yet available. This causes the position updates of the 3D objects to be non-fluid in the views, due to imperfect topic synchronization. Indeed, the timestamp synchronization is normally handled by a
message_filterobject (see this issue and the relevant pull request).
In June, a new release of ROS2 (Dashing Diademata) will be released. It will introduce features that are missing with respect to ROS1. We will be ready to support it to improve the tracking capability and the TF broadcasting, and to introduce other new features.