more changes (I will squash this commit)
specifically I: - used more descriptive error codes - added some of the CMake logic - More .c files - Changed some of the documentation to be clearer
This commit is contained in:
parent
4b55f8e1cc
commit
c24a214403
17 changed files with 470 additions and 67 deletions
|
@ -3,11 +3,36 @@ cmake_minimum_required(VERSION 2.8.3)
|
||||||
project(rcl)
|
project(rcl)
|
||||||
|
|
||||||
find_package(ament_cmake REQUIRED)
|
find_package(ament_cmake REQUIRED)
|
||||||
|
find_package(rcl_interfaces REQUIRED)
|
||||||
|
find_package(rmw REQUIRED)
|
||||||
|
find_package(rosidl_generator_cpp REQUIRED)
|
||||||
|
|
||||||
ament_export_dependencies(rmw)
|
ament_export_dependencies(rmw rosidl_generator_cpp)
|
||||||
|
|
||||||
ament_export_include_directories(include)
|
ament_export_include_directories(include)
|
||||||
|
|
||||||
|
include_directories(include)
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c11 -Wall -Wextra")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(${PROJECT_NAME}_sources
|
||||||
|
src/rcl/allocator.c
|
||||||
|
src/rcl/common.c
|
||||||
|
src/rcl/guard_condition.c
|
||||||
|
src/rcl/node.c
|
||||||
|
src/rcl/publisher.c
|
||||||
|
src/rcl/rcl.c
|
||||||
|
src/rcl/subscription.c
|
||||||
|
src/rcl/wait.c
|
||||||
|
)
|
||||||
|
add_library(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_sources})
|
||||||
|
ament_target_dependencies(${PROJECT_NAME}
|
||||||
|
"rcl_interfaces"
|
||||||
|
"rmw"
|
||||||
|
"rosidl_generator_cpp"
|
||||||
|
)
|
||||||
|
|
||||||
if(AMENT_ENABLE_TESTING)
|
if(AMENT_ENABLE_TESTING)
|
||||||
find_package(ament_lint_auto REQUIRED)
|
find_package(ament_lint_auto REQUIRED)
|
||||||
ament_lint_auto_find_test_dependencies()
|
ament_lint_auto_find_test_dependencies()
|
||||||
|
|
|
@ -72,10 +72,16 @@ rcl_get_zero_initialized_guard_condition();
|
||||||
*
|
*
|
||||||
* This function is not thread-safe.
|
* This function is not thread-safe.
|
||||||
*
|
*
|
||||||
|
* \TODO(wjwwood): does this function need a node to be passed to it? (same for fini)
|
||||||
|
*
|
||||||
* \param[inout] guard_condition preallocated guard_condition structure
|
* \param[inout] guard_condition preallocated guard_condition structure
|
||||||
* \param[in] node valid rcl node handle
|
* \param[in] node valid rcl node handle
|
||||||
* \param[in] options the guard_condition's options
|
* \param[in] options the guard_condition's options
|
||||||
* \return RMW_RET_OK if guard_condition was initialized successfully, otherwise RMW_RET_ERROR
|
* \return RCL_RET_OK if guard_condition was initialized successfully, or
|
||||||
|
* RCL_RET_ALREADY_INIT if the guard condition is already initialized, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_BAD_ALLOC if allocating memory failed, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_guard_condition_init(
|
rcl_guard_condition_init(
|
||||||
|
@ -83,16 +89,18 @@ rcl_guard_condition_init(
|
||||||
const rcl_node_t * node,
|
const rcl_node_t * node,
|
||||||
const rcl_guard_condition_options_t * options);
|
const rcl_guard_condition_options_t * options);
|
||||||
|
|
||||||
/// Deinitialize a rcl_guard_condition_t.
|
/// Finalize a rcl_guard_condition_t.
|
||||||
/* After calling, calls to rcl_trigger_guard_condition will fail when using
|
/* After calling, calls to rcl_trigger_guard_condition will fail when using
|
||||||
* this guard condition.
|
* this guard condition.
|
||||||
* However, the given node handle is still valid.
|
* However, the given node handle is still valid.
|
||||||
*
|
*
|
||||||
* This function is not thread-safe.
|
* This function is not thread-safe.
|
||||||
*
|
*
|
||||||
* \param[inout] guard_condition handle to the guard_condition to be deinitialized
|
* \param[inout] guard_condition handle to the guard_condition to be finalized
|
||||||
* \param[in] node handle to the node used to create the guard_condition
|
* \param[in] node handle to the node used to create the guard_condition
|
||||||
* \return RMW_RET_OK if guard_condition was deinitialized successfully, otherwise RMW_RET_ERROR
|
* \return RCL_RET_OK if guard_condition was finalized successfully, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_guard_condition_fini(rcl_guard_condition_t * guard_condition, rcl_node_t * node);
|
rcl_guard_condition_fini(rcl_guard_condition_t * guard_condition, rcl_node_t * node);
|
||||||
|
@ -104,7 +112,7 @@ rcl_guard_condition_get_default_options();
|
||||||
/// Trigger a rcl guard condition.
|
/// Trigger a rcl guard condition.
|
||||||
/* This function can fail, and therefore return NULL, if the:
|
/* This function can fail, and therefore return NULL, if the:
|
||||||
* - guard condition is NULL
|
* - guard condition is NULL
|
||||||
* - guard condition is invalid (never called init, called fini, or invalid node)
|
* - guard condition is invalid (never called init or called fini)
|
||||||
*
|
*
|
||||||
* A guard condition can be triggered from any thread.
|
* A guard condition can be triggered from any thread.
|
||||||
*
|
*
|
||||||
|
@ -112,7 +120,9 @@ rcl_guard_condition_get_default_options();
|
||||||
* with rcl_guard_condition_fini() on the same guard condition.
|
* with rcl_guard_condition_fini() on the same guard condition.
|
||||||
*
|
*
|
||||||
* \param[in] guard_condition handle to the guard_condition to be triggered
|
* \param[in] guard_condition handle to the guard_condition to be triggered
|
||||||
* \return RMW_RET_OK if the message was published, otherwise RMW_RET_ERROR
|
* \return RCL_RET_OK if the guard condition was triggered, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_trigger_guard_condition(const rcl_guard_condition_t * guard_condition);
|
rcl_trigger_guard_condition(const rcl_guard_condition_t * guard_condition);
|
||||||
|
|
|
@ -23,6 +23,9 @@ extern "C"
|
||||||
#include "rcl/allocator.h"
|
#include "rcl/allocator.h"
|
||||||
#include "rcl/types.h"
|
#include "rcl/types.h"
|
||||||
|
|
||||||
|
// Intentional underflow to get max size_t.
|
||||||
|
#define RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID (size_t)-1
|
||||||
|
|
||||||
struct rcl_node_impl_t;
|
struct rcl_node_impl_t;
|
||||||
|
|
||||||
/// Handle for a ROS node.
|
/// Handle for a ROS node.
|
||||||
|
@ -42,6 +45,16 @@ typedef struct rcl_node_options_t {
|
||||||
// rmw_qos_profile_t parameter_qos;
|
// rmw_qos_profile_t parameter_qos;
|
||||||
/// If true, no parameter infrastructure will be setup.
|
/// If true, no parameter infrastructure will be setup.
|
||||||
bool no_parameters;
|
bool no_parameters;
|
||||||
|
/// If set, then this value overrides the ROS_DOMAIN_ID environment variable.
|
||||||
|
/* It defaults to RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID, which will cause the
|
||||||
|
* node to use the ROS domain ID set in the ROS_DOMAIN_ID environment
|
||||||
|
* variable, or on some systems 0 if the environment variable is not set.
|
||||||
|
*
|
||||||
|
* \TODO(wjwwood): Should we put a limit on the ROS_DOMAIN_ID value, that way
|
||||||
|
* we can have a safe value for the default
|
||||||
|
* RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID? (currently max size_t)
|
||||||
|
*/
|
||||||
|
size_t domain_id;
|
||||||
/// Custom allocator used for incidental allocations, e.g. node name string.
|
/// Custom allocator used for incidental allocations, e.g. node name string.
|
||||||
rcl_allocator_t allocator;
|
rcl_allocator_t allocator;
|
||||||
} rcl_node_options_t;
|
} rcl_node_options_t;
|
||||||
|
@ -66,11 +79,13 @@ rcl_get_zero_initialized_node();
|
||||||
*
|
*
|
||||||
* A node contains infrastructure for ROS parameters, which include advertising
|
* A node contains infrastructure for ROS parameters, which include advertising
|
||||||
* publishers and service servers.
|
* publishers and service servers.
|
||||||
* So this function will create those external parameter interfaces even if
|
* This function will create those external parameter interfaces even if
|
||||||
* parameters are not used later.
|
* parameters are not used later.
|
||||||
*
|
*
|
||||||
* This function should be called on a rcl_node_t exactly once, and calling it
|
* The rcl_node_t given must be allocated and zero initalized.
|
||||||
* multiple times is undefined behavior.
|
* Passing an rcl_node_t which has already had this function called on it, more
|
||||||
|
* recently than rcl_node_fini, will fail.
|
||||||
|
* An allocated rcl_node_t with uninitialized memory is undefined behavior.
|
||||||
*
|
*
|
||||||
* Expected usage:
|
* Expected usage:
|
||||||
*
|
*
|
||||||
|
@ -89,22 +104,28 @@ rcl_get_zero_initialized_node();
|
||||||
* \param[inout] node a preallocated node structure
|
* \param[inout] node a preallocated node structure
|
||||||
* \param[in] name the name of the node
|
* \param[in] name the name of the node
|
||||||
* \param[in] options the node options; pass null to use default options
|
* \param[in] options the node options; pass null to use default options
|
||||||
* \return RMW_RET_OK if node was initialized successfully, otherwise RMW_RET_ERROR
|
* \return RCL_RET_OK if node was initialized successfully, or
|
||||||
|
* RCL_RET_ALREADY_INIT if the node has already be initialized, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_BAD_ALLOC if allocating memory failed, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * options);
|
rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * options);
|
||||||
|
|
||||||
/// Deinitialize a rcl_node_t.
|
/// Finalized a rcl_node_t.
|
||||||
/* Shuts down any automatically created infrastructure and deallocates memory.
|
/* Shuts down any automatically created infrastructure and deallocates memory.
|
||||||
* After calling, the rcl_node_t can be safely released.
|
* After calling, the rcl_node_t can be safely deallocated.
|
||||||
*
|
*
|
||||||
* Any middleware primitives created by the user, e.g. publishers, services, etc.,
|
* Any middleware primitives created by the user, e.g. publishers, services, etc.,
|
||||||
* are invalid after deinitialization.
|
* are invalid after deinitialization.
|
||||||
*
|
*
|
||||||
* This function is not thread-safe.
|
* This function is not thread-safe.
|
||||||
*
|
*
|
||||||
* \param[in] node handle to the node to be deinitialized
|
* \param[in] node handle to the node to be finalized
|
||||||
* \return RMW_RET_OK if node was deinitialized successfully, otherwise RMW_RET_ERROR
|
* \return RCL_RET_OK if node was finalized successfully, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_node_fini(rcl_node_t * node);
|
rcl_node_fini(rcl_node_t * node);
|
||||||
|
@ -145,6 +166,27 @@ rcl_node_get_name(const rcl_node_t * node);
|
||||||
const rcl_node_options_t *
|
const rcl_node_options_t *
|
||||||
rcl_node_get_options(const rcl_node_t * node);
|
rcl_node_get_options(const rcl_node_t * node);
|
||||||
|
|
||||||
|
/// Return the ROS domain ID that the node is using.
|
||||||
|
/* This function returns the ROS domain ID that the node is in.
|
||||||
|
*
|
||||||
|
* This function should be used to determine what domain_id was used rather
|
||||||
|
* than checking the domin_id field in the node options, because if
|
||||||
|
* RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID is used when creating the node then
|
||||||
|
* it is not changed after creation, but this function will return the actual
|
||||||
|
* domain_id used.
|
||||||
|
*
|
||||||
|
* The domain_id field must point to an allocated size_t object to which the
|
||||||
|
* ROS domain ID will be written.
|
||||||
|
*
|
||||||
|
* \param[in] node the handle to the node being queried
|
||||||
|
* \return RCL_RET_OK if node the domain ID was retrieved successfully, or
|
||||||
|
* RCL_RET_NODE_INVALID if the node is invalid, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
|
*/
|
||||||
|
rcl_ret_t
|
||||||
|
rcl_node_get_domain_id(const rcl_node_t * node, size_t * domain_id);
|
||||||
|
|
||||||
/// Return the rmw node handle.
|
/// Return the rmw node handle.
|
||||||
/* The handle returned is a pointer to the internally held rmw handle.
|
/* The handle returned is a pointer to the internally held rmw handle.
|
||||||
* This function can fail, and therefore return NULL, if:
|
* This function can fail, and therefore return NULL, if:
|
||||||
|
|
|
@ -256,10 +256,6 @@ rcl_publisher_get_options(rcl_publisher_t * publisher);
|
||||||
rmw_publisher_t *
|
rmw_publisher_t *
|
||||||
rcl_publisher_get_rmw_publisher_handle(rcl_publisher_t * publisher);
|
rcl_publisher_get_rmw_publisher_handle(rcl_publisher_t * publisher);
|
||||||
|
|
||||||
int main() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,13 +29,13 @@ extern "C"
|
||||||
/* Unless otherwise noted, this must be called before using any rcl functions.
|
/* Unless otherwise noted, this must be called before using any rcl functions.
|
||||||
*
|
*
|
||||||
* This function can only be run once after starting the program, and once
|
* This function can only be run once after starting the program, and once
|
||||||
* after each call to rcl_fini.
|
* after each call to rcl_shutdown.
|
||||||
* Repeated calls will fail with RCL_RET_ALREADY_INIT.
|
* Repeated calls will fail with RCL_RET_ALREADY_INIT.
|
||||||
* This function is not thread safe.
|
* This function is not thread safe.
|
||||||
*
|
*
|
||||||
* This function can be called any time after rcl_fini is called, but it
|
* This function can be called any time after rcl_shutdown is called, but it
|
||||||
* cannot be called from within a callback being executed by an rcl executor.
|
* cannot be called from within a callback being executed by an rcl executor.
|
||||||
* For example, you can call rcl_fini from within a timer callback, but
|
* For example, you can call rcl_shutdown from within a timer callback, but
|
||||||
* you have to return from the callback, and therefore exit any in-progress
|
* you have to return from the callback, and therefore exit any in-progress
|
||||||
* call to a spin function, before calling rcl_init again.
|
* call to a spin function, before calling rcl_init again.
|
||||||
*
|
*
|
||||||
|
@ -47,7 +47,7 @@ extern "C"
|
||||||
*
|
*
|
||||||
* \param[in] argc number of strings in argv
|
* \param[in] argc number of strings in argv
|
||||||
* \param[in] argv command line arguments; rcl specific arguments are removed
|
* \param[in] argv command line arguments; rcl specific arguments are removed
|
||||||
* \param[in] allocator allocator to be used during rcl_init and rcl_fini
|
* \param[in] allocator allocator to be used during rcl_init and rcl_shutdown
|
||||||
* \return RCL_RET_OK if initialization is successful, or
|
* \return RCL_RET_OK if initialization is successful, or
|
||||||
* RCL_RET_ALREADY_INIT if rcl_init has already been called, or
|
* RCL_RET_ALREADY_INIT if rcl_init has already been called, or
|
||||||
* RCL_RET_ERROR if an unspecified error occurs.
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
|
@ -74,14 +74,14 @@ rcl_init(int argc, char ** argv, rcl_allocator_t allocator);
|
||||||
* RCL_RET_NOT_INIT if rcl_init has not yet been called
|
* RCL_RET_NOT_INIT if rcl_init has not yet been called
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_fini();
|
rcl_shutdown();
|
||||||
|
|
||||||
/// Returns an uint64_t number that is unique for the latest rcl_init call.
|
/// Returns an uint64_t number that is unique for the latest rcl_init call.
|
||||||
/* If called before rcl_init or after rcl_fini then 0 will be returned. */
|
/* If called before rcl_init or after rcl_shutdown then 0 will be returned. */
|
||||||
uint64_t
|
uint64_t
|
||||||
rcl_get_instance_id();
|
rcl_get_instance_id();
|
||||||
|
|
||||||
/// Return true until rcl_fini is called, then false.
|
/// Return true until rcl_shutdown is called, then false.
|
||||||
/* This function is thread safe. */
|
/* This function is thread safe. */
|
||||||
bool
|
bool
|
||||||
rcl_ok();
|
rcl_ok();
|
||||||
|
|
|
@ -117,7 +117,10 @@ rcl_get_zero_initialized_subscription();
|
||||||
* \param[in] type_support type support object for the topic's type
|
* \param[in] type_support type support object for the topic's type
|
||||||
* \param[in] topic_name the name of the topic
|
* \param[in] topic_name the name of the topic
|
||||||
* \param[in] options subscription options, including quality of service settings
|
* \param[in] options subscription options, including quality of service settings
|
||||||
* \return RMW_RET_OK if subscription was initialized successfully, otherwise RMW_RET_ERROR
|
* \return RCL_RET_OK if subscription was initialized successfully, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_BAD_ALLOC if allocating memory failed, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_subscription_init(
|
rcl_subscription_init(
|
||||||
|
@ -140,7 +143,9 @@ rcl_subscription_init(
|
||||||
*
|
*
|
||||||
* \param[inout] subscription handle to the subscription to be deinitialized
|
* \param[inout] subscription handle to the subscription to be deinitialized
|
||||||
* \param[in] node handle to the node used to create the subscription
|
* \param[in] node handle to the node used to create the subscription
|
||||||
* \return RMW_RET_OK if subscription was deinitialized successfully, otherwise RMW_RET_ERROR
|
* \return RCL_RET_OK if subscription was deinitialized successfully, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_subscription_fini(rcl_subscription_t * subscription, rcl_node_t * node);
|
rcl_subscription_fini(rcl_subscription_t * subscription, rcl_node_t * node);
|
||||||
|
@ -157,7 +162,7 @@ rcl_subscription_get_default_options();
|
||||||
* be checked by this function and therefore no deliberate error will occur.
|
* be checked by this function and therefore no deliberate error will occur.
|
||||||
*
|
*
|
||||||
* TODO(wjwwood) blocking of take?
|
* TODO(wjwwood) blocking of take?
|
||||||
* TODO(wjwwood) pre- and post-conditions for message ownership?
|
* TODO(wjwwood) pre-, during-, and post-conditions for message ownership?
|
||||||
* TODO(wjwwood) is rcl_take thread-safe?
|
* TODO(wjwwood) is rcl_take thread-safe?
|
||||||
*
|
*
|
||||||
* The ros_message pointer should point to an already allocated ROS message
|
* The ros_message pointer should point to an already allocated ROS message
|
||||||
|
@ -184,7 +189,10 @@ rcl_subscription_get_default_options();
|
||||||
* \param[inout] ros_message type-erased ptr to a allocated ROS message
|
* \param[inout] ros_message type-erased ptr to a allocated ROS message
|
||||||
* \param[out] taken pointer to a bool, if set to false a message was not taken
|
* \param[out] taken pointer to a bool, if set to false a message was not taken
|
||||||
* \param[out] message_info rmw struct which contains meta-data for the message
|
* \param[out] message_info rmw struct which contains meta-data for the message
|
||||||
* \return RMW_RET_OK if the message was published, otherwise RMW_RET_ERROR
|
* \return RCL_RET_OK if the message was published, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_BAD_ALLOC if allocating memory failed, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_take(
|
rcl_take(
|
||||||
|
|
|
@ -24,7 +24,10 @@ typedef rmw_ret_t rcl_ret_t;
|
||||||
// rcl specific ret codes start at 100
|
// rcl specific ret codes start at 100
|
||||||
#define RCL_RET_ALREADY_INIT 100
|
#define RCL_RET_ALREADY_INIT 100
|
||||||
#define RCL_RET_NOT_INIT 101
|
#define RCL_RET_NOT_INIT 101
|
||||||
|
#define RCL_RET_BAD_ALLOC 102
|
||||||
|
#define RCL_RET_INVALID_ARGUMENT 103
|
||||||
// rcl node specific ret codes in 2XX
|
// rcl node specific ret codes in 2XX
|
||||||
|
#define RCL_RET_NODE_INVALID 200
|
||||||
// rcl publisher specific ret codes in 3XX
|
// rcl publisher specific ret codes in 3XX
|
||||||
// rcl subscription specific ret codes in 4XX
|
// rcl subscription specific ret codes in 4XX
|
||||||
// rcl service client specific ret codes in 5XX
|
// rcl service client specific ret codes in 5XX
|
||||||
|
|
|
@ -45,7 +45,7 @@ typedef struct rcl_wait_set_t {
|
||||||
/// If set to true, actions like add_subscription will fail until cleared.
|
/// If set to true, actions like add_subscription will fail until cleared.
|
||||||
bool pruned;
|
bool pruned;
|
||||||
/// Implementation specific storage.
|
/// Implementation specific storage.
|
||||||
rcl_wait_set_impl_t * impl;
|
struct rcl_wait_set_impl_t * impl;
|
||||||
} rcl_wait_set_t;
|
} rcl_wait_set_t;
|
||||||
|
|
||||||
/// Return a rcl_wait_set_t struct with members set to NULL.
|
/// Return a rcl_wait_set_t struct with members set to NULL.
|
||||||
|
@ -87,6 +87,8 @@ rcl_get_zero_initialized_wait_set();
|
||||||
* \param[in] allocator the allocator to use when allocating space in the sets
|
* \param[in] allocator the allocator to use when allocating space in the sets
|
||||||
* \return RCL_RET_OK if the wait set is initialized successfully, or
|
* \return RCL_RET_OK if the wait set is initialized successfully, or
|
||||||
* RCL_RET_ALREADY_INIT if the wait set is not zero initialized, or
|
* RCL_RET_ALREADY_INIT if the wait set is not zero initialized, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_BAD_ALLOC if allocating memory failed, or
|
||||||
* RCL_RET_ERROR if an unspecified error occurs.
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
|
@ -110,7 +112,9 @@ rcl_wait_set_init(
|
||||||
* This function is not thread-safe.
|
* This function is not thread-safe.
|
||||||
*
|
*
|
||||||
* \param[inout] wait_set the wait set struct to be finalized.
|
* \param[inout] wait_set the wait set struct to be finalized.
|
||||||
* \return RCL_RET_OK if the finalization was successful, otherwise RCL_RET_ERROR
|
* \return RCL_RET_OK if the finalization was successful, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_wait_set_fini(rcl_wait_set_t * wait_set);
|
rcl_wait_set_fini(rcl_wait_set_t * wait_set);
|
||||||
|
@ -126,6 +130,7 @@ rcl_wait_set_fini(rcl_wait_set_t * wait_set);
|
||||||
* \return RCL_RET_OK if added successfully, or
|
* \return RCL_RET_OK if added successfully, or
|
||||||
* RCL_RET_WAIT_SET_FULL if the subscription set is full, or
|
* RCL_RET_WAIT_SET_FULL if the subscription set is full, or
|
||||||
* RCL_RET_NOT_INIT if the wait set is zero initialized, or
|
* RCL_RET_NOT_INIT if the wait set is zero initialized, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
* RCL_RET_ERROR if an unspecified error occurs.
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
|
@ -144,6 +149,7 @@ rcl_wait_set_add_subscription(
|
||||||
* \param[inout] wait_set struct to have its subscriptions cleared
|
* \param[inout] wait_set struct to have its subscriptions cleared
|
||||||
* \return RCL_RET_OK if cleared successfully, or
|
* \return RCL_RET_OK if cleared successfully, or
|
||||||
* RCL_RET_NOT_INIT if the wait set is zero initialized, or
|
* RCL_RET_NOT_INIT if the wait set is zero initialized, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
* RCL_RET_ERROR if an unspecified error occurs.
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
|
@ -170,6 +176,8 @@ rcl_wait_set_clear_subscriptions(rcl_wait_set_t * wait_set);
|
||||||
* \param[inout] wait_set struct to have its subscriptions cleared
|
* \param[inout] wait_set struct to have its subscriptions cleared
|
||||||
* \param[in] size a size for the new set
|
* \param[in] size a size for the new set
|
||||||
* \return RCL_RET_OK if resized successfully, or
|
* \return RCL_RET_OK if resized successfully, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
|
* RCL_RET_BAD_ALLOC if allocating memory failed, or
|
||||||
* RCL_RET_ERROR if an unspecified error occurs.
|
* RCL_RET_ERROR if an unspecified error occurs.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
|
@ -282,6 +290,7 @@ rcl_wait_set_resize_guard_conditions(rcl_wait_set_t * wait_set, size_t size);
|
||||||
* RCL_RET_TIMEOUT timeout expired before something was ready, or
|
* RCL_RET_TIMEOUT timeout expired before something was ready, or
|
||||||
* RCL_RET_NOT_INIT wait set is zero initialized, or
|
* RCL_RET_NOT_INIT wait set is zero initialized, or
|
||||||
* RCL_RET_WAIT_SET_EMPTY wait set contains no items, or
|
* RCL_RET_WAIT_SET_EMPTY wait set contains no items, or
|
||||||
|
* RCL_RET_INVALID_ARGUMENT if any arugments are invalid, or
|
||||||
* RCL_RET_ERROR an unspecified error occur.
|
* RCL_RET_ERROR an unspecified error occur.
|
||||||
*/
|
*/
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
|
|
|
@ -11,9 +11,14 @@
|
||||||
<buildtool_depend>ament_cmake</buildtool_depend>
|
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||||
|
|
||||||
<build_depend>rmw</build_depend>
|
<build_depend>rmw</build_depend>
|
||||||
|
<!-- This ensures the rmw impls are built first. -->
|
||||||
|
<build_depend>rmw_implementation</build_depend>
|
||||||
|
|
||||||
<build_export_depend>rmw</build_export_depend>
|
<build_export_depend>rmw</build_export_depend>
|
||||||
|
|
||||||
|
<depend>rcl_interfaces</depend>
|
||||||
|
<depend>rosidl_generator_cpp</depend>
|
||||||
|
|
||||||
<test_depend>ament_lint_auto</test_depend>
|
<test_depend>ament_lint_auto</test_depend>
|
||||||
<test_depend>ament_lint_common</test_depend>
|
<test_depend>ament_lint_common</test_depend>
|
||||||
|
|
||||||
|
|
|
@ -40,5 +40,11 @@ __default_reallocate(void * pointer, size_t size, void * state)
|
||||||
rcl_allocator_t
|
rcl_allocator_t
|
||||||
rcl_get_default_allocator()
|
rcl_get_default_allocator()
|
||||||
{
|
{
|
||||||
return {__default_allocate, __default_deallocate, __default_reallocate, NULL};
|
static rcl_allocator_t default_allocator = {
|
||||||
|
__default_allocate,
|
||||||
|
__default_deallocate,
|
||||||
|
__default_reallocate,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
return default_allocator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@ extern "C"
|
||||||
#include "rcl/error_handling.h"
|
#include "rcl/error_handling.h"
|
||||||
#include "rcl/types.h"
|
#include "rcl/types.h"
|
||||||
|
|
||||||
#define RCL_CHECK_PARAMETER_FOR_NULL(parameter, error_return_type) \
|
#define RCL_CHECK_ARGUMENT_FOR_NULL(parameter, error_return_type) \
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(parameter, #parameter " parameter is null", return error_return_type)
|
RCL_CHECK_FOR_NULL_WITH_MSG(parameter, #parameter " argument is null", return error_return_type)
|
||||||
|
|
||||||
#define RCL_CHECK_FOR_NULL_WITH_MSG(value, msg, error_statement) if (!value) { \
|
#define RCL_CHECK_FOR_NULL_WITH_MSG(value, msg, error_statement) if (!value) { \
|
||||||
RCL_SET_ERROR_MSG(msg); \
|
RCL_SET_ERROR_MSG(msg); \
|
||||||
|
|
150
rcl/src/rcl/guard_condition.c
Normal file
150
rcl/src/rcl/guard_condition.c
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rcl/guard_condition.h"
|
||||||
|
|
||||||
|
#include "./common.h"
|
||||||
|
#include "rcl/rcl.h"
|
||||||
|
#include "rmw/rmw.h"
|
||||||
|
|
||||||
|
typedef struct rcl_guard_condition_impl_t {
|
||||||
|
rmw_guard_condition_t * rmw_handle;
|
||||||
|
rcl_guard_condition_options_t options;
|
||||||
|
} rcl_guard_condition_impl_t;
|
||||||
|
|
||||||
|
rcl_guard_condition_t
|
||||||
|
rcl_get_zero_initialized_guard_condition()
|
||||||
|
{
|
||||||
|
static rcl_guard_condition_t null_guard_condition = {0};
|
||||||
|
return null_guard_condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcl_ret_t
|
||||||
|
rcl_guard_condition_init(
|
||||||
|
rcl_guard_condition_t * guard_condition,
|
||||||
|
const rcl_node_t * node,
|
||||||
|
const rcl_guard_condition_options_t * options)
|
||||||
|
{
|
||||||
|
// Perform argument validation.
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(guard_condition, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
const rcl_allocator_t * allocator = &options->allocator;
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
allocator->allocate, "allocate not set", return RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
allocator->deallocate, "deallocate not set", return RCL_RET_INVALID_ARGUMENT);
|
||||||
|
// Ensure the node is valid.
|
||||||
|
if (!node->impl || rcl_node_get_rcl_instance_id(node) != rcl_get_instance_id()) {
|
||||||
|
RCL_SET_ERROR_MSG("node handle is invalid");
|
||||||
|
return RCL_RET_NODE_INVALID;
|
||||||
|
}
|
||||||
|
// Ensure the guard_condition handle is zero initialized.
|
||||||
|
if (guard_condition->impl) {
|
||||||
|
RCL_SET_ERROR_MSG("guard_condition already initialized, or memory was unintialized");
|
||||||
|
return RCL_RET_ALREADY_INIT;
|
||||||
|
}
|
||||||
|
// Allocate space for the guard condition impl.
|
||||||
|
guard_condition->impl = (rcl_guard_condition_impl_t *)allocator->allocate(
|
||||||
|
sizeof(rcl_guard_condition_impl_t), allocator->state);
|
||||||
|
if (!guard_condition->impl) {
|
||||||
|
RCL_SET_ERROR_MSG("allocating memory failed");
|
||||||
|
return RCL_RET_BAD_ALLOC;
|
||||||
|
}
|
||||||
|
// Create the rmw guard condition.
|
||||||
|
guard_condition->impl->rmw_handle = rmw_create_guard_condition();
|
||||||
|
if (!guard_condition->impl->rmw_handle) {
|
||||||
|
// Deallocate impl and exit.
|
||||||
|
allocator->deallocate(guard_condition->impl, allocator->state);
|
||||||
|
RCL_SET_ERROR_MSG(rmw_get_error_string_safe());
|
||||||
|
return RCL_RET_ERROR;
|
||||||
|
}
|
||||||
|
// Copy options into impl.
|
||||||
|
guard_condition->impl->options = *options;
|
||||||
|
return RCL_RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcl_ret_t
|
||||||
|
rcl_guard_condition_fini(rcl_guard_condition_t * guard_condition, rcl_node_t * node)
|
||||||
|
{
|
||||||
|
// Perform argument validation.
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(guard_condition, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
// Ensure the node is valid.
|
||||||
|
if (!node->impl || rcl_node_get_rcl_instance_id(node) != rcl_get_instance_id()) {
|
||||||
|
RCL_SET_ERROR_MSG("node handle is invalid");
|
||||||
|
return RCL_RET_NODE_INVALID;
|
||||||
|
}
|
||||||
|
rcl_ret_t result = RCL_RET_OK;
|
||||||
|
if (guard_condition->impl) {
|
||||||
|
if (guard_condition->impl->rmw_handle) {
|
||||||
|
if (rmw_destroy_guard_condition(guard_condition->impl->rmw_handle) != RMW_RET_OK) {
|
||||||
|
RCL_SET_ERROR_MSG(rmw_get_error_string_safe());
|
||||||
|
result = RCL_RET_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rcl_allocator_t allocator = guard_condition->impl->options.allocator;
|
||||||
|
if (allocator.deallocate) {
|
||||||
|
allocator.deallocate(guard_condition->impl, allocator.state);
|
||||||
|
} else {
|
||||||
|
RCL_SET_ERROR_MSG("deallocate not set");
|
||||||
|
result = RCL_RET_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcl_guard_condition_options_t
|
||||||
|
rcl_guard_condition_get_default_options()
|
||||||
|
{
|
||||||
|
static rcl_guard_condition_options_t default_options = {0};
|
||||||
|
// Must set the allocator after because it is not a compile time constant.
|
||||||
|
default_options.allocator = rcl_get_default_allocator();
|
||||||
|
return default_options;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcl_ret_t
|
||||||
|
rcl_trigger_guard_condition(const rcl_guard_condition_t * guard_condition)
|
||||||
|
{
|
||||||
|
// Perform argument validation.
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(guard_condition, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
guard_condition->impl,
|
||||||
|
"guard condition implementation is invalid",
|
||||||
|
return RCL_RET_INVALID_ARGUMENT);
|
||||||
|
// Trigger the guard condition.
|
||||||
|
if (rmw_trigger_guard_condition(guard_condition->impl->rmw_handle) != RMW_RET_OK) {
|
||||||
|
RCL_SET_ERROR_MSG(rmw_get_error_string_safe());
|
||||||
|
return RCL_RET_ERROR;
|
||||||
|
}
|
||||||
|
return RCL_RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rmw_guard_condition_t *
|
||||||
|
rcl_guard_condition_get_rmw_guard_condition_handle(rcl_guard_condition_t * guard_condition)
|
||||||
|
{
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(guard_condition, NULL);
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
guard_condition->impl, "guard condition implementation is invalid", return NULL);
|
||||||
|
return guard_condition->impl->rmw_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -17,18 +17,18 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "rcl/node.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "rcl/node.h"
|
|
||||||
#include "rcl/rcl.h"
|
#include "rcl/rcl.h"
|
||||||
#include "rmw/rmw.h"
|
#include "rmw/rmw.h"
|
||||||
|
|
||||||
#include "./common.h"
|
#include "./common.h"
|
||||||
|
|
||||||
typedef struct rcl_node_impl_t {
|
typedef struct rcl_node_impl_t {
|
||||||
char * name;
|
|
||||||
rcl_node_options_t options;
|
rcl_node_options_t options;
|
||||||
rmw_node_t * rmw_node_handle;
|
rmw_node_t * rmw_node_handle;
|
||||||
uint64_t rcl_instance_id;
|
uint64_t rcl_instance_id;
|
||||||
|
@ -37,7 +37,8 @@ typedef struct rcl_node_impl_t {
|
||||||
rcl_node_t
|
rcl_node_t
|
||||||
rcl_get_uninitialized_node()
|
rcl_get_uninitialized_node()
|
||||||
{
|
{
|
||||||
return {0};
|
static rcl_node_t null_node = {0};
|
||||||
|
return null_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
|
@ -46,19 +47,22 @@ rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * o
|
||||||
size_t domain_id = 0;
|
size_t domain_id = 0;
|
||||||
char * ros_domain_id;
|
char * ros_domain_id;
|
||||||
rcl_ret_t ret;
|
rcl_ret_t ret;
|
||||||
RCL_CHECK_PARAMETER_FOR_NULL(name, RCL_RET_ERROR);
|
rcl_ret_t fail_ret = RCL_RET_ERROR;
|
||||||
RCL_CHECK_PARAMETER_FOR_NULL(options, RCL_RET_ERROR);
|
RCL_CHECK_ARGUMENT_FOR_NULL(name, RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_PARAMETER_FOR_NULL(node, RCL_RET_ERROR);
|
RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
|
||||||
if (node->impl) {
|
if (node->impl) {
|
||||||
RCL_SET_ERROR_MSG(
|
RCL_SET_ERROR_MSG("node already initialized, or struct memory was unintialized");
|
||||||
"either double call to rcl_node_init or rcl_get_uninitialized_node was not used");
|
return RCL_RET_ALREADY_INIT;
|
||||||
return RCL_RET_ERROR;
|
|
||||||
}
|
}
|
||||||
const rcl_allocator_t * allocator = &options->allocator;
|
const rcl_allocator_t * allocator = &options->allocator;
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
allocator->allocate, "allocate not set", return RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
allocator->deallocate, "deallocate not set", return RCL_RET_INVALID_ARGUMENT);
|
||||||
// Allocate space for the implementation struct.
|
// Allocate space for the implementation struct.
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(allocator->allocate, "allocate not set", return RCL_RET_ERROR);
|
|
||||||
node->impl = (rcl_node_impl_t *)allocator->allocate(sizeof(rcl_node_impl_t), allocator->state);
|
node->impl = (rcl_node_impl_t *)allocator->allocate(sizeof(rcl_node_impl_t), allocator->state);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "allocating memory failed", return RCL_RET_ERROR);
|
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "allocating memory failed", return RCL_RET_BAD_ALLOC);
|
||||||
// Initialize node impl.
|
// Initialize node impl.
|
||||||
// node name
|
// node name
|
||||||
size_t name_len = strlen(name);
|
size_t name_len = strlen(name);
|
||||||
|
@ -66,9 +70,6 @@ rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * o
|
||||||
RCL_SET_ERROR_MSG("node name cannot be empty string");
|
RCL_SET_ERROR_MSG("node name cannot be empty string");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
node->impl->name = (char *)allocator->allocate(strlen(name), allocator->state);
|
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl->name, "allocating memory failed", goto fail);
|
|
||||||
strncpy(node->impl->name, name, strlen(name));
|
|
||||||
// node options
|
// node options
|
||||||
node->impl->options = *options;
|
node->impl->options = *options;
|
||||||
// node rmw_node_handle
|
// node rmw_node_handle
|
||||||
|
@ -79,7 +80,7 @@ rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * o
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (ros_domain_id) {
|
if (ros_domain_id) {
|
||||||
auto number = strtoul(ros_domain_id, NULL, 0);
|
unsigned long number = strtoul(ros_domain_id, NULL, 0);
|
||||||
if (number == ULONG_MAX) {
|
if (number == ULONG_MAX) {
|
||||||
RCL_SET_ERROR_MSG("failed to interpret ROS_DOMAIN_ID as integral number");
|
RCL_SET_ERROR_MSG("failed to interpret ROS_DOMAIN_ID as integral number");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -92,20 +93,20 @@ rcl_node_init(rcl_node_t * node, const char * name, const rcl_node_options_t * o
|
||||||
node->impl->rcl_instance_id = rcl_get_instance_id();
|
node->impl->rcl_instance_id = rcl_get_instance_id();
|
||||||
return RCL_RET_OK;
|
return RCL_RET_OK;
|
||||||
fail:
|
fail:
|
||||||
if (node->impl->name) {
|
|
||||||
allocator->deallocate(node->impl->name, allocator->state);
|
|
||||||
}
|
|
||||||
if (node->impl) {
|
if (node->impl) {
|
||||||
allocator->deallocate(node->impl, allocator->state);
|
allocator->deallocate(node->impl, allocator->state);
|
||||||
}
|
}
|
||||||
return RCL_RET_ERROR;
|
return fail_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_node_fini(rcl_node_t * node)
|
rcl_node_fini(rcl_node_t * node)
|
||||||
{
|
{
|
||||||
RCL_CHECK_PARAMETER_FOR_NULL(node, RCL_RET_ERROR);
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "node implementation is invalid", return RCL_RET_ERROR);
|
if (!node->impl) {
|
||||||
|
// Repeat calls to fini or calling fini on a zero initialized node is ok.
|
||||||
|
return RCL_RET_OK;
|
||||||
|
}
|
||||||
rcl_ret_t result = RCL_RET_OK;
|
rcl_ret_t result = RCL_RET_OK;
|
||||||
rmw_ret_t node_ret = rmw_destroy_node(node->impl->rmw_node_handle);
|
rmw_ret_t node_ret = rmw_destroy_node(node->impl->rmw_node_handle);
|
||||||
if (node_ret != RMW_RET_OK) {
|
if (node_ret != RMW_RET_OK) {
|
||||||
|
@ -113,7 +114,8 @@ rcl_node_fini(rcl_node_t * node)
|
||||||
result = RCL_RET_ERROR;
|
result = RCL_RET_ERROR;
|
||||||
}
|
}
|
||||||
rcl_allocator_t allocator = node->impl->options.allocator;
|
rcl_allocator_t allocator = node->impl->options.allocator;
|
||||||
allocator.deallocate(node->impl->name, allocator.state);
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
allocator.deallocate, "deallocate not set", return RCL_RET_INVALID_ARGUMENT);
|
||||||
allocator.deallocate(node->impl, allocator.state);
|
allocator.deallocate(node->impl, allocator.state);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -121,25 +123,31 @@ rcl_node_fini(rcl_node_t * node)
|
||||||
rcl_node_options_t
|
rcl_node_options_t
|
||||||
rcl_node_get_default_options()
|
rcl_node_get_default_options()
|
||||||
{
|
{
|
||||||
return {false, rcl_get_default_allocator()};
|
static rcl_node_options_t default_options = {
|
||||||
|
.no_parameters = false,
|
||||||
|
.domain_id = RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID,
|
||||||
|
};
|
||||||
|
// Must set the allocator after because it is not a compile time constant.
|
||||||
|
default_options.allocator = rcl_get_default_allocator();
|
||||||
|
return default_options;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
rcl_node_get_name(const rcl_node_t * node)
|
rcl_node_get_name(const rcl_node_t * node)
|
||||||
{
|
{
|
||||||
RCL_CHECK_PARAMETER_FOR_NULL(node, NULL);
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, NULL);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "node implementation is invalid", return NULL);
|
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "node implementation is invalid", return NULL);
|
||||||
if (node->impl->rcl_instance_id != rcl_get_instance_id()) {
|
if (node->impl->rcl_instance_id != rcl_get_instance_id()) {
|
||||||
RCL_SET_ERROR_MSG("rcl node is invalid, rcl instance id does not match");
|
RCL_SET_ERROR_MSG("rcl node is invalid, rcl instance id does not match");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return node->impl->name;
|
return node->impl->rmw_node_handle->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rcl_node_options_t *
|
const rcl_node_options_t *
|
||||||
rcl_node_get_options(const rcl_node_t * node)
|
rcl_node_get_options(const rcl_node_t * node)
|
||||||
{
|
{
|
||||||
RCL_CHECK_PARAMETER_FOR_NULL(node, NULL);
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, NULL);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "node implementation is invalid", return NULL);
|
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "node implementation is invalid", return NULL);
|
||||||
if (node->impl->rcl_instance_id != rcl_get_instance_id()) {
|
if (node->impl->rcl_instance_id != rcl_get_instance_id()) {
|
||||||
RCL_SET_ERROR_MSG("rcl node is invalid, rcl instance id does not match");
|
RCL_SET_ERROR_MSG("rcl node is invalid, rcl instance id does not match");
|
||||||
|
@ -151,7 +159,7 @@ rcl_node_get_options(const rcl_node_t * node)
|
||||||
rmw_node_t *
|
rmw_node_t *
|
||||||
rcl_node_get_rmw_node_handle(const rcl_node_t * node)
|
rcl_node_get_rmw_node_handle(const rcl_node_t * node)
|
||||||
{
|
{
|
||||||
RCL_CHECK_PARAMETER_FOR_NULL(node, NULL);
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, NULL);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "node implementation is invalid", return NULL);
|
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "node implementation is invalid", return NULL);
|
||||||
if (node->impl->rcl_instance_id != rcl_get_instance_id()) {
|
if (node->impl->rcl_instance_id != rcl_get_instance_id()) {
|
||||||
RCL_SET_ERROR_MSG("rcl node is invalid, rcl instance id does not match");
|
RCL_SET_ERROR_MSG("rcl node is invalid, rcl instance id does not match");
|
||||||
|
@ -163,8 +171,8 @@ rcl_node_get_rmw_node_handle(const rcl_node_t * node)
|
||||||
uint64_t
|
uint64_t
|
||||||
rcl_node_get_rcl_instance_id(const rcl_node_t * node)
|
rcl_node_get_rcl_instance_id(const rcl_node_t * node)
|
||||||
{
|
{
|
||||||
RCL_CHECK_PARAMETER_FOR_NULL(node, NULL);
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, 0);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "node implementation is invalid", return NULL);
|
RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "node implementation is invalid", return 0);
|
||||||
return node->impl->rcl_instance_id;
|
return node->impl->rcl_instance_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
91
rcl/src/rcl/publisher.c
Normal file
91
rcl/src/rcl/publisher.c
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rcl/publisher.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "./common.h"
|
||||||
|
#include "rmw/rmw.h"
|
||||||
|
|
||||||
|
typedef struct rcl_publisher_impl_t {
|
||||||
|
rcl_publisher_options_t options;
|
||||||
|
rmw_publisher_t * rmw_handle;
|
||||||
|
} rcl_publisher_impl_t;
|
||||||
|
|
||||||
|
rcl_publisher_t
|
||||||
|
rcl_get_zero_initialized_publisher()
|
||||||
|
{
|
||||||
|
static rcl_publisher_t null_publisher = {0};
|
||||||
|
return null_publisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcl_ret_t
|
||||||
|
rcl_publisher_init(
|
||||||
|
rcl_publisher_t * publisher,
|
||||||
|
const rcl_node_t * node,
|
||||||
|
const rosidl_message_type_support_t * type_support,
|
||||||
|
const char * topic_name,
|
||||||
|
const rcl_publisher_options_t * options)
|
||||||
|
{
|
||||||
|
rcl_ret_t fail_ret = RCL_RET_ERROR;
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(publisher, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(type_support, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(topic_name, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
if (publisher->impl) {
|
||||||
|
RCL_SET_ERROR_MSG("publisher already initialized, or memory was unintialized");
|
||||||
|
return RCL_RET_ALREADY_INIT;
|
||||||
|
}
|
||||||
|
const rcl_allocator_t * allocator = &options->allocator;
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
allocator->allocate, "allocate not set", return RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
allocator->deallocate, "deallocate not set", return RCL_RET_INVALID_ARGUMENT);
|
||||||
|
// Allocate space for the implementation struct.
|
||||||
|
publisher->impl = (rcl_publisher_impl_t *)allocator->allocate(
|
||||||
|
sizeof(rcl_publisher_impl_t), allocator->state);
|
||||||
|
RCL_CHECK_FOR_NULL_WITH_MSG(
|
||||||
|
publisher->impl, "allocating memory failed", return RCL_RET_BAD_ALLOC);
|
||||||
|
// Fill out implementation struct.
|
||||||
|
// rmw handle (create rmw publisher)
|
||||||
|
// TODO(wjwwood): pass along the allocator to rmw when it supports it
|
||||||
|
publisher->impl->rmw_handle = rmw_create_publisher(
|
||||||
|
rcl_node_get_rmw_node_handle(node),
|
||||||
|
type_support,
|
||||||
|
topic_name,
|
||||||
|
&rmw_qos_profile_default);
|
||||||
|
if (!publisher->impl->rmw_handle) {
|
||||||
|
RCL_SET_ERROR_MSG(rmw_get_error_string_safe());
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
// options
|
||||||
|
publisher->impl->options = *options;
|
||||||
|
return RCL_RET_OK;
|
||||||
|
fail:
|
||||||
|
if (publisher->impl) {
|
||||||
|
allocator->deallocate(publisher->impl, allocator->state);
|
||||||
|
}
|
||||||
|
return fail_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -81,10 +81,10 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_fini()
|
rcl_shutdown()
|
||||||
{
|
{
|
||||||
if (!atomic_load(&__rcl_is_initialized)) {
|
if (!atomic_load(&__rcl_is_initialized)) {
|
||||||
RCL_SET_ERROR_MSG("rcl_fini called before rcl_init");
|
RCL_SET_ERROR_MSG("rcl_shutdown called before rcl_init");
|
||||||
return RCL_RET_NOT_INIT;
|
return RCL_RET_NOT_INIT;
|
||||||
}
|
}
|
||||||
__clean_up_init();
|
__clean_up_init();
|
||||||
|
|
26
rcl/src/rcl/subscription.c
Normal file
26
rcl/src/rcl/subscription.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rcl/subscription.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
24
rcl/src/rcl/wait.c
Normal file
24
rcl/src/rcl/wait.c
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rcl/wait.h"
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue