Skip to content
Open
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
15 changes: 15 additions & 0 deletions rclcpp/include/rclcpp/publisher_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,21 @@ class PublisherBase : public std::enable_shared_from_this<PublisherBase>
RCLCPP_PUBLIC
virtual ~PublisherBase();

/// Check if a publisher event type is supported by the active RMW implementation.
/**
* This API allows application code to introspect at runtime whether a
* particular publisher event type is supported by the currently loaded
* RMW implementation, enabling portable code that adapts gracefully
* when switching between RMW implementations.
*
* \param[in] event_type the publisher event type to check
* \return `true` if the event type is supported, `false` otherwise
*/
RCLCPP_PUBLIC
static
bool
event_type_is_supported(const rcl_publisher_event_type_t event_type);

/// Add event handlers for passed in event_callbacks.
RCLCPP_PUBLIC
void
Expand Down
15 changes: 15 additions & 0 deletions rclcpp/include/rclcpp/subscription_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ class SubscriptionBase : public std::enable_shared_from_this<SubscriptionBase>
RCLCPP_PUBLIC
virtual ~SubscriptionBase();

/// Check if a subscription event type is supported by the active RMW implementation.
/**
* This API allows application code to introspect at runtime whether a
* particular subscription event type is supported by the currently loaded
* RMW implementation, enabling portable code that adapts gracefully
* when switching between RMW implementations.
*
* \param[in] event_type the subscription event type to check
* \return `true` if the event type is supported, `false` otherwise
*/
RCLCPP_PUBLIC
static
bool
event_type_is_supported(const rcl_subscription_event_type_t event_type);

/// Add event handlers for passed in event_callbacks.
RCLCPP_PUBLIC
void
Expand Down
7 changes: 7 additions & 0 deletions rclcpp/src/rclcpp/publisher_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <unordered_map>
#include <vector>

#include "rcl/event.h"
#include "rcutils/logging_macros.h"
#include "rmw/impl/cpp/demangle.hpp"

Expand Down Expand Up @@ -131,6 +132,12 @@ PublisherBase::get_topic_name() const
return rcl_publisher_get_topic_name(publisher_handle_.get());
}

bool
PublisherBase::event_type_is_supported(const rcl_publisher_event_type_t event_type)
{
return rcl_publisher_event_type_is_supported(event_type);
}

void
PublisherBase::bind_event_callbacks(
const PublisherEventCallbacks & event_callbacks, bool use_default_callbacks)
Expand Down
7 changes: 7 additions & 0 deletions rclcpp/src/rclcpp/subscription_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "rclcpp/node_interfaces/node_base_interface.hpp"
#include "rclcpp/event_handler.hpp"

#include "rcl/event.h"
#include "rmw/error_handling.h"
#include "rmw/rmw.h"

Expand Down Expand Up @@ -108,6 +109,12 @@ SubscriptionBase::~SubscriptionBase()
ipm->remove_subscription(intra_process_subscription_id_);
}

bool
SubscriptionBase::event_type_is_supported(const rcl_subscription_event_type_t event_type)
{
return rcl_subscription_event_type_is_supported(event_type);
}

void
SubscriptionBase::bind_event_callbacks(
const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks)
Expand Down
86 changes: 71 additions & 15 deletions rclcpp/test/rclcpp/test_qos_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <string>

#include "rclcpp/rclcpp.hpp"
#include "rcl/event.h"
#include "rcutils/logging.h"
#include "rmw/rmw.h"
#include "test_msgs/msg/empty.hpp"
Expand Down Expand Up @@ -73,8 +74,8 @@ TEST_F(TestQosEvent, test_publisher_constructor)
auto publisher = node->create_publisher<test_msgs::msg::Empty>(
topic_name, 10, options);

if (rmw_event_type_is_supported(RMW_EVENT_OFFERED_DEADLINE_MISSED) &&
rmw_event_type_is_supported(RMW_EVENT_LIVELINESS_LOST))
if (rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED) &&
rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_LIVELINESS_LOST))
Comment on lines +77 to +78
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now we have these APIs, so that call rclcpp APIs instead of rmws.

