Skip to content

Commit e67d089

Browse files
committed
Refactor spin and spin_once to mimic rclcpp's Executor API (#324)
* Added rclcpp/rclpy-like executor * Fix comments
1 parent 55071ab commit e67d089

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

rclrs/minimal_pub_sub/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ path = "src/minimal_subscriber.rs"
1313
name = "minimal_publisher"
1414
path = "src/minimal_publisher.rs"
1515

16+
[[bin]]
17+
name = "minimal_two_nodes"
18+
path = "src/minimal_two_nodes.rs"
19+
1620
[[bin]]
1721
name = "zero_copy_subscriber"
1822
path = "src/zero_copy_subscriber.rs"
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use std::env;
2+
use std::sync::atomic::{AtomicU32, Ordering};
3+
use std::sync::{Arc, Mutex};
4+
5+
use anyhow::{Error, Result};
6+
7+
struct MinimalSubscriber {
8+
num_messages: AtomicU32,
9+
node: Arc<rclrs::Node>,
10+
subscription: Mutex<Option<Arc<rclrs::Subscription<std_msgs::msg::String>>>>,
11+
}
12+
13+
impl MinimalSubscriber {
14+
pub fn new(name: &str, topic: &str) -> Result<Arc<Self>, rclrs::RclrsError> {
15+
let context = rclrs::Context::new(env::args())?;
16+
let node = rclrs::create_node(&context, name)?;
17+
let minimal_subscriber = Arc::new(MinimalSubscriber {
18+
num_messages: 0.into(),
19+
node,
20+
subscription: None.into(),
21+
});
22+
23+
let minimal_subscriber_aux = Arc::clone(&minimal_subscriber);
24+
let subscription = minimal_subscriber
25+
.node
26+
.create_subscription::<std_msgs::msg::String, _>(
27+
topic,
28+
rclrs::QOS_PROFILE_DEFAULT,
29+
move |msg: std_msgs::msg::String| {
30+
minimal_subscriber_aux.callback(msg);
31+
},
32+
)?;
33+
*minimal_subscriber.subscription.lock().unwrap() = Some(subscription);
34+
Ok(minimal_subscriber)
35+
}
36+
37+
fn callback(&self, msg: std_msgs::msg::String) {
38+
self.num_messages.fetch_add(1, Ordering::SeqCst);
39+
println!("[{}] I heard: '{}'", self.node.name(), msg.data);
40+
println!(
41+
"[{}] (Got {} messages so far)",
42+
self.node.name(),
43+
self.num_messages.load(Ordering::SeqCst)
44+
);
45+
}
46+
}
47+
48+
fn main() -> Result<(), Error> {
49+
let publisher_context = rclrs::Context::new(env::args())?;
50+
let publisher_node = rclrs::create_node(&publisher_context, "minimal_publisher")?;
51+
52+
let subscriber_node_one = MinimalSubscriber::new("minimal_subscriber_one", "topic")?;
53+
let subscriber_node_two = MinimalSubscriber::new("minimal_subscriber_two", "topic")?;
54+
55+
let publisher = publisher_node
56+
.create_publisher::<std_msgs::msg::String>("topic", rclrs::QOS_PROFILE_DEFAULT)?;
57+
58+
std::thread::spawn(move || -> Result<(), rclrs::RclrsError> {
59+
let mut message = std_msgs::msg::String::default();
60+
let mut publish_count: u32 = 1;
61+
loop {
62+
message.data = format!("Hello, world! {}", publish_count);
63+
println!("Publishing: [{}]", message.data);
64+
publisher.publish(&message)?;
65+
publish_count += 1;
66+
std::thread::sleep(std::time::Duration::from_millis(500));
67+
}
68+
});
69+
70+
let executor = rclrs::SingleThreadedExecutor::new();
71+
72+
executor.add_node(&publisher_node)?;
73+
executor.add_node(&subscriber_node_one.node)?;
74+
executor.add_node(&subscriber_node_two.node)?;
75+
76+
executor.spin().map_err(|err| err.into())
77+
}

0 commit comments

Comments
 (0)