Skip to content
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
5 changes: 5 additions & 0 deletions rclpy/rclpy/action/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
# limitations under the License.

from .client import ActionClient as ActionClient # noqa: F401
# The following graph functions are deprecated.
# Use the corresponding methods on the Node class instead:
# - node.get_action_client_names_and_types_by_node()
# - node.get_action_server_names_and_types_by_node()
# - node.get_action_names_and_types()
from .graph import ( # noqa: F401
get_action_client_names_and_types_by_node as get_action_client_names_and_types_by_node
)
Expand Down
39 changes: 34 additions & 5 deletions rclpy/rclpy/action/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

from typing import List
from typing import Tuple
import warnings

from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy
from rclpy.node import Node


Expand All @@ -26,16 +28,25 @@ def get_action_client_names_and_types_by_node(
"""
Get a list of action names and types for action clients associated with a node.

.. deprecated:: (upcoming release)
Use :meth:`rclpy.node.Node.get_action_client_names_and_types_by_node` instead.

:param node: The node used for discovery.
:param remote_node_name: The name of a remote node to get action clients for.
:param node_namespace: Namespace of the remote node.
:return: List of tuples.
The first element of each tuple is the action name and the second element is a list of
action types.
"""
warnings.warn(
'rclpy.action.get_action_client_names_and_types_by_node() is deprecated. '
'Use rclpy.node.Node.get_action_client_names_and_types_by_node() instead.',
DeprecationWarning,
stacklevel=2
)
with node.handle:
return node.handle.get_action_client_names_and_types_by_node(
remote_node_name, remote_node_namespace)
return _rclpy.rclpy_get_action_client_names_and_types_by_node(
node.handle, remote_node_name, remote_node_namespace)


def get_action_server_names_and_types_by_node(
Expand All @@ -46,26 +57,44 @@ def get_action_server_names_and_types_by_node(
"""
Get a list of action names and types for action servers associated with a node.

.. deprecated:: (upcoming release)
Use :meth:`rclpy.node.Node.get_action_server_names_and_types_by_node` instead.

:param node: The node used for discovery.
:param remote_node_name: The name of a remote node to get action servers for.
:param node_namespace: Namespace of the remote node.
:return: List of tuples.
The first element of each tuple is the action name and the second element is a list of
action types.
"""
warnings.warn(
'rclpy.action.get_action_server_names_and_types_by_node() is deprecated. '
'Use rclpy.node.Node.get_action_server_names_and_types_by_node() instead.',
DeprecationWarning,
stacklevel=2
)
with node.handle:
return node.handle.get_action_server_names_and_types_by_node(
remote_node_name, remote_node_namespace)
return _rclpy.rclpy_get_action_server_names_and_types_by_node(
node.handle, remote_node_name, remote_node_namespace)


def get_action_names_and_types(node: Node) -> List[Tuple[str, List[str]]]:
"""
Get a list of action names and types.

.. deprecated:: (upcoming release)
Use :meth:`rclpy.node.Node.get_action_names_and_types` instead.

:param node: The node used for discovery.
:return: List of action names and types in the ROS graph as tuples.
The first element of each tuple is the action name and the second element is a list of
action types.
"""
warnings.warn(
'rclpy.action.get_action_names_and_types() is deprecated. '
'Use rclpy.node.Node.get_action_names_and_types() instead.',
DeprecationWarning,
stacklevel=2
)
with node.handle:
return node.handle.get_action_names_and_types()
return _rclpy.rclpy_get_action_names_and_types(node.handle)
16 changes: 16 additions & 0 deletions rclpy/rclpy/impl/_rclpy_pybind11.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,22 @@ def rclpy_get_client_names_and_types_by_node(node: Node, node_name: str, node_na
"""Get service names and types for which a remote node has servers."""


def rclpy_get_action_client_names_and_types_by_node(node: Node, node_name: str,
node_namespace: str
) -> list[tuple[str, list[str]]]:
"""Get action client names and types by node."""


def rclpy_get_action_server_names_and_types_by_node(node: Node, node_name: str,
node_namespace: str
) -> list[tuple[str, list[str]]]:
"""Get action server names and types by node."""


def rclpy_get_action_names_and_types(node: Node) -> list[tuple[str, list[str]]]:
"""Get all action names and types in the ROS graph."""


def rclpy_serialize(pymsg: Msg, py_msg_type: type[Msg]) -> bytes:
"""Serialize a ROS message."""

Expand Down
51 changes: 51 additions & 0 deletions rclpy/rclpy/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -2142,6 +2142,57 @@ def get_client_names_and_types_by_node(
return _rclpy.rclpy_get_client_names_and_types_by_node(
self.handle, node_name, node_namespace)

def get_action_client_names_and_types_by_node(
self,
node_name: str,
node_namespace: str
) -> List[Tuple[str, List[str]]]:
"""
Get a list of action names and types for action clients associated with a remote node.

:param node_name: Name of a remote node to get action clients for.
:param node_namespace: Namespace of the remote node.
:return: List of tuples.
The first element of each tuple is the action name and the second element is a list of
action types.
:raise NodeNameNonExistentError: If the node wasn't found.
:raise RuntimeError: Unexpected failure.
"""
with self.handle:
return _rclpy.rclpy_get_action_client_names_and_types_by_node(
self.handle, node_name, node_namespace)

def get_action_server_names_and_types_by_node(
self,
node_name: str,
node_namespace: str
) -> List[Tuple[str, List[str]]]:
"""
Get a list of action names and types for action servers associated with a remote node.

:param node_name: Name of a remote node to get action servers for.
:param node_namespace: Namespace of the remote node.
:return: List of tuples.
The first element of each tuple is the action name and the second element is a list of
action types.
:raise NodeNameNonExistentError: If the node wasn't found.
:raise RuntimeError: Unexpected failure.
"""
with self.handle:
return _rclpy.rclpy_get_action_server_names_and_types_by_node(
self.handle, node_name, node_namespace)

def get_action_names_and_types(self) -> List[Tuple[str, List[str]]]:
"""
Get a list of action names and types in the ROS graph.

:return: List of tuples.
The first element of each tuple is the action name and the second element is a list of
action types.
"""
with self.handle:
return _rclpy.rclpy_get_action_names_and_types(self.handle)

def get_topic_names_and_types(self, no_demangle: bool = False) -> List[Tuple[str, List[str]]]:
"""
Get a list of discovered topic names and types.
Expand Down
13 changes: 12 additions & 1 deletion rclpy/src/rclpy/_rclpy_pybind11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,18 @@ PYBIND11_MODULE(_rclpy_pybind11, m) {
"rclpy_get_client_names_and_types_by_node",
&rclpy::graph_get_client_names_and_types_by_node,
"Get service names and types for which a remote node has clients.");

m.def(
"rclpy_get_action_client_names_and_types_by_node",
&rclpy::graph_get_action_client_names_and_types_by_node,
"Get action client names and types by node.");
m.def(
"rclpy_get_action_server_names_and_types_by_node",
&rclpy::graph_get_action_server_names_and_types_by_node,
"Get action server names and types by node.");
m.def(
"rclpy_get_action_names_and_types",
&rclpy::graph_get_action_names_and_types,
"Get all action names and types in the ROS graph.");
m.def(
"rclpy_serialize", &rclpy::serialize,
"Serialize a ROS message.");
Expand Down
91 changes: 91 additions & 0 deletions rclpy/src/rclpy/graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <rcl/allocator.h>
#include <rcl/error_handling.h>
#include <rcl/graph.h>
#include <rcl_action/graph.h>
#include <rcutils/error_handling.h>

#include <string>
Expand Down Expand Up @@ -343,4 +344,94 @@ graph_get_servers_info_by_service(
rcl_get_servers_info_by_service);
}

py::list
graph_get_action_client_names_and_types_by_node(
Node & node, std::string node_name, std::string node_namespace)
{
rcl_names_and_types_t action_names_and_types = rcl_get_zero_initialized_names_and_types();
rcl_allocator_t allocator = rcl_get_default_allocator();
rcl_ret_t ret = rcl_action_get_client_names_and_types_by_node(
node.rcl_ptr(), &allocator, node_name.c_str(), node_namespace.c_str(),
&action_names_and_types);
if (RCL_RET_OK != ret) {
if (RCL_RET_NODE_NAME_NON_EXISTENT == ret) {
throw NodeNameNonExistentError(
"cannot get action client names and types for nonexistent node");
}
throw RCLError("failed to get action client names and types");
}
RCPPUTILS_SCOPE_EXIT(
{
ret = rcl_names_and_types_fini(&action_names_and_types);
if (RCL_RET_OK != ret) {
RCUTILS_SAFE_FWRITE_TO_STDERR(
"[rclpy|" RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__LINE__) "]: "
"failed to fini action client names and types during error handling: ");
RCUTILS_SAFE_FWRITE_TO_STDERR(rcl_get_error_string().str);
RCUTILS_SAFE_FWRITE_TO_STDERR("\n");
rcl_reset_error();
}
});

return convert_to_py_names_and_types(&action_names_and_types);
}

py::list
graph_get_action_server_names_and_types_by_node(
Node & node, std::string node_name, std::string node_namespace)
{
rcl_names_and_types_t action_names_and_types = rcl_get_zero_initialized_names_and_types();
rcl_allocator_t allocator = rcl_get_default_allocator();
rcl_ret_t ret = rcl_action_get_server_names_and_types_by_node(
node.rcl_ptr(), &allocator, node_name.c_str(), node_namespace.c_str(),
&action_names_and_types);
if (RCL_RET_OK != ret) {
if (RCL_RET_NODE_NAME_NON_EXISTENT == ret) {
throw NodeNameNonExistentError(
"cannot get action server names and types for nonexistent node");
}
throw RCLError("failed to get action server names and types");
}
RCPPUTILS_SCOPE_EXIT(
{
ret = rcl_names_and_types_fini(&action_names_and_types);
if (RCL_RET_OK != ret) {
RCUTILS_SAFE_FWRITE_TO_STDERR(
"[rclpy|" RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__LINE__) "]: "
"failed to fini action server names and types during error handling: ");
RCUTILS_SAFE_FWRITE_TO_STDERR(rcl_get_error_string().str);
RCUTILS_SAFE_FWRITE_TO_STDERR("\n");
rcl_reset_error();
}
});

return convert_to_py_names_and_types(&action_names_and_types);
}

py::list
graph_get_action_names_and_types(Node & node)
{
rcl_names_and_types_t action_names_and_types = rcl_get_zero_initialized_names_and_types();
rcl_allocator_t allocator = rcl_get_default_allocator();
rcl_ret_t ret = rcl_action_get_names_and_types(
node.rcl_ptr(), &allocator, &action_names_and_types);
if (RCL_RET_OK != ret) {
throw RCLError("failed to get action names and types");
}
RCPPUTILS_SCOPE_EXIT(
{
ret = rcl_names_and_types_fini(&action_names_and_types);
if (RCL_RET_OK != ret) {
RCUTILS_SAFE_FWRITE_TO_STDERR(
"[rclpy|" RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__LINE__) "]: "
"failed to fini action names and types during error handling: ");
RCUTILS_SAFE_FWRITE_TO_STDERR(rcl_get_error_string().str);
RCUTILS_SAFE_FWRITE_TO_STDERR("\n");
rcl_reset_error();
}
});

return convert_to_py_names_and_types(&action_names_and_types);
}

} // namespace rclpy
47 changes: 47 additions & 0 deletions rclpy/src/rclpy/graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,53 @@ py::list
graph_get_servers_info_by_service(
Node & node, const char * service_name, bool no_mangle);

/// Get action client names and types by node.
/**
* Raises NodeNameNonExistentError if the remote node was not found
* Raises RCLError if there is an rcl error
*
* \param[in] node Node to get action client names and types
* \param[in] node_name Name of the remote node to query.
* \param[in] node_namespace Namespace of the remote node to query.
* \return List of tuples, where the first element of each tuple is the action
* name (string) and the second element is a list of action types (list of
* strings).
* \see rcl_action_get_client_names_and_types_by_node
*/
py::list
graph_get_action_client_names_and_types_by_node(
Node & node, std::string node_name, std::string node_namespace);

/// Get action server names and types by node.
/**
* Raises NodeNameNonExistentError if the remote node was not found
* Raises RCLError if there is an rcl error
*
* \param[in] node Node to get action server names and types
* \param[in] node_name Name of the remote node to query.
* \param[in] node_namespace Namespace of the remote node to query.
* \return List of tuples, where the first element of each tuple is the action
* name (string) and the second element is a list of action types (list of
* strings).
* \see rcl_action_get_server_names_and_types_by_node
*/
py::list
graph_get_action_server_names_and_types_by_node(
Node & node, std::string node_name, std::string node_namespace);

/// Get all action names and types in the ROS graph.
/**
* Raises RCLError if there is an rcl error
*
* \param[in] node Node to get action names and types
* \return List of tuples, where the first element of each tuple is the action
* name (string) and the second element is a list of action types (list of
* strings).
* \see rcl_action_get_names_and_types
*/
py::list
graph_get_action_names_and_types(Node & node);

} // namespace rclpy

#endif // RCLPY__GRAPH_HPP_
3 changes: 3 additions & 0 deletions rclpy/src/rclpy/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ py::list
Node::get_action_client_names_and_types_by_node(
const char * remote_node_name, const char * remote_node_namespace)
{
// Deprecated: Use _rclpy.rclpy_get_action_client_names_and_types_by_node function instead
rcl_names_and_types_t names_and_types = rcl_get_zero_initialized_names_and_types();
rcl_allocator_t allocator = rcl_get_default_allocator();
rcl_ret_t ret = rcl_action_get_client_names_and_types_by_node(
Expand All @@ -554,6 +555,7 @@ py::list
Node::get_action_server_names_and_types_by_node(
const char * remote_node_name, const char * remote_node_namespace)
{
// Deprecated: Use _rclpy.rclpy_get_action_server_names_and_types_by_node function instead
rcl_names_and_types_t names_and_types = rcl_get_zero_initialized_names_and_types();
rcl_allocator_t allocator = rcl_get_default_allocator();
rcl_ret_t ret = rcl_action_get_server_names_and_types_by_node(
Expand All @@ -572,6 +574,7 @@ Node::get_action_server_names_and_types_by_node(
py::list
Node::get_action_names_and_types()
{
// Deprecated: Use _rclpy.rclpy_get_action_names_and_types function instead
rcl_names_and_types_t names_and_types = rcl_get_zero_initialized_names_and_types();
rcl_allocator_t allocator = rcl_get_default_allocator();
rcl_ret_t ret = rcl_action_get_names_and_types(rcl_node_.get(), &allocator, &names_and_types);
Expand Down
Loading