ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A answers.ros.org

Proposal: Rust Working Group for ROS

TL;DR: Help empower everyone to build reliable and efficient ROS software with Rust!:crab::turtle:

Summary

We’ve had several discussions come up in the past revolving around Rust support for ROS, and so, to help address those, I propose we setup a Rust Working Group to focus on these issues and try to resolve them by getting more people involved in the development, documentation and maintenance of the Rust client library and to improve the general user experience for working with ROS in Rust.

Overview

Rust is a language empowering everyone to build reliable and efficient software. I’ll not list all the manners in which ROS users can benefit from Rust, in terms of performance, reliability, and productivity, but instead encourage you to discover more about Rust, or who Rust Is for from the home page below. Suffice it to say: Rust is very much applicable to the embedded and performance-critical environments pertinent to robotics, while providing zero-cost thread/memory safety seldom guaranteed in other compile-time languages, making system programming more accessible for everyone, even other roboticists from multidisciplinary backgrounds.

This working group will focus to help bolster the usability and adoption of the Rust programming language within the ROS ecosystem, primarily through the development, maintenance and documentation of the Rust client library for ROS2, and respective tooling integration for building and packaging ROS packages written in Rust. Given the current overlap of ROS and Rust developers is still small, and ROS development is federated, growing and fostering a sustainable subcommunity while actively developing Rust support within ROS will take deliberate coordination and regular interactions to grow. Thus, the working group will also serve to attract and connect more ROS users with fellow rustaceans to coordinate our efforts.

I’m still working on setting up a working group repository based on the ROS 2 TSC’s WG template, but I’d like to start hearing from people that are interested in being involved and/or helping with the working group. We’ll have regular open meetings, with meeting notes and the next proposed agenda posted after each meeting. For the benefit of the global community, we’ll record and upload our sessions to the ROS 2 Working Groups YouTube channel:

Meetings

If you’re interested in participating please fill out this Doodle for which times would work best for you and I’ll do my best to select a time that’s international friendly and also not overlapping with existing working groups. I’m thinking biweekly, every other week, alternating between european and asian friendly times if requested. Note: The Doodle’s time zone defaults to PDT (UTC -7), the week may shift to avoid double booking over other ROS events, and most ROS WGs avoid meeting Monday or Friday.

To receive meeting invitations directly via email, join the google group for notifications:

You can chat with the group via matrix at +rosorg-rust:matrix.org . Feel free to join the community as well as the current room, so you can easily see when more specific rooms are added.

Suggestions

I’d appreciate any feedback on topics you think this working group should focus on; so if you have ideas please post them here. Also, I’d like to find a few more team organizers to help manage the working group, e.g. govern meetings, lead technical discussions, review contributions; preferably experienced in one of the following:

Cheers,

Ruffin

18 Likes

To kick things off, I’d like to suggest some initial topics. Also, forgive me if some of this is elementary for most ROS users, but for the sake of our fellow Rustaceans, new to the ROS community, I’ll be including references to general ROS concepts throughout this post.


Client Library

Client libraries are the APIs that allow users to implement their ROS code. They are what users use to get 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.

https://index.ros.org/doc/ros2/Concepts/ROS-2-Client-Libraries

The ROS2 client library for Rust, rclrs, was first announced by @esteve in early 2018:

As rclrs development stalled, a call for more maintainers was posted this year:

Stewardship of the rclrs client library could become a primary objective for the Rust Working Group, contributing to its further development and continual maintenance. Solidifying support for an additional client library would not only positively reflect the maturation of the ROS2 ecosystem, but also help diversify our community; garnering more developers by making ROS more accessible via more programming languages. Additionally, the emergence of an alternative high performant client library could further motivate RCL discipline, curbing feature creep in rclcpp, otherwise eroding feature parity and consistency between all client libraries.

