15 #include "rclcpp/node_interfaces/node_graph.hpp"
26 #include "rclcpp/event.hpp"
27 #include "rclcpp/exceptions.hpp"
28 #include "rclcpp/expand_topic_or_service_name.hpp"
29 #include "rclcpp/graph_listener.hpp"
30 #include "rclcpp/node_interfaces/node_graph_interface.hpp"
31 #include "rcpputils/scope_exit.hpp"
34 using rclcpp::exceptions::throw_from_rcl_error;
38 : node_base_(node_base),
40 node_base->get_context()->get_sub_context<
GraphListener>(node_base->get_context())
42 should_add_to_graph_listener_(true),
46 NodeGraph::~NodeGraph()
51 if (!should_add_to_graph_listener_.exchange(
false)) {
53 graph_listener_->remove_node(
this);
57 std::map<std::string, std::vector<std::string>>
67 &topic_names_and_types);
69 auto error_msg = std::string(
"failed to get topic names and types: ") +
70 rcl_get_error_string().str;
73 error_msg += std::string(
", failed also to cleanup topic names and types, leaking memory: ") +
74 rcl_get_error_string().str;
77 throw std::runtime_error(error_msg);
80 std::map<std::string, std::vector<std::string>> topics_and_types;
81 for (
size_t i = 0; i < topic_names_and_types.names.size; ++i) {
82 std::string topic_name = topic_names_and_types.names.data[i];
83 for (
size_t j = 0; j < topic_names_and_types.types[i].size; ++j) {
84 topics_and_types[topic_name].emplace_back(topic_names_and_types.types[i].data[j]);
91 throw std::runtime_error(
92 std::string(
"could not destroy topic names and types: ") + rcl_get_error_string().str);
96 return topics_and_types;
99 std::map<std::string, std::vector<std::string>>
108 &service_names_and_types);
110 auto error_msg = std::string(
"failed to get service names and types: ") +
111 rcl_get_error_string().str;
115 std::string(
", failed also to cleanup service names and types, leaking memory: ") +
116 rcl_get_error_string().str;
119 throw std::runtime_error(error_msg);
122 std::map<std::string, std::vector<std::string>> services_and_types;
123 for (
size_t i = 0; i < service_names_and_types.names.size; ++i) {
124 std::string service_name = service_names_and_types.names.data[i];
125 for (
size_t j = 0; j < service_names_and_types.types[i].size; ++j) {
126 services_and_types[service_name].emplace_back(service_names_and_types.types[i].data[j]);
133 throw std::runtime_error(
134 std::string(
"could not destroy service names and types: ") + rcl_get_error_string().str);
138 return services_and_types;
141 std::map<std::string, std::vector<std::string>>
143 const std::string & node_name,
144 const std::string & namespace_)
const
153 &service_names_and_types);
155 auto error_msg = std::string(
"failed to get service names and types by node: ") +
156 rcl_get_error_string().str;
160 std::string(
", failed also to cleanup service names and types, leaking memory: ") +
161 rcl_get_error_string().str;
164 throw std::runtime_error(error_msg);
167 std::map<std::string, std::vector<std::string>> services_and_types;
168 for (
size_t i = 0; i < service_names_and_types.names.size; ++i) {
169 std::string service_name = service_names_and_types.names.data[i];
170 for (
size_t j = 0; j < service_names_and_types.types[i].size; ++j) {
171 services_and_types[service_name].emplace_back(service_names_and_types.types[i].data[j]);
177 throw_from_rcl_error(ret,
"could not destroy service names and types");
180 return services_and_types;
183 std::map<std::string, std::vector<std::string>>
185 const std::string & node_name,
186 const std::string & namespace_)
const
189 auto service_names_and_types_finalizer = rcpputils::make_scope_exit(
190 [&service_names_and_types]() {
202 &service_names_and_types);
204 throw_from_rcl_error(ret,
"failed to get service names and types by node");
207 std::map<std::string, std::vector<std::string>> services_and_types;
208 for (
size_t i = 0; i < service_names_and_types.names.size; ++i) {
209 std::string service_name = service_names_and_types.names.data[i];
210 for (
size_t j = 0; j < service_names_and_types.types[i].size; ++j) {
211 services_and_types[service_name].emplace_back(service_names_and_types.types[i].data[j]);
215 return services_and_types;
218 std::map<std::string, std::vector<std::string>>
220 const std::string & node_name,
221 const std::string & namespace_,
222 bool no_demangle)
const
225 auto topic_names_and_types_finalizer = rcpputils::make_scope_exit(
226 [&topic_names_and_types]() {
239 &topic_names_and_types);
241 throw_from_rcl_error(ret,
"failed to get topic names and types by node");
244 std::map<std::string, std::vector<std::string>> topics_and_types;
245 for (
size_t i = 0; i < topic_names_and_types.names.size; ++i) {
246 std::string topic_name = topic_names_and_types.names.data[i];
247 for (
size_t j = 0; j < topic_names_and_types.types[i].size; ++j) {
248 topics_and_types[topic_name].emplace_back(topic_names_and_types.types[i].data[j]);
252 return topics_and_types;
255 std::map<std::string, std::vector<std::string>>
257 const std::string & node_name,
258 const std::string & namespace_,
259 bool no_demangle)
const
262 auto topic_names_and_types_finalizer = rcpputils::make_scope_exit(
263 [&topic_names_and_types]() {
276 &topic_names_and_types);
278 throw_from_rcl_error(ret,
"failed to get topic names and types by node");
281 std::map<std::string, std::vector<std::string>> topics_and_types;
282 for (
size_t i = 0; i < topic_names_and_types.names.size; ++i) {
283 std::string topic_name = topic_names_and_types.names.data[i];
284 for (
size_t j = 0; j < topic_names_and_types.types[i].size; ++j) {
285 topics_and_types[topic_name].emplace_back(topic_names_and_types.types[i].data[j]);
289 return topics_and_types;
292 std::vector<std::string>
295 std::vector<std::string> nodes;
299 names_and_namespaces.begin(),
300 names_and_namespaces.end(),
301 std::back_inserter(nodes),
302 [](std::pair<std::string, std::string> nns) {
303 std::string return_string;
304 if (nns.second.back() ==
'/') {
305 return_string = nns.second + nns.first;
307 return_string = nns.second +
'/' + nns.first;
311 if (return_string.front() !=
'/') {
312 return_string =
"/" + return_string;
314 return return_string;
320 std::vector<std::tuple<std::string, std::string, std::string>>
323 rcutils_string_array_t node_names_c =
324 rcutils_get_zero_initialized_string_array();
325 rcutils_string_array_t node_namespaces_c =
326 rcutils_get_zero_initialized_string_array();
327 rcutils_string_array_t node_enclaves_c =
328 rcutils_get_zero_initialized_string_array();
339 std::string(
"failed to get node names with enclaves: ") + rcl_get_error_string().str;
341 if (rcutils_string_array_fini(&node_names_c) != RCUTILS_RET_OK) {
342 error_msg += std::string(
", failed also to cleanup node names, leaking memory: ") +
343 rcl_get_error_string().str;
346 if (rcutils_string_array_fini(&node_namespaces_c) != RCUTILS_RET_OK) {
347 error_msg += std::string(
", failed also to cleanup node namespaces, leaking memory: ") +
348 rcl_get_error_string().str;
351 if (rcutils_string_array_fini(&node_enclaves_c) != RCUTILS_RET_OK) {
352 error_msg += std::string(
", failed also to cleanup node enclaves, leaking memory: ") +
353 rcl_get_error_string().str;
356 throw std::runtime_error(error_msg);
359 std::vector<std::tuple<std::string, std::string, std::string>> node_tuples;
360 for (
size_t i = 0; i < node_names_c.size; ++i) {
361 if (node_names_c.data[i] && node_namespaces_c.data[i] && node_enclaves_c.data[i]) {
362 node_tuples.emplace_back(
363 std::make_tuple(node_names_c.data[i], node_namespaces_c.data[i], node_enclaves_c.data[i]));
367 std::string error(
"failed to finalize array");
368 rcl_ret_t ret_names = rcutils_string_array_fini(&node_names_c);
369 if (ret_names != RCUTILS_RET_OK) {
370 error += std::string(
", could not destroy node names, leaking memory: ") +
371 rcl_get_error_string().str;
374 rcl_ret_t ret_ns = rcutils_string_array_fini(&node_namespaces_c);
375 if (ret_ns != RCUTILS_RET_OK) {
376 error += std::string(
", could not destroy node namespaces, leaking memory: ") +
377 rcl_get_error_string().str;
381 rcl_ret_t ret_ecv = rcutils_string_array_fini(&node_enclaves_c);
382 if (ret_ecv != RCUTILS_RET_OK) {
383 error += std::string(
", could not destroy node enclaves, leaking memory: ") +
384 rcl_get_error_string().str;
388 if (ret_names != RCUTILS_RET_OK || ret_ns != RCUTILS_RET_OK || ret_ecv != RCUTILS_RET_OK) {
389 throw std::runtime_error(error);
395 std::vector<std::pair<std::string, std::string>>
398 rcutils_string_array_t node_names_c =
399 rcutils_get_zero_initialized_string_array();
400 rcutils_string_array_t node_namespaces_c =
401 rcutils_get_zero_initialized_string_array();
410 auto error_msg = std::string(
"failed to get node names: ") + rcl_get_error_string().str;
412 if (rcutils_string_array_fini(&node_names_c) != RCUTILS_RET_OK) {
413 error_msg += std::string(
", failed also to cleanup node names, leaking memory: ") +
414 rcl_get_error_string().str;
417 if (rcutils_string_array_fini(&node_namespaces_c) != RCUTILS_RET_OK) {
418 error_msg += std::string(
", failed also to cleanup node namespaces, leaking memory: ") +
419 rcl_get_error_string().str;
423 throw std::runtime_error(error_msg);
426 std::vector<std::pair<std::string, std::string>> node_names;
427 node_names.reserve(node_names_c.size);
428 for (
size_t i = 0; i < node_names_c.size; ++i) {
429 if (node_names_c.data[i] && node_namespaces_c.data[i]) {
430 node_names.emplace_back(node_names_c.data[i], node_namespaces_c.data[i]);
435 rcl_ret_t ret_names = rcutils_string_array_fini(&node_names_c);
436 if (ret_names != RCUTILS_RET_OK) {
439 error =
"could not destroy node names";
442 rcl_ret_t ret_ns = rcutils_string_array_fini(&node_namespaces_c);
443 if (ret_ns != RCUTILS_RET_OK) {
446 error +=
", could not destroy node namespaces";
450 if (ret_names != RCUTILS_RET_OK || ret_ns != RCUTILS_RET_OK) {
451 throw std::runtime_error(error);
470 if (ret != RMW_RET_OK) {
472 throw std::runtime_error(
473 std::string(
"could not count publishers: ") + rmw_get_error_string().str);
492 if (ret != RMW_RET_OK) {
494 throw std::runtime_error(
495 std::string(
"could not count subscribers: ") + rmw_get_error_string().str);
514 if (ret != RMW_RET_OK) {
516 throw std::runtime_error(
517 std::string(
"could not count clients: ") + rmw_get_error_string().str);
536 if (ret != RMW_RET_OK) {
538 throw std::runtime_error(
539 std::string(
"could not count services: ") + rmw_get_error_string().str);
555 std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
556 bool bad_ptr_encountered =
false;
557 for (
auto & event_wptr : graph_events_) {
558 auto event_ptr = event_wptr.lock();
562 bad_ptr_encountered =
true;
565 if (bad_ptr_encountered) {
569 graph_events_.begin(),
571 [](
const rclcpp::Event::WeakPtr & wptr) {
572 return wptr.expired();
574 graph_events_.end());
576 graph_users_count_.store(graph_events_.size());
579 graph_cv_.notify_all();
583 throw std::runtime_error(
584 std::string(
"failed to notify wait set on graph change: ") + ex.what());
592 graph_cv_.notify_all();
595 rclcpp::Event::SharedPtr
598 auto event = rclcpp::Event::make_shared();
600 std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
601 graph_events_.push_back(event);
602 graph_users_count_++;
605 if (should_add_to_graph_listener_.exchange(
false)) {
606 graph_listener_->add_node(
this);
607 graph_listener_->start_if_not_started();
614 rclcpp::Event::SharedPtr event,
615 std::chrono::nanoseconds timeout)
620 throw InvalidEventError();
623 std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
624 bool event_in_graph_events =
false;
625 for (
const auto & event_wptr : graph_events_) {
626 if (event == event_wptr.lock()) {
627 event_in_graph_events =
true;
631 if (!event_in_graph_events) {
632 throw EventNotRegisteredError();
635 auto pred = [&event, context = node_base_->
get_context()]() {
636 return event->check() || !
rclcpp::ok(context);
638 std::unique_lock<std::mutex> graph_lock(graph_mutex_);
640 graph_cv_.wait_for(graph_lock, timeout, pred);
647 return graph_users_count_.load();
651 std::vector<rclcpp::TopicEndpointInfo>
654 std::vector<rclcpp::TopicEndpointInfo> topic_info_list;
655 for (
size_t i = 0; i < info_array.size; ++i) {
658 return topic_info_list;
661 template<const
char * Endpo
intType,
typename FunctionT>
662 static std::vector<rclcpp::TopicEndpointInfo>
665 const std::string & topic_name,
667 FunctionT rcl_get_info_by_topic)
683 if (
nullptr == node_options) {
684 throw std::runtime_error(
"Need valid node options in get_info_by_topic()");
688 global_args = &(rcl_node_handle->context->global_arguments);
691 char * remapped_topic_name =
nullptr;
699 &remapped_topic_name);
701 throw_from_rcl_error(ret, std::string(
"Failed to remap topic name ") + fqdn);
702 }
else if (
nullptr != remapped_topic_name) {
703 fqdn = remapped_topic_name;
704 node_options->
allocator.deallocate(remapped_topic_name, node_options->
allocator.state);
708 rcutils_allocator_t allocator = rcutils_get_default_allocator();
711 rcl_get_info_by_topic(rcl_node_handle, &allocator, fqdn.c_str(), no_mangle, &info_array);
714 std::string(
"Failed to get information by topic for ") + EndpointType + std::string(
":");
716 error_msg += std::string(
"function not supported by RMW_IMPLEMENTATION");
718 error_msg += rcl_get_error_string().str;
722 error_msg += std::string(
", failed also to cleanup topic info array, leaking memory: ") +
723 rcl_get_error_string().str;
726 throw_from_rcl_error(ret, error_msg);
729 std::vector<rclcpp::TopicEndpointInfo> topic_info_list = convert_to_topic_info_list(info_array);
732 throw_from_rcl_error(ret,
"rcl_topic_info_array_fini failed.");
735 return topic_info_list;
738 static constexpr
char kPublisherEndpointTypeName[] =
"publishers";
739 std::vector<rclcpp::TopicEndpointInfo>
741 const std::string & topic_name,
742 bool no_mangle)
const
744 return get_info_by_topic<kPublisherEndpointTypeName>(
751 static constexpr
char kSubscriptionEndpointTypeName[] =
"subscriptions";
752 std::vector<rclcpp::TopicEndpointInfo>
754 const std::string & topic_name,
755 bool no_mangle)
const
757 return get_info_by_topic<kSubscriptionEndpointTypeName>(
779 return node_namespace_;
785 return node_namespace_;
800 rclcpp::EndpointType &
803 return endpoint_type_;
806 const rclcpp::EndpointType &
809 return endpoint_type_;
812 std::array<uint8_t, RMW_GID_STORAGE_SIZE> &
815 return endpoint_gid_;
818 const std::array<uint8_t, RMW_GID_STORAGE_SIZE> &
821 return endpoint_gid_;
839 return topic_type_hash_;
842 const rosidl_type_hash_t &
845 return topic_type_hash_;
#define rcl_get_default_allocator
Return a properly initialized rcl_allocator_t with default values.
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
Encapsulation of Quality of Service settings.
RCLCPP_PUBLIC std::string & node_name()
Get a mutable reference to the node name.
RCLCPP_PUBLIC std::string & node_namespace()
Get a mutable reference to the node namespace.
RCLCPP_PUBLIC rosidl_type_hash_t & topic_type_hash()
Get a mutable reference to the type hash of the topic endpoint.
RCLCPP_PUBLIC std::string & topic_type()
Get a mutable reference to the topic type string.
RCLCPP_PUBLIC rclcpp::QoS & qos_profile()
Get a mutable reference to the QoS profile of the topic endpoint.
RCLCPP_PUBLIC rclcpp::EndpointType & endpoint_type()
Get a mutable reference to the topic endpoint type.
RCLCPP_PUBLIC std::array< uint8_t, RMW_GID_STORAGE_SIZE > & endpoint_gid()
Get a mutable reference to the GID of the topic endpoint.
Thrown when an unregistered rclcpp::Event is encountered where a registered one was expected.
Thrown when an invalid rclcpp::Event object or SharedPtr is encountered.
Created when the return code does not match one of the other specialized exceptions.
Notifies many nodes of graph changes by listening in a thread.
Pure virtual interface class for the NodeBase part of the Node API.
virtual RCLCPP_PUBLIC void trigger_notify_guard_condition()=0
Trigger the guard condition that notifies of internal node state changes.
virtual RCLCPP_PUBLIC rcl_node_t * get_rcl_node_handle()=0
Return the rcl_node_t node handle (non-const version).
virtual RCLCPP_PUBLIC rclcpp::Context::SharedPtr get_context()=0
Return the context of the node.
Implementation the NodeGraph part of the Node API.
RCLCPP_PUBLIC std::vector< std::string > get_node_names() const override
Return a vector of existing node names (string).
RCLCPP_PUBLIC std::map< std::string, std::vector< std::string > > get_service_names_and_types() const override
Return a map of existing service names to list of service types.
RCLCPP_PUBLIC std::map< std::string, std::vector< std::string > > get_publisher_names_and_types_by_node(const std::string &node_name, const std::string &namespace_, bool no_demangle=false) const override
Return a map of existing topic names to list of topic types for a specific node.
RCLCPP_PUBLIC std::vector< rclcpp::TopicEndpointInfo > get_publishers_info_by_topic(const std::string &topic_name, bool no_mangle=false) const override
Return the topic endpoint information about publishers on a given topic.
RCLCPP_PUBLIC std::vector< std::pair< std::string, std::string > > get_node_names_and_namespaces() const override
Return a vector of existing node names and namespaces (pair of string).
RCLCPP_PUBLIC size_t count_services(const std::string &service_name) const override
Return the number of services created for a given service.
RCLCPP_PUBLIC std::map< std::string, std::vector< std::string > > get_subscriber_names_and_types_by_node(const std::string &node_name, const std::string &namespace_, bool no_demangle=false) const override
Return a map of existing topic names to list of topic types for a specific node.
RCLCPP_PUBLIC size_t count_subscribers(const std::string &topic_name) const override
Return the number of subscribers who have created a subscription for a given topic.
RCLCPP_PUBLIC std::map< std::string, std::vector< std::string > > get_client_names_and_types_by_node(const std::string &node_name, const std::string &namespace_) const override
Return a map of existing service names and types with a specific node.
RCLCPP_PUBLIC std::vector< rclcpp::TopicEndpointInfo > get_subscriptions_info_by_topic(const std::string &topic_name, bool no_mangle=false) const override
Return the topic endpoint information about subscriptions on a given topic.
RCLCPP_PUBLIC size_t count_graph_users() const override
Return the number of on loan graph events, see get_graph_event().
RCLCPP_PUBLIC std::map< std::string, std::vector< std::string > > get_topic_names_and_types(bool no_demangle=false) const override
Return a map of existing topic names to list of topic types.
RCLCPP_PUBLIC void wait_for_graph_change(rclcpp::Event::SharedPtr event, std::chrono::nanoseconds timeout) override
Wait for a graph event to occur by waiting on an Event to become set.
RCLCPP_PUBLIC std::map< std::string, std::vector< std::string > > get_service_names_and_types_by_node(const std::string &node_name, const std::string &namespace_) const override
Return a map of existing service names to list of service types for a specific node.
RCLCPP_PUBLIC rclcpp::Event::SharedPtr get_graph_event() override
Return a graph event, which will be set anytime a graph change occurs.
RCLCPP_PUBLIC void notify_shutdown() override
Notify any and all blocking node actions that shutdown has occurred.
RCLCPP_PUBLIC std::vector< std::tuple< std::string, std::string, std::string > > get_node_names_with_enclaves() const override
Return a vector of existing node names, namespaces and enclaves (tuple of string).
RCLCPP_PUBLIC size_t count_publishers(const std::string &topic_name) const override
Return the number of publishers that are advertised on a given topic.
RCLCPP_PUBLIC size_t count_clients(const std::string &service_name) const override
Return the number of clients created for a given service.
RCLCPP_PUBLIC void notify_graph_change() override
Notify threads waiting on graph changes.
RCLCPP_PUBLIC const rcl_guard_condition_t * get_graph_guard_condition() const override
Return the rcl guard condition which is triggered when the ROS graph changes.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_count_services(const rcl_node_t *node, const char *service_name, size_t *count)
Return the number of servers on a given service.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_subscriptions_info_by_topic(const rcl_node_t *node, rcutils_allocator_t *allocator, const char *topic_name, bool no_mangle, rcl_topic_endpoint_info_array_t *subscriptions_info)
Return a list of all subscriptions to a topic.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_names_and_types_fini(rcl_names_and_types_t *names_and_types)
Finalize a rcl_names_and_types_t object.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_node_names_with_enclaves(const rcl_node_t *node, rcl_allocator_t allocator, rcutils_string_array_t *node_names, rcutils_string_array_t *node_namespaces, rcutils_string_array_t *enclaves)
Return a list of node names and their associated namespaces and enclaves in the ROS graph.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_service_names_and_types(const rcl_node_t *node, rcl_allocator_t *allocator, rcl_names_and_types_t *service_names_and_types)
Return a list of service names and their types.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_client_names_and_types_by_node(const rcl_node_t *node, rcl_allocator_t *allocator, const char *node_name, const char *node_namespace, rcl_names_and_types_t *service_names_and_types)
Return a list of service client names and types associated with a node.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_publishers_info_by_topic(const rcl_node_t *node, rcutils_allocator_t *allocator, const char *topic_name, bool no_mangle, rcl_topic_endpoint_info_array_t *publishers_info)
Return a list of all publishers to a topic.
rmw_topic_endpoint_info_array_t rcl_topic_endpoint_info_array_t
An array of topic endpoint information.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_service_names_and_types_by_node(const rcl_node_t *node, rcl_allocator_t *allocator, const char *node_name, const char *node_namespace, rcl_names_and_types_t *service_names_and_types)
Return a list of service names and types associated with a node.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_subscriber_names_and_types_by_node(const rcl_node_t *node, rcl_allocator_t *allocator, bool no_demangle, const char *node_name, const char *node_namespace, rcl_names_and_types_t *topic_names_and_types)
Return a list of topic names and types for subscriptions associated with a node.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_count_subscribers(const rcl_node_t *node, const char *topic_name, size_t *count)
Return the number of subscriptions on a given topic.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_count_clients(const rcl_node_t *node, const char *service_name, size_t *count)
Return the number of clients on a given service.
rmw_names_and_types_t rcl_names_and_types_t
A structure that contains topic names and types.
#define rcl_topic_endpoint_info_array_fini
Finalize a topic_endpoint_info_array_t structure.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_publisher_names_and_types_by_node(const rcl_node_t *node, rcl_allocator_t *allocator, bool no_demangle, const char *node_name, const char *node_namespace, rcl_names_and_types_t *topic_names_and_types)
Return a list of topic names and types for publishers associated with a node.
#define rcl_get_zero_initialized_names_and_types
Return a zero-initialized rcl_names_and_types_t structure.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_topic_names_and_types(const rcl_node_t *node, rcl_allocator_t *allocator, bool no_demangle, rcl_names_and_types_t *topic_names_and_types)
Return a list of topic names and their types.
#define rcl_get_zero_initialized_topic_endpoint_info_array
Return a zero-initialized rcl_topic_endpoint_info_t structure.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_get_node_names(const rcl_node_t *node, rcl_allocator_t allocator, rcutils_string_array_t *node_names, rcutils_string_array_t *node_namespaces)
Return a list of node names and their associated namespaces in the ROS graph.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_count_publishers(const rcl_node_t *node, const char *topic_name, size_t *count)
Return the number of publishers on a given topic.
RCLCPP_PUBLIC std::string expand_topic_or_service_name(const std::string &name, const std::string &node_name, const std::string &namespace_, bool is_service=false)
Expand a topic or service name and throw if it is not valid.
RCLCPP_PUBLIC bool ok(rclcpp::Context::SharedPtr context=nullptr)
Check rclcpp's status.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
RCL_PUBLIC RCL_WARN_UNUSED const rcl_node_options_t * rcl_node_get_options(const rcl_node_t *node)
Return the rcl node options.
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_node_get_name(const rcl_node_t *node)
Return the name of the node.
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_node_get_namespace(const rcl_node_t *node)
Return the namespace of the node.
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.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_remap_topic_name(const rcl_arguments_t *local_arguments, const rcl_arguments_t *global_arguments, const char *topic_name, const char *node_name, const char *node_namespace, rcl_allocator_t allocator, char **output_name)
Remap a topic name based on given rules.
Hold output of parsing command line arguments.
Handle for a rcl guard condition.
Structure which encapsulates the options for creating a rcl_node_t.
bool use_global_arguments
If false then only use arguments in this struct, otherwise use global arguments also.
rcl_arguments_t arguments
Command line arguments that apply only to this node.
rcl_allocator_t allocator
If true, no parameter infrastructure will be setup.
#define RCL_RET_UNSUPPORTED
Unsupported return code.
#define RCL_RET_OK
Success return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.