Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add clients & services count #2072

Merged
merged 6 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions rclcpp/include/rclcpp/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,26 @@ class Node : public std::enable_shared_from_this<Node>
size_t
count_subscribers(const std::string & topic_name) const;

/// Return the number of clients created for a given service.
/**
* \param[in] service_name the actual service name used; it will not be automatically remapped.
* \return number of clients that have been created for the given service.
* \throws std::runtime_error if clients could not be counted
*/
RCLCPP_PUBLIC
size_t
count_clients(const std::string & service_name) const;

/// Return the number of services created for a given service.
/**
* \param[in] service_name the actual service name used; it will not be automatically remapped.
* \return number of services that have been created for the given service.
* \throws std::runtime_error if services could not be counted
*/
RCLCPP_PUBLIC
size_t
count_services(const std::string & service_name) const;

/// Return the topic endpoint information about publishers on a given topic.
/**
* The returned parameter is a list of topic endpoint information, where each item will contain
Expand Down
8 changes: 8 additions & 0 deletions rclcpp/include/rclcpp/node_interfaces/node_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ class NodeGraph : public NodeGraphInterface
size_t
count_subscribers(const std::string & topic_name) const override;

RCLCPP_PUBLIC
size_t
count_clients(const std::string & service_name) const override;

RCLCPP_PUBLIC
size_t
count_services(const std::string & service_name) const override;

RCLCPP_PUBLIC
const rcl_guard_condition_t *
get_graph_guard_condition() const override;
Expand Down
18 changes: 18 additions & 0 deletions rclcpp/include/rclcpp/node_interfaces/node_graph_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,24 @@ class NodeGraphInterface
size_t
count_subscribers(const std::string & topic_name) const = 0;

/// Return the number of clients created for a given service.
/*
* \param[in] service_name the actual service name used; it will not be automatically remapped.
*/
RCLCPP_PUBLIC
virtual
size_t
count_clients(const std::string & service_name) const = 0;

/// Return the number of services created for a given service.
/*
* \param[in] service_name the actual service name used; it will not be automatically remapped.
*/
RCLCPP_PUBLIC
virtual
size_t
count_services(const std::string & service_name) const = 0;

/// Return the rcl guard condition which is triggered when the ROS graph changes.
RCLCPP_PUBLIC
virtual
Expand Down
3 changes: 3 additions & 0 deletions rclcpp/include/rclcpp/rclcpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
* - Get the number of publishers or subscribers on a topic:
* - rclcpp::Node::count_publishers()
* - rclcpp::Node::count_subscribers()
* - Get the number of clients or servers on a service:
* - rclcpp::Node::count_clients()
* - rclcpp::Node::count_services()
*
* And components related to logging:
*
Expand Down
12 changes: 12 additions & 0 deletions rclcpp/src/rclcpp/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,18 @@ Node::count_subscribers(const std::string & topic_name) const
return node_graph_->count_subscribers(topic_name);
}

size_t
Node::count_clients(const std::string & service_name) const
{
return node_graph_->count_clients(service_name);
}

size_t
Node::count_services(const std::string & service_name) const
{
return node_graph_->count_services(service_name);
}

std::vector<rclcpp::TopicEndpointInfo>
Node::get_publishers_info_by_topic(const std::string & topic_name, bool no_mangle) const
{
Expand Down
44 changes: 44 additions & 0 deletions rclcpp/src/rclcpp/node_interfaces/node_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,50 @@ NodeGraph::count_subscribers(const std::string & topic_name) const
return count;
}

size_t
NodeGraph::count_clients(const std::string & service_name) const
{
auto rcl_node_handle = node_base_->get_rcl_node_handle();

auto fqdn = rclcpp::expand_topic_or_service_name(
service_name,
rcl_node_get_name(rcl_node_handle),
rcl_node_get_namespace(rcl_node_handle),
true);

size_t count;
auto ret = rcl_count_clients(rcl_node_handle, fqdn.c_str(), &count);
if (ret != RMW_RET_OK) {
// *INDENT-OFF*
throw std::runtime_error(
std::string("could not count clients: ") + rmw_get_error_string().str);
// *INDENT-ON*
}
return count;
}

size_t
NodeGraph::count_services(const std::string & service_name) const
{
auto rcl_node_handle = node_base_->get_rcl_node_handle();

auto fqdn = rclcpp::expand_topic_or_service_name(
service_name,
rcl_node_get_name(rcl_node_handle),
rcl_node_get_namespace(rcl_node_handle),
true);

size_t count;
auto ret = rcl_count_services(rcl_node_handle, fqdn.c_str(), &count);
if (ret != RMW_RET_OK) {
// *INDENT-OFF*
throw std::runtime_error(
std::string("could not count services: ") + rmw_get_error_string().str);
// *INDENT-ON*
}
return count;
}

