Skip to content

Commit 5de661a

Browse files
Minor cleanup and code reorganization
Signed-off-by: Luca Della Vedova <[email protected]>
1 parent 17145d2 commit 5de661a

File tree

6 files changed

+284
-284
lines changed

6 files changed

+284
-284
lines changed

rclrs/src/clock.rs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
use crate::rcl_bindings::*;
2+
use crate::{error::ToResult, time::Time, to_rclrs_result, RclrsError};
3+
use std::sync::{Arc, Mutex};
4+
5+
/// Enum to describe clock type. Redefined for readability and to eliminate the uninitialized case
6+
/// from the `rcl_clock_type_t` enum in the binding.
7+
#[derive(Clone, Debug, Copy)]
8+
pub enum ClockType {
9+
RosTime = 1,
10+
SystemTime = 2,
11+
SteadyTime = 3,
12+
}
13+
14+
impl From<ClockType> for rcl_clock_type_t {
15+
fn from(clock_type: ClockType) -> Self {
16+
match clock_type {
17+
ClockType::RosTime => rcl_clock_type_t::RCL_ROS_TIME,
18+
ClockType::SystemTime => rcl_clock_type_t::RCL_SYSTEM_TIME,
19+
ClockType::SteadyTime => rcl_clock_type_t::RCL_STEADY_TIME,
20+
}
21+
}
22+
}
23+
24+
pub struct Clock {
25+
_type: ClockType,
26+
_rcl_clock: Arc<Mutex<rcl_clock_t>>,
27+
// TODO(luca) Implement jump callbacks
28+
}
29+
30+
impl Clock {
31+
// TODO(luca) proper error handling
32+
pub fn new(type_: ClockType) -> Result<Self, RclrsError> {
33+
let mut rcl_clock;
34+
unsafe {
35+
// SAFETY: Getting a default value is always safe.
36+
rcl_clock = Self::init_generic_clock();
37+
let mut allocator = rcutils_get_default_allocator();
38+
rcl_clock_init(type_.into(), &mut rcl_clock, &mut allocator).ok()?;
39+
}
40+
Ok(Self {
41+
_type: type_,
42+
_rcl_clock: Arc::new(Mutex::new(rcl_clock)),
43+
})
44+
}
45+
46+
pub fn rcl_clock(&self) -> Arc<Mutex<rcl_clock_t>> {
47+
self._rcl_clock.clone()
48+
}
49+
50+
pub fn clock_type(&self) -> ClockType {
51+
self._type
52+
}
53+
54+
pub fn set_ros_time(&mut self, enable: bool) {
55+
let mut clock = self._rcl_clock.lock().unwrap();
56+
if enable {
57+
// SAFETY: Safe if clock jump callbacks are not edited, which is guaranteed
58+
// by the mutex
59+
unsafe {
60+
rcl_enable_ros_time_override(&mut *clock);
61+
}
62+
} else {
63+
// SAFETY: Safe if clock jump callbacks are not edited, which is guaranteed
64+
// by the mutex
65+
unsafe {
66+
rcl_disable_ros_time_override(&mut *clock);
67+
}
68+
}
69+
}
70+
71+
pub fn now(&self) -> Result<Time, RclrsError> {
72+
let mut clock = self._rcl_clock.lock().unwrap();
73+
let mut time_point: i64 = 0;
74+
unsafe {
75+
// SAFETY: No preconditions for this function
76+
rcl_clock_get_now(&mut *clock, &mut time_point).ok()?;
77+
}
78+
Ok(Time {
79+
nsec: time_point,
80+
clock_type: self._type,
81+
})
82+
}
83+
84+
/// Helper function to initialize a default clock, same behavior as `rcl_init_generic_clock`.
85+
/// Needed because functions that initialize a clock take as an input a mutable reference
86+
/// to a clock and don't actuall return one, so we need a function to generate one. Doing this
87+
/// instead of a `Default` implementation allows the function to be private and avoids
88+
/// exposing a public API to create an invalid clock
89+
// SAFETY: Getting a default value is always safe.
90+
unsafe fn init_generic_clock() -> rcl_clock_t {
91+
let allocator = rcutils_get_default_allocator();
92+
rcl_clock_t {
93+
type_: rcl_clock_type_t::RCL_CLOCK_UNINITIALIZED,
94+
jump_callbacks: std::ptr::null_mut::<rcl_jump_callback_info_t>(),
95+
num_jump_callbacks: 0,
96+
get_now: None,
97+
data: std::ptr::null_mut::<std::os::raw::c_void>(),
98+
allocator,
99+
}
100+
}
101+
}
102+
103+
impl Drop for Clock {
104+
fn drop(&mut self) {
105+
// SAFETY: No preconditions for this function
106+
let rc = unsafe { rcl_clock_fini(&mut *self._rcl_clock.lock().unwrap()) };
107+
if let Err(e) = to_rclrs_result(rc) {
108+
panic!("Unable to release Clock. {:?}", e)
109+
}
110+
}
111+
}
112+
113+
// SAFETY: The functions accessing this type, including drop(), shouldn't care about the thread
114+
// they are running in. Therefore, this type can be safely sent to another thread.
115+
unsafe impl Send for rcl_clock_t {}

