ROS 2 rclcpp + rcl - kilted  kilted
ROS 2 C++ Client Library with ROS Client Library
create_subscription.hpp
1 // Copyright 2016 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef RCLCPP__CREATE_SUBSCRIPTION_HPP_
16 #define RCLCPP__CREATE_SUBSCRIPTION_HPP_
17 
18 #include <chrono>
19 #include <functional>
20 #include <memory>
21 #include <stdexcept>
22 #include <string>
23 #include <utility>
24 
25 #include "rclcpp/detail/resolve_enable_topic_statistics.hpp"
26 
27 #include "rclcpp/node_interfaces/get_node_timers_interface.hpp"
28 #include "rclcpp/node_interfaces/get_node_topics_interface.hpp"
29 #include "rclcpp/node_interfaces/node_timers_interface.hpp"
30 #include "rclcpp/node_interfaces/node_topics_interface.hpp"
31 
32 #include "rclcpp/create_publisher.hpp"
33 #include "rclcpp/create_timer.hpp"
34 #include "rclcpp/qos.hpp"
35 #include "rclcpp/subscription_factory.hpp"
36 #include "rclcpp/subscription_options.hpp"
37 #include "rclcpp/timer.hpp"
38 #include "rclcpp/topic_statistics/subscription_topic_statistics.hpp"
39 #include "rmw/qos_profiles.h"
40 
41 namespace rclcpp
42 {
43 
44 namespace detail
45 {
46 template<
47  typename MessageT,
48  typename CallbackT,
49  typename AllocatorT,
50  typename SubscriptionT,
51  typename MessageMemoryStrategyT,
52  typename NodeParametersT,
53  typename NodeTopicsT
54 >
55 typename std::shared_ptr<SubscriptionT>
57  NodeParametersT & node_parameters,
58  NodeTopicsT & node_topics,
59  const std::string & topic_name,
60  const rclcpp::QoS & qos,
61  CallbackT && callback,
64  ),
65  typename MessageMemoryStrategyT::SharedPtr msg_mem_strat = (
66  MessageMemoryStrategyT::create_default()
67  )
68 )
69 {
70  using rclcpp::node_interfaces::get_node_topics_interface;
71  auto node_topics_interface = get_node_topics_interface(node_topics);
72 
73  std::shared_ptr<rclcpp::topic_statistics::SubscriptionTopicStatistics>
74  subscription_topic_stats = nullptr;
75 
76  if (rclcpp::detail::resolve_enable_topic_statistics(
77  options,
78  *node_topics_interface->get_node_base_interface()))
79  {
80  if (options.topic_stats_options.publish_period <= std::chrono::milliseconds(0)) {
81  throw std::invalid_argument(
82  "topic_stats_options.publish_period must be greater than 0, specified value of " +
83  std::to_string(options.topic_stats_options.publish_period.count()) + " ms");
84  }
85 
86  std::shared_ptr<Publisher<statistics_msgs::msg::MetricsMessage>>
87  publisher = rclcpp::detail::create_publisher<statistics_msgs::msg::MetricsMessage>(
88  node_parameters,
89  node_topics_interface,
90  options.topic_stats_options.publish_topic,
91  options.topic_stats_options.qos);
92 
93  subscription_topic_stats =
94  std::make_shared<rclcpp::topic_statistics::SubscriptionTopicStatistics>(
95  node_topics_interface->get_node_base_interface()->get_name(), publisher);
96 
97  std::weak_ptr<
99  > weak_subscription_topic_stats(subscription_topic_stats);
100  auto sub_call_back = [weak_subscription_topic_stats]() {
101  auto subscription_topic_stats = weak_subscription_topic_stats.lock();
102  if (subscription_topic_stats) {
103  subscription_topic_stats->publish_message_and_reset_measurements();
104  }
105  };
106 
107  auto node_timer_interface = node_topics_interface->get_node_timers_interface();
108 
109  auto timer = create_wall_timer(
110  std::chrono::duration_cast<std::chrono::nanoseconds>(
111  options.topic_stats_options.publish_period),
112  sub_call_back,
113  options.callback_group,
114  node_topics_interface->get_node_base_interface(),
115  node_timer_interface
116  );
117 
118  subscription_topic_stats->set_publisher_timer(timer);
119  }
120 
121  auto factory = rclcpp::create_subscription_factory<MessageT>(
122  std::forward<CallbackT>(callback),
123  options,
124  msg_mem_strat,
125  subscription_topic_stats
126  );
127 
128  const rclcpp::QoS & actual_qos = options.qos_overriding_options.get_policy_kinds().size() ?
129  rclcpp::detail::declare_qos_parameters(
130  options.qos_overriding_options, node_parameters,
131  node_topics_interface->resolve_topic_name(topic_name),
133  qos;
134 
135  auto sub = node_topics_interface->create_subscription(topic_name, factory, actual_qos);
136  node_topics_interface->add_subscription(sub, options.callback_group);
137 
138  return std::dynamic_pointer_cast<SubscriptionT>(sub);
139 }
140 } // namespace detail
141 
143 
168 template<
169  typename MessageT,
170  typename CallbackT,
171  typename AllocatorT = std::allocator<void>,
172  typename SubscriptionT = rclcpp::Subscription<MessageT, AllocatorT>,
173  typename MessageMemoryStrategyT = typename SubscriptionT::MessageMemoryStrategyType,
174  typename NodeT>
175 typename std::shared_ptr<SubscriptionT>
177  NodeT & node,
178  const std::string & topic_name,
179  const rclcpp::QoS & qos,
180  CallbackT && callback,
183  ),
184  typename MessageMemoryStrategyT::SharedPtr msg_mem_strat = (
185  MessageMemoryStrategyT::create_default()
186  )
187 )
188 {
189  return rclcpp::detail::create_subscription<
190  MessageT, CallbackT, AllocatorT, SubscriptionT, MessageMemoryStrategyT>(
191  node, node, topic_name, qos, std::forward<CallbackT>(callback), options, msg_mem_strat);
192 }
193 
195 
198 template<
199  typename MessageT,
200  typename CallbackT,
201  typename AllocatorT = std::allocator<void>,
202  typename SubscriptionT = rclcpp::Subscription<MessageT, AllocatorT>,
203  typename MessageMemoryStrategyT = typename SubscriptionT::MessageMemoryStrategyType>
204 typename std::shared_ptr<SubscriptionT>
206  rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & node_parameters,
207  rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr & node_topics,
208  const std::string & topic_name,
209  const rclcpp::QoS & qos,
210  CallbackT && callback,
213  ),
214  typename MessageMemoryStrategyT::SharedPtr msg_mem_strat = (
215  MessageMemoryStrategyT::create_default()
216  )
217 )
218 {
219  return rclcpp::detail::create_subscription<
220  MessageT, CallbackT, AllocatorT, SubscriptionT, MessageMemoryStrategyT>(
221  node_parameters, node_topics, topic_name, qos,
222  std::forward<CallbackT>(callback), options, msg_mem_strat);
223 }
224 
225 } // namespace rclcpp
226 
227 #endif // RCLCPP__CREATE_SUBSCRIPTION_HPP_
Encapsulation of Quality of Service settings.
Definition: qos.hpp:116
Subscription implementation, templated on the type of message this subscription receives.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
rclcpp::WallTimer< CallbackT >::SharedPtr create_wall_timer(std::chrono::duration< DurationRepT, DurationT > period, CallbackT callback, rclcpp::CallbackGroup::SharedPtr group, node_interfaces::NodeBaseInterface *node_base, node_interfaces::NodeTimersInterface *node_timers, bool autostart=true)
Convenience method to create a wall timer with node resources.
std::shared_ptr< SubscriptionT > create_subscription(NodeT &node, const std::string &topic_name, const rclcpp::QoS &qos, CallbackT &&callback, const rclcpp::SubscriptionOptionsWithAllocator< AllocatorT > &options=(rclcpp::SubscriptionOptionsWithAllocator< AllocatorT >()), typename MessageMemoryStrategyT::SharedPtr msg_mem_strat=(MessageMemoryStrategyT::create_default()))
Create and return a subscription of the given MessageT type.
Structure containing optional configuration for Subscriptions.