Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions rclc/include/rclc/publisher.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,31 @@ rclc_publisher_init_default(
const rosidl_message_type_support_t * type_support,
const char * topic_name);

/**
* Creates an rcl publisher with quality-of-service option best effort
*
* * <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes (in RCL)
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[inout] publisher a zero_initialized rcl_publisher_t
* \param[in] node the rcl node
* \param[in] type_support the message data type
* \param[in] topic_name the name of published topic
* \return `RCL_RET_OK` if successful
* \return `RCL_ERROR` (or other error code) if an error has occurred
*/
rcl_ret_t
rclc_publisher_init_best_effort(
rcl_publisher_t * publisher,
const rcl_node_t * node,
const rosidl_message_type_support_t * type_support,
const char * topic_name);

#if __cplusplus
}
#endif
Expand Down
26 changes: 26 additions & 0 deletions rclc/include/rclc/subscription.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern "C"
#include <rcl/subscription.h>
#include <rclc/types.h>
#include <rclc/init.h>

/**
* Creates an rcl subscription.
*
Expand All @@ -49,6 +50,31 @@ rclc_subscription_init_default(
const rosidl_message_type_support_t * type_support,
const char * topic_name);

/**
* Creates an rcl subscription with quality of service option best effort
*
* * <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes (in RCL)
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[inout] subscription - a zero-initialized rcl_subscription_t
* \param[in] node the rcl node
* \param[in] type_support the message data type
* \param[in] topic_name the name of subscribed topic
* \return `RCL_RET_OK` if successful
* \return `RCL_ERROR` (or other error code) if an error occurred
*/
rcl_ret_t
rclc_subscription_init_best_effort(
rcl_subscription_t * subscription,
rcl_node_t * node,
const rosidl_message_type_support_t * type_support,
const char * topic_name);

#if __cplusplus
}
#endif
Expand Down
30 changes: 30 additions & 0 deletions rclc/src/rclc/publisher.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,33 @@ rclc_publisher_init_default(
}
return rc;
}

rcl_ret_t
rclc_publisher_init_best_effort(
rcl_publisher_t * publisher,
const rcl_node_t * node,
const rosidl_message_type_support_t * type_support,
const char * topic_name)
{
RCL_CHECK_FOR_NULL_WITH_MSG(
publisher, "publisher is a null pointer", return RCL_RET_INVALID_ARGUMENT);
RCL_CHECK_FOR_NULL_WITH_MSG(
node, "node is a null pointer", return RCL_RET_INVALID_ARGUMENT);
RCL_CHECK_FOR_NULL_WITH_MSG(
type_support, "type_support is a null pointer", return RCL_RET_INVALID_ARGUMENT);
RCL_CHECK_FOR_NULL_WITH_MSG(
topic_name, "topic_name is a null pointer", return RCL_RET_INVALID_ARGUMENT);

rcl_publisher_options_t pub_opt = rcl_publisher_get_default_options();
pub_opt.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT;
rcl_ret_t rc = rcl_publisher_init(
publisher,
node,
type_support,
topic_name,
&pub_opt);
if (rc != RCL_RET_OK) {
PRINT_RCLC_ERROR(rclc_publisher_init_best_effort, rcl_publisher_init);
}
return rc;
}
34 changes: 32 additions & 2 deletions rclc/src/rclc/subscription.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,45 @@ rclc_subscription_init_default(
RCL_CHECK_FOR_NULL_WITH_MSG(
topic_name, "topic_name is a null pointer", return RCL_RET_INVALID_ARGUMENT);

rcl_subscription_options_t sub_ops = rcl_subscription_get_default_options();
rcl_subscription_options_t sub_opt = rcl_subscription_get_default_options();
rcl_ret_t rc = rcl_subscription_init(
subscription,
node,
type_support,
topic_name,
&sub_ops);
&sub_opt);
if (rc != RCL_RET_OK) {
PRINT_RCLC_ERROR(rclc_subscription_init_default, rcl_subscription_init);
}
return rc;
}