Although Rust has particularly good FFI support for C, enabling RCL to be wrapped largely via auto generated bindings, rclrs doesn’t yet expose an idiomatic Rust API for all common functionality. Many core features are still missing, such as services, actions, parameters and component nodes. Additionally, due to the current ROS2 support of non-default clients, code generation for using rosidl message data types with Rust is currently tedious, given rosidl_generator_rs isn’t shipped/registered with binary releases, necessitating recompilation of message packages used by rust packages. Advancing the Rust client library to eventual Tier 1 support could go a long way in improving the out-of-the-box experience for ROS users using Rust.

Building and Packaging

A workspace is a directory containing ROS 2 packages. Before using ROS 2, it’s necessary to source your ROS 2 installation workspace in the terminal you plan to work in. This makes ROS 2’s packages available for you to use in that terminal.

Workspaces in ROS2 are built using colcon, a build tool for building, testing software packages, regardless of language or build system details. Analogously, workspaces in Rust are built using cargo, a build system for building, testing Rust crates.

In addition however, cargo also manages dependencies, downloading and compiling external crates as needed for workspace compilation, a task explicitly out of scope for the colcon build tool. An extension for colcon to support Rust projects built with cargo was initiated, but is not complete enough for rclrs nor example ROS node packages using rclrs.

The current build setup for rclrs is not very robust, and uses a complex hybrid of cargo and cmake to generate and export the targets respectively. Native cargo support in colcon could help simplify Rust integration with ROS workspaces, with rclrs being a prime candidate for dogfooding usability improvements.

Special considerations would include:

  • interplay between cargo and colcon workspaces

  • packaging shared target directories and precompiled rlibs

  • dependency resolution across rust crates/packages

Documentation

One beloved aspect of the Rust ecosystem that draws so much attention, perhaps also driving user adoption, is it’s great documentation. The Rust ecosystem holds high standards for library documentation; fortunately it also ships with a standard documentation generator.

Similarly, documenting the Rust client library API and examples will go a long way in attracting more users and subsequent contributors to help sustain development. As per package documentation requirements are in the process of being formalized, it may be helpful to help flesh out ideas for supporting other languages by prototyping an out-of-box solution using rustdoc for ROS packages written in Rust.

CC: @jhdcs @OTL @lucasw @tomoyafujita @azazdeaz @lelongg @tprk77 @bergercookie @deb0ch

4 Likes

While I’m no expert by any means, I have dabbled in FFI with Rust - both with compiling Rust as a static library and linking / using bindgen/cbindgen, and also using cxx. And tasted some of the quirks of getting them to work together (beware of passing strings - if you make a string in Rust that needs to go to C/C++, always add a null byte). I’ve also worked on getting CMake/cargo to work together too, though I think that colcon-cargo would be our best path forward.

If any of this is at all helpful, I’m more than happy to lend a hand!

1 Like

Hi @ruffsl,

Thanks for kickstarting this discussion! :+1:
I’m by no means an expert when it comes to Rust but I’d be happy to be part of these discussions nonetheless.

A few thoughts:

Stewardship of the rclrs client library could become a primary objective for the Rust Working Group, contributing to its further development and continual maintenance

Yes, absolutely! Even though last time I checked, rclrs did compile successfully and worked over ROS2, setting it up and making changes to it was cumbersome. Improving rclrs and getting it to a state to eventually ship it along in the binary distributions alongside rclcpp should be a priority of the WG.

The current build setup for rclrs is not very robust, and uses a complex hybrid of cargo and cmake to generate and export the targets respectively. Native cargo support in colcon could help simplify Rust integration with ROS workspaces, with rclrs being a prime candidate for dogfooding usability improvements.

I haven’t looked into colcon-cargo in detail yet, but generally, I agree. Ideally, when creating a ROS package in Rust, we shouldn’t require a CMakeLists.txt at all but rather operate entirely inside Cargo.toml / build.rs.

I’ll go through the resources that you posted and get back with more specific comments.

1 Like

I’m interested, but I think you already know that, @ruffsl. :smiley:

I’ve got experience building a client library on top of rcl, and I’ve done some work trying to fix the problems with colcon-cargo in the past.

