ROS 2 rclcpp + rcl - lyrical  lyrical
ROS 2 C++ Client Library with ROS Client Library
wait_for_message.hpp
1 // Copyright 2021 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__WAIT_FOR_MESSAGE_HPP_
16 #define RCLCPP__WAIT_FOR_MESSAGE_HPP_
17 
18 #include <chrono>
19 #include <future>
20 #include <memory>
21 #include <string>
22 
23 #include "rcpputils/scope_exit.hpp"
24 
25 #include "rclcpp/create_subscription.hpp"
26 #include "rclcpp/node.hpp"
27 #include "rclcpp/node_interfaces/node_parameters_interface.hpp"
28 #include "rclcpp/node_interfaces/node_topics_interface.hpp"
29 #include "rclcpp/qos.hpp"
30 #include "rclcpp/visibility_control.hpp"
31 #include "rclcpp/wait_set.hpp"
32 
33 namespace rclcpp
34 {
35 
37 
48 template<class MsgT, class Rep = int64_t, class Period = std::milli>
50  MsgT & out,
51  std::shared_ptr<rclcpp::Subscription<MsgT>> subscription,
52  std::shared_ptr<rclcpp::Context> context,
53  std::chrono::duration<Rep, Period> time_to_wait = std::chrono::duration<Rep, Period>(-1))
54 {
55  auto gc = std::make_shared<rclcpp::GuardCondition>(context);
56  auto shutdown_callback_handle = context->add_on_shutdown_callback(
57  [weak_gc = std::weak_ptr<rclcpp::GuardCondition>{gc}]() {
58  auto strong_gc = weak_gc.lock();
59  if (strong_gc) {
60  strong_gc->trigger();
61  }
62  });
63 
64  rclcpp::WaitSet wait_set({}, {}, {}, {}, {}, {}, context);
65  wait_set.add_subscription(subscription);
66  RCPPUTILS_SCOPE_EXIT(wait_set.remove_subscription(subscription); );
67  wait_set.add_guard_condition(gc);
68  auto ret = wait_set.wait(time_to_wait);
69  if (ret.kind() != rclcpp::WaitResultKind::Ready) {
70  return false;
71  }
72 
73  if (wait_set.get_rcl_wait_set().guard_conditions[0]) {
74  return false;
75  }
76 
78  if (!subscription->take(out, info)) {
79  return false;
80  }
81 
82  return true;
83 }
84 
86 
102 template<class MsgT, class Rep = int64_t, class Period = std::milli>
104  MsgT & out,
105  rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters,
106  rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics,
107  const std::string & topic,
108  std::chrono::duration<Rep, Period> time_to_wait = std::chrono::duration<Rep, Period>(-1),
109  const rclcpp::QoS & qos = rclcpp::SystemDefaultsQoS())
110 {
111  auto sub = rclcpp::create_subscription<MsgT>(
112  node_parameters,
113  node_topics,
114  topic,
115  qos,
116  [](const std::shared_ptr<const MsgT>) {});
117  return wait_for_message<MsgT, Rep, Period>(
118  out, sub, node_topics->get_node_base_interface()->get_context(), time_to_wait);
119 }
120 
122 
133 template<class MsgT, class Rep = int64_t, class Period = std::milli>
135  MsgT & out,
136  rclcpp::Node::SharedPtr node,
137  const std::string & topic,
138  std::chrono::duration<Rep, Period> time_to_wait = std::chrono::duration<Rep, Period>(-1),
139  const rclcpp::QoS & qos = rclcpp::SystemDefaultsQoS())
140 {
141  return wait_for_message<MsgT, Rep, Period>(
142  out,
143  node->get_node_parameters_interface(),
144  node->get_node_topics_interface(),
145  topic,
146  time_to_wait,
147  qos);
148 }
149 
150 } // namespace rclcpp
151 
152 #endif // RCLCPP__WAIT_FOR_MESSAGE_HPP_
Additional meta data about messages taken from subscriptions.
Encapsulation of Quality of Service settings.
Definition: qos.hpp:116
Subscription implementation, templated on the type of message this subscription receives.
Encapsulates sets of waitable items which can be waited on as a group.
void add_subscription(std::shared_ptr< rclcpp::SubscriptionBase > subscription, rclcpp::SubscriptionWaitSetMask mask={})
Add a subscription to this wait set.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
bool wait_for_message(MsgT &out, std::shared_ptr< rclcpp::Subscription< MsgT >> subscription, std::shared_ptr< rclcpp::Context > context, std::chrono::duration< Rep, Period > time_to_wait=std::chrono::duration< Rep, Period >(-1))
Wait for the next incoming message.