rcl_ret_t
rclc_subscription_init_best_effort(
rcl_subscription_t * subscription,
rcl_node_t * node,
const rosidl_message_type_support_t * type_support,
const char * topic_name)
{
RCL_CHECK_FOR_NULL_WITH_MSG(
subscription, "subscription is a null pointer", return RCL_RET_INVALID_ARGUMENT);
RCL_CHECK_FOR_NULL_WITH_MSG(
node, "node is a null pointer", return RCL_RET_INVALID_ARGUMENT);
RCL_CHECK_FOR_NULL_WITH_MSG(
type_support, "type_support is a null pointer", return RCL_RET_INVALID_ARGUMENT);
RCL_CHECK_FOR_NULL_WITH_MSG(
topic_name, "topic_name is a null pointer", return RCL_RET_INVALID_ARGUMENT);

rcl_subscription_options_t sub_opt = rcl_subscription_get_default_options();
sub_opt.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT;
rcl_ret_t rc = rcl_subscription_init(
subscription,
node,
type_support,
topic_name,
&sub_opt);
if (rc != RCL_RET_OK) {
PRINT_RCLC_ERROR(rclc_subscription_init_best_effort, rcl_subscription_init);
}
return rc;
}
45 changes: 45 additions & 0 deletions rclc/test/rclc/test_publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,48 @@ TEST(Test, rclc_publisher_init_default) {
rc = rclc_support_fini(&support);
EXPECT_EQ(RCL_RET_OK, rc);
}

TEST(Test, rclc_publisher_init_best_effort) {
rclc_support_t support;
rcl_ret_t rc;

// preliminary setup
rcl_allocator_t allocator = rcl_get_default_allocator();
rc = rclc_support_init(&support, 0, nullptr, &allocator);
const char * my_name = "test_name";
const char * my_namespace = "test_namespace";
rcl_node_t node = rcl_get_zero_initialized_node();
rc = rclc_node_init_default(&node, my_name, my_namespace, &support);

// test with valid arguments
rcl_publisher_t publisher = rcl_get_zero_initialized_publisher();
const rosidl_message_type_support_t * type_support =
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32);
rc = rclc_publisher_init_best_effort(&publisher, &node, type_support, "topic1");
EXPECT_EQ(RCL_RET_OK, rc);

// check for qos-option best effort
const rcl_publisher_options_t * pub_options = rcl_publisher_get_options(&publisher);
EXPECT_EQ(pub_options->qos.reliability, RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT);

// tests with invalid arguments
rc = rclc_publisher_init_best_effort(nullptr, &node, type_support, "topic1");
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rc);
rcutils_reset_error();
rc = rclc_publisher_init_best_effort(&publisher, nullptr, type_support, "topic1");
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rc);
rcutils_reset_error();
rc = rclc_publisher_init_best_effort(&publisher, &node, nullptr, "topic1");
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rc);
rcutils_reset_error();
rc = rclc_publisher_init_best_effort(&publisher, &node, type_support, nullptr);
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rc);
rcutils_reset_error();
// clean up
rc = rcl_publisher_fini(&publisher, &node);
EXPECT_EQ(RCL_RET_OK, rc);
rc = rcl_node_fini(&node);
EXPECT_EQ(RCL_RET_OK, rc);
rc = rclc_support_fini(&support);
EXPECT_EQ(RCL_RET_OK, rc);
}
45 changes: 45 additions & 0 deletions rclc/test/rclc/test_subscription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,48 @@ TEST(Test, rclc_subscription_init_default) {
rc = rclc_support_fini(&support);
EXPECT_EQ(RCL_RET_OK, rc);
}


TEST(Test, rclc_subscription_init_best_effort) {
rclc_support_t support;
rcl_ret_t rc;

// preliminary setup
rcl_allocator_t allocator = rcl_get_default_allocator();
rc = rclc_support_init(&support, 0, nullptr, &allocator);
const char * my_name = "test_name";
const char * my_namespace = "test_namespace";
rcl_node_t node = rcl_get_zero_initialized_node();
rc = rclc_node_init_default(&node, my_name, my_namespace, &support);

// test with valid arguments

rcl_subscription_t subscription = rcl_get_zero_initialized_subscription();
const rosidl_message_type_support_t * type_support =
ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32);
rc = rclc_subscription_init_best_effort(&subscription, &node, type_support, "topic1");
EXPECT_EQ(RCL_RET_OK, rc);
const rcl_subscription_options_t * sub_options = rcl_subscription_get_options(&subscription);
EXPECT_EQ(sub_options->qos.reliability, RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT);

// tests with invalid arguments
rc = rclc_subscription_init_best_effort(nullptr, &node, type_support, "topic1");
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rc);
rcutils_reset_error();
rc = rclc_subscription_init_best_effort(&subscription, nullptr, type_support, "topic1");
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rc);
rcutils_reset_error();
rc = rclc_subscription_init_best_effort(&subscription, &node, nullptr, "topic1");
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rc);
rcutils_reset_error();
rc = rclc_subscription_init_best_effort(&subscription, &node, type_support, nullptr);
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rc);
rcutils_reset_error();
// clean up
rc = rcl_subscription_fini(&subscription, &node);
EXPECT_EQ(RCL_RET_OK, rc);
rc = rcl_node_fini(&node);
EXPECT_EQ(RCL_RET_OK, rc);
rc = rclc_support_fini(&support);
EXPECT_EQ(RCL_RET_OK, rc);
}