Anything I contribute will have to be outside of work hours until those who ultimately control the budget that pays for my time see the ~640 nm light.

1 Like

Wow. Thanks @ruffsl . This is really helpful and I am interested. I am trying to build self-learning Rust Client for Ros2 (on processing and articles published on medium). Although I am not expert for both :D, I would like to contribute my time to Client or other tools.

Two things I hope that rclrs to have

  1. service and action.
  2. how to use async/await to stop using spinOnce.

Will go through the links posted.
Thanks.

1 Like

I’ve been focusing on both ROS and Rust recently. Rust and ROS have a great overlap in supporting embedded devices with less resources and both have an Embedded working group for that.


https://discourse.ros.org/tags/wg-embedded

Looking at the micro-ROS architecture from the post https://www.freertos.org/2020/09/micro-ros-on-freertos.html, it would be great to have rust as a first class client language to program robust applications on microcontrollers and other embedded devices.

3 Likes

Thanks for opening this thread and WG proposal. I am really interested too. not sure how much i could make contribution since i am not an expert for Rust.

1 Like

Awesome this is going on. I just started learning Rust (and ROS2) and set up a Rust+ROS2 interface for my Neato robot. It’s all in place and only when I started to test I found out that the message generation does not yet handle arrays etc. My bad for not checking earlier.

I’m not well versed enough in Rust nor IDL and the code generator (yet?) to help with that quickly, but I’ll see what I can do.

1 Like

Will this WG have it’s own dedicated instant-messaging chat, like Matrix? Or is it too early to think about that at the moment?

1 Like

Hey y’all, good to see so much enthusiasm, and no worries about being a Rust expert just yet. While it seems we’re all still learning more about the language, I don’t think there’s a better way to do so than with peers and projects that share your interests. I’ll eventually cross-post to Rust community forms and contact some awesome-rust-mentors to help balance the Rust/ROS experience within the WG:

Before reaching out just yet, I’d like to hold a few smaller meetings to start with, including current ROS users using Rust, so we can effectively onboard more rustaceans into the ROS community and WG.


Yeah, the build setup is a bit awkward just yet. Although I recently added a Dockerfile that provides a simple and reproducible build environment, and should help with further development.


I had intended to @ you, but discovered I can only ping 10 folks at a time.
However, I knew you frequent discourse and would spot this in any event. :mag:


That’s a good point. It would be great for the rust client library to support async/await functionality. @wjwwood or @gbiggs , Is there a good adherence resource documenting which surfaces of the public rlc API are Thread-Safe? Can’t seem to find the doxygen pages for Foxy, like for Bouncy:


That reminds me of another limitation noted in rclrs; the message interface has much room to improve.

  • messages are deep-copied and this can be terribly inefficient for big messages like images; the current solution leverages C typesupport implementations and might benefits from a direct serialization/deserialization

Yes, I have a Matrix Room/Community ready :wink: , but haven’t linked to it just yet to keep the discussion centralized on this thread. After our first meeting and need for more synchronous communication, I’ll update the top post and WG contact details in the governance page in the ROS2 index.

2 Likes

I’m one of the most heavy user of rosrust (ROS1).

This robot we published last month uses rosrust heavily.

And i’m personally collecting useful rust libraries for roboticists here,

So, we (I’m CEO of Smile Robotics, Inc) can test the robustness and usefulness of ROS2 rust on our robot and demonstrate its power on real robot when we’ve built the ROS2 rust something!
If our company were very large, we want to provide more power but it will be difficult.

We have some problem in generation of messages when we use rosrust. We can learn a lot of things from the experience of rosrust made by https://github.com/adnanademovic .

4 Likes

There is not, unfortunately. It’s being worked on, but we’re starting from the bottom and working our way up. The RMW interface has recently got excellent documentation.

I spent quite a bit of time in the type support system recently. This could be a good place for me to start, if I can get the time.

CC: @gbiggs

I think most of rcl API are not thread-safe. it is described in the header files, i just did grep with Thread-Safe. besides, there is no mutex lock rcl, i think that design is to make sure the lock in frontend such as rclcpp.

