|
20 | 20 | #include <memory>
|
21 | 21 | #include <stdexcept>
|
22 | 22 | #include <string>
|
| 23 | +#include <type_traits> |
| 24 | +#include <vector> |
23 | 25 |
|
24 | 26 | namespace tier4_autoware_utils
|
25 | 27 | {
|
26 | 28 |
|
27 |
| -template <typename T> |
28 |
| -class InterProcessPollingSubscriber |
| 29 | +template <typename T, int N = 1, typename Enable = void> |
| 30 | +class InterProcessPollingSubscriber; |
| 31 | + |
| 32 | +template <typename T, int N> |
| 33 | +class InterProcessPollingSubscriber<T, N, typename std::enable_if<N == 1>::type> |
29 | 34 | {
|
30 | 35 | public:
|
31 |
| - using SharedPtr = std::shared_ptr<InterProcessPollingSubscriber<T>>; |
| 36 | + using SharedPtr = |
| 37 | + std::shared_ptr<InterProcessPollingSubscriber<T, N, typename std::enable_if<N == 1>::type>>; |
32 | 38 | static SharedPtr create_subscription(
|
33 | 39 | rclcpp::Node * node, const std::string & topic_name, const rclcpp::QoS & qos = rclcpp::QoS{1})
|
34 | 40 | {
|
35 |
| - return std::make_shared<InterProcessPollingSubscriber<T>>(node, topic_name, qos); |
| 41 | + return std::make_shared<InterProcessPollingSubscriber<T, N>>(node, topic_name, qos); |
36 | 42 | }
|
37 | 43 |
|
38 | 44 | private:
|
@@ -71,6 +77,56 @@ class InterProcessPollingSubscriber
|
71 | 77 | };
|
72 | 78 | };
|
73 | 79 |
|
| 80 | +template <typename T, int N> |
| 81 | +class InterProcessPollingSubscriber<T, N, typename std::enable_if<(N >= 2)>::type> |
| 82 | +{ |
| 83 | +public: |
| 84 | + using SharedPtr = |
| 85 | + std::shared_ptr<InterProcessPollingSubscriber<T, N, typename std::enable_if<(N >= 2)>::type>>; |
| 86 | + static SharedPtr create_subscription( |
| 87 | + rclcpp::Node * node, const std::string & topic_name, const rclcpp::QoS & qos = rclcpp::QoS{N}) |
| 88 | + { |
| 89 | + return std::make_shared<InterProcessPollingSubscriber<T, N>>(node, topic_name, qos); |
| 90 | + } |
| 91 | + |
| 92 | +private: |
| 93 | + typename rclcpp::Subscription<T>::SharedPtr subscriber_; |
| 94 | + |
| 95 | +public: |
| 96 | + explicit InterProcessPollingSubscriber( |
| 97 | + rclcpp::Node * node, const std::string & topic_name, const rclcpp::QoS & qos = rclcpp::QoS{N}) |
| 98 | + { |
| 99 | + auto noexec_callback_group = |
| 100 | + node->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive, false); |
| 101 | + auto noexec_subscription_options = rclcpp::SubscriptionOptions(); |
| 102 | + noexec_subscription_options.callback_group = noexec_callback_group; |
| 103 | + |
| 104 | + subscriber_ = node->create_subscription<T>( |
| 105 | + topic_name, qos, |
| 106 | + [node]([[maybe_unused]] const typename T::ConstSharedPtr msg) { assert(false); }, |
| 107 | + noexec_subscription_options); |
| 108 | + if (qos.get_rmw_qos_profile().depth < N) { |
| 109 | + throw std::invalid_argument( |
| 110 | + "InterProcessPollingSubscriber will be used with depth == " + std::to_string(N) + |
| 111 | + ", which may cause inefficient serialization while updateLatestData()"); |
| 112 | + } |
| 113 | + }; |
| 114 | + std::vector<typename T::ConstSharedPtr> takeData() |
| 115 | + { |
| 116 | + std::vector<typename T::ConstSharedPtr> data; |
| 117 | + rclcpp::MessageInfo message_info; |
| 118 | + for (int i = 0; i < N; ++i) { |
| 119 | + auto datum = std::make_shared<T>(); |
| 120 | + if (subscriber_->take(*datum, message_info)) { |
| 121 | + data.push_back(datum); |
| 122 | + } else { |
| 123 | + break; |
| 124 | + } |
| 125 | + } |
| 126 | + return data; |
| 127 | + }; |
| 128 | +}; |
| 129 | + |
74 | 130 | } // namespace tier4_autoware_utils
|
75 | 131 |
|
76 | 132 | #endif // TIER4_AUTOWARE_UTILS__ROS__POLLING_SUBSCRIBER_HPP_
|
0 commit comments