Have you ever wondered how a simple idea can have significant impact on multiple industries at once? This is a story about crafting APIs, brilliantly modern C++, and open-source spirit. It’s the story of Eclipse iceoryx™. It all started with an idea: If you make copies for exchanging data between software modules on a resource-constrained real-time system, you will fail! Solve this problem in your project with a zero-copy API, meet the SOP deadline, and celebrate? By no means! Learn how one open-source project makes AUTOSAR™ Adaptive and ROS™ 2 gear up and go faster.
Zero-copy everywhere or the story of Eclipse iceoryx
Most advanced driver assistance systems (ADAS) implementing functionalities such as lane keep assist or automatic emergency braking are based on microcontroller ECUs. On such ECUs, tens or hundreds of components run sub-tasks at different frequencies. Typically, these components are embedded in an AUTOSAR Classic Runtime Environment (RTE), an industry-standard created to foster interoperability between suppliers and OEMs.
However, with more complex ADAS, the size of the messages being exchanged between the components increased from bytes to kilobytes or even megabytes. Consequently, the AUTOSAR Classic RTE wasn’t sufficient anymore due to the overhead of copying the messages for each subscriber.
For this reason, Robert Bosch GmbH started to develop the Driver Assistance Data DeliverY (DADDY) middleware in 2009. It could transfer messages without making a single copy by sharing memory chunks between the components.
Between the first series production launch in 2012 and 2022, DADDY was deployed by Bosch on millions of ADAS ECUs.
Great story, SOPs done, customer happy, case closed? Not quite yet.
In 2015 the AUTOSAR consortium decided to start working on the next-generation industry-standard, AUTOSAR Adaptive, for POSIX operating systems like Linux and QNX. It was pretty clear from the beginning that a high-performance solution would be essential. As a result, Bosch decided to contribute DADDY’s zero-copy API and created what is known today as ara::com — this was done together with BMW and other AUTOSAR partners. In the meantime, DADDY was ported to POSIX operating systems utilizing shared memory by a team at Bosch around Michael Pöhnl, Kevin Goez, and Simon Hoinkis. This eventually launched the development of the POSIX middleware, which is today known as Eclipse iceoryx.
Contribute a nifty zero-copy API to the industry and rest on the laurels? Certainly not! Living the open-source spirit as we do at Apex.AI means engaging with the community and contributing our work upstream for all to use.
In the meantime, during AUTOSAR Adaptive standardization, the Robotic Operating System (ROS) launched the development of its next-generation real-time-capable ROS in early 2015. As a result, ROS 2 became popular in many industries to build various robotic systems including ADAS and autonomous driving R&D. ROS 2’s predecessor, ROS 1, is used by many automotive OEMs as a pre-development SDK. But up until 2019, ROS 2 was still making those irksome copies when sending a message! But luckily, help was at hand.
In 2019, the autonomous driving middleware team at Bosch around Michael Pöhnl open-sourced the aforementioned POSIX middleware as Eclipse iceoryx. This introduced the zero-copy LoandMessage API to the ROS 2 Foxy Fitzroy release. One of the first users of the new zero-copy API was the rmw_iceoryx binding which allows users to go blazing-fast with their robots using iceoryx. Soon after going open-source, other projects like Eclipse Cyclone DDS TM wanted to speed up their implementation with iceoryx. Michael Pöhnl and Joe Speed had the idea to create an Eclipse ROS middleware by combining Cyclone DDS and iceoryx, which later became the default middleware for ROS 2 Galactic.
Figure 1: The history of Eclipse iceoryx, Source: Apex.AI
Eclipse iceryx Blueberry uses cutting-edge C++
On March 14th, 2022, Eclipse iceoryx Blueberry (v2.0) was released and is used in the latest Apex.Middleware* 1.0 release. Furthermore, it is built into ROS 2 Humble as part of the Eclipse Foundation ROS Middleware with Eclipse Cyclone DDS. The middleware team at Apex.AI contributed many new features and improvements. Check out the following examples to learn more about the two major new features:
But hang on a second; what makes iceoryx so modern in terms of C++?
One of the major philosophical design principles that development at Apex.AI follows is “Design APIs in such a way they are easy to use and hard to misuse”. API design is undoubtedly a complex challenge! You might have already heard about Hyrum’s law:
With a sufficient number of users of an API,
it does not matter what you promise in the contract:
all observable behaviors of your system
will be depended on by somebody.
Avoiding misuse is even more important when aiming for a safe API design in safety-critical systems. One example of how iceoryx tries to follow this philosophy is the avoidance of std::exception’s and usage of an error handling concept inspired by Rust and proposed for C++23 called:
std::expected
How can it help write safer APIs? If you look at the following example, the method doSomething() will return either a valid object of ObjectType or return an enum value of ErrorEnum. By concatenating the and_then and or_else calls, the code becomes very readable and reads like a cooking recipe:
// Signature
iox::cxx::expected<ObjectType, ErrorEnum> doSomething();
// Usage
doSomething()
.and_then([](auto& object)
{
// This callable will be called if doSomething succeeded
// Use the object here in the happy path
})
.or_else([](auto& error)
{
// This callable will be called if doSomething failed
// Handle the error here in the sad path
});
Compared with the usage of exceptions, such an API incentivizes the developer to handle the errors more explicitly. For example, it is harder to forget to catch specific errors. Additionally, by using and_then and or_else, access to invalid objects is avoided.
Furthermore, from a maintainers perspective, propagating only the relevant errors through different layers is still as easy and pleasant to use as with exceptions.
Integration into AUTOSAR Adaptive
Blueberry is not only fast and dependable but also flexible in the application scenarios it supports. Furthermore, since iceoryx was developed parallel with the AUTOSAR Adaptive standardization, its functionality is very close to ara::com.
Recently, the Apex.AI middleware team created an example binding for automotive frameworks with a service-oriented architecture (SOA).
This example consists of two applications and one daemon application, as depicted in the figure below. The daemon is called RouDi, which stands for Routing and Discovery. The skeleton application is the one producing data and owns a MinimalSkeleton object. The proxy application is consuming data and owns a MinimalProxy object. Besides the skeleton and the proxy, each application has a Runtime object that registers with RouDi on creation and sets up the shared memory used for inter-process communication—this is depicted as a hexagon. The MinimalProxy provides an interface to discover the MinimalSkeleton service during runtime. Communication happens zero-copy over events, fields, and methods.
Figure 2: Illustration of included Eclipse iceoryx example, Source: Apex.AI
Check out the example on GitHub.com, and learn how you can speed up your AUTOSAR Adaptive solution with iceoryx.
Click HERE and download the whitepaper: AUTOSAR Adaptive on zero-copy steroids
If you are interested in Apex.AI products for your projects, Contact Us.
We are also growing our team worldwide. Remote and in our Labs. Visit Careers.
*As of January 2023 we renamed our products: Apex.Grace was formerly known as Apex.OS, and Apex.Ida was formerly known as Apex.Middleware.