{
// options arg with one of the callbacks
options.event_callbacks.deadline_callback =
Expand Down Expand Up @@ -123,8 +124,9 @@ TEST_F(TestQosEvent, test_subscription_constructor)
auto subscription = node->create_subscription<test_msgs::msg::Empty>(
topic_name, 10, message_callback, options);

if (rmw_event_type_is_supported(RMW_EVENT_REQUESTED_DEADLINE_MISSED) &&
rmw_event_type_is_supported(RMW_EVENT_LIVELINESS_CHANGED))
if (rclcpp::SubscriptionBase::event_type_is_supported(
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED) &&
rclcpp::SubscriptionBase::event_type_is_supported(RCL_SUBSCRIPTION_LIVELINESS_CHANGED))
{
// options arg with one of the callbacks
options.event_callbacks.deadline_callback =
Expand Down Expand Up @@ -239,7 +241,7 @@ TEST_F(TestQosEvent, construct_destruct_rcl_error) {
// This callback requires some type of parameter, but it could be anything
auto callback = [](int) {};
const rcl_publisher_event_type_t event_type =
!rmw_event_type_is_supported(RMW_EVENT_OFFERED_DEADLINE_MISSED) ?
!rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED) ?
RCL_PUBLISHER_MATCHED : RCL_PUBLISHER_OFFERED_DEADLINE_MISSED;

{
Expand Down Expand Up @@ -277,7 +279,7 @@ TEST_F(TestQosEvent, construct_destruct_rcl_error) {
}

TEST_F(TestQosEvent, execute) {
if (!rmw_event_type_is_supported(RMW_EVENT_OFFERED_DEADLINE_MISSED)) {
if (!rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED)) {
GTEST_SKIP();
}

Expand Down Expand Up @@ -314,7 +316,7 @@ TEST_F(TestQosEvent, add_to_wait_set) {
auto callback = [](int) {};

const rcl_publisher_event_type_t event_type =
!rmw_event_type_is_supported(RMW_EVENT_OFFERED_DEADLINE_MISSED) ?
!rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED) ?
RCL_PUBLISHER_MATCHED : RCL_PUBLISHER_OFFERED_DEADLINE_MISSED;

rclcpp::EventHandler<decltype(callback), decltype(rcl_handle)> handler(
Expand All @@ -338,8 +340,9 @@ TEST_F(TestQosEvent, add_to_wait_set) {

TEST_F(TestQosEvent, test_on_new_event_callback)
{
if (!rmw_event_type_is_supported(RMW_EVENT_REQUESTED_DEADLINE_MISSED) ||
!rmw_event_type_is_supported(RMW_EVENT_OFFERED_DEADLINE_MISSED))
if (!rclcpp::SubscriptionBase::event_type_is_supported(
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED) ||
!rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED))
{
GTEST_SKIP();
}
Expand Down Expand Up @@ -389,8 +392,8 @@ TEST_F(TestQosEvent, test_invalid_on_new_event_callback)
auto sub = node->create_subscription<test_msgs::msg::Empty>(topic_name, 10, message_callback);
auto dummy_cb = [](size_t count_events) {(void)count_events;};

if (rmw_event_type_is_supported(RMW_EVENT_OFFERED_DEADLINE_MISSED) &&
rmw_event_type_is_supported(RMW_EVENT_LIVELINESS_LOST))
if (rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED) &&
rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_LIVELINESS_LOST))
{
EXPECT_NO_THROW(
pub->set_on_new_qos_event_callback(dummy_cb, RCL_PUBLISHER_OFFERED_DEADLINE_MISSED));
Expand All @@ -416,8 +419,9 @@ TEST_F(TestQosEvent, test_invalid_on_new_event_callback)
EXPECT_NO_THROW(
pub->clear_on_new_qos_event_callback(RCL_PUBLISHER_MATCHED));

if (rmw_event_type_is_supported(RMW_EVENT_REQUESTED_DEADLINE_MISSED) &&
rmw_event_type_is_supported(RMW_EVENT_LIVELINESS_CHANGED))
if (rclcpp::SubscriptionBase::event_type_is_supported(
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED) &&
rclcpp::SubscriptionBase::event_type_is_supported(RCL_SUBSCRIPTION_LIVELINESS_CHANGED))
{
EXPECT_NO_THROW(
sub->set_on_new_qos_event_callback(dummy_cb, RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED));
Expand All @@ -443,8 +447,9 @@ TEST_F(TestQosEvent, test_invalid_on_new_event_callback)
EXPECT_NO_THROW(
sub->clear_on_new_qos_event_callback(RCL_SUBSCRIPTION_MATCHED));

if (rmw_event_type_is_supported(RMW_EVENT_REQUESTED_DEADLINE_MISSED) &&
rmw_event_type_is_supported(RMW_EVENT_OFFERED_DEADLINE_MISSED))
if (rclcpp::SubscriptionBase::event_type_is_supported(
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED) &&
rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED))
{
std::function<void(size_t)> invalid_cb;

Expand Down Expand Up @@ -639,3 +644,54 @@ TEST_F(TestQosEvent, test_sub_matched_event_by_option_event_callback)
}
ex.spin_until_future_complete(prom.get_future(), timeout);
}

/*
* Test rclcpp::PublisherBase::event_type_is_supported
*/
TEST_F(TestQosEvent, test_publisher_event_type_is_supported)
{
// Verify rclcpp results are consistent with the underlying rcl results
EXPECT_EQ(
rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED),
rcl_publisher_event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED));
EXPECT_EQ(
rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_LIVELINESS_LOST),
rcl_publisher_event_type_is_supported(RCL_PUBLISHER_LIVELINESS_LOST));
EXPECT_EQ(
rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS),
rcl_publisher_event_type_is_supported(RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS));
EXPECT_EQ(
rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_INCOMPATIBLE_TYPE),
rcl_publisher_event_type_is_supported(RCL_PUBLISHER_INCOMPATIBLE_TYPE));
EXPECT_EQ(
rclcpp::PublisherBase::event_type_is_supported(RCL_PUBLISHER_MATCHED),
rcl_publisher_event_type_is_supported(RCL_PUBLISHER_MATCHED));
}

/*
* Test rclcpp::SubscriptionBase::event_type_is_supported
*/
TEST_F(TestQosEvent, test_subscription_event_type_is_supported)
{
// Verify rclcpp results are consistent with the underlying rcl results
EXPECT_EQ(
rclcpp::SubscriptionBase::event_type_is_supported(
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED),
rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED));
EXPECT_EQ(
rclcpp::SubscriptionBase::event_type_is_supported(RCL_SUBSCRIPTION_LIVELINESS_CHANGED),
rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_LIVELINESS_CHANGED));
EXPECT_EQ(
rclcpp::SubscriptionBase::event_type_is_supported(
RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS),
rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS));
EXPECT_EQ(
rclcpp::SubscriptionBase::event_type_is_supported(RCL_SUBSCRIPTION_MESSAGE_LOST),
rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_MESSAGE_LOST));
EXPECT_EQ(
rclcpp::SubscriptionBase::event_type_is_supported(RCL_SUBSCRIPTION_INCOMPATIBLE_TYPE),
rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_INCOMPATIBLE_TYPE));
EXPECT_EQ(
rclcpp::SubscriptionBase::event_type_is_supported(RCL_SUBSCRIPTION_MATCHED),
rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_MATCHED));
}