ROS 2 rclcpp + rcl - rolling  rolling-e7363f10
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 #include "rcl/node.h"
16 
17 #include <stdbool.h>
18 #include <stddef.h>
19 #include <stdint.h>
20 #include <string.h>
21 
22 #include "rcl/allocator.h"
23 #include "rcl/arguments.h"
24 #include "rcl/error_handling.h"
25 #include "rcl/init_options.h"
26 #include "rcl/logging.h"
27 #include "rcl/logging_rosout.h"
28 #include "rcl/guard_condition.h"
29 #include "rcl/node_options.h"
30 #include "rcl/node_type_cache.h"
31 #include "rcl/remap.h"
32 #include "rcl/security.h"
33 #include "rcl/service.h"
34 #include "rcl/types.h"
35 
36 #include "rcutils/env.h"
37 #include "rcutils/format_string.h"
38 #include "rcutils/logging.h"
39 #include "rcutils/logging_macros.h"
40 #include "rcutils/macros.h"
41 #include "rcutils/repl_str.h"
42 #include "rcutils/strdup.h"
43 #include "rcutils/types/hash_map.h"
44 #include "rcutils/types/rcutils_ret.h"
45 
46 #include "rmw/error_handling.h"
47 #include "rmw/ret_types.h"
48 #include "rmw/rmw.h"
49 #include "rmw/types.h"
50 #include "rmw/validate_namespace.h"
51 #include "rmw/validate_node_name.h"
52 #include "rosidl_runtime_c/string_functions.h"
53 #include "rosidl_runtime_c/type_description/type_description__functions.h"
54 #include "rosidl_runtime_c/type_description/type_source__functions.h"
55 #include "tracetools/tracetools.h"
56 #include "type_description_interfaces/srv/get_type_description.h"
57 
58 #include "./context_impl.h"
59 #include "./node_impl.h"
60 
61 const char * const RCL_DISABLE_LOANED_MESSAGES_ENV_VAR = "ROS_DISABLE_LOANED_MESSAGES";
62 
64 
73 const char * rcl_create_node_logger_name(
74  const char * node_name,
75  const char * node_namespace,
76  const rcl_allocator_t * allocator)
77 {
78  // If the namespace is the root namespace ("/"), the logger name is just the node name.
79  if (strlen(node_namespace) == 1) {
80  return rcutils_strdup(node_name, *allocator);
81  }
82 
83  // Convert the forward slashes in the namespace to the separator used for logger names.
84  // The input namespace has already been expanded and therefore will always be absolute,
85  // i.e. it will start with a forward slash, which we want to ignore.
86  const char * ns_with_separators = rcutils_repl_str(
87  node_namespace + 1, // Ignore the leading forward slash.
88  "/", RCUTILS_LOGGING_SEPARATOR_STRING,
89  allocator);
90  if (NULL == ns_with_separators) {
91  return NULL;
92  }
93 
94  // Join the namespace and node name to create the logger name.
95  char * node_logger_name = rcutils_format_string(
96  *allocator, "%s%s%s", ns_with_separators, RCUTILS_LOGGING_SEPARATOR_STRING, node_name);
97  allocator->deallocate((char *)ns_with_separators, allocator->state);
98  return node_logger_name;
99 }
100 
103 {
104  // All members are initialized to 0 or NULL by C99 6.7.8/10.
105  static rcl_node_t null_node;
106  return null_node;
107 }
108 
109 rcl_ret_t
111  rcl_node_t * node,
112  const char * name,
113  const char * namespace_,
114  rcl_context_t * context,
115  const rcl_node_options_t * options)
116 {
117  const rmw_guard_condition_t * rmw_graph_guard_condition = NULL;
118  rcl_guard_condition_options_t graph_guard_condition_options =
120  rcl_ret_t ret;
121  rcl_ret_t fail_ret = RCL_RET_ERROR;
122  char * remapped_node_name = NULL;
123  const char * local_namespace_ = NULL;
124 
125  // Check options and allocator first, so allocator can be used for errors.
126  RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT);
127  const rcl_allocator_t * allocator = &options->allocator;
128  RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
129 
130  RCL_CHECK_ARGUMENT_FOR_NULL(name, RCL_RET_INVALID_ARGUMENT);
131  RCL_CHECK_ARGUMENT_FOR_NULL(namespace_, RCL_RET_INVALID_ARGUMENT);
132  RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
133  RCUTILS_LOG_DEBUG_NAMED(
134  ROS_PACKAGE_NAME, "Initializing node '%s' in namespace '%s'", name, namespace_);
135  if (node->impl) {
136  RCL_SET_ERROR_MSG("node already initialized, or struct memory was unintialized");
137  return RCL_RET_ALREADY_INIT;
138  }
139  // Make sure rcl has been initialized.
140  RCL_CHECK_FOR_NULL_WITH_MSG(
141  context, "given context in options is NULL", return RCL_RET_INVALID_ARGUMENT);
142  if (!rcl_context_is_valid(context)) {
143  RCL_SET_ERROR_MSG(
144  "the given context is not valid, "
145  "either rcl_init() was not called or rcl_shutdown() was called.");
146  return RCL_RET_NOT_INIT;
147  }
148  // Make sure the node name is valid before allocating memory.
149  int validation_result = 0;
150  ret = rmw_validate_node_name(name, &validation_result, NULL);
151  if (ret != RMW_RET_OK) {
152  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
153  return ret;
154  }
155  if (validation_result != RMW_NODE_NAME_VALID) {
156  const char * msg = rmw_node_name_validation_result_string(validation_result);
157  RCL_SET_ERROR_MSG(msg);
159  }
160 
161  // Process the namespace.
162  if (namespace_[0] == '\0') {
163  // If the namespace is just an empty string, replace with "/"
164  local_namespace_ = rcutils_strdup("/", *allocator);
165  } else if (namespace_[0] == '/') {
166  local_namespace_ = rcutils_strdup(namespace_, *allocator);
167  } else {
168  // If the namespace does not start with a /, add one.
169  local_namespace_ = rcutils_format_string(*allocator, "/%s", namespace_);
170  }
171  RCL_CHECK_FOR_NULL_WITH_MSG(
172  local_namespace_,
173  "failed to format node namespace string",
174  return RCL_RET_BAD_ALLOC);
175 
176  // Make sure the node namespace is valid.
177  validation_result = 0;
178  ret = rmw_validate_namespace(local_namespace_, &validation_result, NULL);
179  if (ret != RMW_RET_OK) {
180  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
181  goto fail;
182  }
183  if (validation_result != RMW_NAMESPACE_VALID) {
184  const char * msg = rmw_namespace_validation_result_string(validation_result);
185  RCL_SET_ERROR_MSG_WITH_FORMAT_STRING("%s, result: %d", msg, validation_result);
186 
188  goto fail;
189  }
190 
191  // Allocate space for the implementation struct.
192  node->impl = (rcl_node_impl_t *)allocator->zero_allocate(
193  1, sizeof(rcl_node_impl_t), allocator->state);
194  RCL_CHECK_FOR_NULL_WITH_MSG(
195  node->impl, "allocating memory failed", ret = RCL_RET_BAD_ALLOC; goto fail);
196  node->impl->options = rcl_node_get_default_options();
197  node->impl->registered_types_by_type_hash = rcutils_get_zero_initialized_hash_map();
198  node->context = context;
199  // Initialize node impl.
200  ret = rcl_node_options_copy(options, &(node->impl->options));
201  if (RCL_RET_OK != ret) {
202  goto fail;
203  }
204 
205  // Remap the node name and namespace if remap rules are given
206  rcl_arguments_t * global_args = NULL;
207  if (node->impl->options.use_global_arguments) {
208  global_args = &(node->context->global_arguments);
209  }
210  ret = rcl_remap_node_name(
211  &(node->impl->options.arguments), global_args, name, *allocator,
212  &remapped_node_name);
213  if (RCL_RET_OK != ret) {
214  goto fail;
215  }
216  if (NULL != remapped_node_name) {
217  name = remapped_node_name;
218  }
219 
220  char * remapped_namespace = NULL;
222  &(node->impl->options.arguments), global_args, name,
223  *allocator, &remapped_namespace);
224  if (RCL_RET_OK != ret) {
225  goto fail;
226  }
227  if (NULL != remapped_namespace) {
228  allocator->deallocate((char *)local_namespace_, allocator->state);
229  local_namespace_ = remapped_namespace;
230  }
231 
232  // compute fully qualfied name of the node.
233  if ('/' == local_namespace_[strlen(local_namespace_) - 1]) {
234  node->impl->fq_name = rcutils_format_string(*allocator, "%s%s", local_namespace_, name);
235  } else {
236  node->impl->fq_name = rcutils_format_string(*allocator, "%s/%s", local_namespace_, name);
237  }
238  RCL_CHECK_FOR_NULL_WITH_MSG(
239  node->impl->fq_name, "creating fully qualified name failed",
240  ret = RCL_RET_BAD_ALLOC; goto fail);
241 
242  // node logger name
243  node->impl->logger_name = rcl_create_node_logger_name(name, local_namespace_, allocator);
244  RCL_CHECK_FOR_NULL_WITH_MSG(
245  node->impl->logger_name, "creating logger name failed", ret = RCL_RET_ERROR; goto fail);
246 
247  RCUTILS_LOG_DEBUG_NAMED(
248  ROS_PACKAGE_NAME, "Using domain ID of '%zu'", context->impl->rmw_context.actual_domain_id);
249 
250  node->impl->rmw_node_handle = rmw_create_node(
251  &(node->context->impl->rmw_context),
252  name, local_namespace_);
253  if (NULL == node->impl->rmw_node_handle) {
254  // Preserve the error set by rmw_create_node rather than overwriting it.
255  RCL_EXPECT_ERROR_IS_SET(RCL_RET_ERROR);
256  ret = RCL_RET_ERROR;
257  goto fail;
258  }
259 
260  // graph guard condition
261  rmw_graph_guard_condition = rmw_node_get_graph_guard_condition(node->impl->rmw_node_handle);
262  if (NULL == rmw_graph_guard_condition) {
263  // Preserve the error set by rmw_node_get_graph_guard_condition.
264  RCL_EXPECT_ERROR_IS_SET(RCL_RET_ERROR);
265  ret = RCL_RET_ERROR;
266  goto fail;
267  }
268 
269  node->impl->graph_guard_condition = (rcl_guard_condition_t *)allocator->allocate(
270  sizeof(rcl_guard_condition_t), allocator->state);
271  RCL_CHECK_FOR_NULL_WITH_MSG(
272  node->impl->graph_guard_condition, "allocating memory failed",
273  ret = RCL_RET_BAD_ALLOC; goto fail);
274  *node->impl->graph_guard_condition = rcl_get_zero_initialized_guard_condition();
275  graph_guard_condition_options.allocator = *allocator;
277  node->impl->graph_guard_condition,
278  rmw_graph_guard_condition,
279  context,
280  graph_guard_condition_options);
281  if (ret != RCL_RET_OK) {
282  // error message already set
283  goto fail;
284  }
285 
286  // To capture all types from builtin topics and services, the type cache needs to be initialized
287  // before any publishers/subscriptions/services/etc can be created
288  ret = rcl_node_type_cache_init(node);
289  if (ret != RCL_RET_OK) {
290  goto fail;
291  }
292 
293  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Node initialized");
294  TRACETOOLS_TRACEPOINT(
296  (const void *)node,
297  (const void *)rcl_node_get_rmw_handle(node),
298  rcl_node_get_name(node),
299  rcl_node_get_namespace(node));
300 
301  allocator->deallocate(remapped_node_name, allocator->state);
302  allocator->deallocate((char *)local_namespace_, allocator->state);
303 
304  return RCL_RET_OK;
305 
306 fail:
307  if (node->impl) {
308  if (NULL != node->impl->registered_types_by_type_hash.impl) {
309  fail_ret = rcl_node_type_cache_fini(node);
310  RCUTILS_LOG_ERROR_EXPRESSION_NAMED(
311  (fail_ret != RCL_RET_OK),
312  ROS_PACKAGE_NAME, "Failed to fini type cache for node: %s", rcl_get_error_string().str);
313  }
314 
315  if (node->impl->graph_guard_condition) {
316  fail_ret = rcl_guard_condition_fini(node->impl->graph_guard_condition);
317  RCUTILS_LOG_ERROR_EXPRESSION_NAMED(
318  fail_ret != RCL_RET_OK, ROS_PACKAGE_NAME,
319  "failed to fini guard condition in error recovery: %s", rcl_get_error_string().str);
320 
321  allocator->deallocate(node->impl->graph_guard_condition, allocator->state);
322  }
323 
324  if (node->impl->rmw_node_handle) {
325  fail_ret = rmw_destroy_node(node->impl->rmw_node_handle);
326  RCUTILS_LOG_ERROR_EXPRESSION_NAMED(
327  fail_ret != RMW_RET_OK, ROS_PACKAGE_NAME,
328  "failed to fini rmw node in error recovery: %s", rmw_get_error_string().str);
329  }
330 
331  allocator->deallocate((char *)node->impl->logger_name, allocator->state);
332 
333  allocator->deallocate((char *)node->impl->fq_name, allocator->state);
334 
335  fail_ret = rcl_node_options_fini(&(node->impl->options));
336  RCUTILS_LOG_ERROR_EXPRESSION_NAMED(
337  fail_ret != RCL_RET_OK, ROS_PACKAGE_NAME,
338  "failed to fini node options: %s", rcl_get_error_string().str);
339 
340  allocator->deallocate(node->impl, allocator->state);
341  }
342 
343  allocator->deallocate(remapped_node_name, allocator->state);
344 
345  allocator->deallocate((char *)local_namespace_, allocator->state);
346 
348 
349  return ret;
350 }
351 
352 rcl_ret_t
354 {
355  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing node");
356  RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_NODE_INVALID);
357  if (!node->impl) {
358  // Repeat calls to fini or calling fini on a zero initialized node is ok.
359  return RCL_RET_OK;
360  }
361  rcl_allocator_t allocator = node->impl->options.allocator;
362  rcl_ret_t result = RCL_RET_OK;
363  rcl_ret_t rcl_ret = RCL_RET_OK;
364  rcl_ret = rcl_node_type_cache_fini(node);
365  if (rcl_ret != RCL_RET_OK) {
366  RCL_SET_ERROR_MSG("Unable to fini type cache for node.");
367  result = RCL_RET_ERROR;
368  }
369  rmw_ret_t rmw_ret = rmw_destroy_node(node->impl->rmw_node_handle);
370  if (rmw_ret != RMW_RET_OK) {
371  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
372  result = RCL_RET_ERROR;
373  }
374  rcl_ret = rcl_guard_condition_fini(node->impl->graph_guard_condition);
375  if (rcl_ret != RCL_RET_OK) {
376  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
377  result = RCL_RET_ERROR;
378  }
379  allocator.deallocate(node->impl->graph_guard_condition, allocator.state);
380  // assuming that allocate and deallocate are ok since they are checked in init
381  allocator.deallocate((char *)node->impl->logger_name, allocator.state);
382  allocator.deallocate((char *)node->impl->fq_name, allocator.state);
383  if (NULL != node->impl->options.arguments.impl) {
384  rcl_ret_t ret = rcl_arguments_fini(&(node->impl->options.arguments));
385  if (ret != RCL_RET_OK) {
386  return ret;
387  }
388  }
389  allocator.deallocate(node->impl, allocator.state);
390  node->impl = NULL;
391  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Node finalized");
392  return result;
393 }
394 
395 bool
397 {
398  RCL_CHECK_FOR_NULL_WITH_MSG(node, "rcl node pointer is invalid", return false);
399  RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "rcl node implementation is invalid", return false);
400  RCL_CHECK_FOR_NULL_WITH_MSG(
401  node->impl->rmw_node_handle, "rcl node's rmw handle is invalid", return false);
402  return true;
403 }
404 
405 bool
407 {
408  bool result = rcl_node_is_valid_except_context(node);
409  if (!result) {
410  return result;
411  }
412  if (!rcl_context_is_valid(node->context)) {
413  RCL_SET_ERROR_MSG("rcl node's context is invalid");
414  return false;
415  }
416  return true;
417 }
418 
419 const char *
421 {
423  return NULL; // error already set
424  }
425  return node->impl->rmw_node_handle->name;
426 }
427 
428 const char *
430 {
432  return NULL; // error already set
433  }
434  return node->impl->rmw_node_handle->namespace_;
435 }
436 
437 const char *
439 {
441  return NULL; // error already set
442  }
443  return node->impl->fq_name;
444 }
445 
446 const rcl_node_options_t *
448 {
450  return NULL; // error already set
451  }
452  return &node->impl->options;
453 }
454 
455 rcl_ret_t
456 rcl_node_get_domain_id(const rcl_node_t * node, size_t * domain_id)
457 {
458  if (!rcl_node_is_valid(node)) {
459  return RCL_RET_NODE_INVALID;
460  }
461  RCL_CHECK_ARGUMENT_FOR_NULL(domain_id, RCL_RET_INVALID_ARGUMENT);
462  rcl_ret_t ret = rcl_context_get_domain_id(node->context, domain_id);
463  if (RCL_RET_OK != ret) {
464  return ret;
465  }
466  return RCL_RET_OK;
467 }
468 
469 rmw_node_t *
471 {
473  return NULL; // error already set
474  }
475  return node->impl->rmw_node_handle;
476 }
477 
478 uint64_t
480 {
482  return 0; // error already set
483  }
484  return rcl_context_get_instance_id(node->context);
485 }
486 
487 const rcl_guard_condition_t *
489 {
491  return NULL; // error already set
492  }
493  return node->impl->graph_guard_condition;
494 }
495 
496 const char *
498 {
500  return NULL; // error already set
501  }
502  return node->impl->logger_name;
503 }
504 
505 rcl_ret_t
506 rcl_get_disable_loaned_message(bool * disable_loaned_message)
507 {
508  const char * env_val = NULL;
509  const char * env_error_str = NULL;
510 
511  RCL_CHECK_ARGUMENT_FOR_NULL(disable_loaned_message, RCL_RET_INVALID_ARGUMENT);
512 
513  env_error_str = rcutils_get_env(RCL_DISABLE_LOANED_MESSAGES_ENV_VAR, &env_val);
514  if (NULL != env_error_str) {
515  RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
516  "Error getting env var: '" RCUTILS_STRINGIFY(RCL_DISABLE_LOANED_MESSAGES_ENV_VAR) "': %s\n",
517  env_error_str);
518  return RCL_RET_ERROR;
519  }
520 
521  *disable_loaned_message = (strcmp(env_val, "1") == 0);
522  return RCL_RET_OK;
523 }
524 
526  rcl_node_t * node,
527  const rmw_request_id_t * request_header,
528  const type_description_interfaces__srv__GetTypeDescription_Request * request,
529  type_description_interfaces__srv__GetTypeDescription_Response * response)
530 {
531  rcl_type_info_t type_info;
532  RCL_CHECK_FOR_NULL_WITH_MSG(node, "invalid node handle", return;);
533  RCL_CHECK_FOR_NULL_WITH_MSG(node->impl, "invalid node", return;);
534  RCL_CHECK_FOR_NULL_WITH_MSG(request_header, "invalid request header", return;);
535  RCL_CHECK_FOR_NULL_WITH_MSG(request, "null request pointer", return;);
536  RCL_CHECK_FOR_NULL_WITH_MSG(response, "null response pointer", return;);
537 
538  if (!type_description_interfaces__srv__GetTypeDescription_Response__init(response)) {
539  RCUTILS_LOG_ERROR_NAMED(
540  ROS_PACKAGE_NAME,
541  "Failed to initialize service response.");
542  return;
543  }
544  response->successful = false;
545 
546  rosidl_type_hash_t type_hash;
547  if (RCUTILS_RET_OK !=
548  rosidl_parse_type_hash_string(request->type_hash.data, &type_hash))
549  {
550  RCUTILS_LOG_ERROR_NAMED(
551  ROS_PACKAGE_NAME, "Failed to parse type hash '%s'",
552  request->type_hash.data);
553  rosidl_runtime_c__String__assign(
554  &response->failure_reason,
555  "Failed to parse type hash");
556  return;
557  }
558 
559  if (RCUTILS_RET_OK !=
560  rcl_node_type_cache_get_type_info(node, &type_hash, &type_info))
561  {
562  rosidl_runtime_c__String__assign(
563  &response->failure_reason,
564  "Type not currently in use by this node");
565  return;
566  }
567 
568  if (!type_description_interfaces__msg__TypeDescription__copy(
569  type_info.type_description, &response->type_description))
570  {
571  rosidl_runtime_c__String__assign(
572  &response->failure_reason,
573  "Failed to populate TypeDescription to response.");
574  return;
575  }
576 
577  if (request->include_type_sources) {
578  if (!type_description_interfaces__msg__TypeSource__Sequence__copy(
579  type_info.type_sources, &response->type_sources))
580  {
581  rosidl_runtime_c__String__assign(
582  &response->failure_reason,
583  "Failed to populate TypeSource_Sequence to response.");
584  return;
585  }
586  }
587 
588  response->successful = true;
589 }
590 
592  rcl_service_t * service,
593  const rcl_node_t * node)
594 {
595  RCL_CHECK_ARGUMENT_FOR_NULL(service, RCL_RET_INVALID_ARGUMENT);
596  RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
597  RCL_CHECK_ARGUMENT_FOR_NULL(node->impl, RCL_RET_NODE_INVALID);
598 
599  if (rcl_service_is_valid(service)) {
600  return RCL_RET_ALREADY_INIT;
601  }
602  rcl_reset_error(); // Reset the error message set by rcl_service_is_valid()
603 
604  char * service_name = NULL;
605  const rosidl_service_type_support_t * type_support =
606  ROSIDL_GET_SRV_TYPE_SUPPORT(
607  type_description_interfaces, srv,
608  GetTypeDescription);
610  rcl_allocator_t allocator = node->context->impl->allocator;
611 
612  // Construct service name
614  node, "~/get_type_description",
615  allocator, true, true, &service_name);
616  if (RCL_RET_OK != ret) {
617  RCL_SET_ERROR_MSG(
618  "Failed to construct ~/get_type_description service name");
619  return ret;
620  }
621 
622  // Initialize service
623  ret = rcl_service_init(
624  service, node,
625  type_support, service_name, &service_ops);
626  allocator.deallocate(service_name, allocator.state);
627 
628  return ret;
629 }
#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:88
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:95
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:106
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 const rcl_node_options_t * rcl_node_get_options(const rcl_node_t *node)
Return the rcl node options.
Definition: node.c:447
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_node_type_description_service_init(rcl_service_t *service, const rcl_node_t *node)
Initialize the node's ~/get_type_description service.
Definition: node.c:591
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:102
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:420
RCL_PUBLIC bool rcl_node_is_valid(const rcl_node_t *node)
Return true if the node is valid, else false.
Definition: node.c:406
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:506
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_node_fini(rcl_node_t *node)
Finalize a rcl_node_t.
Definition: node.c:353
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:429
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:488
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:470
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:438
RCL_PUBLIC void rcl_node_type_description_service_handle_request(rcl_node_t *node, const rmw_request_id_t *request_header, const type_description_interfaces__srv__GetTypeDescription_Request *request, type_description_interfaces__srv__GetTypeDescription_Response *response)
Process a single pending request to the GetTypeDescription service.
Definition: node.c:525
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:479
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:456
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:497
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:110
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:396
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:49
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:35
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_node_options_fini(rcl_node_options_t *options)
Finalize the given node_options.
Definition: node_options.c:76
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:321
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:301
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_service_init(rcl_service_t *service, const rcl_node_t *node, const rosidl_service_type_support_t *type_support, const char *service_name, const rcl_service_options_t *options)
Initialize a rcl service.
Definition: service.c:81
RCL_PUBLIC bool rcl_service_is_valid(const rcl_service_t *service)
Check that the service is valid.
Definition: service.c:421
RCL_PUBLIC RCL_WARN_UNUSED rcl_service_options_t rcl_service_get_default_options(void)
Return the default service options in a rcl_service_options_t.
Definition: service.c:282
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:46
rcl_allocator_t allocator
Allocator used during init and shutdown.
Definition: context_impl.h:38
Encapsulates the non-global state of an init/shutdown cycle.
Definition: context.h:117
rcl_context_impl_t * impl
Implementation specific pointer.
Definition: context.h:123
rcl_arguments_t global_arguments
Global arguments for all nodes which share this context.
Definition: context.h:120
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:41
bool use_global_arguments
If false then only use arguments in this struct, otherwise use global arguments also.
Definition: node_options.h:53
rcl_arguments_t arguments
Command line arguments that apply only to this node.
Definition: node_options.h:56
rcl_allocator_t allocator
If true, no parameter infrastructure will be setup.
Definition: node_options.h:50
Structure which encapsulates a ROS Node.
Definition: node.h:49
rcl_node_impl_t * impl
Private implementation pointer.
Definition: node.h:54
rcl_context_t * context
Context associated with this node.
Definition: node.h:51
Options available for a rcl service.
Definition: service.h:53
Structure which encapsulates a ROS Service.
Definition: service.h:46
#define RCL_RET_NODE_INVALID_NAMESPACE
Invalid node namespace return code.
Definition: types.h:64
#define RCL_RET_NOT_INIT
rcl_init() not yet called return code.
Definition: types.h:44
#define RCL_RET_ALREADY_INIT
rcl_init() already called return code.
Definition: types.h:42
#define RCL_RET_OK
Success return code.
Definition: types.h:28
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
Definition: types.h:34
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
Definition: types.h:36
#define RCL_RET_ERROR
Unspecified error return code.
Definition: types.h:30
#define RCL_RET_NODE_INVALID
Invalid rcl_node_t given return code.
Definition: types.h:60
#define RCL_RET_NODE_INVALID_NAME
Invalid node name return code.
Definition: types.h:62
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:25