22 #include "rcl/error_handling.h"
23 #include "rcutils/macros.h"
24 #include "rcutils/stdatomic_helper.h"
25 #include "rcutils/time.h"
30 atomic_uint_least64_t current_time;
39 return rcutils_steady_time_now(current_time);
47 return rcutils_system_time_now(current_time);
69 return rcl_get_system_time(data, current_time);
71 *current_time = rcutils_atomic_load_uint64_t(&(t->current_time));
103 switch (clock_type) {
106 rcl_init_generic_clock(clock, allocator);
120 rcl_clock_generic_fini(
138 switch (clock->
type) {
159 rcl_init_generic_clock(clock, allocator);
161 if (NULL == clock->
data) {
162 RCL_SET_ERROR_MSG(
"allocating memory failed");
168 atomic_init(&(storage->current_time), 0);
169 storage->active =
false;
170 clock->
get_now = rcl_get_ros_time;
181 RCL_SET_ERROR_MSG(
"clock not of type RCL_ROS_TIME");
184 rcl_clock_generic_fini(clock);
197 rcl_init_generic_clock(clock, allocator);
198 clock->
get_now = rcl_get_steady_time;
209 RCL_SET_ERROR_MSG(
"clock not of type RCL_STEADY_TIME");
212 rcl_clock_generic_fini(clock);
223 rcl_init_generic_clock(clock, allocator);
224 clock->
get_now = rcl_get_system_time;
235 RCL_SET_ERROR_MSG(
"clock not of type RCL_SYSTEM_TIME");
238 rcl_clock_generic_fini(clock);
250 RCL_SET_ERROR_MSG(
"Cannot difference between time points with clocks types.");
271 return clock->
get_now(clock->
data, time_point_value);
273 RCL_SET_ERROR_MSG(
"Clock is not initialized or does not have get_now registered.");
278 rcl_clock_call_callbacks(
303 RCL_SET_ERROR_MSG(
"Clock is not of type RCL_ROS_TIME, cannot enable override.");
307 RCL_CHECK_FOR_NULL_WITH_MSG(
308 storage,
"Clock storage is not initialized, cannot enable override.",
return RCL_RET_ERROR);
309 if (!storage->active) {
313 rcl_clock_call_callbacks(clock, &time_jump,
true);
314 storage->active =
true;
315 rcl_clock_call_callbacks(clock, &time_jump,
false);
325 RCL_SET_ERROR_MSG(
"Clock is not of type RCL_ROS_TIME, cannot disable override.");
329 RCL_CHECK_FOR_NULL_WITH_MSG(
330 storage,
"Clock storage is not initialized, cannot enable override.",
return RCL_RET_ERROR);
331 if (storage->active) {
335 rcl_clock_call_callbacks(clock, &time_jump,
true);
336 storage->active =
false;
337 rcl_clock_call_callbacks(clock, &time_jump,
false);
350 RCL_SET_ERROR_MSG(
"Clock is not of type RCL_ROS_TIME, cannot query override state.");
354 RCL_CHECK_FOR_NULL_WITH_MSG(
355 storage,
"Clock storage is not initialized, cannot enable override.",
return RCL_RET_ERROR);
356 *is_enabled = storage->active;
367 RCL_SET_ERROR_MSG(
"Clock is not of type RCL_ROS_TIME, cannot set time override.");
371 RCL_CHECK_FOR_NULL_WITH_MSG(
372 storage,
"Clock storage is not initialized, cannot enable override.",
return RCL_RET_ERROR);
374 if (storage->active) {
377 rcl_ret_t ret = rcl_get_ros_time(storage, ¤t_time);
382 rcl_clock_call_callbacks(clock, &time_jump,
true);
383 rcutils_atomic_store(&(storage->current_time), time_value);
384 rcl_clock_call_callbacks(clock, &time_jump,
false);
386 rcutils_atomic_store(&(storage->current_time), time_value);
402 RCL_SET_ERROR_MSG(
"forward jump threshold must be positive or zero");
406 RCL_SET_ERROR_MSG(
"backward jump threshold must be negative or zero");
414 RCL_SET_ERROR_MSG(
"callback/user_data are already added to this clock");
423 if (NULL == callbacks) {
424 RCL_SET_ERROR_MSG(
"Failed to realloc jump callbacks");
446 bool found_callback =
false;
449 if (found_callback) {
452 found_callback =
true;
455 if (!found_callback) {
456 RCL_SET_ERROR_MSG(
"jump callback was not found");
468 if (NULL == callbacks) {
469 RCL_SET_ERROR_MSG(
"Failed to shrink jump callbacks");
#define RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, msg, fail_statement)
Check that the given allocator is initialized, or fail with a message.
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
Encapsulation of a time source.
rcl_jump_callback_info_t * jump_callbacks
An array of added jump callbacks.
void * data
Clock storage.
rcl_allocator_t allocator
Custom allocator used for internal allocations.
rcl_ret_t(* get_now)(void *data, rcl_time_point_value_t *now)
Pointer to get_now function.
rcl_clock_type_t type
Clock type.
size_t num_jump_callbacks
Number of callbacks in jump_callbacks.
A duration of time, measured in nanoseconds and its source.
rcl_duration_value_t nanoseconds
Duration in nanoseconds and its source.
Struct to describe an added callback.
void * user_data
Pointer passed to the callback.
rcl_jump_threshold_t threshold
Threshold to decide when to call the callback.
rcl_jump_callback_t callback
Callback to fucntion.
Describe the prerequisites for calling a time jump callback.
rcl_duration_t min_forward
bool on_clock_change
True to call callback when the clock type changes.
rcl_duration_t min_backward
Struct to describe a jump in time.
rcl_clock_change_t clock_change
Indicate whether or not the source of time changed.
rcl_duration_t delta
The new time minus the last time before the jump.
A single point in time, measured in nanoseconds, the reference point is based on the source.
rcl_clock_type_t clock_type
Clock type of the point in time.
rcl_time_point_value_t nanoseconds
Nanoseconds of the point in time.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_ros_clock_init(rcl_clock_t *clock, rcl_allocator_t *allocator)
Initialize a clock as a RCL_ROS_TIME time source.
enum rcl_clock_type_e rcl_clock_type_t
Time source type, used to indicate the source of a time measurement.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_steady_clock_init(rcl_clock_t *clock, rcl_allocator_t *allocator)
Initialize a clock as a RCL_STEADY_TIME time source.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_enable_ros_time_override(rcl_clock_t *clock)
Enable the ROS time abstraction override.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_difference_times(const rcl_time_point_t *start, const rcl_time_point_t *finish, rcl_duration_t *delta)
Compute the difference between two time points.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_steady_clock_fini(rcl_clock_t *clock)
Finalize a clock as a RCL_STEADY_TIME time source.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_clock_get_now(rcl_clock_t *clock, rcl_time_point_value_t *time_point_value)
Fill the time point value with the current value of the associated clock.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_clock_fini(rcl_clock_t *clock)
Finalize a clock.
@ RCL_ROS_TIME_DEACTIVATED
The source switched to SYSTEM_TIME from ROS_TIME.
@ RCL_ROS_TIME_NO_CHANGE
The source before and after the jump is ROS_TIME.
@ RCL_ROS_TIME_ACTIVATED
The source switched to ROS_TIME from SYSTEM_TIME.
rcutils_time_point_value_t rcl_time_point_value_t
A single point in time, measured in nanoseconds since the Unix epoch.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_system_clock_init(rcl_clock_t *clock, rcl_allocator_t *allocator)
Initialize a clock as a RCL_SYSTEM_TIME time source.
RCL_PUBLIC RCL_WARN_UNUSED bool rcl_clock_time_started(rcl_clock_t *clock)
Check if the clock has started.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_ros_clock_fini(rcl_clock_t *clock)
Finalize a clock as a RCL_ROS_TIME time source.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_disable_ros_time_override(rcl_clock_t *clock)
Disable the ROS time abstraction override.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_clock_add_jump_callback(rcl_clock_t *clock, rcl_jump_threshold_t threshold, rcl_jump_callback_t callback, void *user_data)
Add a callback to be called when a time jump exceeds a threshold.
void(* rcl_jump_callback_t)(const rcl_time_jump_t *time_jump, bool before_jump, void *user_data)
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_is_enabled_ros_time_override(rcl_clock_t *clock, bool *is_enabled)
Check if the RCL_ROS_TIME time source has the override enabled.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_clock_remove_jump_callback(rcl_clock_t *clock, rcl_jump_callback_t callback, void *user_data)
Remove a previously added time jump callback.
@ RCL_ROS_TIME
Use ROS time.
@ RCL_SYSTEM_TIME
Use system time.
@ RCL_CLOCK_UNINITIALIZED
Clock uninitialized.
@ RCL_STEADY_TIME
Use a steady clock time.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_system_clock_fini(rcl_clock_t *clock)
Finalize a clock as a RCL_SYSTEM_TIME time source.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_set_ros_time_override(rcl_clock_t *clock, rcl_time_point_value_t time_value)
Set the current time for this RCL_ROS_TIME time source.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_clock_init(rcl_clock_type_t clock_type, rcl_clock_t *clock, rcl_allocator_t *allocator)
Initialize a clock based on the passed type.
RCL_PUBLIC RCL_WARN_UNUSED bool rcl_clock_valid(rcl_clock_t *clock)
Check if the clock has valid values.
#define RCL_RET_OK
Success return code.
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
#define RCL_RET_ERROR
Unspecified error return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.