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 "rclcpp/utilities.hpp"
33 #include "rcpputils/scope_exit.hpp"
36 using rclcpp::exceptions::throw_from_rcl_error;
40 : node_base_(node_base),
41 should_add_to_graph_listener_(true),
45 NodeGraph::~NodeGraph()
50 if (!should_add_to_graph_listener_.exchange(
false)) {
52 node_base_->
get_context()->get_graph_listener()->remove_node(
this);
56 std::map<std::string, std::vector<std::string>>
66 &topic_names_and_types);
68 auto error_msg = std::string(
"failed to get topic names and types: ") +
69 rcl_get_error_string().str;
72 error_msg += std::string(
", failed also to cleanup topic names and types, leaking memory: ") +
73 rcl_get_error_string().str;
76 throw std::runtime_error(error_msg);
79 std::map<std::string, std::vector<std::string>> topics_and_types;
80 for (
size_t i = 0; i < topic_names_and_types.names.size; ++i) {
81 std::string topic_name = topic_names_and_types.names.data[i];
82 for (
size_t j = 0; j < topic_names_and_types.types[i].size; ++j) {
83 topics_and_types[topic_name].emplace_back(topic_names_and_types.types[i].data[j]);
90 throw std::runtime_error(
91 std::string(
"could not destroy topic names and types: ") + rcl_get_error_string().str);
95 return topics_and_types;
98 std::map<std::string, std::vector<std::string>>
107 &service_names_and_types);
109 auto error_msg = std::string(
"failed to get service names and types: ") +
110 rcl_get_error_string().str;
114 std::string(
", failed also to cleanup service names and types, leaking memory: ") +
115 rcl_get_error_string().str;
118 throw std::runtime_error(error_msg);
121 std::map<std::string, std::vector<std::string>> services_and_types;
122 for (
size_t i = 0; i < service_names_and_types.names.size; ++i) {
123 std::string service_name = service_names_and_types.names.data[i];
124 for (
size_t j = 0; j < service_names_and_types.types[i].size; ++j) {
125 services_and_types[service_name].emplace_back(service_names_and_types.types[i].data[j]);
132 throw std::runtime_error(
133 std::string(
"could not destroy service names and types: ") + rcl_get_error_string().str);
137 return services_and_types;
140 std::map<std::string, std::vector<std::string>>
142 const std::string & node_name,
143 const std::string & namespace_)
const
152 &service_names_and_types);
154 auto error_msg = std::string(
"failed to get service names and types by node: ") +
155 rcl_get_error_string().str;
159 std::string(
", failed also to cleanup service names and types, leaking memory: ") +
160 rcl_get_error_string().str;
163 throw std::runtime_error(error_msg);
166 std::map<std::string, std::vector<std::string>> services_and_types;
167 for (
size_t i = 0; i < service_names_and_types.names.size; ++i) {
168 std::string service_name = service_names_and_types.names.data[i];
169 for (
size_t j = 0; j < service_names_and_types.types[i].size; ++j) {
170 services_and_types[service_name].emplace_back(service_names_and_types.types[i].data[j]);
176 throw_from_rcl_error(ret,
"could not destroy service names and types");
179 return services_and_types;
182 std::map<std::string, std::vector<std::string>>
184 const std::string & node_name,
185 const std::string & namespace_)
const
188 auto service_names_and_types_finalizer = rcpputils::make_scope_exit(
189 [&service_names_and_types]() {
201 &service_names_and_types);
203 throw_from_rcl_error(ret,
"failed to get service names and types by node");
206 std::map<std::string, std::vector<std::string>> services_and_types;
207 for (
size_t i = 0; i < service_names_and_types.names.size; ++i) {
208 std::string service_name = service_names_and_types.names.data[i];
209 for (
size_t j = 0; j < service_names_and_types.types[i].size; ++j) {
210 services_and_types[service_name].emplace_back(service_names_and_types.types[i].data[j]);
214 return services_and_types;
217 std::map<std::string, std::vector<std::string>>
219 const std::string & node_name,
220 const std::string & namespace_,
221 bool no_demangle)
const
224 auto topic_names_and_types_finalizer = rcpputils::make_scope_exit(
225 [&topic_names_and_types]() {
238 &topic_names_and_types);
240 throw_from_rcl_error(ret,
"failed to get topic names and types by node");
243 std::map<std::string, std::vector<std::string>> topics_and_types;
244 for (
size_t i = 0; i < topic_names_and_types.names.size; ++i) {
245 std::string topic_name = topic_names_and_types.names.data[i];
246 for (
size_t j = 0; j < topic_names_and_types.types[i].size; ++j) {
247 topics_and_types[topic_name].emplace_back(topic_names_and_types.types[i].data[j]);
251 return topics_and_types;
254 std::map<std::string, std::vector<std::string>>
256 const std::string & node_name,
257 const std::string & namespace_,
258 bool no_demangle)
const
261 auto topic_names_and_types_finalizer = rcpputils::make_scope_exit(
262 [&topic_names_and_types]() {
275 &topic_names_and_types);
277 throw_from_rcl_error(ret,
"failed to get topic names and types by node");
280 std::map<std::string, std::vector<std::string>> topics_and_types;
281 for (
size_t i = 0; i < topic_names_and_types.names.size; ++i) {
282 std::string topic_name = topic_names_and_types.names.data[i];
283 for (
size_t j = 0; j < topic_names_and_types.types[i].size; ++j) {
284 topics_and_types[topic_name].emplace_back(topic_names_and_types.types[i].data[j]);
288 return topics_and_types;
291 std::vector<std::string>
294 std::vector<std::string> nodes;
298 names_and_namespaces.begin(),
299 names_and_namespaces.end(),
300 std::back_inserter(nodes),
301 [](std::pair<std::string, std::string> nns) {
302 std::string return_string;
303 if (nns.second.back() ==
'/') {
304 return_string = nns.second + nns.first;
306 return_string = nns.second +
'/' + nns.first;
310 if (return_string.front() !=
'/') {
311 return_string =
"/" + return_string;
313 return return_string;
319 std::vector<std::tuple<std::string, std::string, std::string>>
322 rcutils_string_array_t node_names_c =
323 rcutils_get_zero_initialized_string_array();
324 rcutils_string_array_t node_namespaces_c =
325 rcutils_get_zero_initialized_string_array();
326 rcutils_string_array_t node_enclaves_c =
327 rcutils_get_zero_initialized_string_array();
338 std::string(
"failed to get node names with enclaves: ") + rcl_get_error_string().str;
340 if (rcutils_string_array_fini(&node_names_c) != RCUTILS_RET_OK) {
341 error_msg += std::string(
", failed also to cleanup node names, leaking memory: ") +
342 rcl_get_error_string().str;
345 if (rcutils_string_array_fini(&node_namespaces_c) != RCUTILS_RET_OK) {
346 error_msg += std::string(
", failed also to cleanup node namespaces, leaking memory: ") +
347 rcl_get_error_string().str;
350 if (rcutils_string_array_fini(&node_enclaves_c) != RCUTILS_RET_OK) {
351 error_msg += std::string(
", failed also to cleanup node enclaves, leaking memory: ") +
352 rcl_get_error_string().str;
355 throw std::runtime_error(error_msg);
358 std::vector<std::tuple<std::string, std::string, std::string>> node_tuples;
359 for (
size_t i = 0; i < node_names_c.size; ++i) {
360 if (node_names_c.data[i] && node_namespaces_c.data[i] && node_enclaves_c.data[i]) {
361 node_tuples.emplace_back(
362 std::make_tuple(node_names_c.data[i], node_namespaces_c.data[i], node_enclaves_c.data[i]));
366 std::string error(
"failed to finalize array");
367 rcl_ret_t ret_names = rcutils_string_array_fini(&node_names_c);
368 if (ret_names != RCUTILS_RET_OK) {
369 error += std::string(
", could not destroy node names, leaking memory: ") +
370 rcl_get_error_string().str;
373 rcl_ret_t ret_ns = rcutils_string_array_fini(&node_namespaces_c);
374 if (ret_ns != RCUTILS_RET_OK) {
375 error += std::string(
", could not destroy node namespaces, leaking memory: ") +
376 rcl_get_error_string().str;
380 rcl_ret_t ret_ecv = rcutils_string_array_fini(&node_enclaves_c);
381 if (ret_ecv != RCUTILS_RET_OK) {
382 error += std::string(
", could not destroy node enclaves, leaking memory: ") +
383 rcl_get_error_string().str;
387 if (ret_names != RCUTILS_RET_OK || ret_ns != RCUTILS_RET_OK || ret_ecv != RCUTILS_RET_OK) {
388 throw std::runtime_error(error);
394 std::vector<std::pair<std::string, std::string>>
397 rcutils_string_array_t node_names_c =
398 rcutils_get_zero_initialized_string_array();
399 rcutils_string_array_t node_namespaces_c =
400 rcutils_get_zero_initialized_string_array();
409 auto error_msg = std::string(
"failed to get node names: ") + rcl_get_error_string().str;
411 if (rcutils_string_array_fini(&node_names_c) != RCUTILS_RET_OK) {
412 error_msg += std::string(
", failed also to cleanup node names, leaking memory: ") +
413 rcl_get_error_string().str;
416 if (rcutils_string_array_fini(&node_namespaces_c) != RCUTILS_RET_OK) {
417 error_msg += std::string(
", failed also to cleanup node namespaces, leaking memory: ") +
418 rcl_get_error_string().str;
421 RCUTILS_LOG_ERROR_NAMED(
"rclcpp",
"%s", error_msg.c_str());
422 throw std::runtime_error(error_msg);
425 std::vector<std::pair<std::string, std::string>> node_names;
426 node_names.reserve(node_names_c.size);
427 for (
size_t i = 0; i < node_names_c.size; ++i) {
428 if (node_names_c.data[i] && node_namespaces_c.data[i]) {
429 node_names.emplace_back(node_names_c.data[i], node_namespaces_c.data[i]);
434 rcl_ret_t ret_names = rcutils_string_array_fini(&node_names_c);
435 if (ret_names != RCUTILS_RET_OK) {
436 error = std::string(
"could not destroy node names: ") + rcl_get_error_string().str;
438 rcl_ret_t ret_ns = rcutils_string_array_fini(&node_namespaces_c);
439 if (ret_ns != RCUTILS_RET_OK) {
440 error += std::string(
", could not destroy node namespaces: ") + rcl_get_error_string().str;
443 if (ret_names != RCUTILS_RET_OK || ret_ns != RCUTILS_RET_OK) {
444 RCUTILS_LOG_ERROR_NAMED(
"rclcpp",
"%s", error.c_str());
445 throw std::runtime_error(error);
464 if (ret != RMW_RET_OK) {
466 throw std::runtime_error(
467 std::string(
"could not count publishers: ") + rmw_get_error_string().str);
486 if (ret != RMW_RET_OK) {
488 throw std::runtime_error(
489 std::string(
"could not count subscribers: ") + rmw_get_error_string().str);
508 if (ret != RMW_RET_OK) {
510 throw std::runtime_error(
511 std::string(
"could not count clients: ") + rmw_get_error_string().str);
530 if (ret != RMW_RET_OK) {
532 throw std::runtime_error(
533 std::string(
"could not count services: ") + rmw_get_error_string().str);
549 std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
550 bool bad_ptr_encountered =
false;
551 for (
auto & event_wptr : graph_events_) {
552 auto event_ptr = event_wptr.lock();
556 bad_ptr_encountered =
true;
559 if (bad_ptr_encountered) {
563 graph_events_.begin(),
565 [](
const rclcpp::Event::WeakPtr & wptr) {
566 return wptr.expired();
568 graph_events_.end());
570 graph_users_count_.store(graph_events_.size());
573 graph_cv_.notify_all();
577 throw std::runtime_error(
578 std::string(
"failed to notify wait set on graph change: ") + ex.what());
586 graph_cv_.notify_all();
589 rclcpp::Event::SharedPtr
592 auto event = rclcpp::Event::make_shared();
594 std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
595 graph_events_.push_back(event);
596 graph_users_count_++;
599 if (should_add_to_graph_listener_.exchange(
false)) {
600 node_base_->
get_context()->get_graph_listener()->add_node(
this);
601 node_base_->
get_context()->get_graph_listener()->start_if_not_started();
608 rclcpp::Event::SharedPtr event,
609 std::chrono::nanoseconds timeout)
614 throw InvalidEventError();
617 std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
618 bool event_in_graph_events =
false;
619 for (
const auto & event_wptr : graph_events_) {
620 if (event == event_wptr.lock()) {
621 event_in_graph_events =
true;
625 if (!event_in_graph_events) {
626 throw EventNotRegisteredError();
629 auto pred = [&event, context = node_base_->
get_context()]() {
630 return event->check() || !
rclcpp::ok(context);
632 std::unique_lock<std::mutex> graph_lock(graph_mutex_);
634 graph_cv_.wait_for(graph_lock, timeout, pred);
641 return graph_users_count_.load();
645 std::vector<rclcpp::TopicEndpointInfo>
648 std::vector<rclcpp::TopicEndpointInfo> topic_info_list;
649 topic_info_list.reserve(info_array.size);
650 for (
size_t i = 0; i < info_array.size; ++i) {
651 topic_info_list.emplace_back(info_array.info_array[i]);
653 return topic_info_list;
656 template<const
char * Endpo
intType,
typename FunctionT>
657 static std::vector<rclcpp::TopicEndpointInfo>
660 const std::string & topic_name,
662 FunctionT rcl_get_info_by_topic)
678 if (
nullptr == node_options) {
679 throw std::runtime_error(
"Need valid node options in get_info_by_topic()");
683 global_args = &(rcl_node_handle->context->global_arguments);
686 char * remapped_topic_name =
nullptr;
694 &remapped_topic_name);
696 throw_from_rcl_error(ret, std::string(
"Failed to remap topic name ") + fqdn);
697 }
else if (
nullptr != remapped_topic_name) {
698 fqdn = remapped_topic_name;
699 node_options->
allocator.deallocate(remapped_topic_name, node_options->
allocator.state);
703 rcutils_allocator_t allocator = rcutils_get_default_allocator();
706 rcl_get_info_by_topic(rcl_node_handle, &allocator, fqdn.c_str(), no_mangle, &info_array);
709 std::string(
"Failed to get information by topic for ") + EndpointType + std::string(
":");
711 error_msg += std::string(
"function not supported by RMW_IMPLEMENTATION");
713 error_msg += rcl_get_error_string().str;
717 error_msg += std::string(
", failed also to cleanup topic info array, leaking memory: ") +
718 rcl_get_error_string().str;
721 throw_from_rcl_error(ret, error_msg);
724 std::vector<rclcpp::TopicEndpointInfo> topic_info_list = convert_to_topic_info_list(info_array);
727 throw_from_rcl_error(ret,
"rcl_topic_info_array_fini failed.");
730 return topic_info_list;
733 static constexpr
char kPublisherEndpointTypeName[] =
"publishers";
734 std::vector<rclcpp::TopicEndpointInfo>
736 const std::string & topic_name,
737 bool no_mangle)
const
739 return get_info_by_topic<kPublisherEndpointTypeName>(
746 static constexpr
char kSubscriptionEndpointTypeName[] =
"subscriptions";
747 std::vector<rclcpp::TopicEndpointInfo>
749 const std::string & topic_name,
750 bool no_mangle)
const
752 return get_info_by_topic<kSubscriptionEndpointTypeName>(
760 std::vector<rclcpp::ServiceEndpointInfo>
761 convert_to_service_info_list(
const rcl_service_endpoint_info_array_t & info_array)
763 std::vector<rclcpp::ServiceEndpointInfo> service_info_list;
764 service_info_list.reserve(info_array.size);
765 for (
size_t i = 0; i < info_array.size; ++i) {
766 service_info_list.emplace_back(info_array.info_array[i]);
768 return service_info_list;
771 template<const
char * Endpo
intType,
typename FunctionT>
772 static std::vector<rclcpp::ServiceEndpointInfo>
775 const std::string & service_name,
777 FunctionT rcl_get_info_by_service)
793 if (
nullptr == node_options) {
794 throw std::runtime_error(
"Need valid node options in get_info_by_service()");
798 global_args = &(rcl_node_handle->context->global_arguments);
801 char * remapped_service_name =
nullptr;
809 &remapped_service_name);
811 throw_from_rcl_error(ret, std::string(
"Failed to remap service name ") + fqdn);
812 }
else if (
nullptr != remapped_service_name) {
813 fqdn = remapped_service_name;
814 node_options->
allocator.deallocate(remapped_service_name, node_options->
allocator.state);
818 rcutils_allocator_t allocator = rcutils_get_default_allocator();
819 rcl_service_endpoint_info_array_t info_array =
822 rcl_get_info_by_service(rcl_node_handle, &allocator, fqdn.c_str(), no_mangle, &info_array);
825 std::string(
"Failed to get information by service for ") + EndpointType + std::string(
":");
827 error_msg += std::string(
"function not supported by RMW_IMPLEMENTATION");
829 error_msg += rcl_get_error_string().str;
833 error_msg += std::string(
", failed also to cleanup service info array, leaking memory: ") +
834 rcl_get_error_string().str;
837 throw_from_rcl_error(ret, error_msg);
840 std::vector<rclcpp::ServiceEndpointInfo> service_info_list =
841 convert_to_service_info_list(info_array);
844 throw_from_rcl_error(ret,
"rcl_service_info_array_fini failed.");
847 return service_info_list;
850 static constexpr
char kClientEndpointTypeName[] =
"clients";
851 std::vector<rclcpp::ServiceEndpointInfo>
853 const std::string & service_name,
854 bool no_mangle)
const
856 return get_info_by_service<kClientEndpointTypeName>(
863 static constexpr
char kServerEndpointTypeName[] =
"servers";
864 std::vector<rclcpp::ServiceEndpointInfo>
866 const std::string & service_name,
867 bool no_mangle)
const
869 return get_info_by_service<kServerEndpointTypeName>(
891 return node_namespace_;
897 return node_namespace_;
912 rclcpp::EndpointType &
915 return endpoint_type_;
918 const rclcpp::EndpointType &
921 return endpoint_type_;
924 std::array<uint8_t, RMW_GID_STORAGE_SIZE> &
927 return endpoint_gid_;
930 const std::array<uint8_t, RMW_GID_STORAGE_SIZE> &
933 return endpoint_gid_;
951 return topic_type_hash_;
954 const rosidl_type_hash_t &
957 return topic_type_hash_;
975 return node_namespace_;
981 return node_namespace_;
987 return service_type_;
993 return service_type_;
996 rclcpp::EndpointType &
999 return endpoint_type_;
1002 const rclcpp::EndpointType &
1005 return endpoint_type_;
1011 return endpoint_count_;
1017 return endpoint_count_;
1020 std::vector<std::array<uint8_t, RMW_GID_STORAGE_SIZE>> &
1023 return endpoint_gids_;
1026 const std::vector<std::array<uint8_t, RMW_GID_STORAGE_SIZE>> &
1029 return endpoint_gids_;
1032 std::vector<rclcpp::QoS> &
1035 return qos_profiles_;
1038 const std::vector<rclcpp::QoS> &
1041 return qos_profiles_;
1044 rosidl_type_hash_t &
1047 return service_type_hash_;
1050 const rosidl_type_hash_t &
1053 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.