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