rcl
master
C API providing common ROS client library functionality.
|
#include "rosidl_generator_c/service_type_support.h"
#include "rcl/macros.h"
#include "rcl/node.h"
#include "rcl/visibility_control.h"
Go to the source code of this file.
Classes | |
struct | rcl_service_t |
Structure which encapsulates a ROS Service. More... | |
struct | rcl_service_options_t |
Options available for a rcl service. More... | |
Typedefs | |
typedef struct rcl_service_t | rcl_service_t |
Structure which encapsulates a ROS Service. More... | |
typedef struct rcl_service_options_t | rcl_service_options_t |
Options available for a rcl service. More... | |
Functions | |
rcl_service_t | rcl_get_zero_initialized_service (void) |
Return a rcl_service_t struct with members set to NULL . More... | |
rcl_ret_t | rcl_service_init (rcl_service_t *service, const rcl_node_t *node, const rosidl_service_type_support_t *type_support, const char *service_name, const rcl_service_options_t *options) |
Initialize a rcl service. More... | |
rcl_ret_t | rcl_service_fini (rcl_service_t *service, rcl_node_t *node) |
Finalize a rcl_service_t. More... | |
rcl_service_options_t | rcl_service_get_default_options (void) |
Return the default service options in a rcl_service_options_t. More... | |
rcl_ret_t | rcl_take_request (const rcl_service_t *service, rmw_request_id_t *request_header, void *ros_request) |
Take a pending ROS request using a rcl service. More... | |
rcl_ret_t | rcl_send_response (const rcl_service_t *service, rmw_request_id_t *response_header, void *ros_response) |
Send a ROS response to a client using a service. More... | |
const char * | rcl_service_get_service_name (const rcl_service_t *service) |
Get the topic name for the service. More... | |
const rcl_service_options_t * | rcl_service_get_options (const rcl_service_t *service) |
Return the rcl service options. More... | |
rmw_service_t * | rcl_service_get_rmw_handle (const rcl_service_t *service) |
Return the rmw service handle. More... | |
bool | rcl_service_is_valid (const rcl_service_t *service) |
Check that the service is valid. More... | |
typedef struct rcl_service_t rcl_service_t |
Structure which encapsulates a ROS Service.
typedef struct rcl_service_options_t rcl_service_options_t |
Options available for a rcl service.
rcl_service_t rcl_get_zero_initialized_service | ( | void | ) |
Return a rcl_service_t struct with members set to NULL
.
Should be called to get a null rcl_service_t before passing to rcl_service_init().
rcl_ret_t rcl_service_init | ( | rcl_service_t * | service, |
const rcl_node_t * | node, | ||
const rosidl_service_type_support_t * | type_support, | ||
const char * | service_name, | ||
const rcl_service_options_t * | options | ||
) |
Initialize a rcl service.
After calling this function on a rcl_service_t, it can be used to take requests of the given type to the given topic using rcl_take_request(). It can also send a response to a request using rcl_send_response().
The given rcl_node_t must be valid and the resulting rcl_service_t is only valid as long as the given rcl_node_t remains valid.
The rosidl_service_type_support_t is obtained on a per .srv type basis. When the user defines a ROS service, code is generated which provides the required rosidl_service_type_support_t object. This object can be obtained using a language appropriate mechanism.
example_interfaces/AddTwoInts
):For C++ a template function is used:
The rosidl_service_type_support_t object contains service type specific information used to send or take requests and responses.
The topic name must be a c string which follows the topic and service name format rules for unexpanded names, also known as non-fully qualified names:
The options struct allows the user to set the quality of service settings as well as a custom allocator which is used when initializing/finalizing the client to allocate space for incidentals, e.g. the service name string.
Expected usage (for C services):
Attribute | Adherence |
---|---|
Allocates Memory | Yes |
Thread-Safe | No |
Uses Atomics | No |
Lock-Free | Yes |
[out] | service | preallocated service structure |
[in] | node | valid rcl node handle |
[in] | type_support | type support object for the service's type |
[in] | service_name | the name of the service |
[in] | options | service options, including quality of service settings |
RCL_RET_OK
if service was initialized successfully, or RCL_RET_INVALID_ARGUMENT
if any arguments are invalid, or RCL_RET_BAD_ALLOC
if allocating memory failed, or RCL_RET_SERVICE_NAME_INVALID
if the given service name is invalid, or RCL_RET_ERROR
if an unspecified error occurs. rcl_ret_t rcl_service_fini | ( | rcl_service_t * | service, |
rcl_node_t * | node | ||
) |
Finalize a rcl_service_t.
After calling, the node will no longer listen for requests for this service. (assuming this is the only service of this type in this node).
After calling, calls to rcl_wait(), rcl_take_request(), and rcl_send_response() will fail when using this service. Additionally rcl_wait() will be interrupted if currently blocking. However, the given node handle is still valid.
Attribute | Adherence |
---|---|
Allocates Memory | Yes |
Thread-Safe | No |
Uses Atomics | No |
Lock-Free | Yes |
[in,out] | service | handle to the service to be deinitialized |
[in] | node | handle to the node used to create the service |
RCL_RET_OK
if service was deinitialized successfully, or RCL_RET_INVALID_ARGUMENT
if any arguments are invalid, or RCL_RET_ERROR
if an unspecified error occurs. rcl_service_options_t rcl_service_get_default_options | ( | void | ) |
Return the default service options in a rcl_service_options_t.
The defaults are:
rcl_ret_t rcl_take_request | ( | const rcl_service_t * | service, |
rmw_request_id_t * | request_header, | ||
void * | ros_request | ||
) |
Take a pending ROS request using a rcl service.
It is the job of the caller to ensure that the type of the ros_request argument and the type associate with the service, via the type support, match. Passing a different type to rcl_take produces undefined behavior and cannot be checked by this function and therefore no deliberate error will occur.
TODO(jacquelinekay) blocking of take? TODO(jacquelinekay) pre-, during-, and post-conditions for message ownership? TODO(jacquelinekay) is rcl_take_request thread-safe? TODO(jacquelinekay) Should there be an rcl_request_id_t?
The ros_request pointer should point to an already allocated ROS request message struct of the correct type, into which the taken ROS request will be copied if one is available. If taken is false after calling, then the ROS request will be unmodified.
If allocation is required when taking the request, e.g. if space needs to be allocated for a dynamically sized array in the target message, then the allocator given in the service options is used.
request_header is a pointer to pre-allocated a rmw struct containing meta-information about the request (e.g. the sequence number).
Attribute | Adherence |
---|---|
Allocates Memory | Maybe [1] |
Thread-Safe | No |
Uses Atomics | No |
Lock-Free | Yes |
[1] only if required when filling the request, avoided for fixed sizes
[in] | service | the handle to the service from which to take |
[in,out] | request_header | ptr to the struct holding metadata about the request ID |
[in,out] | ros_request | type-erased ptr to an allocated ROS request message |
RCL_RET_OK
if the request was taken, or RCL_RET_INVALID_ARGUMENT
if any arguments are invalid, or RCL_RET_SERVICE_INVALID
if the service is invalid, or RCL_RET_BAD_ALLOC
if allocating memory failed, or RCL_RET_ERROR
if an unspecified error occurs. rcl_ret_t rcl_send_response | ( | const rcl_service_t * | service, |
rmw_request_id_t * | response_header, | ||
void * | ros_response | ||
) |
Send a ROS response to a client using a service.
It is the job of the caller to ensure that the type of the ros_response
parameter and the type associate with the service (via the type support) match. Passing a different type to send_response produces undefined behavior and cannot be checked by this function and therefore no deliberate error will occur.
send_response() is an non-blocking call.
The ROS response message given by the ros_response
void pointer is always owned by the calling code, but should remain constant during rcl_send_response().
e This function is thread safe so long as access to both the service and the ros_response
is synchronized. That means that calling rcl_send_response() from multiple threads is allowed, but calling rcl_send_response() at the same time as non-thread safe service functions is not, e.g. calling rcl_send_response() and rcl_service_fini() concurrently is not allowed. Before calling rcl_send_response() the message can change and after calling rcl_send_response() the message can change, but it cannot be changed during the rcl_send_response() call. The same ros_response
, however, can be passed to multiple calls of rcl_send_response() simultaneously, even if the services differ. The ros_response
is unmodified by rcl_send_response().
Attribute | Adherence |
---|---|
Allocates Memory | No |
Thread-Safe | Yes [1] |
Uses Atomics | No |
Lock-Free | Yes |
[1] for unique pairs of services and responses, see above for more
[in] | service | handle to the service which will make the response |
[in,out] | response_header | ptr to the struct holding metadata about the request ID |
[in] | ros_response | type-erased pointer to the ROS response message |
RCL_RET_OK
if the response was sent successfully, or RCL_RET_INVALID_ARGUMENT
if any arguments are invalid, or RCL_RET_SERVICE_INVALID
if the service is invalid, or RCL_RET_ERROR
if an unspecified error occurs. const char* rcl_service_get_service_name | ( | const rcl_service_t * | service | ) |
Get the topic name for the service.
This function returns the service's internal topic name string. This function can fail, and therefore return NULL
, if the:
NULL
The returned string is only valid as long as the service is valid. The value of the string may change if the topic name changes, and therefore copying the string is recommended if this is a concern.
Attribute | Adherence |
---|---|
Allocates Memory | No |
Thread-Safe | No |
Uses Atomics | No |
Lock-Free | Yes |
[in] | service | the pointer to the service |
NULL
const rcl_service_options_t* rcl_service_get_options | ( | const rcl_service_t * | service | ) |
Return the rcl service options.
This function returns the service's internal options struct. This function can fail, and therefore return NULL
, if the:
NULL
The returned struct is only valid as long as the service is valid. The values in the struct may change if the service's options change, and therefore copying the struct is recommended if this is a concern.
Attribute | Adherence |
---|---|
Allocates Memory | No |
Thread-Safe | No |
Uses Atomics | No |
Lock-Free | Yes |
[in] | service | pointer to the service |
NULL
rmw_service_t* rcl_service_get_rmw_handle | ( | const rcl_service_t * | service | ) |
Return the rmw service handle.
The handle returned is a pointer to the internally held rmw handle. This function can fail, and therefore return NULL
, if the:
NULL
The returned handle is made invalid if the service is finalized or if rcl_shutdown() is called. The returned handle is not guaranteed to be valid for the life time of the service as it may be finalized and recreated itself. Therefore it is recommended to get the handle from the service using this function each time it is needed and avoid use of the handle concurrently with functions that might change it.
Attribute | Adherence |
---|---|
Allocates Memory | No |
Thread-Safe | No |
Uses Atomics | No |
Lock-Free | Yes |
[in] | service | pointer to the rcl service |
NULL
bool rcl_service_is_valid | ( | const rcl_service_t * | service | ) |
Check that the service is valid.
The bool returned is false
if service
is invalid. The bool returned is true
otherwise. In the case where false
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 |
[in] | service | pointer to the rcl service |
true
if service
is valid, otherwise false