// Copyright 2016 Open Source Robotics Foundation, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** \mainpage rcl: Common functionality ROS lifecycle * * `rcl_lifecycle` provides a pure C implementation of the ROS concept of lifecycle. * It builds on top of the implementation of topics and services in `rcl`. * * `rcl_lifecycle` consists of functions and structs for the following ROS lifecycle entities: * * - Lifecycle states * - Lifecycle transitions * - Lifecycle state machine * - Lifecycle triggers * * Some useful abstractions: * * - Return codes and other types * - rcl_lifecycle/data_types.h */ #ifndef RCL_LIFECYCLE__RCL_LIFECYCLE_H_ #define RCL_LIFECYCLE__RCL_LIFECYCLE_H_ #ifdef __cplusplus extern "C" { #endif #include #include "rcl_lifecycle/data_types.h" #include "rcl_lifecycle/default_state_machine.h" #include "rcl_lifecycle/visibility_control.h" /// Return a rcl_lifecycle_state_t struct with members set to `NULL` or 0. /** * Should be called to get a null rcl_lifecycle_state_t before passing to * rcl_lifecycle_state_init(). * * \return rcl_lifecycle_state_t a initilized struct */ RCL_LIFECYCLE_PUBLIC rcl_lifecycle_state_t rcl_lifecycle_get_zero_initialized_state(); /// Initialize a rcl_lifecycle_state_init. /** * This function initializes a state based on an `id` and a `label`. * * The given `rcl_lifecycle_state_t` must be zero initialized with the function * `rcl_lifecycle_get_zero_initialized_state()` and must not be already initialized * by this function. * The allocator will be used to allocate the label string. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[inout] state pointer to the state struct to be initialized * \param[in] id identifier of the state * \param[in] label label of the state * \param[in] allocator a valid allocator used to initialized the lifecycle state * \return `RCL_RET_OK` if state was initialized successfully, or * \return `RCL_RET_ERROR` if an unspecified error occurs. */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lifecycle_state_init( rcl_lifecycle_state_t * state, unsigned int id, const char * label, const rcl_allocator_t * allocator); /// Finalize a rcl_lifecycle_state_t. /** * * Calling this will set the rcl_lifecycle_state_t struct into the an unitialized state that is * functionally the same as before rcl_lifecycle_state_init was called. This function make the * rcl_lifecycle_state_t invalid. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[inout] state struct to be finalized * \param[in] allocator a valid allocator used to finalize the lifecycle state * \return `RCL_RET_OK` if the state was finalized successfully, or * \return `RCL_RET_ERROR` if an unspecified error occurs. */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lifecycle_state_fini( rcl_lifecycle_state_t * state, const rcl_allocator_t * allocator); /// Return a rcl_lifecycle_transition_t struct with members set to `NULL` or 0. /** * Should be called to get a null rcl_lifecycle_transition_t before passing to * rcl_lifecycle_transition_init(). */ RCL_LIFECYCLE_PUBLIC rcl_lifecycle_transition_t rcl_lifecycle_get_zero_initialized_transition(); /// Initialize a transition from a start state to the goal state. /** * The given `rcl_lifecycle_transition_t` must be zero initialized with the function * `rcl_lifecycle_get_zero_initialized_transition()` and must not be already initialized * by this function. * The allocator will be used to allocate the label string and the rcl_lifecycle_state_t structs. * * Note: the transition pointer will take ownership * of the start and goal state. When calling * rcl_lifecycle_transition_fini(), the two states * will be freed. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[in] transition to a preallocated, zero-initialized transition structure * to be initialized. * \param[in] id identifier of the transition * \param[in] label label of the transition * \param[in] start the value where the transition is initialized * \param[in] goal the objetive of the transition * \param[in] allocator a valid allocator used to finalize the lifecycle state * \return `RCL_RET_OK` if the transition is initialized successfully, or * \return `RCL_RET_ERROR` if an unspecified error occurs. */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lifecycle_transition_init( rcl_lifecycle_transition_t * transition, unsigned int id, const char * label, rcl_lifecycle_state_t * start, rcl_lifecycle_state_t * goal, const rcl_allocator_t * allocator); /// Finalize a rcl_lifecycle_transition_t. /** * Calling this will set the rcl_lifecycle_transition_t struct into the an unitialized state that is * functionally the same as before rcl_lifecycle_transition_init was called. This function make the * rcl_lifecycle_transition_t invalid. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[inout] transition struct to be finalized * \param[in] allocator a valid allocator used to finalize the transition * \return `RCL_RET_OK` if the state was finalized successfully, or * \return `RCL_RET_ERROR` if an unspecified error occurs. */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lifecycle_transition_fini( rcl_lifecycle_transition_t * transition, const rcl_allocator_t * allocator); /// Return a rcl_lifecycle_state_machine_t struct with members set to `NULL` or 0. /** * Should be called to get a null rcl_lifecycle_state_machine_t before passing to * rcl_lifecycle_state_machine_init(). */ RCL_LIFECYCLE_PUBLIC rcl_lifecycle_state_machine_t rcl_lifecycle_get_zero_initialized_state_machine(); /// Initialize state machine /** * This function initialize the state machine: one publisher to publish transitions messages * and a set of services to get information about states and transitions. * If `default_state` is `true` then a new default state machine is initialized. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[inout] state_machine struct to be initialized * \param[in] node_handle a valid (not finalized) handle to the node used to create the publisher * and the services * \param[in] ts_pub_notify pointer to transition publisher, it used to publish the transitions * \param[in] ts_srv_change_state pointer to the service that allows to trigger changes on the state * \param[in] ts_srv_get_state pointer to the service that allows to get the current state * \param[in] ts_srv_get_available_states pointer to the service that allows to get the available states * \param[in] ts_srv_get_available_transitions pointer to the service that allows to get the * available transitions * \param[in] ts_srv_get_transition_graph pointer to the service that allows to get transitions from * the graph * \param[in] default_states if `true` a new default state machine is initialized, otherwise * the state_machine pointer is only used to initialize the interfaces * \param[in] allocator a valid allocator used to initialized the state machine * \return `RCL_RET_OK` if the state machine was initialized successfully, or * \return `RCL_RET_ERROR` if an unspecified error occurs. */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lifecycle_state_machine_init( rcl_lifecycle_state_machine_t * state_machine, rcl_node_t * node_handle, const rosidl_message_type_support_t * ts_pub_notify, const rosidl_service_type_support_t * ts_srv_change_state, const rosidl_service_type_support_t * ts_srv_get_state, const rosidl_service_type_support_t * ts_srv_get_available_states, const rosidl_service_type_support_t * ts_srv_get_available_transitions, const rosidl_service_type_support_t * ts_srv_get_transition_graph, bool default_states, const rcl_allocator_t * allocator); /// Finalize a rcl_lifecycle_state_machine_t. /** * Calling this will set the rcl_lifecycle_state_machine_t struct into the an unitialized state that is * functionally the same as before rcl_lifecycle_state_machine_init was called. This function make the * rcl_lifecycle_state_machine_t invalid. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | Yes * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[inout] state_machine struct to be finalized * \param[in] node_handle valid (not finalized) handle to the node * \param[in] allocator a valid allocator used to finalize the state machine * \return `RCL_RET_OK` if the state was finalized successfully, or * \return `RCL_RET_ERROR` if an unspecified error occurs. */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lifecycle_state_machine_fini( rcl_lifecycle_state_machine_t * state_machine, rcl_node_t * node_handle, const rcl_allocator_t * allocator); /// Check if a state machine is active. /** * If the state is initialized then returns `RCL_RET_OK`, otherwise returns `RCL_RET_ERROR` * In the case where `RCL_RET_ERROR` is to be returned, an error message is set. * This function cannot fail. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[in] state_machine pointer to the state machine struct * \return `RCL_RET_OK` if the state is initialized, or * \return `RCL_RET_ERROR` if an unspecified error occurs. */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lifecycle_state_machine_is_initialized( const rcl_lifecycle_state_machine_t * state_machine); /// Get a state by id. /** * A pointer to the internally transition struct is returned * based on the `id`. If the `id` is not set in the state then returns NULL. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[in] state pointer to the state struct * \param[in] id identifier to be find in the valid transitions * \return a pointer to the lifecycle transition if the `id` exists or otherwise it return NULL */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED const rcl_lifecycle_transition_t * rcl_lifecycle_get_transition_by_id( const rcl_lifecycle_state_t * state, uint8_t id); /// Get a state by id. /** * A pointer to the internally transition struct is returned * based on the `label`. If the `label` is not set in the state then returns NULL. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[in] state pointer to the state struct * \param[in] label label to be find in the valid transitions * \return a pointer to the lifecycle transition if the label exists or otherwise it return NULL */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED const rcl_lifecycle_transition_t * rcl_lifecycle_get_transition_by_label( const rcl_lifecycle_state_t * state, const char * label); /// Trigger a state by id. /** * This function will trigger a transition based on the `id`. If the argument * `publish_notification` is `true` then a message will be published in the * ROS 2 network notifying the transition, if `false` no message will be published. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[in] state_machine pointer to the state machine struct * \param[in] id identifier of the transition to be triggered * \param[in] publish_notification if the value is `true` a message will be published * notifying the transition, otherwise no message will be published * \return `RCL_RET_OK` if the transition was triggered successfully, or * \return `RCL_RET_ERROR` if an unspecified error occurs. */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lifecycle_trigger_transition_by_id( rcl_lifecycle_state_machine_t * state_machine, uint8_t id, bool publish_notification); /// Trigger a state by label. /** * This function will trigger a transition base on the `label`. If the argument * `publish_notification` is `true` then a message will be published in the * ROS 2 network notifying the transition, if `false` no message will be published. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[in] state_machine pointer to the state machine struct * \param[in] label of the transition to be triggered * \param[in] publish_notification if the value is `true` a message will be published * notifying the transition, otherwise no message will be published * \return `RCL_RET_OK` if the transition was triggered successfully, or * \return `RCL_RET_ERROR` if an unspecified error occurs. */ RCL_LIFECYCLE_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_lifecycle_trigger_transition_by_label( rcl_lifecycle_state_machine_t * state_machine, const char * label, bool publish_notification); /// Print the state machine data /** * This function will print in the standard output the data in the * rcl_lifecycle_state_machine_t struct. * *
* Attribute | Adherence * ------------------ | ------------- * Allocates Memory | No * Thread-Safe | No * Uses Atomics | No * Lock-Free | Yes * * \param[in] state_machine pointer to the state machine struct to print */ RCL_LIFECYCLE_PUBLIC void rcl_print_state_machine(const rcl_lifecycle_state_machine_t * state_machine); #ifdef __cplusplus } #endif // extern "C" #endif // RCL_LIFECYCLE__RCL_LIFECYCLE_H_