Skip to content

Commit 9e28ee7

Browse files
committed
Keep track of time elapsed between timer calls
Signed-off-by: Michael X. Grey <[email protected]>
1 parent a72ebd6 commit 9e28ee7

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

rclrs/src/timer.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ pub struct Timer {
3333
pub(crate) handle: TimerHandle,
3434
/// The callback function that runs when the timer is due.
3535
callback: Arc<Mutex<Option<AnyTimerCallback>>>,
36+
/// What was the last time lapse between calls to this timer
37+
last_elapse: Mutex<Duration>,
3638
/// We hold onto the Timer's clock for the whole lifespan of the Timer to
3739
/// make sure the underlying `rcl_clock_t` remains valid.
3840
pub(crate) in_use_by_wait_set: Arc<AtomicBool>,
@@ -79,6 +81,18 @@ impl Timer {
7981
Ok(is_canceled)
8082
}
8183

84+
/// Get the last time lapse between calls to the timer.
85+
///
86+
/// This is different from [`Self::time_since_last_call`] because it remains
87+
/// constant between calls to the Timer.
88+
///
89+
/// It keeps track of the what the value of [`Self::time_since_last_call`]
90+
/// was immediately before the most recent call to the callback. This will
91+
/// be [`Duration::ZERO`] if the `Timer` has never been triggered.
92+
pub fn last_elapse(&self) -> Duration {
93+
*self.last_elapse.lock().unwrap()
94+
}
95+
8296
/// Retrieves the time since the last call to the callback
8397
pub fn time_since_last_call(&self) -> Result<Duration, RclrsError> {
8498
let mut time_value_ns: i64 = 0;
@@ -121,6 +135,11 @@ impl Timer {
121135
Ok(is_ready)
122136
}
123137

138+
/// Get the clock that this timer runs on.
139+
pub fn clock(&self) -> &Clock {
140+
&self.handle.clock
141+
}
142+
124143
/// Set a new callback for the timer. This will return whatever callback
125144
/// was already present unless you are calling the function from inside of
126145
/// the timer's callback, in which case you will receive [`None`].
@@ -219,6 +238,7 @@ impl Timer {
219238
let timer = Timer {
220239
handle: TimerHandle { rcl_timer, clock },
221240
callback: Arc::new(Mutex::new(Some(callback))),
241+
last_elapse: Mutex::new(Duration::ZERO),
222242
in_use_by_wait_set: Arc::new(AtomicBool::new(false)),
223243
};
224244
Ok(timer)
@@ -227,6 +247,15 @@ impl Timer {
227247
/// Force the timer to be called, even if it is not ready to be triggered yet.
228248
/// We could consider making this public, but the behavior may confuse users.
229249
fn call(&self) -> Result<(), RclrsError> {
250+
// Keep track of the time elapsed since the last call. We need to run
251+
// this before we trigger rcl_call.
252+
let last_elapse = self.time_since_last_call().unwrap_or(Duration::ZERO);
253+
*self.last_elapse.lock().unwrap() = last_elapse;
254+
255+
if let Err(err) = self.rcl_call() {
256+
log_error!("timer", "Unable to call timer: {err:?}",);
257+
}
258+
230259
let Some(callback) = self.callback.lock().unwrap().take() else {
231260
log_error!(
232261
"timer".once(),
@@ -253,10 +282,6 @@ impl Timer {
253282
}
254283
}
255284

256-
if let Err(err) = self.rcl_call() {
257-
log_error!("timer", "Unable to call timer: {err:?}",);
258-
}
259-
260285
Ok(())
261286
}
262287

0 commit comments

Comments
 (0)