Eduardo Reis
Eduardo Reis

Reputation: 1971

How to list nodes in ROS with `rclpy`?

I want to obtain the same result as ros2 node list using rclpy but I haven't found a way yet.

Here is what I have tried.

import rclpy

rclpy.init()

node = rclpy.create_node("list_nodes_example")

# Use the get_node_names_and_namespaces() method to get the list of nodes and their namespaces
node_namespaces = node.get_node_names_and_namespaces()

# Print out the nodes and their namespaces
for name, namespace in node_namespaces:
    print(namespace + name)

node.destroy_node()
rclpy.shutdown()

This only show the node it creates instead of all the nodes in the ROS workspace.

Upvotes: 2

Views: 2681

Answers (2)

wew84
wew84

Reputation: 41

You can access the code of what ros2 node list does as it's Python.

import rclpy
from ros2node.api import get_node_names

rclpy.init()
node = rclpy.create_node("list_nodes_example")
available_nodes = get_node_names(node=node, include_hidden_nodes=False)
for name, namespace, full_name in available_nodes:
    print(f"Found node {name} in namespace {namespace} (full name: {full_name}")
node.destroy_node()
rclpy.shutdown()

Upvotes: 3

BTables
BTables

Reputation: 4843

get_node_names_and_namespaces actually shows all the discovered nodes from the current node's context, not nodes it has created. There isn't a (clean) way to do this using the Node class since it serves as an endpoint and doesn't have in depth knowledge of the system as a whole; because it doesn't need to.

In ROS1 there was the rosnode package, but to my knowledge there is no equivalent in ROS2. Unfortunately, your best option is probably to run the command directly inside the script. Depending on frequency of calls, you can either use sys.command or subprocess. For example:

import subprocess
cmd_str = 'source /opt/ros/foxy/setup.bash;ros2 node list'

node_list = subprocess.run(cmd_str, shell=True)
print(node_list)

Upvotes: 1

Related Questions