ROS 2 rclcpp + rcl - humble  humble
ROS 2 C++ Client Library with ROS Client Library
node.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/node.h"
21 
22 #include <limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "rcl/arguments.h"
28 #include "rcl/error_handling.h"
29 #include "rcl/init_options.h"
30 #include "rcl/localhost.h"
31 #include "rcl/logging.h"
32 #include "rcl/logging_rosout.h"
33 #include "rcl/rcl.h"
34 #include "rcl/remap.h"
35 #include "rcl/security.h"
36 
37 #include "rcutils/env.h"
38 #include "rcutils/filesystem.h"
39 #include "rcutils/find.h"
40 #include "rcutils/format_string.h"
41 #include "rcutils/logging_macros.h"
42 #include "rcutils/macros.h"
43 #include "rcutils/repl_str.h"
44 #include "rcutils/snprintf.h"
45 #include "rcutils/strdup.h"
46 
47 #include "rmw/error_handling.h"
48 #include "rmw/security_options.h"
49 #include "rmw/rmw.h"
50 #include "rmw/validate_namespace.h"
51 #include "rmw/validate_node_name.h"
52 #include "tracetools/tracetools.h"
53 
54 #include "./context_impl.h"
55 
56 const char * const RCL_DISABLE_LOANED_MESSAGES_ENV_VAR = "ROS_DISABLE_LOANED_MESSAGES";
57 
59 {
60  rcl_node_options_t options;
61  rmw_node_t * rmw_node_handle;
62  rcl_guard_condition_t * graph_guard_condition;
63  const char * logger_name;
64  const char * fq_name;
65 };
66 
67 
69 
78 const char * rcl_create_node_logger_name(
79  const char * node_name,
80  const char * node_namespace,
81  const rcl_allocator_t * allocator)
82 {
83  // If the namespace is the root namespace ("/"), the logger name is just the node name.
84  if (strlen(node_namespace) == 1) {
85  return rcutils_strdup(node_name, *allocator);
86  }
87 
88  // Convert the forward slashes in the namespace to the separator used for logger names.
89  // The input namespace has already been expanded and therefore will always be absolute,
90  // i.e. it will start with a forward slash, which we want to ignore.
91  const char * ns_with_separators = rcutils_repl_str(
92  node_namespace + 1, // Ignore the leading forward slash.
93  "/", RCUTILS_LOGGING_SEPARATOR_STRING,
94  allocator);
95  if (NULL == ns_with_separators) {
96  return NULL;
97  }
98 
99  // Join the namespace and node name to create the logger name.
100  char * node_logger_name = rcutils_format_string(
101  *allocator, "%s%s%s", ns_with_separators, RCUTILS_LOGGING_SEPARATOR_STRING, node_name);
102  allocator->deallocate((char *)ns_with_separators, allocator->state);
103  return node_logger_name;
104 }
105 
108 {
109  static rcl_node_t null_node = {
110  .context = 0,
111  .impl = 0
112  };
113  return null_node;
114 }
115 
116 rcl_ret_t
118  rcl_node_t * node,
119  const char * name,
120  const char * namespace_,
121  rcl_context_t * context,
122  const rcl_node_options_t * options)
123 {
124  const rmw_guard_condition_t * rmw_graph_guard_condition = NULL;
125  rcl_guard_condition_options_t graph_guard_condition_options =
127  rcl_ret_t ret;
128  rcl_ret_t fail_ret = RCL_RET_ERROR;
129  char * remapped_node_name = NULL;
130 
131  // Check options and allocator first, so allocator can be used for errors.
132  RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT);
133  const rcl_allocator_t * allocator = &options->allocator;
134  RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
135 
136  RCL_CHECK_ARGUMENT_FOR_NULL(name, RCL_RET_INVALID_ARGUMENT);
137  RCL_CHECK_ARGUMENT_FOR_NULL(namespace_, RCL_RET_INVALID_ARGUMENT);
138  RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
139  RCUTILS_LOG_DEBUG_NAMED(
140  ROS_PACKAGE_NAME, "Initializing node '%s' in namespace '%s'", name, namespace_);
141  if (node->impl) {
142  RCL_SET_ERROR_MSG("node already initialized, or struct memory was unintialized");
143  return RCL_RET_ALREADY_INIT;
144  }
145  // Make sure rcl has been initialized.
146  RCL_CHECK_FOR_NULL_WITH_MSG(
147  context, "given context in options is NULL", return RCL_RET_INVALID_ARGUMENT);
148  if (!rcl_context_is_valid(context)) {
149  RCL_SET_ERROR_MSG(
150  "the given context is not valid, "
151  "either rcl_init() was not called or rcl_shutdown() was called.");
152  return RCL_RET_NOT_INIT;
153  }
154  // Make sure the node name is valid before allocating memory.
155  int validation_result = 0;
156  ret = rmw_validate_node_name(name, &validation_result, NULL);
157  if (ret != RMW_RET_OK) {
158  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
159  return ret;
160  }
161  if (validation_result != RMW_NODE_NAME_VALID) {
162  const char * msg = rmw_node_name_validation_result_string(validation_result);
163  RCL_SET_ERROR_MSG(msg);
165  }
166 
167  // Process the namespace.
168  size_t namespace_length = strlen(namespace_);
169  const char * local_namespace_ = namespace_;
170  bool should_free_local_namespace_ = false;
171  // If the namespace is just an empty string, replace with "/"
172  if (namespace_length == 0) {
173  // Have this special case to avoid a memory allocation when "" is passed.
174  local_namespace_ = "/";
175  }
176 
177  // If the namespace does not start with a /, add one.
178  if (namespace_length > 0 && namespace_[0] != '/') {
179  local_namespace_ = rcutils_format_string(*allocator, "/%s", namespace_);
180  RCL_CHECK_FOR_NULL_WITH_MSG(
181  local_namespace_,
182  "failed to format node namespace string",
183  ret = RCL_RET_BAD_ALLOC; goto cleanup);
184  should_free_local_namespace_ = true;
185  }
186  // Make sure the node namespace is valid.
187  validation_result = 0;
188  ret = rmw_validate_namespace(local_namespace_, &validation_result, NULL);
189  if (ret != RMW_RET_OK) {
190  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
191  goto cleanup;
192  }
193  if (validation_result != RMW_NAMESPACE_VALID) {
194  const char * msg = rmw_namespace_validation_result_string(validation_result);
195  RCL_SET_ERROR_MSG_WITH_FORMAT_STRING("%s, result: %d", msg, validation_result);
196 
198  goto cleanup;
199  }
200 
201  // Allocate space for the implementation struct.
202  node->impl = (rcl_node_impl_t *)allocator->allocate(sizeof(rcl_node_impl_t), allocator->state);
203  RCL_CHECK_FOR_NULL_WITH_MSG(
204  node->impl, "allocating memory failed", ret = RCL_RET_BAD_ALLOC; goto cleanup);
205  node->impl->rmw_node_handle = NULL;
206  node->impl->graph_guard_condition = NULL;
207  node->impl->logger_name = NULL;
208  node->impl->fq_name = NULL;
209  node->impl->options = rcl_node_get_default_options();
210  node->context = context;
211  // Initialize node impl.
212  ret = rcl_node_options_copy(options, &(node->impl->options));
213  if (RCL_RET_OK != ret) {
214  goto fail;
215  }
216 
217  // Remap the node name and namespace if remap rules are given
218  rcl_arguments_t * global_args = NULL;
219  if (node->impl->options.use_global_arguments) {
220  global_args = &(node->context->global_arguments);
221  }
222  ret = rcl_remap_node_name(
223  &(node->impl->options.arguments), global_args, name, *allocator,
224  &remapped_node_name);
225  if (RCL_RET_OK != ret) {
226  goto fail;
227  } else if (NULL != remapped_node_name) {
228  name = remapped_node_name;
229  }
230  char * remapped_namespace = NULL;
232  &(node->impl->options.arguments), global_args, name,
233  *allocator, &remapped_namespace);
234  if (RCL_RET_OK != ret) {
235  goto fail;
236  } else if (NULL != remapped_namespace) {
237  if (should_free_local_namespace_) {
238  allocator->deallocate((char *)local_namespace_, allocator->state);
239  }
240  should_free_local_namespace_ = true;
241  local_namespace_ = remapped_namespace;
242  }
243 
244  // compute fully qualfied name of the node.
245  if ('/' == local_namespace_[strlen(local_namespace_) - 1]) {
246  node->impl->fq_name = rcutils_format_string(*allocator, "%s%s", local_namespace_, name);
247  } else {
248  node->impl->fq_name = rcutils_format_string(*allocator, "%s/%s", local_namespace_, name);
249  }
250 
251  // node logger name
252  node->impl->logger_name = rcl_create_node_logger_name(name, local_namespace_, allocator);
253  RCL_CHECK_FOR_NULL_WITH_MSG(
254  node->impl->logger_name, "creating logger name failed", goto fail);
255 
256  RCUTILS_LOG_DEBUG_NAMED(
257  ROS_PACKAGE_NAME, "Using domain ID of '%zu'", context->impl->rmw_context.actual_domain_id);
258 
259  node->impl->rmw_node_handle = rmw_create_node(
260  &(node->context->impl->rmw_context),
261  name, local_namespace_);
262 
263  RCL_CHECK_FOR_NULL_WITH_MSG(
264  node->impl->rmw_node_handle, rmw_get_error_string().str, goto fail);
265  // graph guard condition
266  rmw_graph_guard_condition = rmw_node_get_graph_guard_condition(node->impl->rmw_node_handle);
267  RCL_CHECK_FOR_NULL_WITH_MSG(
268  rmw_graph_guard_condition, rmw_get_error_string().str, goto fail);
269 
270  node->impl->graph_guard_condition = (rcl_guard_condition_t *)allocator->allocate(
271  sizeof(rcl_guard_condition_t), allocator->state);
272  RCL_CHECK_FOR_NULL_WITH_MSG(
273  node->impl->graph_guard_condition,
274  "allocating memory failed",
275  goto fail);
276  *node->impl->graph_guard_condition = rcl_get_zero_initialized_guard_condition();
277  graph_guard_condition_options.allocator = *allocator;
279  node->impl->graph_guard_condition,
280  rmw_graph_guard_condition,
281  context,
282  graph_guard_condition_options);
283  if (ret != RCL_RET_OK) {
284  // error message already set
285  goto fail;
286  }
287  // The initialization for the rosout publisher requires the node to be in initialized to a point
288  // that it can create new topic publishers
289  if (rcl_logging_rosout_enabled() && node->impl->options.enable_rosout) {
291  if (ret != RCL_RET_OK) {
292  // error message already set
293  goto fail;
294  }
295  }
296  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Node initialized");
297  ret = RCL_RET_OK;
298  TRACEPOINT(
300  (const void *)node,
301  (const void *)rcl_node_get_rmw_handle(node),
302  rcl_node_get_name(node),
303  rcl_node_get_namespace(node));
304  goto cleanup;
305 fail:
306  if (node->impl) {
308  node->impl->options.enable_rosout &&
309  node->impl->logger_name)
310  {
312  RCUTILS_LOG_ERROR_EXPRESSION_NAMED(
313  (ret != RCL_RET_OK && ret != RCL_RET_NOT_INIT),
314  ROS_PACKAGE_NAME, "Failed to fini publisher for node: %i", ret);
315  allocator->deallocate((char *)node->impl->logger_name, allocator->state);
316  }
317  if (node->impl->fq_name) {
318  allocator->deallocate((char *)node->impl->fq_name, allocator->state);
319  }
320  if (node->impl->rmw_node_handle) {
321  ret = rmw_destroy_node(node->impl->rmw_node_handle);
322  if (ret != RMW_RET_OK) {
323  RCUTILS_LOG_ERROR_NAMED(
324  ROS_PACKAGE_NAME,
325  "failed to fini rmw node in error recovery: %s", rmw_get_error_string().str
326  );
327  }
328  }
329  if (node->impl->graph_guard_condition) {
330  ret = rcl_guard_condition_fini(node->impl->graph_guard_condition);
331  if (ret != RCL_RET_OK) {
332  RCUTILS_LOG_ERROR_NAMED(
333  ROS_PACKAGE_NAME,
334  "failed to fini guard condition in error recovery: %s", rcl_get_error_string().str
335  );
336  }
337  allocator->deallocate(node->impl->graph_guard_condition, allocator->state);
338  }
339  if (NULL != node->impl->options.arguments.impl) {
340  ret = rcl_arguments_fini(&(node->impl->options.arguments));
341  if (ret != RCL_RET_OK) {
342  RCUTILS_LOG_ERROR_NAMED(
343  ROS_PACKAGE_NAME,
344  "failed to fini arguments in error recovery: %s", rcl_get_error_string().str
345  );
346  }
347  }
348  allocator->deallocate(node->impl, allocator->state);
349  }
351 
352  ret = fail_ret;
353  // fall through from fail -> cleanup
354 cleanup:
355  if (should_free_local_namespace_) {
356  allocator->deallocate((char *)local_namespace_, allocator->state);
357  local_namespace_ = NULL;
358  }
359  if (NULL != remapped_node_name) {
360  allocator->deallocate(remapped_node_name, allocator->state);
361  }
362  return ret;
363 }
364 
365 rcl_ret_t
367 {
368  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing node");
369  RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_NODE_INVALID);
370  if (!node->impl) {
371  // Repeat calls to fini or calling fini on a zero initialized node is ok.
372  return RCL_RET_OK;
373  }
374  rcl_allocator_t allocator = node->impl->options.allocator;
375  rcl_ret_t result = RCL_RET_OK;
376  rcl_ret_t rcl_ret = RCL_RET_OK;
377  if (rcl_logging_rosout_enabled() && node->impl->options.enable_rosout) {
379  if (rcl_ret != RCL_RET_OK && rcl_ret != RCL_RET_NOT_INIT) {
380  RCL_SET_ERROR_MSG("Unable to fini publisher for node.");
381  result = RCL_RET_ERROR;
382  }
383  }
384  rmw_ret_t rmw_ret = rmw_destroy_node(node->impl->rmw_node_handle);
385  if (rmw_ret != RMW_RET_OK) {
386  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
387  result = RCL_RET_ERROR;
388  }
389  rcl_ret = rcl_guard_condition_fini(node->impl->graph_guard_condition);
390  if (rcl_ret != RCL_RET_OK) {
391  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
392  result = RCL_RET_ERROR;
393  }
394  allocator.deallocate(node->impl->graph_guard_condition, allocator.state);
395  // assuming that allocate and deallocate are ok since they are checked in init
396  allocator.deallocate((char *)node->impl->logger_name, allocator.state);
397  allocator.deallocate((char *)node->impl->fq_name, allocator.state);
398  if (NULL != node->impl->options.arguments.impl) {
399  rcl_ret_t ret = rcl_arguments_fini(&(node->impl->options.arguments));
400  if (ret != RCL_RET_OK) {
401  return ret;
402  }
403  }
404  allocator.deallocate(node->impl, allocator.state);
405  node->impl = NULL;
406  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Node finalized");
407  return result;
408 }
409 
410 bool
412 {
413  RCL_CHECK_FOR_NULL_WITH_MSG(node, "rcl node pointer is invalid", return false);
414  RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "rcl node implementation is invalid", return false);
415  RCL_CHECK_FOR_NULL_WITH_MSG(
416  node->impl->rmw_node_handle, "rcl node's rmw handle is invalid", return false);
417  return true;
418 }
419 
420 bool
422 {
423  bool result = rcl_node_is_valid_except_context(node);
424  if (!result) {
425  return result;
426  }
427  if (!rcl_context_is_valid(node->context)) {
428  RCL_SET_ERROR_MSG("rcl node's context is invalid");
429  return false;
430  }
431  return true;
432 }
433 
434 const char *
436 {
438  return NULL; // error already set
439  }
440  return node->impl->rmw_node_handle->name;
441 }
442 
443 const char *
445 {
447  return NULL; // error already set
448  }
449  return node->impl->rmw_node_handle->namespace_;
450 }
451 
452 const char *
454 {
456  return NULL; // error already set
457  }
458  return node->impl->fq_name;
459 }
460 
461 const rcl_node_options_t *
463 {
465  return NULL; // error already set
466  }
467  return &node->impl->options;
468 }
469 
470 rcl_ret_t
471 rcl_node_get_domain_id(const rcl_node_t * node, size_t * domain_id)
472 {
473  if (!rcl_node_is_valid(node)) {
474  return RCL_RET_NODE_INVALID;
475  }
476  RCL_CHECK_ARGUMENT_FOR_NULL(domain_id, RCL_RET_INVALID_ARGUMENT);
477  rcl_ret_t ret = rcl_context_get_domain_id(node->context, domain_id);
478  if (RCL_RET_OK != ret) {
479  return ret;
480  }
481  return RCL_RET_OK;
482 }
483 
484 rmw_node_t *
486 {
488  return NULL; // error already set
489  }
490  return node->impl->rmw_node_handle;
491 }
492 
493 uint64_t
495 {
497  return 0; // error already set
498  }
499  return rcl_context_get_instance_id(node->context);
500 }
501 
502 const rcl_guard_condition_t *
504 {
506  return NULL; // error already set
507  }
508  return node->impl->graph_guard_condition;
509 }
510 
511 const char *
513 {
515  return NULL; // error already set
516  }
517  return node->impl->logger_name;
518 }
519 
520 rcl_ret_t
521 rcl_get_disable_loaned_message(bool * disable_loaned_message)
522 {
523  const char * env_val = NULL;
524  const char * env_error_str = NULL;
525 
526  RCL_CHECK_ARGUMENT_FOR_NULL(disable_loaned_message, RCL_RET_INVALID_ARGUMENT);
527 
528  env_error_str = rcutils_get_env(RCL_DISABLE_LOANED_MESSAGES_ENV_VAR, &env_val);
529  if (NULL != env_error_str) {
530  RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
531  "Error getting env var: '" RCUTILS_STRINGIFY(RCL_DISABLE_LOANED_MESSAGES_ENV_VAR) "': %s\n",
532  env_error_str);
533  return RCL_RET_ERROR;
534  }
535 
536  *disable_loaned_message = (strcmp(env_val, "1") == 0);
537  return RCL_RET_OK;
538 }
539 #ifdef __cplusplus
540 }
541 #endif
#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 rcl_ret_t rcl_arguments_fini(rcl_arguments_t *args)
Reclaim resources held inside rcl_arguments_t structure.
RCL_PUBLIC RCL_WARN_UNUSED rcl_context_instance_id_t rcl_context_get_instance_id(const rcl_context_t *context)
Returns an unsigned integer that is unique to the given context, or 0 if invalid.
Definition: context.c:76
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_context_get_domain_id(rcl_context_t *context, size_t *domain_id)
Returns the context domain id.
Definition: context.c:83
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 RCL_WARN_UNUSED rcl_guard_condition_t rcl_get_zero_initialized_guard_condition(void)
Return a rcl_guard_condition_t struct with members set to NULL.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_guard_condition_fini(rcl_guard_condition_t *guard_condition)
Finalize a rcl_guard_condition_t.
RCL_PUBLIC RCL_WARN_UNUSED rcl_guard_condition_options_t rcl_guard_condition_get_default_options(void)
Return the default options in a rcl_guard_condition_options_t struct.
rcl_ret_t rcl_guard_condition_init_from_rmw(rcl_guard_condition_t *guard_condition, const rmw_guard_condition_t *rmw_guard_condition, rcl_context_t *context, const rcl_guard_condition_options_t options)
Same as rcl_guard_condition_init(), but reusing an existing rmw handle.
RCL_PUBLIC RCL_WARN_UNUSED bool rcl_logging_rosout_enabled(void)
See if logging rosout is enabled.
Definition: logging.c:146
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_logging_rosout_init_publisher_for_node(rcl_node_t *node)
Creates a rosout publisher for a node and registers it to be used by the logging system.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_logging_rosout_fini_publisher_for_node(rcl_node_t *node)
Deregisters a rosout publisher for a node and cleans up allocated resources.
RCL_PUBLIC RCL_WARN_UNUSED const rcl_node_options_t * rcl_node_get_options(const rcl_node_t *node)
Return the rcl node options.
Definition: node.c:462
RCL_PUBLIC RCL_WARN_UNUSED rcl_node_t rcl_get_zero_initialized_node(void)
Return a rcl_node_t struct with members initialized to NULL.
Definition: node.c:107
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:435
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 rcl_ret_t rcl_node_fini(rcl_node_t *node)
Finalize a rcl_node_t.
Definition: node.c:366
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:444
RCL_PUBLIC RCL_WARN_UNUSED const rcl_guard_condition_t * rcl_node_get_graph_guard_condition(const rcl_node_t *node)
Return a guard condition which is triggered when the ROS graph changes.
Definition: node.c:503
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 const char * rcl_node_get_fully_qualified_name(const rcl_node_t *node)
Return the fully qualified name of the node.
Definition: node.c:453
RCL_PUBLIC RCL_WARN_UNUSED uint64_t rcl_node_get_rcl_instance_id(const rcl_node_t *node)
Return the associated rcl instance id.
Definition: node.c:494
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_node_get_domain_id(const rcl_node_t *node, size_t *domain_id)
Return the ROS domain ID that the node is using.
Definition: node.c:471
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:512
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_node_init(rcl_node_t *node, const char *name, const char *namespace_, rcl_context_t *context, const rcl_node_options_t *options)
Initialize a ROS node.
Definition: node.c:117
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_node_options_copy(const rcl_node_options_t *options, rcl_node_options_t *options_out)
Copy one options structure into another.
Definition: node_options.c:44
RCL_PUBLIC rcl_node_options_t rcl_node_get_default_options(void)
Return the default node options in a rcl_node_options_t.
Definition: node_options.c:30
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_remap_node_namespace(const rcl_arguments_t *local_arguments, const rcl_arguments_t *global_arguments, const char *node_name, rcl_allocator_t allocator, char **output_namespace)
Remap a namespace based on given rules.
Definition: remap.c:314
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_remap_node_name(const rcl_arguments_t *local_arguments, const rcl_arguments_t *global_arguments, const char *node_name, rcl_allocator_t allocator, char **output_name)
Remap a node name based on given rules.
Definition: remap.c:294
Hold output of parsing command line arguments.
Definition: arguments.h:36
rcl_arguments_impl_t * impl
Private implementation pointer.
Definition: arguments.h:38
rmw_context_t rmw_context
rmw context.
Definition: context_impl.h:40
Encapsulates the non-global state of an init/shutdown cycle.
Definition: context.h:114
rcl_context_impl_t * impl
Implementation specific pointer.
Definition: context.h:120
rcl_arguments_t global_arguments
Global arguments for all nodes which share this context.
Definition: context.h:117
Options available for a rcl guard condition.
rcl_allocator_t allocator
Custom allocator for the guard condition, used for internal allocations.
Handle for a rcl guard condition.
Structure which encapsulates the options for creating a rcl_node_t.
Definition: node_options.h:35
bool use_global_arguments
If false then only use arguments in this struct, otherwise use global arguments also.
Definition: node_options.h:47
rcl_arguments_t arguments
Command line arguments that apply only to this node.
Definition: node_options.h:50
bool enable_rosout
Flag to enable rosout for this node.
Definition: node_options.h:53
rcl_allocator_t allocator
If true, no parameter infrastructure will be setup.
Definition: node_options.h:44
Structure which encapsulates a ROS Node.
Definition: node.h:42
rcl_node_impl_t * impl
Private implementation pointer.
Definition: node.h:47
rcl_context_t * context
Context associated with this node.
Definition: node.h:44
#define RCL_RET_NODE_INVALID_NAMESPACE
Invalid node namespace return code.
Definition: types.h:60
#define RCL_RET_NOT_INIT
rcl_init() not yet called return code.
Definition: types.h:42
#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
#define RCL_RET_NODE_INVALID
Invalid rcl_node_t given return code.
Definition: types.h:56
#define RCL_RET_NODE_INVALID_NAME
Invalid node name return code.
Definition: types.h:58
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:23