ROS 2 rclcpp + rcl - lyrical  lyrical
ROS 2 C++ Client Library with ROS Client Library
service.c
1 // Copyright 2016 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/service.h"
21 
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include "rcl/error_handling.h"
26 #include "rcl/node.h"
27 #include "rcl/node_type_cache.h"
28 #include "rcl/publisher.h"
29 #include "rcl/time.h"
30 #include "rcl/types.h"
31 #include "rcutils/logging_macros.h"
32 #include "rcutils/macros.h"
33 #include "rmw/error_handling.h"
34 #include "rmw/rmw.h"
35 #include "service_msgs/msg/service_event_info.h"
36 #include "tracetools/tracetools.h"
37 
38 #include "rosidl_runtime_c/service_type_support_struct.h"
39 
40 #include "./common.h"
41 #include "./service_event_publisher.h"
42 #include "./service_impl.h"
43 
46 {
47  // All members are initialized to 0 or NULL by C99 6.7.8/10.
48  static rcl_service_t null_service;
49  return null_service;
50 }
51 
52 static
54 unconfigure_service_introspection(
55  rcl_node_t * node,
56  struct rcl_service_impl_s * service_impl,
57  rcl_allocator_t * allocator)
58 {
59  if (service_impl == NULL) {
60  return RCL_RET_ERROR;
61  }
62 
63  if (service_impl->service_event_publisher == NULL) {
64  return RCL_RET_OK;
65  }
66 
67  rcl_ret_t ret = rcl_service_event_publisher_fini(service_impl->service_event_publisher, node);
68 
69  allocator->deallocate(service_impl->service_event_publisher, allocator->state);
70  service_impl->service_event_publisher = NULL;
71 
72  return ret;
73 }
74 
77  rcl_service_t * service,
78  const rcl_node_t * node,
79  const rosidl_service_type_support_t * type_support,
80  const char * service_name,
81  const rcl_service_options_t * options)
82 {
83  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
84  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ALREADY_INIT);
85  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
86  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_BAD_ALLOC);
87  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
88  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_SERVICE_NAME_INVALID);
89 
90  // Check options and allocator first, so the allocator can be used in errors.
91  RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT);
92  rcl_allocator_t * allocator = (rcl_allocator_t *)&options->allocator;
93  RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
94 
95  RCL_CHECK_ARGUMENT_FOR_NULL(service, RCL_RET_INVALID_ARGUMENT);
96  if (!rcl_node_is_valid(node)) {
97  return RCL_RET_NODE_INVALID; // error already set
98  }
99  RCL_CHECK_ARGUMENT_FOR_NULL(type_support, RCL_RET_INVALID_ARGUMENT);
100  RCL_CHECK_ARGUMENT_FOR_NULL(service_name, RCL_RET_INVALID_ARGUMENT);
101  RCUTILS_LOG_DEBUG_NAMED(
102  ROS_PACKAGE_NAME, "Initializing service for service name '%s'", service_name);
103  if (service->impl) {
104  RCL_SET_ERROR_MSG("service already initialized, or memory was unintialized");
105  return RCL_RET_ALREADY_INIT;
106  }
107 
108  // Allocate space for the implementation struct.
109  service->impl = (rcl_service_impl_t *)allocator->zero_allocate(
110  1, sizeof(rcl_service_impl_t), allocator->state);
111  RCL_CHECK_FOR_NULL_WITH_MSG(
112  service->impl, "allocating memory failed",
113  return RCL_RET_BAD_ALLOC;);
114 
115  // Expand and remap the given service name.
117  node,
118  service_name,
119  *allocator,
120  true,
121  false,
122  &service->impl->remapped_service_name);
123  if (ret != RCL_RET_OK) {
126  } else if (ret != RCL_RET_BAD_ALLOC) {
127  ret = RCL_RET_ERROR;
128  }
129  goto free_service_impl;
130  }
131  RCUTILS_LOG_DEBUG_NAMED(
132  ROS_PACKAGE_NAME, "Expanded and remapped service name '%s'",
133  service->impl->remapped_service_name);
134 
135  if (RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL == options->qos.durability) {
136  RCUTILS_LOG_WARN_NAMED(
137  ROS_PACKAGE_NAME,
138  "Warning: Setting QoS durability to 'transient local' for service servers "
139  "can cause them to receive requests from clients that have since terminated.");
140  }
141  // Fill out implementation struct.
142  // rmw handle (create rmw service)
143  // TODO(wjwwood): pass along the allocator to rmw when it supports it
144  service->impl->rmw_handle = rmw_create_service(
146  type_support,
147  service->impl->remapped_service_name,
148  &options->qos);
149  if (!service->impl->rmw_handle) {
150  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
151  ret = RCL_RET_ERROR;
152  goto free_remapped_service_name;
153  }
154 
155  // get actual qos, and store it
156  rmw_ret_t rmw_ret = rmw_service_request_subscription_get_actual_qos(
157  service->impl->rmw_handle,
158  &service->impl->actual_request_subscription_qos);
159  if (RMW_RET_OK != rmw_ret) {
160  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
161  ret = rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
162  goto destroy_service;
163  }
164 
165  rmw_ret = rmw_service_response_publisher_get_actual_qos(
166  service->impl->rmw_handle,
167  &service->impl->actual_response_publisher_qos);
168  if (RMW_RET_OK != rmw_ret) {
169  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
170  ret = rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
171  goto destroy_service;
172  }
173 
174  // ROS specific namespacing conventions is not retrieved by get_actual_qos
175  service->impl->actual_request_subscription_qos.avoid_ros_namespace_conventions =
176  options->qos.avoid_ros_namespace_conventions;
177  service->impl->actual_response_publisher_qos.avoid_ros_namespace_conventions =
178  options->qos.avoid_ros_namespace_conventions;
179 
180  // options
181  service->impl->options = *options;
182  service->impl->in_use_by_waitset = false;
183 
184  if (RCL_RET_OK != rcl_node_type_cache_register_type(
185  node, type_support->get_type_hash_func(type_support),
186  type_support->get_type_description_func(type_support),
187  type_support->get_type_description_sources_func(type_support)))
188  {
189  rcutils_reset_error();
190  RCL_SET_ERROR_MSG("Failed to register type for service");
191  ret = RCL_RET_ERROR;
192  goto destroy_service;
193  }
194  service->impl->type_hash = *type_support->get_type_hash_func(type_support);
195 
196  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Service initialized");
197  TRACETOOLS_TRACEPOINT(
199  (const void *)service,
200  (const void *)node,
201  (const void *)service->impl->rmw_handle,
202  service->impl->remapped_service_name);
203 
204  return RCL_RET_OK;
205 
206 destroy_service:
207  rmw_ret = rmw_destroy_service(rcl_node_get_rmw_handle(node), service->impl->rmw_handle);
208  if (RMW_RET_OK != rmw_ret) {
209  RCUTILS_SAFE_FWRITE_TO_STDERR(rmw_get_error_string().str);
210  RCUTILS_SAFE_FWRITE_TO_STDERR("\n");
211  }
212 
213 free_remapped_service_name:
214  allocator->deallocate(service->impl->remapped_service_name, allocator->state);
215  service->impl->remapped_service_name = NULL;
216 
217 free_service_impl:
218  allocator->deallocate(service->impl, allocator->state);
219  service->impl = NULL;
220 
221  return ret;
222 }
223 
224 rcl_ret_t
226 {
227  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_SERVICE_INVALID);
228  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
229  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
230  RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
231 
232  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing service");
233  RCL_CHECK_ARGUMENT_FOR_NULL(service, RCL_RET_SERVICE_INVALID);
235  return RCL_RET_NODE_INVALID; // error already set
236  }
237 
238  rcl_ret_t result = RCL_RET_OK;
239  if (service->impl) {
240  rcl_allocator_t allocator = service->impl->options.allocator;
241  rmw_node_t * rmw_node = rcl_node_get_rmw_handle(node);
242  if (!rmw_node) {
244  }
245 
246  rcl_ret_t rcl_ret = unconfigure_service_introspection(node, service->impl, &allocator);
247  if (RCL_RET_OK != rcl_ret) {
248  RCL_SET_ERROR_MSG(rcl_get_error_string().str);
249  result = rcl_ret;
250  }
251 
252  rmw_ret_t ret = rmw_destroy_service(rmw_node, service->impl->rmw_handle);
253  if (ret != RMW_RET_OK) {
254  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
255  result = RCL_RET_ERROR;
256  }
257 
258  if (
259  ROSIDL_TYPE_HASH_VERSION_UNSET != service->impl->type_hash.version &&
260  RCL_RET_OK != rcl_node_type_cache_unregister_type(node, &service->impl->type_hash))
261  {
262  RCUTILS_SAFE_FWRITE_TO_STDERR(rcl_get_error_string().str);
263  result = RCL_RET_ERROR;
264  }
265 
266  allocator.deallocate(service->impl->remapped_service_name, allocator.state);
267  service->impl->remapped_service_name = NULL;
268 
269  allocator.deallocate(service->impl, allocator.state);
270  service->impl = NULL;
271  }
272  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Service finalized");
273  return result;
274 }
275 
278 {
279  // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING
280  rcl_service_options_t default_options;
281  // Must set the allocator and qos after because they are not a compile time constant.
282  default_options.qos = rmw_qos_profile_services_default;
283  default_options.allocator = rcl_get_default_allocator();
284  return default_options;
285 }
286 
287 const char *
289 {
290  const rcl_service_options_t * options = rcl_service_get_options(service);
291  if (!options) {
292  return NULL;
293  }
294  RCL_CHECK_FOR_NULL_WITH_MSG(service->impl->rmw_handle, "service is invalid", return NULL);
295  return service->impl->rmw_handle->service_name;
296 }
297 
298 const rcl_service_options_t *
300 {
301  if (!rcl_service_is_valid(service)) {
302  return NULL; // error already set
303  }
304  return &service->impl->options;
305 }
306 
307 rmw_service_t *
309 {
310  if (!rcl_service_is_valid(service)) {
311  return NULL; // error already set
312  }
313  return service->impl->rmw_handle;
314 }
315 
316 rcl_ret_t
318  const rcl_service_t * service,
319  rmw_service_info_t * request_header,
320  void * ros_request)
321 {
322  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Service server taking service request");
323  if (!rcl_service_is_valid(service)) {
324  return RCL_RET_SERVICE_INVALID; // error already set
325  }
326  RCL_CHECK_ARGUMENT_FOR_NULL(request_header, RCL_RET_INVALID_ARGUMENT);
327  RCL_CHECK_ARGUMENT_FOR_NULL(ros_request, RCL_RET_INVALID_ARGUMENT);
328  const rcl_service_options_t * options = rcl_service_get_options(service);
329  RCL_CHECK_FOR_NULL_WITH_MSG(options, "Failed to get service options", return RCL_RET_ERROR);
330 
331  bool taken = false;
332  rmw_ret_t ret = rmw_take_request(
333  service->impl->rmw_handle, request_header, ros_request, &taken);
334  if (RMW_RET_OK != ret) {
335  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
336  if (RMW_RET_BAD_ALLOC == ret) {
337  return RCL_RET_BAD_ALLOC;
338  }
339  return RCL_RET_ERROR;
340  }
341  RCUTILS_LOG_DEBUG_NAMED(
342  ROS_PACKAGE_NAME, "Service take request succeeded: %s", taken ? "true" : "false");
343  if (!taken) {
345  }
346  if (service->impl->service_event_publisher != NULL) {
347  rcl_ret_t rclret = rcl_send_service_event_message(
348  service->impl->service_event_publisher,
349  service_msgs__msg__ServiceEventInfo__REQUEST_RECEIVED,
350  ros_request,
351  request_header->request_id.sequence_number,
352  request_header->request_id.writer_guid);
353  if (RCL_RET_OK != rclret) {
354  RCL_SET_ERROR_MSG(rcl_get_error_string().str);
355  return rclret;
356  }
357  }
358  return RCL_RET_OK;
359 }
360 
361 rcl_ret_t
363  const rcl_service_t * service,
364  rmw_request_id_t * request_header,
365  void * ros_request)
366 {
367  rmw_service_info_t header;
368  header.request_id = *request_header;
369  rcl_ret_t ret = rcl_take_request_with_info(service, &header, ros_request);
370  *request_header = header.request_id;
371  return ret;
372 }
373 
374 rcl_ret_t
376  const rcl_service_t * service,
377  rmw_request_id_t * request_header,
378  void * ros_response)
379 {
380  rcl_ret_t ret;
381  RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Sending service response");
382  if (!rcl_service_is_valid(service)) {
383  return RCL_RET_SERVICE_INVALID; // error already set
384  }
385  RCL_CHECK_ARGUMENT_FOR_NULL(request_header, RCL_RET_INVALID_ARGUMENT);
386  RCL_CHECK_ARGUMENT_FOR_NULL(ros_response, RCL_RET_INVALID_ARGUMENT);
387  const rcl_service_options_t * options = rcl_service_get_options(service);
388  RCL_CHECK_FOR_NULL_WITH_MSG(options, "Failed to get service options", return RCL_RET_ERROR);
389 
390  ret = rmw_send_response(service->impl->rmw_handle, request_header, ros_response);
391  if (ret != RMW_RET_OK) {
392  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
393  if (ret == RMW_RET_TIMEOUT) {
394  return RCL_RET_TIMEOUT;
395  }
396  return RCL_RET_ERROR;
397  }
398 
399  // publish out the introspected content
400  if (service->impl->service_event_publisher != NULL) {
401  ret = rcl_send_service_event_message(
402  service->impl->service_event_publisher,
403  service_msgs__msg__ServiceEventInfo__RESPONSE_SENT,
404  ros_response,
405  request_header->sequence_number,
406  request_header->writer_guid);
407  if (RCL_RET_OK != ret) {
408  RCL_SET_ERROR_MSG(rcl_get_error_string().str);
409  return ret;
410  }
411  }
412  return RCL_RET_OK;
413 }
414 
415 bool
417 {
418  RCL_CHECK_FOR_NULL_WITH_MSG(service, "service pointer is invalid", return false);
419  RCL_CHECK_FOR_NULL_WITH_MSG(
420  service->impl, "service's implementation is invalid", return false);
421  RCL_CHECK_FOR_NULL_WITH_MSG(
422  service->impl->rmw_handle, "service's rmw handle is invalid", return false);
423  return true;
424 }
425 
426 const rmw_qos_profile_t *
428 {
429  if (!rcl_service_is_valid(service)) {
430  return NULL;
431  }
432  return &service->impl->actual_request_subscription_qos;
433 }
434 
435 const rmw_qos_profile_t *
437 {
438  if (!rcl_service_is_valid(service)) {
439  return NULL;
440  }
441  return &service->impl->actual_response_publisher_qos;
442 }
443 
444 rcl_ret_t
446  const rcl_service_t * service,
447  rcl_event_callback_t callback,
448  const void * user_data)
449 {
450  if (!rcl_service_is_valid(service)) {
451  // error state already set
453  }
454 
455  return rmw_service_set_on_new_request_callback(
456  service->impl->rmw_handle,
457  callback,
458  user_data);
459 }
460 
461 rcl_ret_t
463  rcl_service_t * service,
464  rcl_node_t * node,
465  rcl_clock_t * clock,
466  const rosidl_service_type_support_t * type_support,
467  const rcl_publisher_options_t publisher_options,
468  rcl_service_introspection_state_t introspection_state)
469 {
470  if (!rcl_service_is_valid(service)) {
471  return RCL_RET_SERVICE_INVALID; // error already set
472  }
473  RCL_CHECK_ARGUMENT_FOR_NULL(node, RCL_RET_INVALID_ARGUMENT);
474  RCL_CHECK_ARGUMENT_FOR_NULL(clock, RCL_RET_INVALID_ARGUMENT);
475  RCL_CHECK_ARGUMENT_FOR_NULL(type_support, RCL_RET_INVALID_ARGUMENT);
476 
477  rcl_allocator_t allocator = service->impl->options.allocator;
478 
479  if (introspection_state == RCL_SERVICE_INTROSPECTION_OFF) {
480  return unconfigure_service_introspection(node, service->impl, &allocator);
481  }
482 
483  if (service->impl->service_event_publisher == NULL) {
484  // We haven't been introspecting, so we need to allocate the service event publisher
485 
486  service->impl->service_event_publisher = allocator.allocate(
487  sizeof(rcl_service_event_publisher_t), allocator.state);
488  RCL_CHECK_FOR_NULL_WITH_MSG(
489  service->impl->service_event_publisher, "allocating memory failed",
490  return RCL_RET_BAD_ALLOC;);
491 
492  *service->impl->service_event_publisher = rcl_get_zero_initialized_service_event_publisher();
493  rcl_ret_t ret = rcl_service_event_publisher_init(
494  service->impl->service_event_publisher, node, clock, publisher_options,
495  service->impl->remapped_service_name, type_support);
496  if (RCL_RET_OK != ret) {
497  allocator.deallocate(service->impl->service_event_publisher, allocator.state);
498  service->impl->service_event_publisher = NULL;
499  return ret;
500  }
501  }
502 
503  return rcl_service_event_publisher_change_state(
504  service->impl->service_event_publisher, introspection_state);
505 }
506 
507 #ifdef __cplusplus
508 }
509 #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 bool rcl_node_is_valid(const rcl_node_t *node)
Return true if the node is valid, else false.
Definition: node.c:402
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:466
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:392
RCL_PUBLIC RCL_WARN_UNUSED const rmw_qos_profile_t * rcl_service_request_subscription_get_actual_qos(const rcl_service_t *service)
Get the actual qos settings of the service's request subscription.
Definition: service.c:427
RCL_PUBLIC RCL_WARN_UNUSED rmw_service_t * rcl_service_get_rmw_handle(const rcl_service_t *service)
Return the rmw service handle.
Definition: service.c:308
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_service_get_service_name(const rcl_service_t *service)
Get the topic name for the service.
Definition: service.c:288
RCL_PUBLIC RCL_WARN_UNUSED const rmw_qos_profile_t * rcl_service_response_publisher_get_actual_qos(const rcl_service_t *service)
Get the actual qos settings of the service's response publisher.
Definition: service.c:436
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:76
RCL_PUBLIC RCL_WARN_UNUSED const rcl_service_options_t * rcl_service_get_options(const rcl_service_t *service)
Return the rcl service options.
Definition: service.c:299
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_service_configure_service_introspection(rcl_service_t *service, rcl_node_t *node, rcl_clock_t *clock, const rosidl_service_type_support_t *type_support, const rcl_publisher_options_t publisher_options, rcl_service_introspection_state_t introspection_state)
Configure service introspection features for the service.
Definition: service.c:462
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_take_request_with_info(const rcl_service_t *service, rmw_service_info_t *request_header, void *ros_request)
Take a pending ROS request using a rcl service.
Definition: service.c:317
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_service_set_on_new_request_callback(const rcl_service_t *service, rcl_event_callback_t callback, const void *user_data)
Set the on new request callback function for the service.
Definition: service.c:445
RCL_PUBLIC bool rcl_service_is_valid(const rcl_service_t *service)
Check that the service is valid.
Definition: service.c:416
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_service_fini(rcl_service_t *service, rcl_node_t *node)
Finalize a rcl_service_t.
Definition: service.c:225
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:277
RCL_PUBLIC RCL_WARN_UNUSED rcl_service_t rcl_get_zero_initialized_service(void)
Return a rcl_service_t struct with members set to NULL.
Definition: service.c:45
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_take_request(const rcl_service_t *service, rmw_request_id_t *request_header, void *ros_request)
Backwards compatibility function to take a pending ROS request using a rcl service.
Definition: service.c:362
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_send_response(const rcl_service_t *service, rmw_request_id_t *response_header, void *ros_response)
Send a ROS response to a client using a service.
Definition: service.c:375
Encapsulation of a time source.
Definition: time.h:138
Structure which encapsulates a ROS Node.
Definition: node.h:45
Options available for a rcl publisher.
Definition: publisher.h:44
Options available for a rcl service.
Definition: service.h:50
rmw_qos_profile_t qos
Middleware quality of service settings for the service.
Definition: service.h:52
rcl_allocator_t allocator
Custom allocator for the service, used for incidental allocations.
Definition: service.h:55
Structure which encapsulates a ROS Service.
Definition: service.h:43
rcl_service_impl_t * impl
Pointer to the service implementation.
Definition: service.h:45
#define RCL_RET_SERVICE_INVALID
Invalid rcl_service_t given return code.
Definition: types.h:85
#define RCL_RET_UNKNOWN_SUBSTITUTION
Topic name substitution is unknown.
Definition: types.h:51
#define RCL_RET_SERVICE_NAME_INVALID
Service name (same as topic name) does not pass validation.
Definition: types.h:49
#define RCL_RET_ALREADY_INIT
rcl_init() already called return code.
Definition: types.h:41
#define RCL_RET_OK
Success return code.
Definition: types.h:27
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
Definition: types.h:33
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
Definition: types.h:35
#define RCL_RET_ERROR
Unspecified error return code.
Definition: types.h:29
#define RCL_RET_SERVICE_TAKE_FAILED
Failed to take a request from the service return code.
Definition: types.h:87
#define RCL_RET_NODE_INVALID
Invalid rcl_node_t given return code.
Definition: types.h:59
#define RCL_RET_TIMEOUT
Timeout occurred return code.
Definition: types.h:31
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:24