ROS 2 rclcpp + rcl - kilted  kilted
ROS 2 C++ Client Library with ROS Client Library
node_topics.cpp
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 #include "rclcpp/node_interfaces/node_topics.hpp"
16 
17 #include <stdexcept>
18 #include <string>
19 
20 #include "rclcpp/callback_group.hpp"
21 #include "rclcpp/exceptions.hpp"
22 #include "rclcpp/node_interfaces/node_base_interface.hpp"
23 #include "rclcpp/node_interfaces/node_timers_interface.hpp"
24 #include "rclcpp/publisher_base.hpp"
25 #include "rclcpp/publisher_factory.hpp"
26 #include "rclcpp/subscription_base.hpp"
27 #include "rclcpp/subscription_factory.hpp"
28 #include "rclcpp/qos.hpp"
29 
30 using rclcpp::exceptions::throw_from_rcl_error;
31 
33 
34 NodeTopics::NodeTopics(
37 : node_base_(node_base), node_timers_(node_timers)
38 {}
39 
40 NodeTopics::~NodeTopics()
41 {}
42 
43 rclcpp::PublisherBase::SharedPtr
44 NodeTopics::create_publisher(
45  const std::string & topic_name,
46  const rclcpp::PublisherFactory & publisher_factory,
47  const rclcpp::QoS & qos)
48 {
49  // Create the MessageT specific Publisher using the factory, but return it as PublisherBase.
50  return publisher_factory.create_typed_publisher(node_base_, topic_name, qos);
51 }
52 
53 void
54 NodeTopics::add_publisher(
55  rclcpp::PublisherBase::SharedPtr publisher,
56  rclcpp::CallbackGroup::SharedPtr callback_group)
57 {
58  // Assign to a group.
59  if (callback_group) {
60  if (!node_base_->callback_group_in_node(callback_group)) {
62  }
63  } else {
64  callback_group = node_base_->get_default_callback_group();
65  }
66 
67  for (auto & key_event_pair : publisher->get_event_handlers()) {
68  auto publisher_event = key_event_pair.second;
69  callback_group->add_waitable(publisher_event);
70  }
71 
72  // Notify the executor that a new publisher was created using the parent Node.
73  try {
74  node_base_->trigger_notify_guard_condition();
75  callback_group->trigger_notify_guard_condition();
76  } catch (const rclcpp::exceptions::RCLError & ex) {
77  throw std::runtime_error(
78  std::string("failed to notify wait set on publisher creation: ") + ex.what());
79  }
80 }
81 
82 rclcpp::SubscriptionBase::SharedPtr
83 NodeTopics::create_subscription(
84  const std::string & topic_name,
85  const rclcpp::SubscriptionFactory & subscription_factory,
86  const rclcpp::QoS & qos)
87 {
88  // Create the MessageT specific Subscription using the factory, but return a SubscriptionBase.
89  return subscription_factory.create_typed_subscription(node_base_, topic_name, qos);
90 }
91 
92 void
93 NodeTopics::add_subscription(
94  rclcpp::SubscriptionBase::SharedPtr subscription,
95  rclcpp::CallbackGroup::SharedPtr callback_group)
96 {
97  // Assign to a group.
98  if (callback_group) {
99  if (!node_base_->callback_group_in_node(callback_group)) {
100  throw rclcpp::exceptions::MissingGroupNodeException("subscription");
101  }
102  } else {
103  callback_group = node_base_->get_default_callback_group();
104  }
105 
106  callback_group->add_subscription(subscription);
107 
108  for (auto & key_event_pair : subscription->get_event_handlers()) {
109  auto subscription_event = key_event_pair.second;
110  callback_group->add_waitable(subscription_event);
111  }
112 
113  auto intra_process_waitable = subscription->get_intra_process_waitable();
114  if (nullptr != intra_process_waitable) {
115  // Add to the callback group to be notified about intra-process msgs.
116  callback_group->add_waitable(intra_process_waitable);
117  }
118 
119  // Notify the executor that a new subscription was created using the parent Node.
120  try {
121  node_base_->trigger_notify_guard_condition();
122  callback_group->trigger_notify_guard_condition();
123  } catch (const rclcpp::exceptions::RCLError & ex) {
124  throw std::runtime_error(
125  std::string("failed to notify wait set on subscription creation: ") + ex.what());
126  }
127 }
128 
130 NodeTopics::get_node_base_interface() const
131 {
132  return node_base_;
133 }
134 
136 NodeTopics::get_node_timers_interface() const
137 {
138  return node_timers_;
139 }
140 
141 std::string
142 NodeTopics::resolve_topic_name(const std::string & name, bool only_expand) const
143 {
144  return node_base_->resolve_topic_or_service_name(name, false, only_expand);
145 }
Encapsulation of Quality of Service settings.
Definition: qos.hpp:116
Thrown when a callback group is missing from the node, when it wants to utilize the group.
Definition: exceptions.hpp:244
Created when the return code does not match one of the other specialized exceptions.
Definition: exceptions.hpp:162
Pure virtual interface class for the NodeBase part of the Node API.
virtual RCLCPP_PUBLIC void trigger_notify_guard_condition()=0
Trigger the guard condition that notifies of internal node state changes.
virtual RCLCPP_PUBLIC bool callback_group_in_node(rclcpp::CallbackGroup::SharedPtr group)=0
Return true if the given callback group is associated with this node.
virtual RCLCPP_PUBLIC rclcpp::CallbackGroup::SharedPtr get_default_callback_group()=0
Return the default callback group.
virtual RCLCPP_PUBLIC std::string resolve_topic_or_service_name(const std::string &name, bool is_service, bool only_expand=false) const =0
Expand and remap a given topic or service name.
Pure virtual interface class for the NodeTimers part of the Node API.
Implementation of the NodeTopics part of the Node API.
Definition: node_topics.hpp:42
RCLCPP_PUBLIC std::string resolve_topic_name(const std::string &name, bool only_expand=false) const override
Get a remapped and expanded topic name given an input name.
Factory with functions used to create a MessageT specific PublisherT.
Factory containing a function used to create a Subscription<MessageT>.