-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.rs
111 lines (92 loc) · 3.45 KB
/
main.rs
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
use ros_core_rs::core::MasterClient;
use std::thread;
use tokio::select;
use url::Url;
const ROS_MASTER_URI: &str = "http://0.0.0.0:11311";
const TOPIC_NAME: &str = "/chatter";
#[tokio::main]
async fn main() -> anyhow::Result<()> {
env_logger::init();
// Spawn a Tokio task to run the ROS master
let core_cancel = tokio_util::sync::CancellationToken::new();
let t_core = tokio::spawn({
let core_cancel = core_cancel.clone();
async move {
let uri = Url::parse(ROS_MASTER_URI).unwrap();
let socket_address = ros_core_rs::url_to_socket_addr(&uri)?;
let master = ros_core_rs::core::Master::new(&socket_address);
select! {
serve = master.serve() => {
serve
},
_ = core_cancel.cancelled() => {
Ok(())
}
}
}
});
// Initialize the ROS node
rosrust::loop_init("talker_listener", 1000);
// Spawn a Tokio task to publish messages
let t_talker = tokio::task::spawn_blocking(move || {
// Create publisher
let chatter_pub = rosrust::publish(TOPIC_NAME, 100).unwrap();
let mut count = 0;
// Create object that maintains 10Hz between sleep requests
let rate = rosrust::rate(10.0);
// Breaks when a shutdown signal is sent
while rosrust::is_ok() {
// Create string message
let mut msg = rosrust_msg::std_msgs::String::default();
msg.data = format!("hello world {}", count);
log::info!("I wrote {}", msg.data);
// Send string message to topic via publisher
chatter_pub.send(msg).unwrap();
// Sleep to maintain 10Hz rate
rate.sleep();
count += 1;
}
});
// Wait for the publisher to be available
let master_url = Url::parse(ROS_MASTER_URI).expect("Failed to parse URL.");
let master_client = MasterClient::new(&master_url);
loop {
let (_, _, published_topics) = master_client.get_published_topics("", "").await.unwrap();
if published_topics
.iter()
.any(|(topic_name, _)| topic_name == TOPIC_NAME)
{
break;
}
thread::sleep(std::time::Duration::from_millis(1000));
}
// Spawn a Tokio task to subscribe to messages
let t_listener = tokio::task::spawn_blocking(move || {
// Create subscriber
// The subscriber is stopped when the returned object is destroyed
let mut _subscriber_info;
loop {
_subscriber_info =
rosrust::subscribe(TOPIC_NAME, 2, |v: rosrust_msg::std_msgs::String| {
// Callback for handling received messages
log::info!("I heard {}", v.data);
});
if _subscriber_info.is_ok() {
break;
}
log::info!("publisher not found. Will retry until it becomes available...");
thread::sleep(std::time::Duration::from_millis(1000));
}
log::info!("We successfully subscribes to the publisher");
// Block the thread until a shutdown signal is received
rosrust::spin();
});
tokio::signal::ctrl_c().await?;
// Wind down clients
rosrust::shutdown();
let (_r1, _r2) = tokio::join!(t_talker, t_listener);
// Wind down core
core_cancel.cancel();
let _r3 = tokio::join!(t_core);
Ok(())
}