ROS 2 rclcpp + rcl - rolling  rolling-a919a6e5
ROS 2 C++ Client Library with ROS Client Library
subscription_base.cpp
1 // Copyright 2015 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/subscription_base.hpp"
16 
17 #include <cstdio>
18 #include <memory>
19 #include <string>
20 #include <unordered_map>
21 #include <vector>
22 
23 #include "rcpputils/scope_exit.hpp"
24 
25 #include "rclcpp/dynamic_typesupport/dynamic_message.hpp"
26 #include "rclcpp/exceptions.hpp"
27 #include "rclcpp/expand_topic_or_service_name.hpp"
28 #include "rclcpp/experimental/intra_process_manager.hpp"
29 #include "rclcpp/logging.hpp"
30 #include "rclcpp/node_interfaces/node_base_interface.hpp"
31 #include "rclcpp/event_handler.hpp"
32 
33 #include "rmw/error_handling.h"
34 #include "rmw/rmw.h"
35 
36 #include "rosidl_dynamic_typesupport/types.h"
37 
39 
40 SubscriptionBase::SubscriptionBase(
42  const rosidl_message_type_support_t & type_support_handle,
43  const std::string & topic_name,
44  const rcl_subscription_options_t & subscription_options,
45  const SubscriptionEventCallbacks & event_callbacks,
46  bool use_default_callbacks,
47  DeliveredMessageKind delivered_message_kind)
48 : node_base_(node_base),
49  node_handle_(node_base_->get_shared_rcl_node_handle()),
50  node_logger_(rclcpp::get_node_logger(node_handle_.get())),
51  use_intra_process_(false),
52  intra_process_subscription_id_(0),
53  event_callbacks_(event_callbacks),
54  type_support_(type_support_handle),
55  delivered_message_kind_(delivered_message_kind)
56 {
57  auto custom_deletor = [node_handle = this->node_handle_](rcl_subscription_t * rcl_subs)
58  {
59  if (rcl_subscription_fini(rcl_subs, node_handle.get()) != RCL_RET_OK) {
60  RCLCPP_ERROR(
61  rclcpp::get_node_logger(node_handle.get()).get_child("rclcpp"),
62  "Error in destruction of rcl subscription handle: %s",
63  rcl_get_error_string().str);
64  rcl_reset_error();
65  }
66  delete rcl_subs;
67  };
68 
69  subscription_handle_ = std::shared_ptr<rcl_subscription_t>(
70  new rcl_subscription_t, custom_deletor);
71  *subscription_handle_.get() = rcl_get_zero_initialized_subscription();
72 
74  subscription_handle_.get(),
75  node_handle_.get(),
76  &type_support_handle,
77  topic_name.c_str(),
78  &subscription_options);
79  if (ret != RCL_RET_OK) {
80  if (ret == RCL_RET_TOPIC_NAME_INVALID) {
81  auto rcl_node_handle = node_handle_.get();
82  // this will throw on any validation problem
83  rcl_reset_error();
85  topic_name,
86  rcl_node_get_name(rcl_node_handle),
87  rcl_node_get_namespace(rcl_node_handle));
88  }
89  rclcpp::exceptions::throw_from_rcl_error(ret, "could not create subscription");
90  }
91 
92  bind_event_callbacks(event_callbacks_, use_default_callbacks);
93 }
94 
96 {
97  if (!use_intra_process_) {
98  return;
99  }
100  auto ipm = weak_ipm_.lock();
101  if (!ipm) {
102  // TODO(ivanpauno): should this raise an error?
103  RCLCPP_WARN(
104  rclcpp::get_logger("rclcpp"),
105  "Intra process manager died before than a subscription.");
106  return;
107  }
108  ipm->remove_subscription(intra_process_subscription_id_);
109 }
110 
111 void
113  const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks)
114 {
115  try {
116  if (event_callbacks.deadline_callback) {
117  this->add_event_handler(
118  event_callbacks.deadline_callback,
119  RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED);
120  }
121  } catch (const UnsupportedEventTypeException & /*exc*/) {
122  RCLCPP_WARN(
123  rclcpp::get_logger("rclcpp"),
124  "Failed to add event handler for deadline; not supported");
125  }
126 
127  try {
128  if (event_callbacks.liveliness_callback) {
129  this->add_event_handler(
130  event_callbacks.liveliness_callback,
131  RCL_SUBSCRIPTION_LIVELINESS_CHANGED);
132  }
133  } catch (const UnsupportedEventTypeException & /*exc*/) {
134  RCLCPP_WARN(
135  rclcpp::get_logger("rclcpp"),
136  "Failed to add event handler for liveliness; not supported");
137  }
138 
139  QOSRequestedIncompatibleQoSCallbackType incompatible_qos_cb;
140  if (event_callbacks.incompatible_qos_callback) {
141  incompatible_qos_cb = event_callbacks.incompatible_qos_callback;
142  } else if (use_default_callbacks) {
143  // Register default callback when not specified
144  incompatible_qos_cb = [this](QOSRequestedIncompatibleQoSInfo & info) {
145  this->default_incompatible_qos_callback(info);
146  };
147  }
148  // Register default callback when not specified
149  try {
150  if (incompatible_qos_cb) {
151  this->add_event_handler(incompatible_qos_cb, RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS);
152  }
153  } catch (const UnsupportedEventTypeException & /*exc*/) {
154  RCLCPP_WARN(
155  rclcpp::get_logger("rclcpp"),
156  "Failed to add event handler for incompatible qos; not supported");
157  }
158 
159  IncompatibleTypeCallbackType incompatible_type_cb;
160  if (event_callbacks.incompatible_type_callback) {
161  incompatible_type_cb = event_callbacks.incompatible_type_callback;
162  } else if (use_default_callbacks) {
163  // Register default callback when not specified
164  incompatible_type_cb = [this](IncompatibleTypeInfo & info) {
165  this->default_incompatible_type_callback(info);
166  };
167  }
168  try {
169  if (incompatible_type_cb) {
170  this->add_event_handler(incompatible_type_cb, RCL_SUBSCRIPTION_INCOMPATIBLE_TYPE);
171  }
172  } catch (UnsupportedEventTypeException & /*exc*/) {
173  RCLCPP_WARN(
174  rclcpp::get_logger("rclcpp"),
175  "Failed to add event handler for incompatible type; not supported");
176  }
177 
178  try {
179  if (event_callbacks.message_lost_callback) {
180  this->add_event_handler(
181  event_callbacks.message_lost_callback,
182  RCL_SUBSCRIPTION_MESSAGE_LOST);
183  }
184  } catch (const UnsupportedEventTypeException & /*exc*/) {
185  RCLCPP_WARN(
186  rclcpp::get_logger("rclcpp"),
187  "Failed to add event handler for message lost; not supported");
188  }
189 
190  try {
191  if (event_callbacks.matched_callback) {
192  this->add_event_handler(
193  event_callbacks.matched_callback,
194  RCL_SUBSCRIPTION_MATCHED);
195  }
196  } catch (const UnsupportedEventTypeException & /*exc*/) {
197  RCLCPP_WARN(
198  rclcpp::get_logger("rclcpp"),
199  "Failed to add event handler for matched; not supported");
200  }
201 }
202 
203 const char *
205 {
206  return rcl_subscription_get_topic_name(subscription_handle_.get());
207 }
208 
209 std::shared_ptr<rcl_subscription_t>
210 SubscriptionBase::get_subscription_handle()
211 {
212  return subscription_handle_;
213 }
214 
215 std::shared_ptr<const rcl_subscription_t>
216 SubscriptionBase::get_subscription_handle() const
217 {
218  return subscription_handle_;
219 }
220 
221 const
222 std::unordered_map<rcl_subscription_event_type_t, std::shared_ptr<rclcpp::EventHandlerBase>> &
224 {
225  return event_handlers_;
226 }
227 
230 {
231  const rmw_qos_profile_t * qos = rcl_subscription_get_actual_qos(subscription_handle_.get());
232  if (!qos) {
233  auto msg = std::string("failed to get qos settings: ") + rcl_get_error_string().str;
234  rcl_reset_error();
235  throw std::runtime_error(msg);
236  }
237 
239 }
240 
241 bool
242 SubscriptionBase::take_type_erased(void * message_out, rclcpp::MessageInfo & message_info_out)
243 {
244  rcl_ret_t ret = rcl_take(
245  this->get_subscription_handle().get(),
246  message_out,
247  &message_info_out.get_rmw_message_info(),
248  nullptr // rmw_subscription_allocation_t is unused here
249  );
250  TRACETOOLS_TRACEPOINT(rclcpp_take, static_cast<const void *>(message_out));
252  return false;
253  } else if (RCL_RET_OK != ret) {
254  rclcpp::exceptions::throw_from_rcl_error(ret);
255  }
256  if (
257  matches_any_intra_process_publishers(&message_info_out.get_rmw_message_info().publisher_gid))
258  {
259  // In this case, the message will be delivered via intra-process and
260  // we should ignore this copy of the message.
261  return false;
262  }
263  return true;
264 }
265 
266 bool
268  rclcpp::SerializedMessage & message_out,
269  rclcpp::MessageInfo & message_info_out)
270 {
272  this->get_subscription_handle().get(),
273  &message_out.get_rcl_serialized_message(),
274  &message_info_out.get_rmw_message_info(),
275  nullptr);
276  TRACETOOLS_TRACEPOINT(
277  rclcpp_take,
278  static_cast<const void *>(&message_out.get_rcl_serialized_message()));
280  return false;
281  } else if (RCL_RET_OK != ret) {
282  rclcpp::exceptions::throw_from_rcl_error(ret);
283  }
284  return true;
285 }
286 
287 const rosidl_message_type_support_t &
288 SubscriptionBase::get_message_type_support_handle() const
289 {
290  return type_support_;
291 }
292 
293 bool
295 {
296  return delivered_message_kind_ == rclcpp::DeliveredMessageKind::SERIALIZED_MESSAGE;
297 }
298 
301 {
302  return delivered_message_kind_;
303 }
304 
305 size_t
307 {
308  size_t inter_process_publisher_count = 0;
309 
310  rmw_ret_t status = rcl_subscription_get_publisher_count(
311  subscription_handle_.get(),
312  &inter_process_publisher_count);
313 
314  if (RCL_RET_OK != status) {
315  rclcpp::exceptions::throw_from_rcl_error(status, "failed to get get publisher count");
316  }
317  return inter_process_publisher_count;
318 }
319 
320 void
322  uint64_t intra_process_subscription_id,
323  IntraProcessManagerWeakPtr weak_ipm)
324 {
325  intra_process_subscription_id_ = intra_process_subscription_id;
326  weak_ipm_ = weak_ipm;
327  use_intra_process_ = true;
328 }
329 
330 bool
332 {
333  bool retval = rcl_subscription_can_loan_messages(subscription_handle_.get());
334  if (retval) {
335  // TODO(clalancette): The loaned message interface is currently not safe to use with
336  // shared_ptr callbacks. If a user takes a copy of the shared_ptr, it can get freed from
337  // underneath them via rcl_return_loaned_message_from_subscription(). The correct solution is
338  // to return the loaned message in a custom deleter, but that needs to be carefully handled
339  // with locking. Warn the user about this until we fix it.
340  RCLCPP_WARN_ONCE(
341  this->node_logger_,
342  "Loaned messages are only safe with const ref subscription callbacks. "
343  "If you are using any other kind of subscriptions, "
344  "set the ROS_DISABLE_LOANED_MESSAGES environment variable to 1 (the default).");
345  }
346  return retval;
347 }
348 
349 rclcpp::Waitable::SharedPtr
351 {
352  // If not using intra process, shortcut to nullptr.
353  if (!use_intra_process_) {
354  return nullptr;
355  }
356  // Get the intra process manager.
357  auto ipm = weak_ipm_.lock();
358  if (!ipm) {
359  throw std::runtime_error(
360  "SubscriptionBase::get_intra_process_waitable() called "
361  "after destruction of intra process manager");
362  }
363 
364  // Use the id to retrieve the subscription intra-process from the intra-process manager.
365  return ipm->get_subscription_intra_process(intra_process_subscription_id_);
366 }
367 
368 void
369 SubscriptionBase::default_incompatible_qos_callback(
370  rclcpp::QOSRequestedIncompatibleQoSInfo & event) const
371 {
372  std::string policy_name = qos_policy_name_from_kind(event.last_policy_kind);
373  RCLCPP_WARN(
374  rclcpp::get_logger(rcl_node_get_logger_name(node_handle_.get())),
375  "New publisher discovered on topic '%s', offering incompatible QoS. "
376  "No messages will be sent to it. "
377  "Last incompatible policy: %s",
378  get_topic_name(),
379  policy_name.c_str());
380 }
381 
382 void
383 SubscriptionBase::default_incompatible_type_callback(
384  [[maybe_unused]] rclcpp::IncompatibleTypeInfo & event) const
385 {
386  RCLCPP_WARN(
387  rclcpp::get_logger(rcl_node_get_logger_name(node_handle_.get())),
388  "Incompatible type on topic '%s', no messages will be sent to it.", get_topic_name());
389 }
390 
391 bool
392 SubscriptionBase::matches_any_intra_process_publishers(const rmw_gid_t * sender_gid) const
393 {
394  if (!use_intra_process_) {
395  return false;
396  }
397  auto ipm = weak_ipm_.lock();
398  if (!ipm) {
399  throw std::runtime_error(
400  "intra process publisher check called "
401  "after destruction of intra process manager");
402  }
403  return ipm->matches_any_publishers(sender_gid);
404 }
405 
406 bool
408  void * pointer_to_subscription_part,
409  bool in_use_state)
410 {
411  if (nullptr == pointer_to_subscription_part) {
412  throw std::invalid_argument("pointer_to_subscription_part is unexpectedly nullptr");
413  }
414  if (this == pointer_to_subscription_part) {
415  return subscription_in_use_by_wait_set_.exchange(in_use_state);
416  }
417  if (get_intra_process_waitable().get() == pointer_to_subscription_part) {
418  return intra_process_subscription_waitable_in_use_by_wait_set_.exchange(in_use_state);
419  }
420  for (const auto & key_event_pair : event_handlers_) {
421  auto qos_event = key_event_pair.second;
422  if (qos_event.get() == pointer_to_subscription_part) {
423  return qos_events_in_use_by_wait_set_[qos_event.get()].exchange(in_use_state);
424  }
425  }
426  throw std::runtime_error("given pointer_to_subscription_part does not match any part");
427 }
428 
429 std::vector<rclcpp::NetworkFlowEndpoint>
431 {
432  rcutils_allocator_t allocator = rcutils_get_default_allocator();
433  rcl_network_flow_endpoint_array_t network_flow_endpoint_array =
434  rcl_get_zero_initialized_network_flow_endpoint_array();
435  rcl_ret_t ret = rcl_subscription_get_network_flow_endpoints(
436  subscription_handle_.get(), &allocator, &network_flow_endpoint_array);
437  if (RCL_RET_OK != ret) {
438  auto error_msg = std::string("Error obtaining network flows of subscription: ") +
439  rcl_get_error_string().str;
440  rcl_reset_error();
441  if (RCL_RET_OK !=
442  rcl_network_flow_endpoint_array_fini(&network_flow_endpoint_array))
443  {
444  error_msg += std::string(". Also error cleaning up network flow array: ") +
445  rcl_get_error_string().str;
446  rcl_reset_error();
447  }
448  rclcpp::exceptions::throw_from_rcl_error(ret, error_msg);
449  }
450 
451  std::vector<rclcpp::NetworkFlowEndpoint> network_flow_endpoint_vector;
452  for (size_t i = 0; i < network_flow_endpoint_array.size; ++i) {
453  network_flow_endpoint_vector.push_back(
455  network_flow_endpoint_array.
456  network_flow_endpoint[i]));
457  }
458 
459  ret = rcl_network_flow_endpoint_array_fini(&network_flow_endpoint_array);
460  if (RCL_RET_OK != ret) {
461  rclcpp::exceptions::throw_from_rcl_error(ret, "error cleaning up network flow array");
462  }
463 
464  return network_flow_endpoint_vector;
465 }
466 
467 void
469  rcl_event_callback_t callback,
470  const void * user_data)
471 {
473  subscription_handle_.get(),
474  callback,
475  user_data);
476 
477  if (RCL_RET_OK != ret) {
478  using rclcpp::exceptions::throw_from_rcl_error;
479  throw_from_rcl_error(ret, "failed to set the on new message callback for subscription");
480  }
481 }
482 
483 bool
485 {
486  return rcl_subscription_is_cft_enabled(subscription_handle_.get());
487 }
488 
489 void
491  const std::string & filter_expression,
492  const std::vector<std::string> & expression_parameters)
493 {
496 
497  std::vector<const char *> cstrings = get_c_vector_string(expression_parameters);
499  subscription_handle_.get(),
500  get_c_string(filter_expression),
501  cstrings.size(),
502  cstrings.data(),
503  &options);
504  if (RCL_RET_OK != ret) {
505  rclcpp::exceptions::throw_from_rcl_error(
506  ret, "failed to init subscription content_filtered_topic option");
507  }
508  RCPPUTILS_SCOPE_EXIT(
509  {
511  subscription_handle_.get(), &options);
512  if (RCL_RET_OK != ret) {
513  RCLCPP_ERROR(
514  rclcpp::get_logger("rclcpp"),
515  "Failed to fini subscription content_filtered_topic option: %s",
516  rcl_get_error_string().str);
517  rcl_reset_error();
518  }
519  });
520 
522  subscription_handle_.get(),
523  &options);
524 
525  if (RCL_RET_OK != ret) {
526  rclcpp::exceptions::throw_from_rcl_error(ret, "failed to set cft expression parameters");
527  }
528 }
529 
532 {
533  rclcpp::ContentFilterOptions ret_options;
536 
538  subscription_handle_.get(),
539  &options);
540 
541  if (RCL_RET_OK != ret) {
542  rclcpp::exceptions::throw_from_rcl_error(ret, "failed to get cft expression parameters");
543  }
544 
545  RCPPUTILS_SCOPE_EXIT(
546  {
548  subscription_handle_.get(), &options);
549  if (RCL_RET_OK != ret) {
550  RCLCPP_ERROR(
551  rclcpp::get_logger("rclcpp"),
552  "Failed to fini subscription content_filtered_topic option: %s",
553  rcl_get_error_string().str);
554  rcl_reset_error();
555  }
556  });
557 
558  rmw_subscription_content_filter_options_t & content_filter_options =
559  options.rmw_subscription_content_filter_options;
560  ret_options.filter_expression = content_filter_options.filter_expression;
561 
562  for (size_t i = 0; i < content_filter_options.expression_parameters.size; ++i) {
563  ret_options.expression_parameters.push_back(
564  content_filter_options.expression_parameters.data[i]);
565  }
566 
567  return ret_options;
568 }
569 
570 
571 // DYNAMIC TYPE ==================================================================================
572 bool
573 SubscriptionBase::take_dynamic_message(
575  rclcpp::MessageInfo & /*message_info_out*/)
576 {
577  throw std::runtime_error("Unimplemented");
578  return false;
579 }
RCLCPP_PUBLIC Logger get_child(const std::string &suffix)
Return a logger that is a descendant of this logger.
Definition: logger.cpp:73
Additional meta data about messages taken from subscriptions.
const rmw_message_info_t & get_rmw_message_info() const
Return the message info as the underlying rmw message info type.
Encapsulation of Quality of Service settings.
Definition: qos.hpp:116
Object oriented version of rcl_serialized_message_t with destructor to avoid memory leaks.
rcl_serialized_message_t & get_rcl_serialized_message()
Get the underlying rcl_serialized_t handle.
RCLCPP_PUBLIC size_t get_publisher_count() const
Get matching publisher count.
RCLCPP_PUBLIC rclcpp::QoS get_actual_qos() const
Get the actual QoS settings, after the defaults have been determined.
RCLCPP_PUBLIC bool can_loan_messages() const
Check if subscription instance can loan messages.
void set_on_new_message_callback(std::function< void(size_t)> callback)
Set a callback to be called when each new message is received.
RCLCPP_PUBLIC rclcpp::Waitable::SharedPtr get_intra_process_waitable() const
Return the waitable for intra-process.
RCLCPP_PUBLIC std::vector< rclcpp::NetworkFlowEndpoint > get_network_flow_endpoints() const
Get network flow endpoints.
RCLCPP_PUBLIC void setup_intra_process(uint64_t intra_process_subscription_id, IntraProcessManagerWeakPtr weak_ipm)
Implemenation detail.
RCLCPP_PUBLIC DeliveredMessageKind get_delivered_message_kind() const
Return the delivered message kind.
RCLCPP_PUBLIC bool take_serialized(rclcpp::SerializedMessage &message_out, rclcpp::MessageInfo &message_info_out)
Take the next inter-process message, in its serialized form, from the subscription.
RCLCPP_PUBLIC bool take_type_erased(void *message_out, rclcpp::MessageInfo &message_info_out)
Take the next inter-process message from the subscription as a type erased pointer.
RCLCPP_PUBLIC bool exchange_in_use_by_wait_set_state(void *pointer_to_subscription_part, bool in_use_state)
Exchange state of whether or not a part of the subscription is used by a wait set.
RCLCPP_PUBLIC void set_content_filter(const std::string &filter_expression, const std::vector< std::string > &expression_parameters={})
Set the filter expression and expression parameters for the subscription.
virtual RCLCPP_PUBLIC ~SubscriptionBase()
Destructor.
RCLCPP_PUBLIC bool is_cft_enabled() const
Check if content filtered topic feature of the subscription instance is enabled.
RCLCPP_PUBLIC void bind_event_callbacks(const SubscriptionEventCallbacks &event_callbacks, bool use_default_callbacks)
Add event handlers for passed in event_callbacks.
RCLCPP_PUBLIC const std::unordered_map< rcl_subscription_event_type_t, std::shared_ptr< rclcpp::EventHandlerBase > > & get_event_handlers() const
Get all the QoS event handlers associated with this subscription.
RCLCPP_PUBLIC rclcpp::ContentFilterOptions get_content_filter() const
Get the filter expression and expression parameters for the subscription.
RCLCPP_PUBLIC bool is_serialized() const
Return if the subscription is serialized.
RCLCPP_PUBLIC const char * get_topic_name() const
Get the topic that this subscription is subscribed on.
Pure virtual interface class for the NodeBase part of the Node API.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC std::string expand_topic_or_service_name(const std::string &name, const std::string &node_name, const std::string &namespace_, bool is_service=false)
Expand a topic or service name and throw if it is not valid.
RCLCPP_PUBLIC Logger get_node_logger(const rcl_node_t *node)
Return a named logger using an rcl_node_t.
Definition: logger.cpp:45
DeliveredMessageKind
The kind of message that the subscription delivers in its callback, used by the executor.
RCLCPP_PUBLIC std::vector< const char * > get_c_vector_string(const std::vector< std::string > &strings_in)
Return the std::vector of C string from the given std::vector<std::string>.
Definition: utilities.cpp:218
RCLCPP_PUBLIC const char * get_c_string(const char *string_in)
Return the given string.
Definition: utilities.cpp:206
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Definition: logger.cpp:34
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_node_get_name(const rcl_node_t *node)
Return the name of the node.
Definition: node.c:408
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_node_get_namespace(const rcl_node_t *node)
Return the namespace of the node.
Definition: node.c:417
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_node_get_logger_name(const rcl_node_t *node)
Return the logger name of the node.
Definition: node.c:485
Options available for a rcl subscription.
Definition: subscription.h:47
Structure which encapsulates a ROS Subscription.
Definition: subscription.h:40
Options to configure content filtered topic in the subscription.
std::string filter_expression
Filter expression is similar to the WHERE part of an SQL clause.
static QoSInitialization from_rmw(const rmw_qos_profile_t &rmw_qos)
Create a QoSInitialization from an existing rmw_qos_profile_t, using its history and depth.
Definition: qos.cpp:63
Contains callbacks for non-message events that a Subscription can receive from the middleware.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_subscription_content_filter_options_fini(const rcl_subscription_t *subscription, rcl_subscription_content_filter_options_t *options)
Reclaim rcl_subscription_content_filter_options_t structure.
Definition: subscription.c:455
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_subscription_init(rcl_subscription_t *subscription, const rcl_node_t *node, const rosidl_message_type_support_t *type_support, const char *topic_name, const rcl_subscription_options_t *options)
Initialize a ROS subscription.
Definition: subscription.c:51
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_subscription_get_topic_name(const rcl_subscription_t *subscription)
Get the topic name for the subscription.
Definition: subscription.c:740
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_subscription_set_on_new_message_callback(const rcl_subscription_t *subscription, rcl_event_callback_t callback, const void *user_data)
Set the on new message callback function for the subscription.
Definition: subscription.c:823
RCL_PUBLIC bool rcl_subscription_can_loan_messages(const rcl_subscription_t *subscription)
Check if subscription instance can loan messages.
Definition: subscription.c:809
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_subscription_fini(rcl_subscription_t *subscription, rcl_node_t *node)
Finalize a rcl_subscription_t.
Definition: subscription.c:180
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_take(const rcl_subscription_t *subscription, void *ros_message, rmw_message_info_t *message_info, rmw_subscription_allocation_t *allocation)
Take a ROS message from a topic using a rcl subscription.
Definition: subscription.c:542
RCL_PUBLIC RCL_WARN_UNUSED rmw_ret_t rcl_subscription_get_publisher_count(const rcl_subscription_t *subscription, size_t *publisher_count)
Get the number of publishers matched to a subscription.
Definition: subscription.c:778
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_take_serialized_message(const rcl_subscription_t *subscription, rcl_serialized_message_t *serialized_message, rmw_message_info_t *message_info, rmw_subscription_allocation_t *allocation)
Take a serialized raw message from a topic using a rcl subscription.
Definition: subscription.c:623
RCL_PUBLIC RCL_WARN_UNUSED rcl_subscription_content_filter_options_t rcl_get_zero_initialized_subscription_content_filter_options(void)
Return the zero initialized subscription content filter options.
Definition: subscription.c:387
RCL_PUBLIC RCL_WARN_UNUSED bool rcl_subscription_is_cft_enabled(const rcl_subscription_t *subscription)
Check if the content filtered topic feature is enabled in the subscription.
Definition: subscription.c:475
RCL_PUBLIC RCL_WARN_UNUSED const rmw_qos_profile_t * rcl_subscription_get_actual_qos(const rcl_subscription_t *subscription)
Get the actual qos settings of the subscription.
Definition: subscription.c:800
RCL_PUBLIC RCL_WARN_UNUSED rcl_subscription_t rcl_get_zero_initialized_subscription(void)
Return a rcl_subscription_t struct with members set to NULL.
Definition: subscription.c:43
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_subscription_get_content_filter(const rcl_subscription_t *subscription, rcl_subscription_content_filter_options_t *options)
Retrieve the filter expression of the subscription.
Definition: subscription.c:518
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_subscription_set_content_filter(const rcl_subscription_t *subscription, const rcl_subscription_content_filter_options_t *options)
Set the filter expression and expression parameters for the subscription.
Definition: subscription.c:484
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_subscription_content_filter_options_init(const rcl_subscription_t *subscription, const char *filter_expression, size_t expression_parameters_argc, const char *expression_parameter_argv[], rcl_subscription_content_filter_options_t *options)
Initialize the content filter options for the given subscription options.
Definition: subscription.c:396
#define RCL_RET_SUBSCRIPTION_TAKE_FAILED
Failed to take a message from the subscription return code.
Definition: types.h:75
#define RCL_RET_OK
Success return code.
Definition: types.h:27
#define RCL_RET_TOPIC_NAME_INVALID
Topic name does not pass validation.
Definition: types.h:47
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:24