|
1 |
| -// Copyright 2024 TIER IV, Inc. |
| 1 | +// Copyright 2025 The Autoware Contributors |
2 | 2 | //
|
3 | 3 | // Licensed under the Apache License, Version 2.0 (the "License");
|
4 | 4 | // you may not use this file except in compliance with the License.
|
|
11 | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12 | 12 | // See the License for the specific language governing permissions and
|
13 | 13 | // limitations under the License.
|
| 14 | + |
14 | 15 | #ifndef AUTOWARE_UTILS__ROS__POLLING_SUBSCRIBER_HPP_
|
15 | 16 | #define AUTOWARE_UTILS__ROS__POLLING_SUBSCRIBER_HPP_
|
16 | 17 |
|
17 |
| -#include <rclcpp/rclcpp.hpp> |
18 |
| - |
19 |
| -#include <memory> |
20 |
| -#include <stdexcept> |
21 |
| -#include <string> |
22 |
| -#include <vector> |
23 |
| - |
24 |
| -namespace autoware_utils |
25 |
| -{ |
26 |
| - |
27 |
| -/** |
28 |
| - * @brief Creates a SensorDataQoS profile with a single depth. |
29 |
| - * @return rclcpp::SensorDataQoS The QoS profile with depth set to 1. |
30 |
| - */ |
31 |
| -inline rclcpp::SensorDataQoS single_depth_sensor_qos() |
32 |
| -{ |
33 |
| - rclcpp::SensorDataQoS qos; |
34 |
| - qos.get_rmw_qos_profile().depth = 1; |
35 |
| - return qos; |
36 |
| -} |
37 |
| - |
38 |
| -namespace polling_policy |
39 |
| -{ |
40 |
| - |
41 |
| -/** |
42 |
| - * @brief Polling policy that keeps the latest received message. |
43 |
| - * |
44 |
| - * This policy retains the latest received message and provides it when requested. If a new message |
45 |
| - * is received, it overwrites the previously stored message. |
46 |
| - * |
47 |
| - * @tparam MessageT The message type. |
48 |
| - */ |
49 |
| -template <typename MessageT> |
50 |
| -class Latest |
51 |
| -{ |
52 |
| -private: |
53 |
| - typename MessageT::ConstSharedPtr data_{nullptr}; ///< Data pointer to store the latest data |
54 |
| - |
55 |
| -protected: |
56 |
| - /** |
57 |
| - * @brief Check the QoS settings for the subscription. |
58 |
| - * |
59 |
| - * @param qos The QoS profile to check. |
60 |
| - * @throws std::invalid_argument If the QoS depth is not 1. |
61 |
| - */ |
62 |
| - void check_qos(const rclcpp::QoS & qos) |
63 |
| - { |
64 |
| - if (qos.get_rmw_qos_profile().depth > 1) { |
65 |
| - throw std::invalid_argument( |
66 |
| - "InterProcessPollingSubscriber will be used with depth > 1, which may cause inefficient " |
67 |
| - "serialization while updateLatestData()"); |
68 |
| - } |
69 |
| - } |
70 |
| - |
71 |
| -public: |
72 |
| - /** |
73 |
| - * @brief Retrieve the latest data. If no new data has been received, the previously received data |
74 |
| - * |
75 |
| - * @return typename MessageT::ConstSharedPtr The latest data. |
76 |
| - */ |
77 |
| - typename MessageT::ConstSharedPtr take_data(); |
78 |
| -}; |
79 |
| - |
80 |
| -/** |
81 |
| - * @brief Polling policy that keeps the newest received message. |
82 |
| - * |
83 |
| - * @tparam MessageT The message type. |
84 |
| - */ |
85 |
| -template <typename MessageT> |
86 |
| -class Newest |
87 |
| -{ |
88 |
| -protected: |
89 |
| - /** |
90 |
| - * @brief Check the QoS settings for the subscription. |
91 |
| - * |
92 |
| - * @param qos The QoS profile to check. |
93 |
| - * @throws std::invalid_argument If the QoS depth is not 1. |
94 |
| - */ |
95 |
| - void check_qos(const rclcpp::QoS & qos) |
96 |
| - { |
97 |
| - if (qos.get_rmw_qos_profile().depth > 1) { |
98 |
| - throw std::invalid_argument( |
99 |
| - "InterProcessPollingSubscriber will be used with depth > 1, which may cause inefficient " |
100 |
| - "serialization while updateLatestData()"); |
101 |
| - } |
102 |
| - } |
103 |
| - |
104 |
| -public: |
105 |
| - /** |
106 |
| - * @brief Retrieve the newest data. If no new data has been received, nullptr is returned. |
107 |
| - * |
108 |
| - * @return typename MessageT::ConstSharedPtr The newest data. |
109 |
| - */ |
110 |
| - typename MessageT::ConstSharedPtr take_data(); |
111 |
| -}; |
112 |
| - |
113 |
| -/** |
114 |
| - * @brief Polling policy that keeps all received messages. |
115 |
| - * |
116 |
| - * @tparam MessageT The message type. |
117 |
| - */ |
118 |
| -template <typename MessageT> |
119 |
| -class All |
120 |
| -{ |
121 |
| -protected: |
122 |
| - /** |
123 |
| - * @brief Check the QoS settings for the subscription. |
124 |
| - * |
125 |
| - * @param qos The QoS profile to check. |
126 |
| - */ |
127 |
| - void check_qos(const rclcpp::QoS &) {} |
128 |
| - |
129 |
| -public: |
130 |
| - /** |
131 |
| - * @brief Retrieve all data. |
132 |
| - * |
133 |
| - * @return std::vector<typename MessageT::ConstSharedPtr> The list of all received data. |
134 |
| - */ |
135 |
| - std::vector<typename MessageT::ConstSharedPtr> take_data(); |
136 |
| -}; |
137 |
| - |
138 |
| -} // namespace polling_policy |
139 |
| - |
140 |
| -/** |
141 |
| - * @brief Subscriber class that uses a specified polling policy. |
142 |
| - * |
143 |
| - * @tparam MessageT The message type. |
144 |
| - * @tparam PollingPolicy The polling policy to use. |
145 |
| - */ |
146 |
| -template <typename MessageT, template <typename> class PollingPolicy = polling_policy::Latest> |
147 |
| -class InterProcessPollingSubscriber : public PollingPolicy<MessageT> |
148 |
| -{ |
149 |
| - friend PollingPolicy<MessageT>; |
150 |
| - |
151 |
| -private: |
152 |
| - typename rclcpp::Subscription<MessageT>::SharedPtr subscriber_; ///< Subscription object |
153 |
| - |
154 |
| -public: |
155 |
| - using SharedPtr = std::shared_ptr<InterProcessPollingSubscriber<MessageT, PollingPolicy>>; |
156 |
| - |
157 |
| - /** |
158 |
| - * @brief Construct a new InterProcessPollingSubscriber object. |
159 |
| - * |
160 |
| - * @param node The node to attach the subscriber to. |
161 |
| - * @param topic_name The topic name to subscribe to. |
162 |
| - * @param qos The QoS profile to use for the subscription. |
163 |
| - */ |
164 |
| - explicit InterProcessPollingSubscriber( |
165 |
| - rclcpp::Node * node, const std::string & topic_name, const rclcpp::QoS & qos = rclcpp::QoS{1}) |
166 |
| - { |
167 |
| - this->check_qos(qos); |
168 |
| - |
169 |
| - auto noexec_callback_group = |
170 |
| - node->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive, false); |
171 |
| - |
172 |
| - auto noexec_subscription_options = rclcpp::SubscriptionOptions(); |
173 |
| - noexec_subscription_options.callback_group = noexec_callback_group; |
174 |
| - |
175 |
| - subscriber_ = node->create_subscription<MessageT>( |
176 |
| - topic_name, qos, |
177 |
| - [node]([[maybe_unused]] const typename MessageT::ConstSharedPtr msg) { assert(false); }, |
178 |
| - noexec_subscription_options); |
179 |
| - } |
180 |
| - |
181 |
| - /** |
182 |
| - * @brief Create a subscription. |
183 |
| - * |
184 |
| - * @param node The node to attach the subscriber to. |
185 |
| - * @param topic_name The topic name to subscribe to. |
186 |
| - * @param qos The QoS profile to use for the subscription. |
187 |
| - * @return SharedPtr The created subscription. |
188 |
| - */ |
189 |
| - static SharedPtr create_subscription( |
190 |
| - rclcpp::Node * node, const std::string & topic_name, const rclcpp::QoS & qos = rclcpp::QoS{1}) |
191 |
| - { |
192 |
| - return std::make_shared<InterProcessPollingSubscriber<MessageT, PollingPolicy>>( |
193 |
| - node, topic_name, qos); |
194 |
| - } |
195 |
| - |
196 |
| - typename rclcpp::Subscription<MessageT>::SharedPtr subscriber() { return subscriber_; } |
197 |
| -}; |
198 |
| - |
199 |
| -namespace polling_policy |
200 |
| -{ |
201 |
| - |
202 |
| -template <typename MessageT> |
203 |
| -typename MessageT::ConstSharedPtr Latest<MessageT>::take_data() |
204 |
| -{ |
205 |
| - auto & subscriber = |
206 |
| - static_cast<InterProcessPollingSubscriber<MessageT, Latest> *>(this)->subscriber_; |
207 |
| - auto new_data = std::make_shared<MessageT>(); |
208 |
| - rclcpp::MessageInfo message_info; |
209 |
| - const bool success = subscriber->take(*new_data, message_info); |
210 |
| - if (success) { |
211 |
| - data_ = new_data; |
212 |
| - } |
213 |
| - |
214 |
| - return data_; |
215 |
| -} |
216 |
| - |
217 |
| -template <typename MessageT> |
218 |
| -typename MessageT::ConstSharedPtr Newest<MessageT>::take_data() |
219 |
| -{ |
220 |
| - auto & subscriber = |
221 |
| - static_cast<InterProcessPollingSubscriber<MessageT, Newest> *>(this)->subscriber_; |
222 |
| - auto new_data = std::make_shared<MessageT>(); |
223 |
| - rclcpp::MessageInfo message_info; |
224 |
| - const bool success = subscriber->take(*new_data, message_info); |
225 |
| - if (success) { |
226 |
| - return new_data; |
227 |
| - } |
228 |
| - return nullptr; |
229 |
| -} |
230 |
| - |
231 |
| -template <typename MessageT> |
232 |
| -std::vector<typename MessageT::ConstSharedPtr> All<MessageT>::take_data() |
233 |
| -{ |
234 |
| - auto & subscriber = |
235 |
| - static_cast<InterProcessPollingSubscriber<MessageT, All> *>(this)->subscriber_; |
236 |
| - std::vector<typename MessageT::ConstSharedPtr> data; |
237 |
| - rclcpp::MessageInfo message_info; |
238 |
| - for (;;) { |
239 |
| - auto datum = std::make_shared<MessageT>(); |
240 |
| - if (subscriber->take(*datum, message_info)) { |
241 |
| - data.push_back(datum); |
242 |
| - } else { |
243 |
| - break; |
244 |
| - } |
245 |
| - } |
246 |
| - return data; |
247 |
| -} |
| 18 | +// NOLINTBEGIN(build/namespaces, whitespace/line_length) |
| 19 | +// clang-format off |
248 | 20 |
|
249 |
| -} // namespace polling_policy |
| 21 | +#pragma message("#include <autoware_utils/ros/polling_subscriber.hpp> is deprecated. Use #include <autoware_utils_rclcpp/polling_subscriber.hpp> instead.") |
| 22 | +#include <autoware_utils_rclcpp/polling_subscriber.hpp> |
| 23 | +namespace autoware_utils { using namespace autoware_utils_rclcpp; } |
250 | 24 |
|
251 |
| -} // namespace autoware_utils |
| 25 | +// clang-format on |
| 26 | +// NOLINTEND |
252 | 27 |
|
253 | 28 | #endif // AUTOWARE_UTILS__ROS__POLLING_SUBSCRIBER_HPP_
|
0 commit comments