diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 62e8a5c..ff464f6 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -916,6 +916,12 @@ public: void register_param_change_callback(CallbackT && callback); + + /// Get the fully-qualified names of all available nodes. + /** + * The fully-qualified name includes the local namespace and name of the node. + * \return A vector of fully-qualified names of nodes. + */ RCLCPP_PUBLIC std::vector get_node_names() const; diff --git a/rclcpp/src/rclcpp/node_interfaces/node_graph.cpp b/rclcpp/src/rclcpp/node_interfaces/node_graph.cpp index d03e781..48d087f 100644 --- a/rclcpp/src/rclcpp/node_interfaces/node_graph.cpp +++ b/rclcpp/src/rclcpp/node_interfaces/node_graph.cpp @@ -14,6 +14,7 @@ #include "rclcpp/node_interfaces/node_graph.hpp" +#include #include #include #include @@ -136,9 +137,24 @@ NodeGraph::get_node_names() const std::vector nodes; auto names_and_namespaces = get_node_names_and_namespaces(); - for (const auto & it : names_and_namespaces) { - nodes.push_back(it.first); - } + std::transform(names_and_namespaces.begin(), + names_and_namespaces.end(), + std::back_inserter(nodes), + [](std::pair nns) { + std::string return_string; + if (nns.second.back() == '/') { + return_string = nns.second + nns.first; + } else { + return_string = nns.second + '/' + nns.first; + } + // Quick check to make sure that we start with a slash + // Since fully-qualified strings need to + if (return_string.front() != '/') { + return_string = "/" + return_string; + } + return return_string; + } + ); return nodes; } @@ -173,10 +189,12 @@ NodeGraph::get_node_names_and_namespaces() const throw std::runtime_error(error_msg); } - std::vector> node_names(node_names_c.size); + + std::vector> node_names; + node_names.reserve(node_names_c.size); for (size_t i = 0; i < node_names_c.size; ++i) { if (node_names_c.data[i] && node_namespaces_c.data[i]) { - node_names.push_back(std::make_pair(node_names_c.data[i], node_namespaces_c.data[i])); + node_names.emplace_back(node_names_c.data[i], node_namespaces_c.data[i]); } } diff --git a/rclcpp/test/test_node.cpp b/rclcpp/test/test_node.cpp index 6dc7e70..bb3ac35 100644 --- a/rclcpp/test/test_node.cpp +++ b/rclcpp/test/test_node.cpp @@ -14,9 +14,10 @@ #include -#include #include #include +#include +#include #include #include "rclcpp/exceptions.hpp" @@ -99,6 +100,23 @@ TEST_F(TestNode, get_name_and_namespace) { EXPECT_STREQ("/my/ns", node->get_namespace()); EXPECT_STREQ("/my/ns/my_node", node->get_fully_qualified_name()); } + { + auto node1 = std::make_shared("my_node1", "my/ns"); + auto node2 = std::make_shared("my_node2", "my/ns"); + auto node3 = std::make_shared("my_node3", "/ns2"); + auto node4 = std::make_shared("my_node4", "my/ns3"); + auto names_and_namespaces = node1->get_node_names(); + auto name_namespace_set = std::unordered_set(names_and_namespaces.begin(), + names_and_namespaces.end()); + std::function Set_Contains = [&](std::string string_key) + { + return name_namespace_set.find(string_key) != name_namespace_set.end(); + }; + EXPECT_TRUE(Set_Contains("/my/ns/my_node1")); + EXPECT_TRUE(Set_Contains("/my/ns/my_node2")); + EXPECT_TRUE(Set_Contains("/ns2/my_node3")); + EXPECT_TRUE(Set_Contains("/my/ns3/my_node4")); + } } TEST_F(TestNode, subnode_get_name_and_namespace) { diff --git a/rclcpp_components/test/test_component_manager_api.cpp b/rclcpp_components/test/test_component_manager_api.cpp index e1db03a..3e267b5 100644 --- a/rclcpp_components/test/test_component_manager_api.cpp +++ b/rclcpp_components/test/test_component_manager_api.cpp @@ -117,10 +117,10 @@ TEST_F(TestComponentManager, load_components) return std::find(node_names.begin(), node_names.end(), name) != node_names.end(); }; - EXPECT_TRUE(find_in_nodes("test_component_foo")); - EXPECT_TRUE(find_in_nodes("test_component_bar")); - EXPECT_TRUE(find_in_nodes("test_component_baz")); - EXPECT_TRUE(find_in_nodes("test_component_bing")); + EXPECT_TRUE(find_in_nodes("/test_component_foo")); + EXPECT_TRUE(find_in_nodes("/test_component_bar")); + EXPECT_TRUE(find_in_nodes("/test_component_baz")); + EXPECT_TRUE(find_in_nodes("/ns/test_component_bing")); } TEST_F(TestComponentManager, load_invalid_components) @@ -263,7 +263,7 @@ TEST_F(TestComponentManager, unload_component) auto find_in_nodes = [node_names](std::string name) { return std::find(node_names.begin(), node_names.end(), name) != node_names.end(); }; - EXPECT_TRUE(find_in_nodes("test_component_foo")); + EXPECT_TRUE(find_in_nodes("/test_component_foo")); { auto client = node->create_client(