The docs are there:

I don’t think it will be easy to integrate into async/await just based on my knowledge of similar systems like Python’s asyncio and the underlying libraries like libevent, libev, or libuv. As they generally require a file handle like object that can be used with even lower level interfaces like select, kqueue, or epoll, and the way that most DDS implementations are structured they cannot give us access to those handles and/or they are not portable. So you typically end up with a sub optimal solution which requires extra threads, synchronization, and context switching overhead which you’d prefer to avoid I think. So it’s possible, but complicated. That being said, it’s possible the framework is more flexible than I’m used to and allows you to integrate them more nicely, but I can’t imagine how atm.

Very little of the rcl API is thread-safe, the idea being that the calling code is usually a client library for a specific programming language and therefore is better suited to handling things like threading and synchronization. Also, it allows you to write client libraries that are explicitly not thread-safe (maybe always single threaded) and therefore get some benefits.

The only functions that are required to be thread-safe in a non-trivial way, that I know of off hand, are rcl_publish(), rcl_take(), and maybe similar functions for Services. These are not enforced at the rcl level, but instead rely on the middleware implementation to ensure this via rmw_publish() and rmw_take().

2 Likes

Yes! Rust WG! ADLINK is all in on rust. Eclipse Cyclone DDS sister project Zenoh is 100% Rust. zenoh-plugin-dds gives ROS 2 scalable fault tolerant discovery; bridging via wireless (WiFi, 4G, 5G, LoRa) for swarms, V2X, cloud; and micro-controller support with rmw_zenoh for micro-ROS being released soon. Here is presentation & ROS 2 demo done for Autoware TSC https://youtu.be/VQ-Fvm4vIYg

Here is a cyclonedds rust binding https://github.com/atolab/cdds-rust
… and here is another because our friend Sojan James of Samsung HARMAN Automotive “wanted to give my favorite DDS a binding for my favorite language” https://github.com/sjames/cyclonedds-sys
Read Sojan’s “The case for using Rust for Automotive software

8 Likes

To be honest, I really love the little love dragon logo :smile:

3 Likes

My current job is to work on ROS 2 development, and my company supports my working on rclrs; so if any of you feel like you have ideas of things to work on, but don’t have the time/support to work on it, let me know. I can try and help you.

For example: @gbiggs - You wanted to work on setting up the type support system in rclrs. I’ve been trying to get rclrs to play nicely with VSCode + Rust-Analyzer, and one of the hangups is it gets confused by messages, and can’t recognize them as types. I’d be very interested in lending a hand if you have some ideas on that.

I don’t think it will be easy to integrate into async/await just based on my knowledge of similar systems like Python’s asyncio and the underlying libraries like libevent , libev , or libuv . As they generally require a file handle like object that can be used with even lower level interfaces like select , kqueue , or epoll , and the way that most DDS implementations are structured they cannot give us access to those handles and/or they are not portable. So you typically end up with a sub optimal solution which requires extra threads, synchronization, and context switching overhead which you’d prefer to avoid I think. So it’s possible, but complicated. That being said, it’s possible the framework is more flexible than I’m used to and allows you to integrate them more nicely, but I can’t imagine how atm.

I just took a look into this. According to Ferrous Systems, async/await is currently supported as a source code transformation in the compiler: https://ferrous-systems.com/blog/stable-async-on-embedded/. As of May, they used Thread Local Storage, but Ferrous Systems pushed a change to the compiler to get away from that. They also worked on enabling async/await for no_std, which means we’d have access to it in embedded systems.

However, I’m not sure it’s on stable yet. According to the post, they said it’d be 4 weeks until stable, but I’ve not located the exact stable release this was implemented in. Of course, I could just be blind…

If I’ve said anything incorrect, please feel free to correct me! I’ve not used async/await functionality yet!

EDIT: Found the release: no_std support was added in Rust 1.44: https://github.com/rust-lang/rust/blob/master/RELEASES.md