ros2_rust
ros2_rust copied to clipboard
Port executor API from ROS2
We currently use simple spin functions to interact with waitsets and any waitable entities (subscriptions, clients, services, etc.), porting the executor API would help us implement more waitable entities (e.g. timers) and support running more than one node in a single program.
Would we be able to use some crates to help implement this solution (such as tokio or rayon), or do we want to make this a sort of 1:1 port of what rclcpp does?
@jhdcs for now I'd just port the rclcpp / rclpy API 1:1 as a first step, but then offer the possibility to integrate with async_std, tokio, etc. so that existing Rust applications can integrate with ROS2. Not sure how that'd look like, for example via an implementation of the ROS2 executor API that can call both the RMW constructs (e.g. waitsets) and the Rust executor crates. The Future implementation is highly dependent on the executor, so it'll require some work.
This is an issue where I feel there is a lot to learn for us about what a good design would be.
For instance, if we tried to port the rclcpp API 1:1, we'd run into CallbackGroup being used a lot in the executor. Does the concept of a callback group make sense in Rust? There is no need to use a callback group to "guard access to shared critical or non-thread-safe resources" since the language forces you to be thread-safe.
Async is tricky too. One observation is that it would probably be possible to make all things that can be waited on, like nodes, subscriptions, timers etc., instances of std::task::Future, and then we would not need to write our own executor, we could simply use the tokio or smolexecutor in the single-threaded or multi-threaded configuration. This is not a suggestion yet to actually do this.
The Future implementation is highly dependent on the executor, so it'll require some work.
I thought a Future is generally independent of the async executor?
I believe the wake implementation ends up being executor specific.