ROS 2 rclcpp + rcl - humble  humble
ROS 2 C++ Client Library with ROS Client Library
publisher.c
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 #ifdef __cplusplus
16 extern "C"
17 {
18 #endif
19 
20 #include "rcl/publisher.h"
21 
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include "rcl/allocator.h"
26 #include "rcl/error_handling.h"
27 #include "rcl/node.h"
28 #include "rcutils/logging_macros.h"
29 #include "rcutils/macros.h"
30 #include "rcl/time.h"
31 #include "rmw/time.h"
32 #include "rmw/error_handling.h"
33 #include "tracetools/tracetools.h"
34 
35 #include "./common.h"
36 #include "./publisher_impl.h"
37 
40 {
41  static rcl_publisher_t null_publisher = {0};
42  return null_publisher;
43 }
44 
47  rcl_publisher_t * publisher,
48  const rcl_node_t * node,
49  const rosidl_message_type_support_t * type_support,
50  const char * topic_name,
51  const rcl_publisher_options_t * options
52 )
53 {
54  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
55  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ALREADY_INIT);
56  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
57  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_BAD_ALLOC);
58  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
59  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_TOPIC_NAME_INVALID);
60 
61  rcl_ret_t fail_ret = RCL_RET_ERROR;
62 
63  // Check options and allocator first, so allocator can be used with errors.
64  RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT);
65  rcl_allocator_t * allocator = (rcl_allocator_t *)&options->allocator;
66  RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
67 
68  RCL_CHECK_ARGUMENT_FOR_NULL(publisher, RCL_RET_INVALID_ARGUMENT);
69  if (publisher->impl) {
70  RCL_SET_ERROR_MSG("publisher already initialized, or memory was unintialized");
71  return RCL_RET_ALREADY_INIT;
72  }
73  if (!rcl_node_is_valid(node)) {
74  return RCL_RET_NODE_INVALID; // error already set
75  }
76  RCL_CHECK_ARGUMENT_FOR_NULL(type_support, RCL_RET_INVALID_ARGUMENT);
77  RCL_CHECK_ARGUMENT_FOR_NULL(topic_name, RCL_RET_INVALID_ARGUMENT);
78  RCUTILS_LOG_DEBUG_NAMED(
79  ROS_PACKAGE_NAME, "Initializing publisher for topic name '%s'", topic_name);
80 
81  // Expand and remap the given topic name.
82  char * remapped_topic_name = NULL;
84  node,
85  topic_name,
86  *allocator,
87  false,
88  false,
89  &remapped_topic_name);
90  if (ret != RCL_RET_OK) {
93  } else if (ret != RCL_RET_BAD_ALLOC) {
94  ret = RCL_RET_ERROR;
95  }
96  goto cleanup;
97  }
98  RCUTILS_LOG_DEBUG_NAMED(
99  ROS_PACKAGE_NAME, "Expanded and remapped topic name '%s'", remapped_topic_name);
100 
101  // Allocate space for the implementation struct.
102  publisher->impl = (rcl_publisher_impl_t *)allocator->allocate(
103  sizeof(rcl_publisher_impl_t), allocator->state);
104  RCL_CHECK_FOR_NULL_WITH_MSG(
105  publisher->impl, "allocating memory failed", ret = RCL_RET_BAD_ALLOC; goto cleanup);
106 
107  // Fill out implementation struct.
108  // rmw handle (create rmw publisher)
109  // TODO(wjwwood): pass along the allocator to rmw when it supports it
110  publisher->impl->rmw_handle = rmw_create_publisher(
112  type_support,
113  remapped_topic_name,
114  &(options->qos),
115  &(options->rmw_publisher_options));
116  RCL_CHECK_FOR_NULL_WITH_MSG(
117  publisher->impl->rmw_handle, rmw_get_error_string().str, goto fail);
118  // get actual qos, and store it
119  rmw_ret_t rmw_ret = rmw_publisher_get_actual_qos(
120  publisher->impl->rmw_handle,
121  &publisher->impl->actual_qos);
122  if (RMW_RET_OK != rmw_ret) {
123  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
124  goto fail;
125  }
126  publisher->impl->actual_qos.avoid_ros_namespace_conventions =
127  options->qos.avoid_ros_namespace_conventions;
128  // options
129  publisher->impl->options = *options;
130  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Publisher initialized");
131  // context
132  publisher->impl->context = node->context;
133  TRACEPOINT(
135  (const void *)publisher,
136  (const void *)node,
137  (const void *)publisher->impl->rmw_handle,
138  remapped_topic_name,
139  options->qos.depth);
140  goto cleanup;
141 fail:
142  if (publisher->impl) {
143  if (publisher->impl->rmw_handle) {
144  rmw_ret_t rmw_fail_ret = rmw_destroy_publisher(
145  rcl_node_get_rmw_handle(node), publisher->impl->rmw_handle);
146  if (RMW_RET_OK != rmw_fail_ret) {
147  RCUTILS_SAFE_FWRITE_TO_STDERR(rmw_get_error_string().str);
148  RCUTILS_SAFE_FWRITE_TO_STDERR("\n");
149  }
150  }
151 
152  allocator->deallocate(publisher->impl, allocator->state);
153  publisher->impl = NULL;
154  }
155 
156  ret = fail_ret;
157  // Fall through to cleanup
158 cleanup:
159  allocator->deallocate(remapped_topic_name, allocator->state);
160  return ret;
161 }
162 
163 rcl_ret_t
165 {
166  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_PUBLISHER_INVALID);
167  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
168  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
169  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
170 
171  rcl_ret_t result = RCL_RET_OK;
172  RCL_CHECK_ARGUMENT_FOR_NULL(publisher, RCL_RET_PUBLISHER_INVALID);
174  return RCL_RET_NODE_INVALID; // error already set
175  }
176 
177  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing publisher");
178  if (publisher->impl) {
179  rcl_allocator_t allocator = publisher->impl->options.allocator;
180  rmw_node_t * rmw_node = rcl_node_get_rmw_handle(node);
181  if (!rmw_node) {
183  }
184  rmw_ret_t ret =
185  rmw_destroy_publisher(rmw_node, publisher->impl->rmw_handle);
186  if (ret != RMW_RET_OK) {
187  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
188  result = RCL_RET_ERROR;
189  }
190  allocator.deallocate(publisher->impl, allocator.state);
191  publisher->impl = NULL;
192  }
193  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Publisher finalized");
194  return result;
195 }
196 
199 {
200  // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING
201  static rcl_publisher_options_t default_options;
202  // Must set the allocator and qos after because they are not a compile time constant.
203  default_options.qos = rmw_qos_profile_default;
204  default_options.allocator = rcl_get_default_allocator();
205  default_options.rmw_publisher_options = rmw_get_default_publisher_options();
206  return default_options;
207 }
208 
209 rcl_ret_t
211  const rcl_publisher_t * publisher,
212  const rosidl_message_type_support_t * type_support,
213  void ** ros_message)
214 {
215  if (!rcl_publisher_is_valid(publisher)) {
216  return RCL_RET_PUBLISHER_INVALID; // error already set
217  }
218  return rcl_convert_rmw_ret_to_rcl_ret(
219  rmw_borrow_loaned_message(publisher->impl->rmw_handle, type_support, ros_message));
220 }
221 
222 rcl_ret_t
224  const rcl_publisher_t * publisher,
225  void * loaned_message)
226 {
227  if (!rcl_publisher_is_valid(publisher)) {
228  return RCL_RET_PUBLISHER_INVALID; // error already set
229  }
230  RCL_CHECK_ARGUMENT_FOR_NULL(loaned_message, RCL_RET_INVALID_ARGUMENT);
231  return rcl_convert_rmw_ret_to_rcl_ret(
232  rmw_return_loaned_message_from_publisher(publisher->impl->rmw_handle, loaned_message));
233 }
234 
235 rcl_ret_t
237  const rcl_publisher_t * publisher,
238  const void * ros_message,
239  rmw_publisher_allocation_t * allocation)
240 {
241  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_PUBLISHER_INVALID);
242  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
243 
244  if (!rcl_publisher_is_valid(publisher)) {
245  return RCL_RET_PUBLISHER_INVALID; // error already set
246  }
247  RCL_CHECK_ARGUMENT_FOR_NULL(ros_message, RCL_RET_INVALID_ARGUMENT);
248  TRACEPOINT(rcl_publish, (const void *)publisher, (const void *)ros_message);
249  if (rmw_publish(publisher->impl->rmw_handle, ros_message, allocation) != RMW_RET_OK) {
250  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
251  return RCL_RET_ERROR;
252  }
253  return RCL_RET_OK;
254 }
255 
256 rcl_ret_t
258  const rcl_publisher_t * publisher,
259  const rcl_serialized_message_t * serialized_message,
260  rmw_publisher_allocation_t * allocation)
261 {
262  if (!rcl_publisher_is_valid(publisher)) {
263  return RCL_RET_PUBLISHER_INVALID; // error already set
264  }
265  RCL_CHECK_ARGUMENT_FOR_NULL(serialized_message, RCL_RET_INVALID_ARGUMENT);
266  rmw_ret_t ret = rmw_publish_serialized_message(
267  publisher->impl->rmw_handle, serialized_message, allocation);
268  if (ret != RMW_RET_OK) {
269  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
270  if (ret == RMW_RET_BAD_ALLOC) {
271  return RCL_RET_BAD_ALLOC;
272  }
273  return RCL_RET_ERROR;
274  }
275  return RCL_RET_OK;
276 }
277 
278 rcl_ret_t
280  const rcl_publisher_t * publisher,
281  void * ros_message,
282  rmw_publisher_allocation_t * allocation)
283 {
284  if (!rcl_publisher_is_valid(publisher)) {
285  return RCL_RET_PUBLISHER_INVALID; // error already set
286  }
287  RCL_CHECK_ARGUMENT_FOR_NULL(ros_message, RCL_RET_INVALID_ARGUMENT);
288  rmw_ret_t ret = rmw_publish_loaned_message(publisher->impl->rmw_handle, ros_message, allocation);
289  if (ret != RMW_RET_OK) {
290  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
291  return RCL_RET_ERROR;
292  }
293  return RCL_RET_OK;
294 }
295 
296 rcl_ret_t
298 {
299  if (!rcl_publisher_is_valid(publisher)) {
300  return RCL_RET_PUBLISHER_INVALID; // error already set
301  }
302  if (rmw_publisher_assert_liveliness(publisher->impl->rmw_handle) != RMW_RET_OK) {
303  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
304  return RCL_RET_ERROR;
305  }
306  return RCL_RET_OK;
307 }
308 
309 rcl_ret_t
311 {
312  if (!rcl_publisher_is_valid(publisher)) {
313  return RCL_RET_PUBLISHER_INVALID; // error already set
314  }
315 
316  rmw_time_t rmw_timeout;
317  if (timeout > 0) {
318  rmw_timeout.sec = RCL_NS_TO_S(timeout);
319  rmw_timeout.nsec = timeout % 1000000000;
320  } else if (timeout < 0) {
321  rmw_time_t infinite = RMW_DURATION_INFINITE;
322  rmw_timeout = infinite;
323  } else {
324  rmw_time_t zero = RMW_DURATION_UNSPECIFIED;
325  rmw_timeout = zero;
326  }
327 
328  rmw_ret_t ret = rmw_publisher_wait_for_all_acked(publisher->impl->rmw_handle, rmw_timeout);
329  if (ret != RMW_RET_OK) {
330  if (ret == RMW_RET_TIMEOUT) {
331  return RCL_RET_TIMEOUT;
332  }
333  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
334  if (ret == RMW_RET_UNSUPPORTED) {
335  return RCL_RET_UNSUPPORTED;
336  } else {
337  return RCL_RET_ERROR;
338  }
339  }
340 
341  return RCL_RET_OK;
342 }
343 
344 const char *
346 {
347  if (!rcl_publisher_is_valid_except_context(publisher)) {
348  return NULL; // error already set
349  }
350  return publisher->impl->rmw_handle->topic_name;
351 }
352 
353 #define _publisher_get_options(pub) & pub->impl->options
354 
357 {
358  if (!rcl_publisher_is_valid_except_context(publisher)) {
359  return NULL; // error already set
360  }
361  return _publisher_get_options(publisher);
362 }
363 
364 rmw_publisher_t *
366 {
367  if (!rcl_publisher_is_valid_except_context(publisher)) {
368  return NULL; // error already set
369  }
370  return publisher->impl->rmw_handle;
371 }
372 
375 {
376  if (!rcl_publisher_is_valid_except_context(publisher)) {
377  return NULL; // error already set
378  }
379  return publisher->impl->context;
380 }
381 
382 bool
384 {
385  if (!rcl_publisher_is_valid_except_context(publisher)) {
386  return false; // error already set
387  }
388  if (!rcl_context_is_valid(publisher->impl->context)) {
389  RCL_SET_ERROR_MSG("publisher's context is invalid");
390  return false;
391  }
392  RCL_CHECK_FOR_NULL_WITH_MSG(
393  publisher->impl->rmw_handle, "publisher's rmw handle is invalid", return false);
394  return true;
395 }
396 
397 bool
399 {
400  RCL_CHECK_FOR_NULL_WITH_MSG(publisher, "publisher pointer is invalid", return false);
401  RCL_CHECK_FOR_NULL_WITH_MSG(
402  publisher->impl, "publisher implementation is invalid", return false);
403  RCL_CHECK_FOR_NULL_WITH_MSG(
404  publisher->impl->rmw_handle, "publisher's rmw handle is invalid", return false);
405  return true;
406 }
407 
408 rcl_ret_t
410  const rcl_publisher_t * publisher,
411  size_t * subscription_count)
412 {
413  if (!rcl_publisher_is_valid(publisher)) {
415  }
416  RCL_CHECK_ARGUMENT_FOR_NULL(subscription_count, RCL_RET_INVALID_ARGUMENT);
417 
418  rmw_ret_t ret = rmw_publisher_count_matched_subscriptions(
419  publisher->impl->rmw_handle, subscription_count);
420 
421  if (ret != RMW_RET_OK) {
422  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
423  return rcl_convert_rmw_ret_to_rcl_ret(ret);
424  }
425  return RCL_RET_OK;
426 }
427 
428 const rmw_qos_profile_t *
430 {
431  if (!rcl_publisher_is_valid_except_context(publisher)) {
432  return NULL;
433  }
434  return &publisher->impl->actual_qos;
435 }
436 
437 bool
439 {
440  if (!rcl_publisher_is_valid(publisher)) {
441  return false; // error message already set
442  }
443 
444  bool disable_loaned_message = false;
445  rcl_ret_t ret = rcl_get_disable_loaned_message(&disable_loaned_message);
446  if (ret == RCL_RET_OK && disable_loaned_message) {
447  return false;
448  }
449 
450  return publisher->impl->rmw_handle->can_loan_messages;
451 }
452 
453 #ifdef __cplusplus
454 }
455 #endif
#define rcl_get_default_allocator
Return a properly initialized rcl_allocator_t with default values.
Definition: allocator.h:37
#define RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, msg, fail_statement)
Check that the given allocator is initialized, or fail with a message.
Definition: allocator.h:56
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
Definition: allocator.h:31
RCL_PUBLIC RCL_WARN_UNUSED bool rcl_context_is_valid(const rcl_context_t *context)
Return true if the given context is currently valid, otherwise false.
Definition: context.c:94
RCL_PUBLIC bool rcl_node_is_valid(const rcl_node_t *node)
Return true if the node is valid, else false.
Definition: node.c:421
RCL_PUBLIC rcl_ret_t rcl_get_disable_loaned_message(bool *disable_loaned_message)
Check if loaned message is disabled, according to the environment variable.
Definition: node.c:521
RCL_PUBLIC RCL_WARN_UNUSED rmw_node_t * rcl_node_get_rmw_handle(const rcl_node_t *node)
Return the rmw node handle.
Definition: node.c:485
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_node_resolve_name(const rcl_node_t *node, const char *input_name, rcl_allocator_t allocator, bool is_service, bool only_expand, char **output_name)
Expand a given name into a fully-qualified topic name and apply remapping rules.
RCL_PUBLIC bool rcl_node_is_valid_except_context(const rcl_node_t *node)
Return true if node is valid, except for the context being valid.
Definition: node.c:411
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_init(rcl_publisher_t *publisher, const rcl_node_t *node, const rosidl_message_type_support_t *type_support, const char *topic_name, const rcl_publisher_options_t *options)
Initialize a rcl publisher.
Definition: publisher.c:46
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publish_loaned_message(const rcl_publisher_t *publisher, void *ros_message, rmw_publisher_allocation_t *allocation)
Publish a loaned message on a topic using a publisher.
Definition: publisher.c:279
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:310
RCL_PUBLIC bool rcl_publisher_is_valid(const rcl_publisher_t *publisher)
Return true if the publisher is valid, otherwise false.
Definition: publisher.c:383
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publish_serialized_message(const rcl_publisher_t *publisher, const rcl_serialized_message_t *serialized_message, rmw_publisher_allocation_t *allocation)
Publish a serialized message on a topic using a publisher.
Definition: publisher.c:257
RCL_PUBLIC RCL_WARN_UNUSED rcl_context_t * rcl_publisher_get_context(const rcl_publisher_t *publisher)
Return the context associated with this publisher.
Definition: publisher.c:374
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publish(const rcl_publisher_t *publisher, const void *ros_message, rmw_publisher_allocation_t *allocation)
Publish a ROS message on a topic using a publisher.
Definition: publisher.c:236
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_borrow_loaned_message(const rcl_publisher_t *publisher, const rosidl_message_type_support_t *type_support, void **ros_message)
Borrow a loaned message.
Definition: publisher.c:210
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_get_subscription_count(const rcl_publisher_t *publisher, size_t *subscription_count)
Get the number of subscriptions matched to a publisher.
Definition: publisher.c:409
RCL_PUBLIC RCL_WARN_UNUSED rmw_publisher_t * rcl_publisher_get_rmw_handle(const rcl_publisher_t *publisher)
Return the rmw publisher handle.
Definition: publisher.c:365
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_publisher_get_topic_name(const rcl_publisher_t *publisher)
Get the topic name for the publisher.
Definition: publisher.c:345
RCL_PUBLIC RCL_WARN_UNUSED const rmw_qos_profile_t * rcl_publisher_get_actual_qos(const rcl_publisher_t *publisher)
Get the actual qos settings of the publisher.
Definition: publisher.c:429
RCL_PUBLIC RCL_WARN_UNUSED rcl_publisher_options_t rcl_publisher_get_default_options(void)
Return the default publisher options in a rcl_publisher_options_t.
Definition: publisher.c:198
RCL_PUBLIC bool rcl_publisher_is_valid_except_context(const rcl_publisher_t *publisher)
Return true if the publisher is valid except the context, otherwise false.
Definition: publisher.c:398
RCL_PUBLIC RCL_WARN_UNUSED const rcl_publisher_options_t * rcl_publisher_get_options(const rcl_publisher_t *publisher)
Return the rcl publisher options.
Definition: publisher.c:356
RCL_PUBLIC RCL_WARN_UNUSED rcl_publisher_t rcl_get_zero_initialized_publisher(void)
Return a rcl_publisher_t struct with members set to NULL.
Definition: publisher.c:39
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_fini(rcl_publisher_t *publisher, rcl_node_t *node)
Finalize a rcl_publisher_t.
Definition: publisher.c:164
RCL_PUBLIC bool rcl_publisher_can_loan_messages(const rcl_publisher_t *publisher)
Check if publisher instance can loan messages.
Definition: publisher.c:438
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_return_loaned_message_from_publisher(const rcl_publisher_t *publisher, void *loaned_message)
Return a loaned message previously borrowed from a publisher.
Definition: publisher.c:223
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_assert_liveliness(const rcl_publisher_t *publisher)
Manually assert that this Publisher is alive (for RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC)
Definition: publisher.c:297
Encapsulates the non-global state of an init/shutdown cycle.
Definition: context.h:114
Structure which encapsulates a ROS Node.
Definition: node.h:42
rcl_context_t * context
Context associated with this node.
Definition: node.h:44
Options available for a rcl publisher.
Definition: publisher.h:44
rmw_qos_profile_t qos
Middleware quality of service settings for the publisher.
Definition: publisher.h:46
rmw_publisher_options_t rmw_publisher_options
rmw specific publisher options, e.g. the rmw implementation specific payload.
Definition: publisher.h:51
rcl_allocator_t allocator
Custom allocator for the publisher, used for incidental allocations.
Definition: publisher.h:49
Structure which encapsulates a ROS Publisher.
Definition: publisher.h:37
rcl_publisher_impl_t * impl
Pointer to the publisher implementation.
Definition: publisher.h:39
#define RCL_NS_TO_S
Convenience macro to convert nanoseconds to seconds.
Definition: time.h:39
rcutils_duration_value_t rcl_duration_value_t
A duration of time, measured in nanoseconds.
Definition: time.h:48
#define RCL_RET_UNSUPPORTED
Unsupported return code.
Definition: types.h:36
#define RCL_RET_UNKNOWN_SUBSTITUTION
Topic name substitution is unknown.
Definition: types.h:50
#define RCL_RET_ALREADY_INIT
rcl_init() already called return code.
Definition: types.h:40
#define RCL_RET_OK
Success return code.
Definition: types.h:26
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
Definition: types.h:32
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
Definition: types.h:34
#define RCL_RET_ERROR
Unspecified error return code.
Definition: types.h:28
rmw_serialized_message_t rcl_serialized_message_t
typedef for rmw_serialized_message_t;
Definition: types.h:127
#define RCL_RET_NODE_INVALID
Invalid rcl_node_t given return code.
Definition: types.h:56
#define RCL_RET_TOPIC_NAME_INVALID
Topic name does not pass validation.
Definition: types.h:46
#define RCL_RET_TIMEOUT
Timeout occurred return code.
Definition: types.h:30
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:23
#define RCL_RET_PUBLISHER_INVALID
Invalid rcl_publisher_t given return code.
Definition: types.h:66