rclrs/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ mod rcl_bindings;
2626
#[cfg(feature = "dyn_msg")]
2727
pub mod dynamic_message;
2828

29-
use std::sync::{Arc, Mutex};
29+
use std::sync::Arc;
3030
use std::time::Duration;
3131

3232
pub use arguments::*;
@@ -115,12 +115,10 @@ pub fn spin(node: Arc<Node>) -> Result<(), RclrsError> {
115115
/// # Ok::<(), RclrsError>(())
116116
/// ```
117117
pub fn create_node(context: &Context, node_name: &str) -> Result<Arc<Node>, RclrsError> {
118-
println!("Creating node");
119-
let mut node = Arc::new(Node::builder(context, node_name).build()?);
118+
let node = Arc::new(Node::builder(context, node_name).build()?);
120119
*node._time_source.lock().unwrap() =
121120
Some(TimeSourceBuilder::new(node.clone(), node.get_clock()).build());
122121
Ok(node)
123-
//Ok(Arc::new(Node::builder(context, node_name).build()?))
124122
}
125123

126124
/// Creates a [`NodeBuilder`][1].

rclrs/src/node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl Node {
9999
/// See [`NodeBuilder::new()`] for documentation.
100100
#[allow(clippy::new_ret_no_self)]
101101
pub fn new(context: &Context, node_name: &str) -> Result<Node, RclrsError> {
102-
Self::builder(context, node_name).build().into()
102+
Self::builder(context, node_name).build()
103103
}
104104

105105
pub fn get_clock(&self) -> Arc<Mutex<Clock>> {

rclrs/src/node/builder.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ impl NodeBuilder {
276276
)?
277277
};
278278
let rcl_node_mtx = Arc::new(Mutex::new(rcl_node));
279-
let mut node = Node {
279+
let node = Node {
280280
rcl_node_mtx,
281281
rcl_context_mtx: self.context.clone(),
282282
clients_mtx: Mutex::new(vec![]),
@@ -287,11 +287,6 @@ impl NodeBuilder {
287287
_time_source: Arc::new(Mutex::new(None)),
288288
_parameter_map,
289289
};
290-
/*
291-
let node_mtx = Arc::new(node);
292-
node._time_source = Some(Arc::new(Mutex::new(TimeSourceBuilder::new(node_mtx).build())));
293-
*/
294-
//node._time_source = Some(Arc::new(Mutex::new(TimeSourceBuilder::new(node_mtx).build())));
295290

296291
Ok(node)
297292
}

0 commit comments

Comments
 (0)