From c1777181805b47d139617f9a8cf88341bfb4cfdf Mon Sep 17 00:00:00 2001 From: Emerson Knapp <537409+emersonknapp@users.noreply.github.com> Date: Mon, 1 Apr 2019 19:54:49 -0700 Subject: [PATCH] Update rclcpp functionality to use new interfaces (#4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New interfaces for incoming QoS features Adds new PublisherOptions and SubscriptionOptions classes, with new Publisher and Subscriber constructors to accept them. Adds the liveliness assertion callbacks that will be needed for the new Liveliness QoS policy Signed-off-by: Emerson Knapp * Fix options usage in implementation, and add test to catch that code path. Signed-off-by: Emerson Knapp * rclcpp QoS implementation (#2) * Add interfaces for events in memory_strategy Signed-off-by: Miaofei * refactor waitables Signed-off-by: Miaofei * Attempt to fix cppcheck (#646) Signed-off-by: Shane Loretz * add event callbacks to publisher, subscriber, client, service Signed-off-by: Miaofei * fix some ros2 build issues Signed-off-by: Miaofei * Add a method to the LifecycleNode class to get the logging interface (#652) There are getters for the other interfaces, but the logging interface appears to have been overlooked. Signed-off-by: Michael Jeronimo * Add Doxyfile for rclcpp_action Signed-off-by: Jacob Perron * Add documentation to rclcpp_action Signed-off-by: Jacob Perron * update to use separated action types (#601) * match renamed action types * fix action type casting * rename type/field to use correct term * rename custom GoalID type to avoid naming collision, update types using unique_identifier_msgs * remove obsolete comments * change signature of set_succeeded / set_canceled * change signature of on_terminal_state_(uuid_, result_msg);set_succeeded / set_canceled * change signature of set_aborted * change signature of publish_feedback * update another test Signed-off-by: Miaofei * update client-facing API Signed-off-by: Miaofei * Don't hardcode int64_t for duration type representations (#648) In LLVM's `libcxx`, `int64_t` doesn't match chrono literals. See example below. To compile, run `clang++-6.0 -stdlib=libc++ -std=c++14 TEST.cpp` ``` using namespace std::chrono_literals; template bool wait_for_service( std::chrono::duration timeout ) { return timeout == std::chrono::nanoseconds(0); } int main() { wait_for_service(2s); return 0; } ``` Result of compilation ``` TEST.cpp:6:1: note: candidate template ignored: could not match 'long' against 'long long' wait_for_service( ``` Signed-off-by: Emerson Knapp Signed-off-by: Steven! Ragnarök * improve usability of the SubscriptionOptions and PublisherOptions classes Signed-off-by: Miaofei * Fix test_time_source test (#639) * Fix flakey test Signed-off-by: Pete Baughman * Fix lint and uncrustify issues Signed-off-by: Pete Baughman * fix lint errors Signed-off-by: Miaofei * apply uncrustify Signed-off-by: Miaofei * add section about DCO to CONTRIBUTING.md * update for rcl API changes Signed-off-by: Miaofei * Fix lint and build warnings and API inconsistency Signed-off-by: Emerson Knapp * Avoid race that triggers timer too often (#621) The two distinct operations of acquiring and subsequent checking of a timer have to be protected by one lock_guard against races with other threads. The releasing of a timer has to be protected by the same lock. Given this requirement there is no use for a second mutex. Signed-off-by: Marko Durkovic * Back out Waitable and GraphEvent-related changes Signed-off-by: Emerson Knapp * add publisher and subscription events to AllocatorMemoryStrategy * Add stub API for assert_liveliness * Fix use_sim_time issue on LifeCycleNode (#651) Signed-off-by: vinnamkim * revert changes to client and services address PR comments Signed-off-by: Miaofei * Add parameter-related templates to LifecycleNode (#645) * Add parameter-related templates to LifecycleNode Signed-off-by: vinnamkim * Update rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp Co-Authored-By: vinnamkim * Update rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp * update API calls into rcl * fix linter errors in rclcpp_lifecycle (#672) Signed-off-by: Karsten Knese * Update to use the new interface definitions Signed-off-by: Emerson Knapp * Remove duplicate event_handlers_ --- rclcpp/CMakeLists.txt | 9 + rclcpp/include/rclcpp/create_subscription.hpp | 2 +- rclcpp/include/rclcpp/node.hpp | 98 +++++++++- rclcpp/include/rclcpp/node_impl.hpp | 121 +++++++++++- rclcpp/include/rclcpp/publisher.hpp | 30 +-- rclcpp/include/rclcpp/publisher_options.hpp | 162 +--------------- rclcpp/include/rclcpp/qos_event.hpp | 8 +- rclcpp/include/rclcpp/subscription.hpp | 16 +- .../include/rclcpp/subscription_options.hpp | 174 +----------------- rclcpp/src/rclcpp/subscription.cpp | 1 + rclcpp/test/test_pub_sub_option_interface.cpp | 56 ++++++ .../rclcpp_lifecycle/lifecycle_node_impl.hpp | 2 + 12 files changed, 324 insertions(+), 355 deletions(-) create mode 100644 rclcpp/test/test_pub_sub_option_interface.cpp diff --git a/rclcpp/CMakeLists.txt b/rclcpp/CMakeLists.txt index 6d6bc01b97..e705f325a9 100644 --- a/rclcpp/CMakeLists.txt +++ b/rclcpp/CMakeLists.txt @@ -249,6 +249,15 @@ if(BUILD_TESTING) ) target_link_libraries(test_publisher ${PROJECT_NAME}) endif() + ament_add_gtest(test_pub_sub_option_interface test/test_pub_sub_option_interface.cpp) + if(TARGET test_pub_sub_option_interface) + ament_target_dependencies(test_pub_sub_option_interface + test_msgs + ) + target_link_libraries(test_pub_sub_option_interface + ${PROJECT_NAME} + ) + endif() ament_add_gtest(test_publisher_subscription_count_api test/test_publisher_subscription_count_api.cpp) if(TARGET test_publisher_subscription_count_api) ament_target_dependencies(test_publisher_subscription_count_api diff --git a/rclcpp/include/rclcpp/create_subscription.hpp b/rclcpp/include/rclcpp/create_subscription.hpp index aa1f547039..e765d376e2 100644 --- a/rclcpp/include/rclcpp/create_subscription.hpp +++ b/rclcpp/include/rclcpp/create_subscription.hpp @@ -54,7 +54,7 @@ create_subscription( auto factory = rclcpp::create_subscription_factory ( std::forward(callback), - event_callbacks, + event_callbacks, msg_mem_strat, allocator); diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 3f0cde52e5..55bf131003 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -139,13 +139,44 @@ class Node : public std::enable_shared_from_this const std::vector & get_callback_groups() const; - /// Create and return a Publisher. + /// Create and return a Publisher. Note: This constructor is deprecated /** * \param[in] topic_name The topic for this publisher to publish on. * \param[in] group The callback group for this publisher. NULL for no callback group. * \param[in] options Additional options to control creation of the publisher. * \return Shared pointer to the created publisher. */ + template< + typename MessageT, typename Alloc = std::allocator, + typename PublisherT = ::rclcpp::Publisher> + std::shared_ptr + create_publisher( + const std::string & topic_name, + size_t qos_history_depth, + std::shared_ptr allocator = nullptr); + + /// Create and return a Publisher. Note: this constructor is deprecated + /** + * \param[in] topic_name The topic for this publisher to publish on. + * \param[in] qos_profile The quality of service profile to pass on to the rmw implementation. + * \param[in] allocator Optional custom allocator. + * \return Shared pointer to the created publisher. + */ + template< + typename MessageT, typename Alloc = std::allocator, + typename PublisherT = ::rclcpp::Publisher> + std::shared_ptr + create_publisher( + const std::string & topic_name, + const rmw_qos_profile_t & qos_profile = rmw_qos_profile_default, + std::shared_ptr allocator = nullptr); + + /// Create and return a Publisher. + /** + * \param[in] topic_name The topic for this publisher to publish on. + * \param[in] options Additional options for the created Publisher + * \return Shared pointer to the created publisher. + */ template< typename MessageT, typename Alloc = std::allocator, @@ -153,10 +184,39 @@ class Node : public std::enable_shared_from_this std::shared_ptr create_publisher( const std::string & topic_name, + const PublisherOptions & options, + rclcpp::callback_group::CallbackGroup::SharedPtr callback_group = nullptr); + + /// Create and return a Subscription. Note: this constructor is deprecated + /** + * \param[in] topic_name The topic to subscribe on. + * \param[in] callback The user-defined callback function. + * \param[in] qos_profile The quality of service profile to pass on to the rmw implementation. + * \param[in] group The callback group for this subscription. NULL for no callback group. + * \param[in] ignore_local_publications True to ignore local publications. + * \param[in] msg_mem_strat The message memory strategy to use for allocating messages. + * \param[in] allocator Optional custom allocator. + * \return Shared pointer to the created subscription. + */ + /* TODO(jacquelinekay): + Windows build breaks when static member function passed as default + argument to msg_mem_strat, nullptr is a workaround. + */ + template< + typename MessageT, + typename CallbackT, + typename Alloc = std::allocator, + typename SubscriptionT = rclcpp::Subscription< + typename rclcpp::subscription_traits::has_message_type::type, Alloc>> + std::shared_ptr + create_subscription( + const std::string & topic_name, + CallbackT && callback, + const rmw_qos_profile_t & qos_profile = rmw_qos_profile_default, rclcpp::callback_group::CallbackGroup::SharedPtr group = nullptr, const PublisherOptions & options = PublisherOptions()); - /// Create and return a Subscription. + /// Create and return a Subscription. Note: this constructor is deprecated /** * \param[in] topic_name The topic to subscribe on. * \param[in] callback The user-defined callback function. @@ -185,6 +245,34 @@ class Node : public std::enable_shared_from_this typename rclcpp::subscription_traits::has_message_type::type, Alloc>::SharedPtr msg_mem_strat = nullptr); + /// Create and return a Subscription. + /** + * \param[in] topic_name The topic to subscribe on. + * \param[in] callback The user-defined callback function to receive a message + * \param[in] options Additional options for the creation of the Subscription + * \param[in] msg_mem_strat The message memory strategy to use for allocating messages. + * \return Shared pointer to the created subscription. + */ + /* TODO(jacquelinekay): + Windows build breaks when static member function passed as default + argument to msg_mem_strat, nullptr is a workaround. + */ + template< + typename MessageT, + typename CallbackT, + typename Alloc = std::allocator, + typename SubscriptionT = rclcpp::Subscription< + typename rclcpp::subscription_traits::has_message_type::type, Alloc>> + std::shared_ptr + create_subscription( + const std::string & topic_name, + CallbackT && callback, + const SubscriptionOptions & options, + rclcpp::callback_group::CallbackGroup::SharedPtr callback_group = nullptr, + typename rclcpp::message_memory_strategy::MessageMemoryStrategy< + typename rclcpp::subscription_traits::has_message_type::type, Alloc>::SharedPtr + msg_mem_strat = nullptr); + /// Create a timer. /** * \param[in] period Time interval between triggers of the callback. @@ -549,13 +637,11 @@ class Node : public std::enable_shared_from_this const NodeOptions & get_node_options() const; - /// Manually assert that this Node is alive (for RMW_QOS_POLICY_MANUAL_BY_NODE) /** * If the rmw Liveliness policy is set to RMW_QOS_POLICY_MANUAL_BY_NODE, the creator of this - * node must manually call `assert_liveliness` on a regular basis to signal to the rest of the - * system that this Node is still alive. - * This function must be called at least as often as the qos_profile's liveliness_lease_duration + * Node must manually call `assert_liveliness` periodically to signal that this Node + * is still alive. Must be called at least as often as qos_profile's Liveliness lease_duration */ RCLCPP_PUBLIC void diff --git a/rclcpp/include/rclcpp/node_impl.hpp b/rclcpp/include/rclcpp/node_impl.hpp index 7fb4e177e1..47941920dc 100644 --- a/rclcpp/include/rclcpp/node_impl.hpp +++ b/rclcpp/include/rclcpp/node_impl.hpp @@ -51,6 +51,21 @@ namespace rclcpp { +template +std::shared_ptr +Node::create_publisher( + const std::string & topic_name, + size_t qos_history_depth, + std::shared_ptr allocator) +{ + if (!allocator) { + allocator = std::make_shared(); + } + rmw_qos_profile_t qos = rmw_qos_profile_default; + qos.depth = qos_history_depth; + return this->create_publisher(topic_name, qos, allocator); +} + RCLCPP_LOCAL inline std::string @@ -67,8 +82,8 @@ template std::shared_ptr Node::create_publisher( const std::string & topic_name, - rclcpp::callback_group::CallbackGroup::SharedPtr group, - const PublisherOptions & options) + const rmw_qos_profile_t & qos_profile, + std::shared_ptr allocator) { std::shared_ptr allocator = options.allocator(); if (!allocator) { @@ -78,8 +93,30 @@ Node::create_publisher( return rclcpp::create_publisher( this->node_topics_.get(), extend_name_with_sub_namespace(topic_name, this->get_sub_namespace()), - options.qos_profile(), - options.event_callbacks(), + qos_profile, + PublisherEventCallbacks(), + nullptr, + this->get_node_options().use_intra_process_comms(), + allocator); +} + +template +std::shared_ptr +Node::create_publisher( + const std::string & topic_name, + const PublisherOptions & options, + rclcpp::callback_group::CallbackGroup::SharedPtr group) +{ + std::shared_ptr allocator = options.allocator; + if (!allocator) { + allocator = std::make_shared(); + } + + return rclcpp::create_publisher( + this->node_topics_.get(), + extend_name_with_sub_namespace(topic_name, this->get_sub_namespace()), + options.qos_profile, + options.event_callbacks, group, this->get_node_options().use_intra_process_comms(), allocator); @@ -94,8 +131,8 @@ std::shared_ptr Node::create_subscription( const std::string & topic_name, CallbackT && callback, + const rmw_qos_profile_t & qos_profile, rclcpp::callback_group::CallbackGroup::SharedPtr group, - const SubscriptionOptions & options, typename rclcpp::message_memory_strategy::MessageMemoryStrategy< typename rclcpp::subscription_traits::has_message_type::type, Alloc>::SharedPtr msg_mem_strat) @@ -116,8 +153,8 @@ Node::create_subscription( this->node_topics_.get(), extend_name_with_sub_namespace(topic_name, this->get_sub_namespace()), std::forward(callback), - options.qos_profile(), - options.event_callbacks(), + qos_profile, + SubscriptionEventCallbacks(), group, options.ignore_local_publications(), this->get_node_options().use_intra_process_comms(), @@ -125,6 +162,76 @@ Node::create_subscription( allocator); } +template< + typename MessageT, + typename CallbackT, + typename Alloc, + typename SubscriptionT> +std::shared_ptr +Node::create_subscription( + const std::string & topic_name, + CallbackT && callback, + const SubscriptionOptions & options, + rclcpp::callback_group::CallbackGroup::SharedPtr group, + typename rclcpp::message_memory_strategy::MessageMemoryStrategy< + typename rclcpp::subscription_traits::has_message_type::type, Alloc>::SharedPtr + msg_mem_strat) +{ + using CallbackMessageT = typename rclcpp::subscription_traits::has_message_type::type; + + std::shared_ptr allocator = options.allocator; + if (!allocator) { + allocator = std::make_shared(); + } + + if (!msg_mem_strat) { + using rclcpp::message_memory_strategy::MessageMemoryStrategy; + msg_mem_strat = MessageMemoryStrategy::create_default(); + } + + return rclcpp::create_subscription( + this->node_topics_.get(), + extend_name_with_sub_namespace(topic_name, this->get_sub_namespace()), + std::forward(callback), + options.qos_profile, + options.event_callbacks, + group, + options.ignore_local_publications, + this->get_node_options().use_intra_process_comms(), + msg_mem_strat, + allocator); +} + +template< + typename MessageT, + typename CallbackT, + typename Alloc, + typename SubscriptionT> +std::shared_ptr +Node::create_subscription( + const std::string & topic_name, + CallbackT && callback, + size_t qos_history_depth, + rclcpp::callback_group::CallbackGroup::SharedPtr group, + bool ignore_local_publications, + typename rclcpp::message_memory_strategy::MessageMemoryStrategy< + typename rclcpp::subscription_traits::has_message_type::type, Alloc>::SharedPtr + msg_mem_strat, + std::shared_ptr allocator) +{ + rmw_qos_profile_t qos = rmw_qos_profile_default; + qos.depth = qos_history_depth; + + return this->create_subscription( + topic_name, + std::forward(callback), + qos, + group, + ignore_local_publications, + msg_mem_strat, + allocator); +} + template typename rclcpp::WallTimer::SharedPtr Node::create_wall_timer( diff --git a/rclcpp/include/rclcpp/publisher.hpp b/rclcpp/include/rclcpp/publisher.hpp index b02a3b7a03..4439ae221c 100644 --- a/rclcpp/include/rclcpp/publisher.hpp +++ b/rclcpp/include/rclcpp/publisher.hpp @@ -31,22 +31,24 @@ #include "rosidl_typesupport_cpp/message_type_support.hpp" #include "rcl_interfaces/msg/intra_process_message.hpp" -#include "rclcpp/publisher_options.hpp" -#include "rclcpp/waitable.hpp" -#include "rclcpp/qos_event.hpp" -#include "rclcpp/exceptions.hpp" #include "rclcpp/allocator/allocator_common.hpp" #include "rclcpp/allocator/allocator_deleter.hpp" +#include "rclcpp/exceptions.hpp" #include "rclcpp/macros.hpp" +#include "rclcpp/publisher_options.hpp" +#include "rclcpp/qos_event.hpp" +#include "rclcpp/type_support_decl.hpp" #include "rclcpp/visibility_control.hpp" namespace rclcpp { -// Forward declaration is used for friend statement. namespace node_interfaces { +// NOTE(emersonknapp) Forward declaration avoids including node_base_interface.hpp which causes +// circular inclusion from callback_group.hpp class NodeBaseInterface; +// Forward declaration is used for friend statement. class NodeTopicsInterface; } @@ -140,9 +142,8 @@ class PublisherBase /// Manually assert that this Publisher is alive (for RMW_QOS_POLICY_MANUAL_BY_TOPIC) /** * If the rmw Liveliness policy is set to RMW_QOS_POLICY_MANUAL_BY_TOPIC, the creator of this - * Publisher must manually call `assert_liveliness` on a regular basis to signal to the rest of - * the system that this Node is still alive. - * This function must be called at least as often as the qos_profile's liveliness_lease_duration + * Publisher must manually call `assert_liveliness` periodically to signal that this Publisher + * is still alive. Must be called at least as often as qos_profile's Liveliness lease_duration */ RCLCPP_PUBLIC void @@ -188,11 +189,12 @@ class PublisherBase const EventCallbackT & callback, const rcl_publisher_event_type_t event_type) { - event_handlers_.emplace_back(std::make_shared>( + auto handler = std::make_shared>( callback, rcl_publisher_event_init, &publisher_handle_, - event_type)); + event_type); + event_handlers_.emplace_back(handler); } std::shared_ptr rcl_node_handle_; @@ -240,12 +242,12 @@ class Publisher : public PublisherBase { allocator::set_allocator_for_deleter(&message_deleter_, message_allocator_.get()); - if (event_callbacks.deadline_callback_) { - this->add_event_handler(event_callbacks.deadline_callback_, + if (event_callbacks.deadline_callback) { + this->add_event_handler(event_callbacks.deadline_callback, RCL_PUBLISHER_OFFERED_DEADLINE_MISSED); } - if (event_callbacks.liveliness_callback_) { - this->add_event_handler(event_callbacks.liveliness_callback_, + if (event_callbacks.liveliness_callback) { + this->add_event_handler(event_callbacks.liveliness_callback, RCL_PUBLISHER_LIVELINESS_LOST); } } diff --git a/rclcpp/include/rclcpp/publisher_options.hpp b/rclcpp/include/rclcpp/publisher_options.hpp index 1b87f6c4c2..3de956d693 100644 --- a/rclcpp/include/rclcpp/publisher_options.hpp +++ b/rclcpp/include/rclcpp/publisher_options.hpp @@ -19,171 +19,27 @@ #include #include -#include "rclcpp/visibility_control.hpp" #include "rclcpp/qos_event.hpp" +#include "rclcpp/visibility_control.hpp" namespace rclcpp { +/// Contains callbacks for various types of events a Publisher can receive from the middleware struct PublisherEventCallbacks { - QOSDeadlineOfferedCallbackType deadline_callback_; - QOSLivelinessLostCallbackType liveliness_callback_; + QOSDeadlineOfferedCallbackType deadline_callback; + QOSLivelinessLostCallbackType liveliness_callback; }; +/// Structure containing configuration options for Publishers/Subscribers template> -class PublisherOptions +struct PublisherOptions { -public: - /// Create PublisherOptions with default values, optionally specifying the allocator to use. - /** - * Default values for the node options: - * - * - context = rclcpp::contexts::default_context::get_global_default_context() - * - arguments = {} - * - initial_parameters = {} - * - use_global_arguments = true - * - use_intra_process_comms = false - * - start_parameter_services = true - * - start_publisher_publisher = true - * - publisher_qos_profile = rmw_qos_profile_default - * - allocator = rcl_get_default_allocator() - * - * \param[in] allocator allocator to use in construction of PublisherOptions. - */ - RCLCPP_PUBLIC - PublisherOptions() = default; - - RCLCPP_PUBLIC - explicit PublisherOptions(const rmw_qos_profile_t & qos_profile) - : publisher_qos_profile_(qos_profile) {} - - /// Destructor. - RCLCPP_PUBLIC - virtual - ~PublisherOptions() = default; - - /// Copy constructor. - RCLCPP_PUBLIC - PublisherOptions(const PublisherOptions & other) = default; - - /// Assignment operator. - RCLCPP_PUBLIC - PublisherOptions & - operator=(const PublisherOptions & other) = default; - - - /// Return a reference to the publisher_qos_profile QoS. - RCLCPP_PUBLIC - const rmw_qos_profile_t & - qos_profile() const - { - return publisher_qos_profile_; - } - - RCLCPP_PUBLIC - rmw_qos_profile_t & - qos_profile() - { - return publisher_qos_profile_; - } - - /// Set the publisher_qos_profile QoS, return this for parameter idiom. - /** - * The QoS settings to be used for the publisher - */ - RCLCPP_PUBLIC - PublisherOptions & - qos_profile(const rmw_qos_profile_t & publisher_qos_profile) - { - publisher_qos_profile_ = publisher_qos_profile; - return *this; - } - - RCLCPP_PUBLIC - size_t & - qos_history_depth() - { - return publisher_qos_profile_.depth; - } - - RCLCPP_PUBLIC - PublisherOptions & - qos_history_depth(size_t depth) - { - publisher_qos_profile_.depth = depth; - return *this; - } - - - RCLCPP_PUBLIC - const QOSDeadlineOfferedCallbackType & - deadline_callback() const - { - return callbacks_.deadline_callback_; - } - - RCLCPP_PUBLIC - PublisherOptions & - deadline_callback(const QOSDeadlineOfferedCallbackType & callback) - { - callbacks_.deadline_callback_ = callback; - return *this; - } - - RCLCPP_PUBLIC - const QOSLivelinessLostCallbackType & - liveliness_callback() const - { - return callbacks_.liveliness_callback_; - } - - RCLCPP_PUBLIC - PublisherOptions & - liveliness_callback(const QOSLivelinessLostCallbackType & callback) - { - callbacks_.liveliness_callback_ = callback; - return *this; - } - - RCLCPP_PUBLIC - const PublisherEventCallbacks & - event_callbacks() const - { - return callbacks_; - } - - - /// Return the rcl_allocator_t to be used. - RCLCPP_PUBLIC - std::shared_ptr - allocator() const - { - return allocator_; - } - - /// Set the rcl_allocator_t to be used, may cause deallocation of existing rcl_publisher_options_t - /** - * This will cause the internal rcl_publisher_options_t struct to be invalidated. - */ - RCLCPP_PUBLIC - PublisherOptions & - allocator(std::shared_ptr allocator) - { - allocator_ = allocator; - return *this; - } - -private: - // IMPORTANT: if any of these default values are changed, please update the - // documentation in this class. - - PublisherEventCallbacks callbacks_; - - rmw_qos_profile_t publisher_qos_profile_ = rmw_qos_profile_default; - - std::shared_ptr allocator_ = nullptr; + PublisherEventCallbacks event_callbacks; + rmw_qos_profile_t qos_profile = rmw_qos_profile_default; + std::shared_ptr allocator = nullptr; }; } // namespace rclcpp diff --git a/rclcpp/include/rclcpp/qos_event.hpp b/rclcpp/include/rclcpp/qos_event.hpp index 08833a6a1d..026eb5227e 100644 --- a/rclcpp/include/rclcpp/qos_event.hpp +++ b/rclcpp/include/rclcpp/qos_event.hpp @@ -34,10 +34,10 @@ using QOSDeadlineOfferedInfo = rmw_offered_deadline_missed_status_t; using QOSLivelinessChangedInfo = rmw_liveliness_changed_status_t; using QOSLivelinessLostInfo = rmw_liveliness_lost_status_t; -using QOSDeadlineRequestedCallbackType = std::function; -using QOSDeadlineOfferedCallbackType = std::function; -using QOSLivelinessChangedCallbackType = std::function; -using QOSLivelinessLostCallbackType = std::function; +using QOSDeadlineRequestedCallbackType = std::function; +using QOSDeadlineOfferedCallbackType = std::function; +using QOSLivelinessChangedCallbackType = std::function; +using QOSLivelinessLostCallbackType = std::function; class QOSEventHandlerBase : public Waitable diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index 6e12d85414..4547ce506f 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -38,9 +38,12 @@ #include "rclcpp/expand_topic_or_service_name.hpp" #include "rclcpp/macros.hpp" #include "rclcpp/message_memory_strategy.hpp" +#include "rclcpp/qos_event.hpp" +#include "rclcpp/subscription_options.hpp" #include "rclcpp/subscription_traits.hpp" #include "rclcpp/type_support_decl.hpp" #include "rclcpp/visibility_control.hpp" +#include "rclcpp/waitable.hpp" namespace rclcpp { @@ -159,11 +162,12 @@ class SubscriptionBase const EventCallbackT & callback, const rcl_subscription_event_type_t event_type) { - event_handlers_.emplace_back(std::make_shared>( + auto handler = std::make_shared>( callback, rcl_subscription_event_init, get_subscription_handle().get(), - event_type)); + event_type); + event_handlers_.emplace_back(handler); } using IntraProcessManagerWeakPtr = @@ -239,12 +243,12 @@ class Subscription : public SubscriptionBase get_intra_process_message_callback_(nullptr), matches_any_intra_process_publishers_(nullptr) { - if (event_callbacks.deadline_callback_) { - this->add_event_handler(event_callbacks.deadline_callback_, + if (event_callbacks.deadline_callback) { + this->add_event_handler(event_callbacks.deadline_callback, RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED); } - if (event_callbacks.liveliness_callback_) { - this->add_event_handler(event_callbacks.liveliness_callback_, + if (event_callbacks.liveliness_callback) { + this->add_event_handler(event_callbacks.liveliness_callback, RCL_SUBSCRIPTION_LIVELINESS_CHANGED); } } diff --git a/rclcpp/include/rclcpp/subscription_options.hpp b/rclcpp/include/rclcpp/subscription_options.hpp index 6d6dc9fda4..5d378eada7 100644 --- a/rclcpp/include/rclcpp/subscription_options.hpp +++ b/rclcpp/include/rclcpp/subscription_options.hpp @@ -19,181 +19,27 @@ #include #include -#include "rclcpp/visibility_control.hpp" #include "rclcpp/qos_event.hpp" - +#include "rclcpp/visibility_control.hpp" namespace rclcpp { +/// Contains callbacks for non-message events that a Subscriber can receive from the middleware struct SubscriptionEventCallbacks { - QOSDeadlineRequestedCallbackType deadline_callback_; - QOSLivelinessChangedCallbackType liveliness_callback_; + QOSDeadlineRequestedCallbackType deadline_callback; + QOSLivelinessChangedCallbackType liveliness_callback; }; + template> -class SubscriptionOptions +struct SubscriptionOptions { -public: - /// Create SubscriptionOptions with default values, optionally specifying the allocator to use. - /** - * Default values for the node options: - * - * - deadline_callback = nullptr - * - liveliness_callback = nullptr - * - subscription_qos_profile = rmw_qos_profile_default - * - ignore_local_publications = false - * - allocator = nullptr - * - * \param[in] allocator allocator to use in construction of SubscriptionOptions. - */ - RCLCPP_PUBLIC - SubscriptionOptions() = default; - - RCLCPP_PUBLIC - explicit SubscriptionOptions(const rmw_qos_profile_t & qos_profile) - : subscription_qos_profile_(qos_profile) {} - - /// Destructor. - RCLCPP_PUBLIC - virtual - ~SubscriptionOptions() = default; - - /// Copy constructor. - RCLCPP_PUBLIC - SubscriptionOptions(const SubscriptionOptions & other) = default; - - /// Assignment operator. - RCLCPP_PUBLIC - SubscriptionOptions & - operator=(const SubscriptionOptions & other) = default; - - - /// Return a reference to the subscription_qos_profile QoS. - RCLCPP_PUBLIC - const rmw_qos_profile_t & - qos_profile() const - { - return subscription_qos_profile_; - } - - RCLCPP_PUBLIC - rmw_qos_profile_t & - qos_profile() - { - return subscription_qos_profile_; - } - - /// Set the subscription_qos_profile QoS, return this for parameter idiom. - /** - * The QoS settings to be used for the subscription - */ - RCLCPP_PUBLIC - SubscriptionOptions & - qos_profile(const rmw_qos_profile_t & subscription_qos_profile) - { - subscription_qos_profile_ = subscription_qos_profile; - return *this; - } - - RCLCPP_PUBLIC - size_t & - qos_history_depth() - { - return subscription_qos_profile_.depth; - } - - RCLCPP_PUBLIC - SubscriptionOptions & - qos_history_depth(size_t depth) - { - subscription_qos_profile_.depth = depth; - return *this; - } - - - RCLCPP_PUBLIC - const QOSDeadlineRequestedCallbackType & - deadline_callback() const - { - return callbacks_.deadline_callback_; - } - - RCLCPP_PUBLIC - SubscriptionOptions & - deadline_callback(const QOSDeadlineRequestedCallbackType & callback) - { - callbacks_.deadline_callback_ = callback; - return *this; - } - - RCLCPP_PUBLIC - const QOSLivelinessChangedCallbackType & - liveliness_callback() const - { - return callbacks_.liveliness_callback_; - } - - RCLCPP_PUBLIC - SubscriptionOptions & - liveliness_callback(const QOSLivelinessChangedCallbackType & callback) - { - callbacks_.liveliness_callback_ = callback; - return *this; - } - - - RCLCPP_PUBLIC - const SubscriptionEventCallbacks & - event_callbacks() const - { - return callbacks_; - } - - - RCLCPP_PUBLIC - bool - ignore_local_publications() const - { - return ignore_local_publications_; - } - - RCLCPP_PUBLIC - SubscriptionOptions & - ignore_local_publications(bool ignore) - { - ignore_local_publications_ = ignore; - return *this; - } - - /// Return the std::shared_ptr to be used. - RCLCPP_PUBLIC - std::shared_ptr - allocator() const - { - return allocator_; - } - - RCLCPP_PUBLIC - SubscriptionOptions & - allocator(std::shared_ptr allocator) - { - allocator_ = allocator; - return *this; - } - -private: - // IMPORTANT: if any of these default values are changed, please update the - // documentation in this class. - - SubscriptionEventCallbacks callbacks_; - - rmw_qos_profile_t subscription_qos_profile_ = rmw_qos_profile_default; - - bool ignore_local_publications_ = false; - - std::shared_ptr allocator_ = nullptr; + SubscriptionEventCallbacks event_callbacks; + rmw_qos_profile_t qos_profile = rmw_qos_profile_default; + bool ignore_local_publications = false; + std::shared_ptr allocator = nullptr; }; } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/subscription.cpp b/rclcpp/src/rclcpp/subscription.cpp index 438f2e2ed8..1180c1bcf5 100644 --- a/rclcpp/src/rclcpp/subscription.cpp +++ b/rclcpp/src/rclcpp/subscription.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "rclcpp/exceptions.hpp" #include "rclcpp/expand_topic_or_service_name.hpp" diff --git a/rclcpp/test/test_pub_sub_option_interface.cpp b/rclcpp/test/test_pub_sub_option_interface.cpp new file mode 100644 index 0000000000..b3030958ff --- /dev/null +++ b/rclcpp/test/test_pub_sub_option_interface.cpp @@ -0,0 +1,56 @@ +// Copyright 2019 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. + +#include + +#include +#include + +#include "rclcpp/rclcpp.hpp" +#include "test_msgs/msg/empty.hpp" + +class TestPublisher : public ::testing::Test +{ +protected: + static void SetUpTestCase() + { + rclcpp::init(0, nullptr); + } + + void SetUp() + { + node = std::make_shared("my_node", "/ns"); + } + + void TearDown() + { + node.reset(); + } + + rclcpp::Node::SharedPtr node; +}; + +/* + Testing construction and destruction. + */ +TEST_F(TestPublisher, construction_and_destruction) { + rclcpp::PublisherOptions<> pub_options; + auto publisher = node->create_publisher("topic", pub_options); + + rclcpp::SubscriptionOptions<> sub_options; + auto subscription = node->create_subscription( + "topic", + [](std::shared_ptr test_msg) {(void) test_msg;}, + sub_options); +} diff --git a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp index ae83aca436..579f7e8727 100644 --- a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp +++ b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp @@ -28,6 +28,7 @@ #include "rclcpp/create_publisher.hpp" #include "rclcpp/create_service.hpp" #include "rclcpp/create_subscription.hpp" +#include "rclcpp/subscription_options.hpp" #include "rclcpp/type_support_decl.hpp" #include "lifecycle_publisher.hpp" @@ -132,6 +133,7 @@ LifecycleNode::create_subscription( topic_name, std::forward(callback), qos, + rclcpp::SubscriptionEventCallbacks(), group, ignore_local_publications, msg_mem_strat,