1use std::sync::{Arc, RwLock};
23use crate::{
4 tf_buffer::TfBuffer,
5 tf_error::TfError,
6 transforms::{geometry_msgs::TransformStamped, tf2_msgs::TFMessage},
7};
89///This struct tries to be the same as the C++ version of `TransformListener`. Use this struct to lookup transforms.
10///
11/// Example usage:
12///
13/// ```no_run
14/// use tf_rosrust::TfListener;
15///
16/// rosrust::init("listener");
17/// let listener = TfListener::new();
18///
19/// let rate = rosrust::rate(1.0);
20/// while rosrust::is_ok() {
21/// let tf = listener.lookup_transform("camera", "base_link", rosrust::Time::new());
22/// println!("{tf:?}");
23/// rate.sleep();
24/// }
25/// ```
26/// Do note that unlike the C++ variant of the TfListener, only one TfListener can be created at a time. Like its C++ counterpart,
27/// it must be scoped to exist through the lifetime of the program. One way to do this is using an `Arc` or `RwLock`.
28pub struct TfListener {
29 buffer: Arc<RwLock<TfBuffer>>,
30 _static_subscriber: rosrust::Subscriber,
31 _dynamic_subscriber: rosrust::Subscriber,
32}
3334impl TfListener {
35/// Create a new TfListener
36pub fn new() -> Self {
37Self::new_with_buffer(TfBuffer::new())
38 }
3940pub fn new_with_buffer(tf_buffer: TfBuffer) -> Self {
41let buff = RwLock::new(tf_buffer);
42let arc = Arc::new(buff);
43let r1 = arc.clone();
44let _dynamic_subscriber = rosrust::subscribe("tf", 100, move |v: TFMessage| {
45 r1.write().unwrap().handle_incoming_transforms(v, false);
46 })
47 .unwrap();
4849let r2 = arc.clone();
50let _static_subscriber = rosrust::subscribe("tf_static", 100, move |v: TFMessage| {
51 r2.write().unwrap().handle_incoming_transforms(v, true);
52 })
53 .unwrap();
5455 TfListener {
56 buffer: arc,
57 _static_subscriber,
58 _dynamic_subscriber,
59 }
60 }
6162/// Looks up a transform within the tree at a given time.
63pub fn lookup_transform(
64&self,
65 from: &str,
66 to: &str,
67 time: rosrust::Time,
68 ) -> Result<TransformStamped, TfError> {
69self.buffer.read().unwrap().lookup_transform(from, to, time)
70 }
7172/// Looks up a transform within the tree at a given time.
73pub fn lookup_transform_with_time_travel(
74&self,
75 from: &str,
76 time1: rosrust::Time,
77 to: &str,
78 time2: rosrust::Time,
79 fixed_frame: &str,
80 ) -> Result<TransformStamped, TfError> {
81self.buffer
82 .read()
83 .unwrap()
84 .lookup_transform_with_time_travel(from, time1, to, time2, fixed_frame)
85 }
86}
8788impl Default for TfListener {
89fn default() -> Self {
90 TfListener::new()
91 }
92}