15 #include "rclcpp/node_interfaces/node_graph.hpp"
27 #include "rclcpp/event.hpp"
28 #include "rclcpp/exceptions.hpp"
29 #include "rclcpp/expand_topic_or_service_name.hpp"
30 #include "rclcpp/graph_listener.hpp"
31 #include "rclcpp/node_interfaces/node_graph_interface.hpp"
32 #include "rcpputils/scope_exit.hpp"
35 using rclcpp::exceptions::throw_from_rcl_error;
39 : node_base_(node_base),
40 should_add_to_graph_listener_(true),
44 NodeGraph::~NodeGraph()
49 if (!should_add_to_graph_listener_.exchange(
false)) {
51 node_base_->
get_context()->get_graph_listener()->remove_node(
this);
55 std::map<std::string, std::vector<std::string>>
65 &topic_names_and_types);
67 auto error_msg = std::string(
"failed to get topic names and types: ") +
68 rcl_get_error_string().str;
71 error_msg += std::string(
", failed also to cleanup topic names and types, leaking memory: ") +
72 rcl_get_error_string().str;
75 throw std::runtime_error(error_msg);
78 std::map<std::string, std::vector<std::string>> topics_and_types;
79 for (
size_t i = 0; i < topic_names_and_types.names.size; ++i) {
80 std::string topic_name = topic_names_and_types.names.data[i];
81 for (
size_t j = 0; j < topic_names_and_types.types[i].size; ++j) {
82 topics_and_types[topic_name].emplace_back(topic_names_and_types.types[i].data[j]);
89 throw std::runtime_error(
90 std::string(
"could not destroy topic names and types: ") + rcl_get_error_string().str);
94 return topics_and_types;
97 std::map<std::string, std::vector<std::string>>
106 &service_names_and_types);
108 auto error_msg = std::string(
"failed to get service names and types: ") +
109 rcl_get_error_string().str;
113 std::string(
", failed also to cleanup service names and types, leaking memory: ") +
114 rcl_get_error_string().str;
117 throw std::runtime_error(error_msg);
120 std::map<std::string, std::vector<std::string>> services_and_types;
121 for (
size_t i = 0; i < service_names_and_types.names.size; ++i) {
122 std::string service_name = service_names_and_types.names.data[i];
123 for (
size_t j = 0; j < service_names_and_types.types[i].size; ++j) {
124 services_and_types[service_name].emplace_back(service_names_and_types.types[i].data[j]);
131 throw std::runtime_error(
132 std::string(
"could not destroy service names and types: ") + rcl_get_error_string().str);
136 return services_and_types;
139 std::map<std::string, std::vector<std::string>>
141 const std::string & node_name,
142 const std::string & namespace_)
const
151 &service_names_and_types);
153 auto error_msg = std::string(
"failed to get service names and types by node: ") +
154 rcl_get_error_string().str;
158 std::string(
", failed also to cleanup service names and types, leaking memory: ") +
159 rcl_get_error_string().str;
162 throw std::runtime_error(error_msg);
165 std::map<std::string, std::vector<std::string>> services_and_types;
166 for (
size_t i = 0; i < service_names_and_types.names.size; ++i) {
167 std::string service_name = service_names_and_types.names.data[i];
168 for (
size_t j = 0; j < service_names_and_types.types[i].size; ++j) {
169 services_and_types[service_name].emplace_back(service_names_and_types.types[i].data[j]);
175 throw_from_rcl_error(ret,
"could not destroy service names and types");
178 return services_and_types;
181 std::map<std::string, std::vector<std::string>>
183 const std::string & node_name,
184 const std::string & namespace_)
const
187 auto service_names_and_types_finalizer = rcpputils::make_scope_exit(
188 [&service_names_and_types]() {
200 &service_names_and_types);
202 throw_from_rcl_error(ret,
"failed to get service names and types by node");
205 std::map<std::string, std::vector<std::string>> services_and_types;
206 for (
size_t i = 0; i < service_names_and_types.names.size; ++i) {
207 std::string service_name = service_names_and_types.names.data[i];
208 for (
size_t j = 0; j < service_names_and_types.types[i].size; ++j) {
209 services_and_types[service_name].emplace_back(service_names_and_types.types[i].data[j]);
213 return services_and_types;
216 std::map<std::string, std::vector<std::string>>
218 const std::string & node_name,
219 const std::string & namespace_,
220 bool no_demangle)
const
223 auto topic_names_and_types_finalizer = rcpputils::make_scope_exit(
224 [&topic_names_and_types]() {
237 &topic_names_and_types);
239 throw_from_rcl_error(ret,
"failed to get topic names and types by node");
242 std::map<std::string, std::vector<std::string>> topics_and_types;
243 for (
size_t i = 0; i < topic_names_and_types.names.size; ++i) {
244 std::string topic_name = topic_names_and_types.names.data[i];
245 for (
size_t j = 0; j < topic_names_and_types.types[i].size; ++j) {
246 topics_and_types[topic_name].emplace_back(topic_names_and_types.types[i].data[j]);
250 return topics_and_types;
253 std::map<std::string, std::vector<std::string>>
255 const std::string & node_name,
256 const std::string & namespace_,
257 bool no_demangle)
const
260 auto topic_names_and_types_finalizer = rcpputils::make_scope_exit(
261 [&topic_names_and_types]() {
274 &topic_names_and_types);
276 throw_from_rcl_error(ret,
"failed to get topic names and types by node");
279 std::map<std::string, std::vector<std::string>> topics_and_types;
280 for (
size_t i = 0; i < topic_names_and_types.names.size; ++i) {
281 std::string topic_name = topic_names_and_types.names.data[i];
282 for (
size_t j = 0; j < topic_names_and_types.types[i].size; ++j) {
283 topics_and_types[topic_name].emplace_back(topic_names_and_types.types[i].data[j]);
287 return topics_and_types;
290 std::vector<std::string>
293 std::vector<std::string> nodes;
297 names_and_namespaces.begin(),
298 names_and_namespaces.end(),
299 std::back_inserter(nodes),
300 [](std::pair<std::string, std::string> nns) {
301 std::string return_string;
302 if (nns.second.back() ==
'/') {
303 return_string = nns.second + nns.first;
305 return_string = nns.second +
'/' + nns.first;
309 if (return_string.front() !=
'/') {
310 return_string =
"/" + return_string;
312 return return_string;
318 std::vector<std::tuple<std::string, std::string, std::string>>
321 rcutils_string_array_t node_names_c =
322 rcutils_get_zero_initialized_string_array();
323 rcutils_string_array_t node_namespaces_c =
324 rcutils_get_zero_initialized_string_array();
325 rcutils_string_array_t node_enclaves_c =
326 rcutils_get_zero_initialized_string_array();
337 std::string(
"failed to get node names with enclaves: ") + rcl_get_error_string().str;
339 if (rcutils_string_array_fini(&node_names_c) != RCUTILS_RET_OK) {
340 error_msg += std::string(
", failed also to cleanup node names, leaking memory: ") +
341 rcl_get_error_string().str;
344 if (rcutils_string_array_fini(&node_namespaces_c) != RCUTILS_RET_OK) {
345 error_msg += std::string(
", failed also to cleanup node namespaces, leaking memory: ") +
346 rcl_get_error_string().str;
349 if (rcutils_string_array_fini(&node_enclaves_c) != RCUTILS_RET_OK) {
350 error_msg += std::string(
", failed also to cleanup node enclaves, leaking memory: ") +
351 rcl_get_error_string().str;
354 throw std::runtime_error(error_msg);
357 std::vector<std::tuple<std::string, std::string, std::string>> node_tuples;
358 for (
size_t i = 0; i < node_names_c.size; ++i) {
359 if (node_names_c.data[i] && node_namespaces_c.data[i] && node_enclaves_c.data[i]) {
360 node_tuples.emplace_back(
361 std::make_tuple(node_names_c.data[i], node_namespaces_c.data[i], node_enclaves_c.data[i]));
365 std::string error(
"failed to finalize array");
366 rcl_ret_t ret_names = rcutils_string_array_fini(&node_names_c);
367 if (ret_names != RCUTILS_RET_OK) {
368 error += std::string(
", could not destroy node names, leaking memory: ") +
369 rcl_get_error_string().str;
372 rcl_ret_t ret_ns = rcutils_string_array_fini(&node_namespaces_c);
373 if (ret_ns != RCUTILS_RET_OK) {
374 error += std::string(
", could not destroy node namespaces, leaking memory: ") +
375 rcl_get_error_string().str;
379 rcl_ret_t ret_ecv = rcutils_string_array_fini(&node_enclaves_c);
380 if (ret_ecv != RCUTILS_RET_OK) {
381 error += std::string(
", could not destroy node enclaves, leaking memory: ") +
382 rcl_get_error_string().str;
386 if (ret_names != RCUTILS_RET_OK || ret_ns != RCUTILS_RET_OK || ret_ecv != RCUTILS_RET_OK) {
387 throw std::runtime_error(error);
393 std::vector<std::pair<std::string, std::string>>
396 rcutils_string_array_t node_names_c =
397 rcutils_get_zero_initialized_string_array();
398 rcutils_string_array_t node_namespaces_c =
399 rcutils_get_zero_initialized_string_array();
408 auto error_msg = std::string(
"failed to get node names: ") + rcl_get_error_string().str;
410 if (rcutils_string_array_fini(&node_names_c) != RCUTILS_RET_OK) {
411 error_msg += std::string(
", failed also to cleanup node names, leaking memory: ") +
412 rcl_get_error_string().str;
415 if (rcutils_string_array_fini(&node_namespaces_c) != RCUTILS_RET_OK) {
416 error_msg += std::string(
", failed also to cleanup node namespaces, leaking memory: ") +
417 rcl_get_error_string().str;
420 RCUTILS_LOG_ERROR_NAMED(
"rclcpp",
"%s", error_msg.c_str());
421 throw std::runtime_error(error_msg);
424 std::vector<std::pair<std::string, std::string>> node_names;
425 node_names.reserve(node_names_c.size);
426 for (
size_t i = 0; i < node_names_c.size; ++i) {
427 if (node_names_c.data[i] && node_namespaces_c.data[i]) {
428 node_names.emplace_back(node_names_c.data[i], node_namespaces_c.data[i]);
433 rcl_ret_t ret_names = rcutils_string_array_fini(&node_names_c);
434 if (ret_names != RCUTILS_RET_OK) {
435 error = std::string(
"could not destroy node names: ") + rcl_get_error_string().str;
437 rcl_ret_t ret_ns = rcutils_string_array_fini(&node_namespaces_c);
438 if (ret_ns != RCUTILS_RET_OK) {
439 error += std::string(
", could not destroy node namespaces: ") + rcl_get_error_string().str;
442 if (ret_names != RCUTILS_RET_OK || ret_ns != RCUTILS_RET_OK) {
443 RCUTILS_LOG_ERROR_NAMED(
"rclcpp",
"%s", error.c_str());
444 throw std::runtime_error(error);
463 if (ret != RMW_RET_OK) {
465 throw std::runtime_error(
466 std::string(
"could not count publishers: ") + rmw_get_error_string().str);
485 if (ret != RMW_RET_OK) {
487 throw std::runtime_error(
488 std::string(
"could not count subscribers: ") + rmw_get_error_string().str);
507 if (ret != RMW_RET_OK) {
509 throw std::runtime_error(
510 std::string(
"could not count clients: ") + rmw_get_error_string().str);
529 if (ret != RMW_RET_OK) {
531 throw std::runtime_error(
532 std::string(
"could not count services: ") + rmw_get_error_string().str);
548 std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
549 bool bad_ptr_encountered =
false;
550 for (
auto & event_wptr : graph_events_) {
551 auto event_ptr = event_wptr.lock();
555 bad_ptr_encountered =
true;
558 if (bad_ptr_encountered) {
562 graph_events_.begin(),
564 [](
const rclcpp::Event::WeakPtr & wptr) {
565 return wptr.expired();
567 graph_events_.end());
569 graph_users_count_.store(graph_events_.size());
572 graph_cv_.notify_all();
576 throw std::runtime_error(
577 std::string(
"failed to notify wait set on graph change: ") + ex.what());
585 graph_cv_.notify_all();
588 rclcpp::Event::SharedPtr
591 auto event = rclcpp::Event::make_shared();
593 std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
594 graph_events_.push_back(event);
595 graph_users_count_++;
598 if (should_add_to_graph_listener_.exchange(
false)) {
599 node_base_->
get_context()->get_graph_listener()->add_node(
this);
600 node_base_->
get_context()->get_graph_listener()->start_if_not_started();
607 rclcpp::Event::SharedPtr event,
608 std::chrono::nanoseconds timeout)
613 throw InvalidEventError();
616 std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
617 bool event_in_graph_events =
false;
618 for (
const auto & event_wptr : graph_events_) {
619 if (event == event_wptr.lock()) {
620 event_in_graph_events =
true;
624 if (!event_in_graph_events) {
625 throw EventNotRegisteredError();
628 auto pred = [&event, context = node_base_->
get_context()]() {
629 return event->check() || !
rclcpp::ok(context);
631 std::unique_lock<std::mutex> graph_lock(graph_mutex_);
633 graph_cv_.wait_for(graph_lock, timeout, pred);
640 return graph_users_count_.load();
644 std::vector<rclcpp::TopicEndpointInfo>
647 std::vector<rclcpp::TopicEndpointInfo> topic_info_list;
648 topic_info_list.reserve(info_array.size);
649 for (
size_t i = 0; i < info_array.size; ++i) {
650 topic_info_list.emplace_back(info_array.info_array[i]);
652 return topic_info_list;
655 template<const
char * Endpo
intType,
typename FunctionT>
656 static std::vector<rclcpp::TopicEndpointInfo>
659 const std::string & topic_name,
661 FunctionT rcl_get_info_by_topic)
677 if (
nullptr == node_options) {
678 throw std::runtime_error(
"Need valid node options in get_info_by_topic()");
682 global_args = &(rcl_node_handle->context->global_arguments);
685 char * remapped_topic_name =
nullptr;
693 &remapped_topic_name);
695 throw_from_rcl_error(ret, std::string(
"Failed to remap topic name ") + fqdn);
696 }
else if (
nullptr != remapped_topic_name) {
697 fqdn = remapped_topic_name;
698 node_options->
allocator.deallocate(remapped_topic_name, node_options->
allocator.state);
702 rcutils_allocator_t allocator = rcutils_get_default_allocator();
705 rcl_get_info_by_topic(rcl_node_handle, &allocator, fqdn.c_str(), no_mangle, &info_array);
708 std::string(
"Failed to get information by topic for ") + EndpointType + std::string(
":");
710 error_msg += std::string(
"function not supported by RMW_IMPLEMENTATION");
712 error_msg += rcl_get_error_string().str;
716 error_msg += std::string(
", failed also to cleanup topic info array, leaking memory: ") +
717 rcl_get_error_string().str;
720 throw_from_rcl_error(ret, error_msg);
723 std::vector<rclcpp::TopicEndpointInfo> topic_info_list = convert_to_topic_info_list(info_array);
726 throw_from_rcl_error(ret,
"rcl_topic_info_array_fini failed.");
729 return topic_info_list;
732 static constexpr
char kPublisherEndpointTypeName[] =
"publishers";
733 std::vector<rclcpp::TopicEndpointInfo>
735 const std::string & topic_name,
736 bool no_mangle)
const
738 return get_info_by_topic<kPublisherEndpointTypeName>(
745 static constexpr
char kSubscriptionEndpointTypeName[] =
"subscriptions";
746 std::vector<rclcpp::TopicEndpointInfo>
748 const std::string & topic_name,
749 bool no_mangle)
const
751 return get_info_by_topic<kSubscriptionEndpointTypeName>(
759 std::vector<rclcpp::ServiceEndpointInfo>
760 convert_to_service_info_list(
const rcl_service_endpoint_info_array_t & info_array)
762 std::vector<rclcpp::ServiceEndpointInfo> service_info_list;
763 service_info_list.reserve(info_array.size);
764 for (
size_t i = 0; i < info_array.size; ++i) {
765 service_info_list.emplace_back(info_array.info_array[i]);
767 return service_info_list;
770 template<const
char * Endpo
intType,
typename FunctionT>
771 static std::vector<rclcpp::ServiceEndpointInfo>
774 const std::string & service_name,
776 FunctionT rcl_get_info_by_service)
792 if (
nullptr == node_options) {
793 throw std::runtime_error(
"Need valid node options in get_info_by_service()");
797 global_args = &(rcl_node_handle->context->global_arguments);
800 char * remapped_service_name =
nullptr;
808 &remapped_service_name);
810 throw_from_rcl_error(ret, std::string(
"Failed to remap service name ") + fqdn);
811 }
else if (
nullptr != remapped_service_name) {
812 fqdn = remapped_service_name;
813 node_options->
allocator.deallocate(remapped_service_name, node_options->
allocator.state);
817 rcutils_allocator_t allocator = rcutils_get_default_allocator();
818 rcl_service_endpoint_info_array_t info_array =
821 rcl_get_info_by_service(rcl_node_handle, &allocator, fqdn.c_str(), no_mangle, &info_array);
824 std::string(
"Failed to get information by service for ") + EndpointType + std::string(
":");
826 error_msg += std::string(
"function not supported by RMW_IMPLEMENTATION");
828 error_msg += rcl_get_error_string().str;
832 error_msg += std::string(
", failed also to cleanup service info array, leaking memory: ") +
833 rcl_get_error_string().str;
836 throw_from_rcl_error(ret, error_msg);
839 std::vector<rclcpp::ServiceEndpointInfo> service_info_list =
840 convert_to_service_info_list(info_array);
843 throw_from_rcl_error(ret,
"rcl_service_info_array_fini failed.");
846 return service_info_list;
849 static constexpr
char kClientEndpointTypeName[] =
"clients";
850 std::vector<rclcpp::ServiceEndpointInfo>
852 const std::string & service_name,
853 bool no_mangle)
const
855 return get_info_by_service<kClientEndpointTypeName>(
862 static constexpr
char kServerEndpointTypeName[] =
"servers";
863 std::vector<rclcpp::ServiceEndpointInfo>
865 const std::string & service_name,
866 bool no_mangle)
const
868 return get_info_by_service<kServerEndpointTypeName>(
890 return node_namespace_;
896 return node_namespace_;
911 rclcpp::EndpointType &
914 return endpoint_type_;
917 const rclcpp::EndpointType &
920 return endpoint_type_;
923 std::array<uint8_t, RMW_GID_STORAGE_SIZE> &
926 return endpoint_gid_;
929 const std::array<uint8_t, RMW_GID_STORAGE_SIZE> &
932 return endpoint_gid_;
950 return topic_type_hash_;
953 const rosidl_type_hash_t &
956 return topic_type_hash_;
974 return node_namespace_;
980 return node_namespace_;
986 return service_type_;
992 return service_type_;
995 rclcpp::EndpointType &
998 return endpoint_type_;
1001 const rclcpp::EndpointType &
1004 return endpoint_type_;
1010 return endpoint_count_;
1016 return endpoint_count_;
1019 std::vector<std::array<uint8_t, RMW_GID_STORAGE_SIZE>> &
1022 return endpoint_gids_;
1025 const std::vector<std::array<uint8_t, RMW_GID_STORAGE_SIZE>> &
1028 return endpoint_gids_;
1031 std::vector<rclcpp::QoS> &
1034 return qos_profiles_;
1037 const std::vector<rclcpp::QoS> &
1040 return qos_profiles_;
1043 rosidl_type_hash_t &
1046 return service_type_hash_;
1049 const rosidl_type_hash_t &
1052 return service_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 rclcpp::EndpointType & endpoint_type()
Get a mutable reference to the service endpoint type.
RCLCPP_PUBLIC std::string & node_name()
Get a mutable reference to the node name.
RCLCPP_PUBLIC size_t & endpoint_count()
Get a mutable reference to the endpoint count.
RCLCPP_PUBLIC rosidl_type_hash_t & service_type_hash()
Get a mutable reference to the type hash of the service endpoint.
RCLCPP_PUBLIC std::vector< rclcpp::QoS > & qos_profiles()
Get a mutable reference to the QoS profile of the service endpoint.
RCLCPP_PUBLIC std::string & node_namespace()
Get a mutable reference to the node namespace.
RCLCPP_PUBLIC std::vector< std::array< uint8_t, RMW_GID_STORAGE_SIZE > > & endpoint_gids()
Get a mutable reference to the GID of the service endpoint.
RCLCPP_PUBLIC std::string & service_type()
Get a mutable reference to the service type string.
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 std::vector< rclcpp::ServiceEndpointInfo > get_clients_info_by_service(const std::string &service_name, bool no_mangle=false) const override
Return the service endpoint information about clients on a given service.
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 std::vector< rclcpp::ServiceEndpointInfo > get_servers_info_by_service(const std::string &service_name, bool no_mangle=false) const override
Return the service endpoint information about servers on 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_get_servers_info_by_service(const rcl_node_t *node, rcutils_allocator_t *allocator, const char *service_name, bool no_mangle, rcl_service_endpoint_info_array_t *servers_info)
Return a list of all servers to a service.
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.
#define rcl_service_endpoint_info_array_fini
Finalize a service_endpoint_info_array_t structure.
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.
#define rcl_get_zero_initialized_service_endpoint_info_array
Return a zero-initialized rcl_service_endpoint_info_t structure.
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_get_clients_info_by_service(const rcl_node_t *node, rcutils_allocator_t *allocator, const char *service_name, bool no_mangle, rcl_service_endpoint_info_array_t *clients_info)
Return a list of all clients to a service.
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(const rclcpp::Context::SharedPtr &context=rclcpp::contexts::get_global_default_context())
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_service_name(const rcl_arguments_t *local_arguments, const rcl_arguments_t *global_arguments, const char *service_name, const char *node_name, const char *node_namespace, rcl_allocator_t allocator, char **output_name)
Remap a service name based on given rules.
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.