const rcl_guard_condition_t *
NodeGraph::get_graph_guard_condition() const
{
Expand Down
19 changes: 19 additions & 0 deletions rclcpp/test/rclcpp/node_interfaces/test_node_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ TEST_F(TestNodeGraph, construct_from_node)

EXPECT_EQ(0u, node_graph()->count_publishers("not_a_topic"));
EXPECT_EQ(0u, node_graph()->count_subscribers("not_a_topic"));
EXPECT_EQ(0u, node_graph()->count_clients("not_a_service"));
EXPECT_EQ(0u, node_graph()->count_services("not_a_service"));

EXPECT_NE(nullptr, node_graph()->get_graph_guard_condition());

// get_graph_event is non-const
Expand Down Expand Up @@ -534,6 +537,22 @@ TEST_F(TestNodeGraph, count_subscribers_rcl_error)
std::runtime_error("could not count subscribers: error not set"));
}

TEST_F(TestNodeGraph, count_clients_rcl_error)
{
auto mock = mocking_utils::patch_and_return("lib:rclcpp", rcl_count_clients, RCL_RET_ERROR);
RCLCPP_EXPECT_THROW_EQ(
node_graph()->count_clients("service"),
std::runtime_error("could not count clients: error not set"));
}

TEST_F(TestNodeGraph, count_services_rcl_error)
{
auto mock = mocking_utils::patch_and_return("lib:rclcpp", rcl_count_services, RCL_RET_ERROR);
RCLCPP_EXPECT_THROW_EQ(
node_graph()->count_services("service"),
std::runtime_error("could not count services: error not set"));
}

TEST_F(TestNodeGraph, notify_shutdown)
{
EXPECT_NO_THROW(node()->get_node_graph_interface()->notify_shutdown());
Expand Down
3 changes: 3 additions & 0 deletions rclcpp/test/rclcpp/test_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3311,6 +3311,9 @@ TEST_F(TestNode, get_entity_names) {
const auto service_names_and_types = node->get_service_names_and_types();
EXPECT_EQ(service_names_and_types.end(), service_names_and_types.find("service"));

EXPECT_EQ(0u, node->count_clients("service"));
EXPECT_EQ(0u, node->count_services("service"));

const auto service_names_and_types_by_node =
node->get_service_names_and_types_by_node("node", "/ns");
EXPECT_EQ(
Expand Down
16 changes: 16 additions & 0 deletions rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,22 @@ class LifecycleNode : public node_interfaces::LifecycleNodeInterface,
size_t
count_subscribers(const std::string & topic_name) const;

/// Return the number of clients created for a given service.
/**
* \sa rclcpp::Node::count_clients
*/
RCLCPP_LIFECYCLE_PUBLIC
size_t
count_clients(const std::string & service_name) const;

/// Return the number of services created for a given service.
/**
* \sa rclcpp::Node::count_services
*/
RCLCPP_LIFECYCLE_PUBLIC
size_t
count_services(const std::string & service_name) const;

/// Return the topic endpoint information about publishers on a given topic.
/**
* \sa rclcpp::Node::get_publishers_info_by_topic
Expand Down
12 changes: 12 additions & 0 deletions rclcpp_lifecycle/src/lifecycle_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,18 @@ LifecycleNode::count_subscribers(const std::string & topic_name) const
return node_graph_->count_subscribers(topic_name);
}

size_t
LifecycleNode::count_clients(const std::string & service_name) const
{
return node_graph_->count_clients(service_name);
}

size_t
LifecycleNode::count_services(const std::string & service_name) const
{
return node_graph_->count_services(service_name);
}

std::vector<rclcpp::TopicEndpointInfo>
LifecycleNode::get_publishers_info_by_topic(const std::string & topic_name, bool no_mangle) const
{
Expand Down
11 changes: 11 additions & 0 deletions rclcpp_lifecycle/test/test_lifecycle_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,17 @@ TEST_F(TestDefaultStateMachine, test_graph_services) {
EXPECT_STREQ(
service_names_and_types["/testnode/get_transition_graph"][0].c_str(),
"lifecycle_msgs/srv/GetAvailableTransitions");

EXPECT_EQ(0u, test_node->count_clients("/testnode/change_state"));
EXPECT_EQ(0u, test_node->count_clients("/testnode/get_available_states"));
EXPECT_EQ(0u, test_node->count_clients("/testnode/get_available_transitions"));
EXPECT_EQ(0u, test_node->count_clients("/testnode/get_state"));
EXPECT_EQ(0u, test_node->count_clients("/testnode/get_transition_graph"));
EXPECT_EQ(1u, test_node->count_services("/testnode/change_state"));
EXPECT_EQ(1u, test_node->count_services("/testnode/get_available_states"));
EXPECT_EQ(1u, test_node->count_services("/testnode/get_available_transitions"));
EXPECT_EQ(1u, test_node->count_services("/testnode/get_state"));
EXPECT_EQ(1u, test_node->count_services("/testnode/get_transition_graph"));
}

TEST_F(TestDefaultStateMachine, test_graph_services_by_node) {
Expand Down