r2r/lib.rs
1//! Easy to use, runtime-agnostic async rust bindings for ROS2.
2//! ---
3//!
4//! Minimal bindings for ROS2 that do *not* require hooking in to the
5//! ROS2 build infrastructure -- `cargo build` is all you
6//! need. Convenience Rust types are created by calling into the c
7//! introspection libraries. This circumvents the ROS2 .msg/.idl
8//! pipeline by relying on already generated C code. By default, the
9//! behavior is to build bindings to the RCL and all message types
10//! that can be found in the currently sourced ros environment.
11//!
12//! What works?
13//!---
14//!- Up to date with ROS2 ~Dashing~ ~Eloquent~ Foxy Galactic Humble
15//!- Building Rust types
16//!- Publish/subscribe
17//!- Services
18//!- Actions
19//!- Parameter handling
20//!
21//! ---
22//!
23//! After having sourced ROS2 (see README for more details), you can
24//! try the following example:
25//!
26//! ``` rust
27//! use futures::{executor::LocalPool, future, stream::StreamExt, task::LocalSpawnExt};
28//! use r2r::QosProfile;
29//!
30//! fn main() -> Result<(), Box<dyn std::error::Error>> {
31//! let ctx = r2r::Context::create()?;
32//! let mut node = r2r::Node::create(ctx, "node", "namespace")?;
33//! let subscriber =
34//! node.subscribe::<r2r::std_msgs::msg::String>("/topic", QosProfile::default())?;
35//! let publisher =
36//! node.create_publisher::<r2r::std_msgs::msg::String>("/topic", QosProfile::default())?;
37//! let mut timer = node.create_wall_timer(std::time::Duration::from_millis(1000))?;
38//!
39//! // Set up a simple task executor.
40//! let mut pool = LocalPool::new();
41//! let spawner = pool.spawner();
42//!
43//! // Run the subscriber in one task, printing the messages
44//! spawner.spawn_local(async move {
45//! subscriber
46//! .for_each(|msg| {
47//! println!("got new msg: {}", msg.data);
48//! future::ready(())
49//! })
50//! .await
51//! })?;
52//!
53//! // Run the publisher in another task
54//! spawner.spawn_local(async move {
55//! let mut counter = 0;
56//! loop {
57//! let _elapsed = timer.tick().await.unwrap();
58//! let msg = r2r::std_msgs::msg::String {
59//! data: format!("Hello, world! ({})", counter),
60//! };
61//! publisher.publish(&msg).unwrap();
62//! counter += 1;
63//! }
64//! })?;
65//!
66//! // Main loop spins ros.
67//! loop {
68//! node.spin_once(std::time::Duration::from_millis(100));
69//! pool.run_until_stalled();
70//! }
71//! }
72//! ```
73
74// otherwise crates using r2r needs to specify the same version of indexmap and uuid as
75// this crate depend on, which seem like bad user experience.
76pub extern crate indexmap;
77pub extern crate uuid;
78
79mod error;
80pub use error::{Error, Result};
81
82mod msg_types;
83pub use msg_types::{
84 generated_msgs::*, WrappedActionTypeSupport, WrappedNativeMsg as NativeMsg,
85 WrappedNativeMsgUntyped, WrappedServiceTypeSupport, WrappedTypesupport,
86};
87
88mod utils;
89pub use utils::*;
90
91mod subscribers;
92
93mod publishers;
94pub use publishers::{Publisher, PublisherUntyped};
95
96mod services;
97pub use services::ServiceRequest;
98
99mod clients;
100pub use clients::{Client, ClientUntyped};
101
102mod action_common;
103pub use action_common::GoalStatus;
104
105mod action_clients;
106pub use action_clients::{ActionClient, ActionClientGoal};
107
108mod action_clients_untyped;
109pub use action_clients_untyped::{ActionClientGoalUntyped, ActionClientUntyped};
110
111mod action_servers;
112pub use action_servers::{ActionServerCancelRequest, ActionServerGoal, ActionServerGoalRequest};
113
114mod context;
115pub use context::Context;
116
117mod parameters;
118pub use parameters::{Parameter, ParameterValue, RosParams, WrongParameterType};
119
120pub use r2r_macros::RosParams;
121
122mod clocks;
123pub use clocks::{Clock, ClockType};
124
125mod nodes;
126pub use nodes::{Node, Timer};
127
128pub mod qos;
129
130#[cfg(r2r__rosgraph_msgs__msg__Clock)]
131mod time_source;
132#[cfg(r2r__rosgraph_msgs__msg__Clock)]
133pub use time_source::TimeSource;
134
135pub use qos::QosProfile;
136
137/// The ros version currently built against.
138#[cfg(r2r__ros__distro__foxy)]
139pub const ROS_DISTRO: &str = "foxy";
140#[cfg(r2r__ros__distro__galactic)]
141pub const ROS_DISTRO: &str = "galactic";
142#[cfg(r2r__ros__distro__humble)]
143pub const ROS_DISTRO: &str = "humble";
144#[cfg(r2r__ros__distro__iron)]
145pub const ROS_DISTRO: &str = "iron";
146#[cfg(r2r__ros__distro__jazzy)]
147pub const ROS_DISTRO: &str = "jazzy";
148
149#[cfg(r2r__ros__distro__rolling)]
150pub const ROS_DISTRO: &str = "rolling";
151
152#[cfg(not(any(
153 r2r__ros__distro__foxy,
154 r2r__ros__distro__galactic,
155 r2r__ros__distro__humble,
156 r2r__ros__distro__iron,
157 r2r__ros__distro__jazzy,
158
159 r2r__ros__distro__rolling
160)))]
161pub const ROS_DISTRO: &str = "unknown";