@@ -33,6 +33,8 @@ pub struct Timer {
33
33
pub ( crate ) handle : TimerHandle ,
34
34
/// The callback function that runs when the timer is due.
35
35
callback : Arc < Mutex < Option < AnyTimerCallback > > > ,
36
+ /// What was the last time lapse between calls to this timer
37
+ last_elapse : Mutex < Duration > ,
36
38
/// We hold onto the Timer's clock for the whole lifespan of the Timer to
37
39
/// make sure the underlying `rcl_clock_t` remains valid.
38
40
pub ( crate ) in_use_by_wait_set : Arc < AtomicBool > ,
@@ -79,6 +81,18 @@ impl Timer {
79
81
Ok ( is_canceled)
80
82
}
81
83
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
+
82
96
/// Retrieves the time since the last call to the callback
83
97
pub fn time_since_last_call ( & self ) -> Result < Duration , RclrsError > {
84
98
let mut time_value_ns: i64 = 0 ;
@@ -121,6 +135,11 @@ impl Timer {
121
135
Ok ( is_ready)
122
136
}
123
137
138
+ /// Get the clock that this timer runs on.
139
+ pub fn clock ( & self ) -> & Clock {
140
+ & self . handle . clock
141
+ }
142
+
124
143
/// Set a new callback for the timer. This will return whatever callback
125
144
/// was already present unless you are calling the function from inside of
126
145
/// the timer's callback, in which case you will receive [`None`].
@@ -219,6 +238,7 @@ impl Timer {
219
238
let timer = Timer {
220
239
handle : TimerHandle { rcl_timer, clock } ,
221
240
callback : Arc :: new ( Mutex :: new ( Some ( callback) ) ) ,
241
+ last_elapse : Mutex :: new ( Duration :: ZERO ) ,
222
242
in_use_by_wait_set : Arc :: new ( AtomicBool :: new ( false ) ) ,
223
243
} ;
224
244
Ok ( timer)
@@ -227,6 +247,15 @@ impl Timer {
227
247
/// Force the timer to be called, even if it is not ready to be triggered yet.
228
248
/// We could consider making this public, but the behavior may confuse users.
229
249
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
+
230
259
let Some ( callback) = self . callback . lock ( ) . unwrap ( ) . take ( ) else {
231
260
log_error ! (
232
261
"timer" . once( ) ,
@@ -253,10 +282,6 @@ impl Timer {
253
282
}
254
283
}
255
284
256
- if let Err ( err) = self . rcl_call ( ) {
257
- log_error ! ( "timer" , "Unable to call timer: {err:?}" , ) ;
258
- }
259
-
260
285
Ok ( ( ) )
261
286
}
262
287
0 commit comments