ROS 2 rclcpp + rcl - kilted  kilted
ROS 2 C++ Client Library with ROS Client Library
publisher_base.hpp
1 // Copyright 2014 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__PUBLISHER_BASE_HPP_
16 #define RCLCPP__PUBLISHER_BASE_HPP_
17 
18 #include <rmw/error_handling.h>
19 #include <rmw/rmw.h>
20 
21 #include <chrono>
22 #include <functional>
23 #include <iostream>
24 #include <memory>
25 #include <sstream>
26 #include <string>
27 #include <unordered_map>
28 #include <utility>
29 #include <vector>
30 
31 #include "rcl/publisher.h"
32 
33 #include "rclcpp/macros.hpp"
34 #include "rclcpp/network_flow_endpoint.hpp"
35 #include "rclcpp/qos.hpp"
36 #include "rclcpp/event_handler.hpp"
37 #include "rclcpp/type_support_decl.hpp"
38 #include "rclcpp/visibility_control.hpp"
39 #include "rcpputils/time.hpp"
40 
41 namespace rclcpp
42 {
43 
44 // Forward declaration is used for friend statement.
45 namespace node_interfaces
46 {
47 class NodeBaseInterface;
48 class NodeTopicsInterface;
49 } // namespace node_interfaces
50 
51 namespace experimental
52 {
57 class IntraProcessManager;
58 } // namespace experimental
59 
60 class PublisherBase : public std::enable_shared_from_this<PublisherBase>
61 {
62  friend ::rclcpp::node_interfaces::NodeTopicsInterface;
63 
64 public:
65  RCLCPP_SMART_PTR_DEFINITIONS(PublisherBase)
66 
67 
76  RCLCPP_PUBLIC
79  const std::string & topic,
80  const rosidl_message_type_support_t & type_support,
81  const rcl_publisher_options_t & publisher_options,
82  const PublisherEventCallbacks & event_callbacks,
83  bool use_default_callbacks);
84 
85  RCLCPP_PUBLIC
86  virtual ~PublisherBase();
87 
89  RCLCPP_PUBLIC
90  void
91  bind_event_callbacks(const PublisherEventCallbacks & event_callbacks, bool use_default_callbacks);
92 
94 
95  RCLCPP_PUBLIC
96  const char *
97  get_topic_name() const;
98 
100 
101  RCLCPP_PUBLIC
102  size_t
103  get_queue_size() const;
104 
106 
107  RCLCPP_PUBLIC
108  const rmw_gid_t &
109  get_gid() const;
110 
112 
113  RCLCPP_PUBLIC
114  std::shared_ptr<rcl_publisher_t>
116 
118 
119  RCLCPP_PUBLIC
120  std::shared_ptr<const rcl_publisher_t>
121  get_publisher_handle() const;
122 
124 
125  RCLCPP_PUBLIC
126  const
127  std::unordered_map<rcl_publisher_event_type_t, std::shared_ptr<rclcpp::EventHandlerBase>> &
128  get_event_handlers() const;
129 
131 
132  RCLCPP_PUBLIC
133  size_t
134  get_subscription_count() const;
135 
137 
138  RCLCPP_PUBLIC
139  size_t
141 
143 
144  RCLCPP_PUBLIC
145  bool
147 
149 
156  RCLCPP_PUBLIC
157  RCUTILS_WARN_UNUSED
158  bool
159  assert_liveliness() const;
160 
162 
172  RCLCPP_PUBLIC
174  get_actual_qos() const;
175 
177 
181  RCLCPP_PUBLIC
182  bool
183  can_loan_messages() const;
184 
186 
191  RCLCPP_PUBLIC
192  bool
193  operator==(const rmw_gid_t & gid) const;
194 
196 
201  RCLCPP_PUBLIC
202  bool
203  operator==(const rmw_gid_t * gid) const;
204 
205  using IntraProcessManagerSharedPtr =
206  std::shared_ptr<rclcpp::experimental::IntraProcessManager>;
207 
209  RCLCPP_PUBLIC
210  void
212  uint64_t intra_process_publisher_id,
213  IntraProcessManagerSharedPtr ipm);
214 
216 
220  RCLCPP_PUBLIC
221  std::vector<rclcpp::NetworkFlowEndpoint>
223 
225 
231  RCLCPP_PUBLIC
232  size_t
234 
236 
257  template<typename DurationRepT = int64_t, typename DurationT = std::milli>
258  bool
260  std::chrono::duration<DurationRepT, DurationT> timeout =
261  std::chrono::duration<DurationRepT, DurationT>(-1)) const
262  {
263  rcl_duration_value_t rcl_timeout = rcpputils::convert_to_nanoseconds(timeout).count();
264 
265  rcl_ret_t ret = rcl_publisher_wait_for_all_acked(publisher_handle_.get(), rcl_timeout);
266  if (ret == RCL_RET_OK) {
267  return true;
268  } else if (ret == RCL_RET_TIMEOUT) {
269  return false;
270  } else {
271  rclcpp::exceptions::throw_from_rcl_error(ret);
272  }
273  }
274 
276 
301  void
303  std::function<void(size_t)> callback,
304  rcl_publisher_event_type_t event_type)
305  {
306  if (event_handlers_.count(event_type) == 0) {
307  RCLCPP_WARN(
308  rclcpp::get_logger("rclcpp"),
309  "Calling set_on_new_qos_event_callback for non registered publisher event_type");
310  return;
311  }
312 
313  if (!callback) {
314  throw std::invalid_argument(
315  "The callback passed to set_on_new_qos_event_callback "
316  "is not callable.");
317  }
318 
319  // The on_ready_callback signature has an extra `int` argument used to disambiguate between
320  // possible different entities within a generic waitable.
321  // We hide that detail to users of this method.
322  std::function<void(size_t, int)> new_callback = std::bind(callback, std::placeholders::_1);
323  event_handlers_[event_type]->set_on_ready_callback(new_callback);
324  }
325 
327  void
329  {
330  if (event_handlers_.count(event_type) == 0) {
331  RCLCPP_WARN(
332  rclcpp::get_logger("rclcpp"),
333  "Calling clear_on_new_qos_event_callback for non registered event_type");
334  return;
335  }
336 
337  event_handlers_[event_type]->clear_on_ready_callback();
338  }
339 
340 protected:
341  template<typename EventCallbackT>
342  void
343  add_event_handler(
344  const EventCallbackT & callback,
345  const rcl_publisher_event_type_t event_type)
346  {
347  auto handler = std::make_shared<EventHandler<EventCallbackT,
348  std::shared_ptr<rcl_publisher_t>>>(
349  callback,
351  publisher_handle_,
352  event_type);
353  event_handlers_.insert(std::make_pair(event_type, handler));
354  }
355 
356  RCLCPP_PUBLIC
357  void default_incompatible_qos_callback(QOSOfferedIncompatibleQoSInfo & info) const;
358 
359  RCLCPP_PUBLIC
360  void default_incompatible_type_callback(IncompatibleTypeInfo & info) const;
361 
362  std::shared_ptr<rcl_node_t> rcl_node_handle_;
363 
364  std::shared_ptr<rcl_publisher_t> publisher_handle_;
365 
366  std::unordered_map<rcl_publisher_event_type_t,
367  std::shared_ptr<rclcpp::EventHandlerBase>> event_handlers_;
368 
369  using IntraProcessManagerWeakPtr =
370  std::weak_ptr<rclcpp::experimental::IntraProcessManager>;
371  bool intra_process_is_enabled_;
372  IntraProcessManagerWeakPtr weak_ipm_;
373  uint64_t intra_process_publisher_id_;
374 
375  rmw_gid_t rmw_gid_;
376 
377  const rosidl_message_type_support_t type_support_;
378 
379  const PublisherEventCallbacks event_callbacks_;
380 };
381 
382 } // namespace rclcpp
383 
384 #endif // RCLCPP__PUBLISHER_BASE_HPP_
RCLCPP_PUBLIC const rmw_gid_t & get_gid() const
Get the global identifier for this publisher (used in rmw and by DDS).
RCLCPP_PUBLIC std::shared_ptr< rcl_publisher_t > get_publisher_handle()
Get the rcl publisher handle.
RCLCPP_PUBLIC size_t get_intra_process_subscription_count() const
Get intraprocess subscription count.
RCLCPP_PUBLIC PublisherBase(rclcpp::node_interfaces::NodeBaseInterface *node_base, const std::string &topic, const rosidl_message_type_support_t &type_support, const rcl_publisher_options_t &publisher_options, const PublisherEventCallbacks &event_callbacks, bool use_default_callbacks)
Default constructor.
RCLCPP_PUBLIC void bind_event_callbacks(const PublisherEventCallbacks &event_callbacks, bool use_default_callbacks)
Add event handlers for passed in event_callbacks.
RCLCPP_PUBLIC rclcpp::QoS get_actual_qos() const
Get the actual QoS settings, after the defaults have been determined.
RCLCPP_PUBLIC const char * get_topic_name() const
Get the topic that this publisher publishes on.
RCLCPP_PUBLIC bool operator==(const rmw_gid_t &gid) const
Compare this publisher to a gid.
RCLCPP_PUBLIC void setup_intra_process(uint64_t intra_process_publisher_id, IntraProcessManagerSharedPtr ipm)
Implementation utility function used to setup intra process publishing after creation.
RCLCPP_PUBLIC size_t get_queue_size() const
Get the queue size for this publisher.
void clear_on_new_qos_event_callback(rcl_publisher_event_type_t event_type)
Unset the callback registered for new qos events, if any.
RCLCPP_PUBLIC bool can_loan_messages() const
Check if publisher instance can loan messages.
RCLCPP_PUBLIC bool is_durability_transient_local() const
Get if durability is transient local.
RCLCPP_PUBLIC size_t get_subscription_count() const
Get subscription count.
RCLCPP_PUBLIC std::vector< rclcpp::NetworkFlowEndpoint > get_network_flow_endpoints() const
Get network flow endpoints.
bool wait_for_all_acked(std::chrono::duration< DurationRepT, DurationT > timeout=std::chrono::duration< DurationRepT, DurationT >(-1)) const
Wait until all published messages are acknowledged or until the specified timeout elapses.
RCLCPP_PUBLIC RCUTILS_WARN_UNUSED bool assert_liveliness() const
Manually assert that this Publisher is alive (for RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC).
RCLCPP_PUBLIC const std::unordered_map< rcl_publisher_event_type_t, std::shared_ptr< rclcpp::EventHandlerBase > > & get_event_handlers() const
Get all the QoS event handlers associated with this publisher.
RCLCPP_PUBLIC size_t lowest_available_ipm_capacity() const
Return the lowest available capacity for all subscription buffers.
void set_on_new_qos_event_callback(std::function< void(size_t)> callback, rcl_publisher_event_type_t event_type)
Set a callback to be called when each new qos event instance occurs.
Encapsulation of Quality of Service settings.
Definition: qos.hpp:116
Pure virtual interface class for the NodeBase part of the Node API.
enum rcl_publisher_event_type_e rcl_publisher_event_type_t
Enumeration of all of the publisher events that may fire.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_event_init(rcl_event_t *event, const rcl_publisher_t *publisher, const rcl_publisher_event_type_t event_type)
Initialize an rcl_event_t with a publisher.
Definition: event.c:47
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Definition: logger.cpp:34
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_wait_for_all_acked(const rcl_publisher_t *publisher, rcl_duration_value_t timeout)
Wait until all published message data is acknowledged or until the specified timeout elapses.
Definition: publisher.c:347
Options available for a rcl publisher.
Definition: publisher.h:44
Contains callbacks for various types of events a Publisher can receive from the middleware.
rcutils_duration_value_t rcl_duration_value_t
A duration of time, measured in nanoseconds.
Definition: time.h:48
#define RCL_RET_OK
Success return code.
Definition: types.h:27
#define RCL_RET_TIMEOUT
Timeout occurred return code.
Definition: types.h:31
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:24