Expand description
§RosLibRust
This crate provides a convenient “async first” library for interacting with ROS. This crate defines generic traits for interacting with ROS-like systems, and implementations of those traits for various backends.
This crate is pure rust and requires no ROS1 or ROS2 dependencies or installation.
This allows writing generic behaviors like:
use roslibrust::{TopicProvider, Publish, Subscribe};
async fn relay<T: TopicProvider>(ros: T) -> roslibrust::Result<()> {
let mut subscriber = ros.subscribe::<std_msgs::String>("in").await?;
let mut publisher = ros.advertise::<std_msgs::String>("out").await?;
while let Ok(msg) = subscriber.next().await {
println!("Got message: {}", msg.data);
publisher.publish(&msg).await?;
}
Ok(())
}
#[tokio::main]
async fn main() -> roslibrust::Result<()> {
// Relay messages over a rosbridge connection with either ROS1 or ROS2!
#[cfg(feature = "rosbridge")]
{
let ros = roslibrust::rosbridge::ClientHandle::new("ws://localhost:9090").await?;
relay(ros).await?;
}
// Relay messages over a native ROS1 connection
#[cfg(feature = "ros1")]
{
let ros = roslibrust::ros1::NodeHandle::new("http://localhost:11311", "relay").await?;
relay(ros).await?;
}
// Relay messages over a mock ROS connection for testing
#[cfg(feature = "mock")]
{
let ros = roslibrust::mock::MockRos::new();
relay(ros).await?;
}
// Relay messages over a zenoh connection compatible with zenoh-ros1-plugin / zenoh-ros1-bridge
#[cfg(feature = "zenoh")]
{
let ros = roslibrust::zenoh::ZenohClient::new(zenoh::open(zenoh::Config::default()).await.unwrap());
relay(ros).await?;
}
// TODO - not supported yet!
// Relay messages over a native ROS2 connection
// let ros = roslibrust::ros2::NodeHandle::new("http://localhost:11311", "relay").await?;
// relay(ros).await?;
Ok(())
}
All of this is backed by common traits for ROS messages, topics, and services. roslibrust_codegen
provides generation of Rust types from both ROS1 and ROS2 .msg/.srv files and
roslibrust_codegen_macro
provides a convenient macro for generating these types:
// Will generate types from all packages in ROS_PACKAGE_PATH
roslibrust_codegen_macro::find_and_generate_ros_messages!();
If you want to see what the generated code looks like check here.
While the macro is useful for getting started, we recommend using roslibrust_codegen
with a build.rs
as shown in example_package.
This allows cargo to know when message files are edited and automatically re-generate the code.
§Getting Started / Examples
Examples can be found in examples.
We recommend looking at the examples prefixed with generic_
first, these examples show the recommended style of using roslibrust
through the generic traits.
Code written this way can be used with any backend, and critically can be tested with the mock backend.
Examples prefixed with ros1_
, rosbridge_
, and zenoh_
show direct use of specific backends if you are only interested in a single backend.
Some backends may provide additional functionality not available through the generic traits.
To get started with writing a node with roslibrust
we recommend looking at example_package and setting up your
Cargo.toml
and build.rs
in a similar way.
Some important tips to keep in mind with using the crate:
- This crate is built around the tokio runtime and requires tokio to work. All backends expect to be created inside a tokio runtime.
- The generic traits
TopicProvider
andServiceProvider
are not object safe due to their generic parameters. This means you cannot use them as trait objects withBox<dyn TopicProvider>
orBox<dyn ServiceProvider>
. Instead, they should be used as compile time generics likefn foo(ros: impl TopicProvider)
orstruct MyNode<T: TopicProvider> { ros: T }
. - By default the roslibrust crate does not include any backends. You must enable the specific backends you want to use with features in
Cargo.toml
likeroslibrust = { version = "0.12", features = ["ros1"] }
.
§Contributing
Contribution through reporting of issues encountered and implementation in PRs is welcome! Before landing a large PR with lots of code implemented, please open an issue if there isn’t a relevant one already available and chat with a maintainer to make sure the design fits well with all supported platforms and any in-progress implementation efforts.
We uphold the rust lang Code of Conduct.
§Minimum Supported Rust Version / MSRV
MSRV is currently set to 1.75 to enable async fn
in traits.
We are likely to increase the MSRV to 1.83 when support for async closures
lands.
Re-exports§
pub use roslibrust_ros1 as ros1;
pub use roslibrust_rosbridge as rosbridge;
pub use roslibrust_zenoh as zenoh;
pub use roslibrust_mock as mock;
pub use roslibrust_codegen as codegen;
Modules§
- md5sum
- Contains functions for calculating md5sums of message definitions These functions are needed both in roslibrust_ros1 and roslibrust_codegen so they’re in this crate
- traits
- Contains the generic traits represent a pubsub system and service system These traits will be implemented for specific backends to provides access to “ROS Like” functionality
Macros§
- find_
and_ generate_ ros_ messages - Given a list of paths, generates struct definitions and trait impls for any ros messages found within those paths. Paths are relative to where rustc is being invoked from your mileage may vary.
- find_
and_ generate_ ros_ messages_ without_ ros_ package_ path - Similar to
find_and_generate_ros_messages
, but does not search theROS_PACKAGE_PATH
environment variable paths (useful in some situations).
Structs§
- Shape
Shifter - A generic message type used by some implementations to provide a generic subscriber / publisher without serialization
Enums§
- Error
- The central error type used throughout roslibrust.
Traits§
- Publish
- Indicates that something is a publisher and has our expected publish Implementors of this trait are expected to auto-cleanup the publisher when dropped
- Ros
- Represents all “standard” ROS functionality generically supported by roslibrust
- RosMessage
Type - Fundamental traits for message types this crate works with This trait will be satisfied for any types generated with this crate’s message_gen functionality
- RosService
Type - Represents a ROS service type definition corresponding to a
.srv
file. - Service
- Defines what it means to be something that is callable as a service
- Service
Fn - This trait describes a function which can validly act as a ROS service server with roslibrust. We’re really just using this as a trait alias as the full definition is overly verbose and trait aliases are unstable.
- Service
Provider - This trait is analogous to TopicProvider, but instead provides the capability to create service servers and service clients
- Subscribe
- Indicates that something is a subscriber and has our expected subscribe method Implementors of this trait are expected to auto-cleanup the subscriber when dropped
- Topic
Provider - This trait generically describes the capability of something to act as an async interface to a set of topics
Type Aliases§
- Result
- Generic result type used throughout roslibrust.