[rcl_action] Implement goal handle (#320)
* Add action goal handle implementation and unit tests * Add check to goal state machine transition function for index out of bounds
This commit is contained in:
parent
1120b2f6a4
commit
b2578bbbda
5 changed files with 498 additions and 59 deletions
|
@ -23,9 +23,8 @@ extern "C"
|
|||
#include "rcl_action/goal_state_machine.h"
|
||||
#include "rcl_action/types.h"
|
||||
#include "rcl_action/visibility_control.h"
|
||||
#include "rcl/allocator.h"
|
||||
|
||||
// Forward declare
|
||||
typedef struct rcl_action_server_t rcl_action_server_t;
|
||||
|
||||
/// Internal rcl action goal implementation struct.
|
||||
struct rcl_action_goal_handle_impl_t;
|
||||
|
@ -55,33 +54,10 @@ rcl_action_get_zero_initialized_goal_handle(void);
|
|||
* Goal information can be accessed with rcl_action_goal_handle_get_message() and
|
||||
* rcl_action_goal_handle_get_info().
|
||||
*
|
||||
* The given rcl_action_server_t must be valid and the resulting rcl_action_goal_handle_t is
|
||||
* only valid as long as the given rcl_action_server_t remains valid.
|
||||
*
|
||||
* Expected usage:
|
||||
*
|
||||
* ```c
|
||||
* #include <rcl/rcl.h>
|
||||
* #include <rcl_action/rcl_action.h>
|
||||
* #include <rosidl_generator_c/action_type_support_struct.h>
|
||||
* #include <example_interfaces/action/fibonacci.h>
|
||||
*
|
||||
* // ... initialize node
|
||||
* const rosidl_action_type_support_t * ts =
|
||||
* ROSIDL_GET_ACTION_TYPE_SUPPORT(example_interfaces, Fibonacci);
|
||||
* rcl_action_server_t action_server = rcl_action_get_zero_initialized_server();
|
||||
* rcl_action_server_options_t action_server_ops = rcl_action_server_get_default_options();
|
||||
* ret = rcl_action_server_init(&action_server, &node, ts, "fibonacci", &action_server_ops);
|
||||
* // ... error handling
|
||||
* rcl_action_goal_handle_t goal_handle = rcl_action_get_zero_initialized_goal_handle();
|
||||
* ret = rcl_action_goal_handle_init(&goal_handle, &action_server);
|
||||
* // ... error handling, and on shutdown do finalization:
|
||||
* ret = rcl_action_goal_handle_fini(&goal_handle);
|
||||
* // ... error handling for rcl_goal_handle_fini()
|
||||
* ret = rcl_action_server_fini(&action_server, &node);
|
||||
* // ... error handling for rcl_action_server_fini()
|
||||
* // ... finalize and error handling for node
|
||||
* ```
|
||||
* Goal handles are typically initialized and finalized by action servers.
|
||||
* I.e. The allocator should be provided by the action server.
|
||||
* Goal handles are created with rcl_action_accept_new_goal() and destroyed with
|
||||
* rcl_action_clear_expired_goals() or rcl_action_server_fini().
|
||||
*
|
||||
* <hr>
|
||||
* Attribute | Adherence
|
||||
|
@ -93,20 +69,21 @@ rcl_action_get_zero_initialized_goal_handle(void);
|
|||
*
|
||||
* \param[out] goal_handle preallocated, zero-initialized, goal handle structure
|
||||
* to be initialized
|
||||
* \param[in] action_server valid rcl action server
|
||||
* \param[in] type_support type support object for the action's type
|
||||
* \param[in] goal_info information about the goal to be copied to the goal handle
|
||||
* \param[in] allocator a valid allocator used to initialized the goal handle
|
||||
* \return `RCL_RET_OK` if goal_handle was initialized successfully, or
|
||||
* \return `RCL_RET_INVALID_ARGUMENT` if the allocator is invalid, or
|
||||
* \return `RCL_RET_ACTION_GOAL_HANDLE_INVALID` if the goal handle is invalid, or
|
||||
* \return `RCL_RET_ACTION_SERVER_INVALID` if the action server is invalid, or
|
||||
* \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
|
||||
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
||||
* \return `RCL_RET_ALREADY_INIT` if the goal handle has already been initialized, or
|
||||
* \return `RCL_RET_BAD_ALLOC` if allocating memory failed
|
||||
*/
|
||||
RCL_ACTION_PUBLIC
|
||||
RCL_WARN_UNUSED
|
||||
rcl_ret_t
|
||||
rcl_action_goal_handle_init(
|
||||
rcl_action_goal_handle_t * goal_handle,
|
||||
const rcl_action_server_t * action_server);
|
||||
rcl_action_goal_info_t * goal_info,
|
||||
rcl_allocator_t allocator);
|
||||
|
||||
/// Finalize a rcl_action_goal_handle_t.
|
||||
/**
|
||||
|
@ -128,11 +105,9 @@ rcl_action_goal_handle_init(
|
|||
* Uses Atomics | No
|
||||
* Lock-Free | Yes
|
||||
*
|
||||
* \param[in] goal_handle struct to be deinitialized
|
||||
* \param[in] action_server used to create the goal handle
|
||||
* \param[inout] goal_handle struct to be deinitialized
|
||||
* \return `RCL_RET_OK` if the goal handle was deinitialized successfully, or
|
||||
* \return `RCL_RET_ACTION_GOAL_HANDLE_INVALID` if the goal handle is invalid, or
|
||||
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
||||
*/
|
||||
RCL_ACTION_PUBLIC
|
||||
RCL_WARN_UNUSED
|
||||
|
@ -156,7 +131,6 @@ rcl_action_goal_handle_fini(rcl_action_goal_handle_t * goal_handle);
|
|||
* \return `RCL_RET_OK` if the goal state was updated successfully, or
|
||||
* \return `RCL_RET_ACTION_GOAL_EVENT_INVALID` if the goal event is invalid, or
|
||||
* \return `RCL_RET_ACTION_GOAL_HANDLE_INVALID` if the goal handle is invalid, or
|
||||
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
||||
*/
|
||||
RCL_ACTION_PUBLIC
|
||||
RCL_WARN_UNUSED
|
||||
|
@ -181,7 +155,7 @@ rcl_action_update_goal_state(
|
|||
* \param[out] goal_info a preallocated struct where the goal info is copied
|
||||
* \return `RCL_RET_OK` if the goal ID was accessed successfully, or
|
||||
* \return `RCL_RET_ACTION_GOAL_HANDLE_INVALID` if the goal handle is invalid, or
|
||||
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
||||
* \return `RCL_RET_INVALID_ARGUMENT` if the goal_info argument is invalid
|
||||
*/
|
||||
RCL_ACTION_PUBLIC
|
||||
RCL_WARN_UNUSED
|
||||
|
@ -206,7 +180,7 @@ rcl_action_goal_handle_get_info(
|
|||
* \param[out] status a preallocated struct where the goal status is copied
|
||||
* \return `RCL_RET_OK` if the goal ID was accessed successfully, or
|
||||
* \return `RCL_RET_ACTION_GOAL_HANDLE_INVALID` if the goal handle is invalid, or
|
||||
* \return `RCL_RET_ERROR` if an unspecified error occurs.
|
||||
* \return `RCL_RET_INVALID_ARGUMENT` if the status argument is invalid
|
||||
*/
|
||||
RCL_ACTION_PUBLIC
|
||||
RCL_WARN_UNUSED
|
||||
|
@ -219,10 +193,6 @@ rcl_action_goal_handle_get_status(
|
|||
/**
|
||||
* This is a non-blocking call.
|
||||
*
|
||||
* The allocator needs to either be a valid allocator or `NULL`, in which case
|
||||
* the default allocator will be used.
|
||||
* The allocator is used when allocation is needed for an error message.
|
||||
*
|
||||
* <hr>
|
||||
* Attribute | Adherence
|
||||
* ------------------ | -------------
|
||||
|
@ -232,26 +202,19 @@ rcl_action_goal_handle_get_status(
|
|||
* Lock-Free | Yes
|
||||
*
|
||||
* \param[in] goal_handle struct containing the goal and metadata
|
||||
* \param[in] error_msg_allocator a valid allocator or `NULL`
|
||||
* \return `true` if a goal is in one of the following states: ACCEPTED, EXECUTING, or CANCELING, or
|
||||
* \return `false` otherwise, also
|
||||
* \return `false` if the goal handle pointer is invalid or the allocator is invalid
|
||||
* \return `false` if the goal handle pointer is invalid
|
||||
*/
|
||||
RCL_ACTION_PUBLIC
|
||||
RCL_WARN_UNUSED
|
||||
bool
|
||||
rcl_action_goal_handle_is_active(
|
||||
const rcl_action_goal_handle_t * goal_handle,
|
||||
rcl_allocator_t * error_msg_allocator);
|
||||
rcl_action_goal_handle_is_active(const rcl_action_goal_handle_t * goal_handle);
|
||||
|
||||
/// Check if a rcl_action_goal_handle_t is valid.
|
||||
/**
|
||||
* This is a non-blocking call.
|
||||
*
|
||||
* The allocator needs to either be a valid allocator or `NULL`, in which case
|
||||
* the default allocator will be used.
|
||||
* The allocator is used when allocation is needed for an error message.
|
||||
*
|
||||
* A goal handle is invalid if:
|
||||
* - the implementation is `NULL` (rcl_action_goal_handle_init() not called or failed)
|
||||
* - rcl_shutdown() has been called since the goal handle has been initialized
|
||||
|
@ -266,16 +229,13 @@ rcl_action_goal_handle_is_active(
|
|||
* Lock-Free | Yes
|
||||
*
|
||||
* \param[in] goal_handle struct to evaluate as valid or not
|
||||
* \param[in] error_msg_allocator a valid allocator or `NULL`
|
||||
* \return `true` if the goal handle is valid, `false` otherwise, also
|
||||
* \return `false` if the allocator is invalid
|
||||
* \return `false` if the goal handle pointer is null
|
||||
*/
|
||||
RCL_ACTION_PUBLIC
|
||||
RCL_WARN_UNUSED
|
||||
bool
|
||||
rcl_action_goal_handle_is_valid(
|
||||
const rcl_action_goal_handle_t * goal_handle,
|
||||
rcl_allocator_t * error_msg_allocator);
|
||||
rcl_action_goal_handle_is_valid(const rcl_action_goal_handle_t * goal_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue