0
$\begingroup$

Rosanswers logo

I would like to get the process ID of ROS nodes (preferably by ROS node name). Are there any limitations when getting the pid by ROS node name? Are there any generic patterns which I can refer to?

I thought about "grepping" for "ros" in the ps listed processes:

ps ax | grep ros

17963 pts/1    Sl+    0:00 /usr/bin/python /opt/ros/indigo/bin/roscore
17975 ?        Ssl    0:00 /usr/bin/python /opt/ros/indigo/bin/rosmaster --core -p 11311 -w 3 __log:=/home/kromer/.ros/log/9db6e284-a466-11e7-b8cd-28f10e310550/master.log
17988 ?        Ssl    0:00 /opt/ros/indigo/lib/rosout/rosout __name:=rosout __log:=/home/kromer/.ros/log/9db6e284-a466-11e7-b8cd-28f10e310550/rosout-1.log
18007 pts/16   S+     0:00 grep --color=auto ros

... or using pgrep to get the pid by ROS node name:

pgrep roscore
17963

pgrep rosmaster
17975

pgrep rosout
17988

(top and htop seemed not suitable.)


Originally posted by thinwybk on ROS Answers with karma: 468 on 2017-09-28

Post score: 2


Original comments

Comment by gvdhoorn on 2017-09-29:
Note btw that this is a classic xy-problem: you ask "how to identify ROS node processes", but you really just want to retrieve of list of PIDs of ROS nodes.

Comment by thinwybk on 2017-09-29:
That's true, thanks for that hint.

Comment by Kurt Leucht on 2017-09-29:
are you looking for the "system" ros nodes (roscore, etc.) or are you looking for ros nodes that users (including yourself) have compiled and started on your machine?

Comment by thinwybk on 2017-09-29:
I am looking primarily for ROS nodes that users are running... not on my machine but on a remote machine.

Comment by gvdhoorn on 2017-09-30:
@Kurt Leucht: small nitpick: afaik, roscore is not considered a node.

Comment by Kurt Leucht on 2017-10-02:
Good to know. Thanks.

Comment by itfanr on 2018-08-29:
There are not elfin_joint_controller_spawner spawned nodes. Is it a bug?

Comment by gvdhoorn on 2018-08-29:
Did you post this under the right question?

Comment by itfanr on 2018-08-30:
I am sorry. I thought a controller_manager will spawn a node before. Now I have known that controller_manager is just a process to inject a library to a hardware controller node and die.

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

Tools like pgrep could definitely work, but perhaps the Slave API would be more efficient (and perhaps less error prone). Specifically the getPid(..) service.


Edit: try this. It prints the PIDs of all nodes known to a specific ROS master.

If you don't specify a XMLRPC URI of a specific ROS master, it will use whatever is currently configured in your shell (ie: the value of the ROS_MASTER_URI env var).

The same information can be retrieved using a bare-bones XMLRPC (Python) client, but it would be a bit more work. It would avoid the dependency on rosgraph and rosnode, so could work from any OS with a suitable XMLRPC client.

#!/usr/bin/env python
import rosnode
import rosgraph
import sys
import argparse

# lots of things 'borrowed' from rosnode

try:
    from xmlrpc.client import ServerProxy
except ImportError:
    from xmlrpclib import ServerProxy

parser = argparse.ArgumentParser()
parser.add_argument('ROS_MASTER_URI', type=str, nargs='?', metavar='URI', help='ROS master URI to use.')
args = parser.parse_args()

ID = '/rosnode'
master = rosgraph.Master(ID, master_uri=args.ROS_MASTER_URI)
print ("Using master at {}".format(master.getUri()))

nodes = rosnode.get_node_names()
print ("Known nodes: " + ', '.join(nodes))

for node in nodes:
    print ("  " + node)

    node_api = rosnode.get_api_uri(master, node)
    if not node_api:
        print("    API URI: error (unknown node: {}?)".format(node))
        continue
    print ("    API URI: " + node_api)

    node = ServerProxy(node_api)
    pid = rosnode._succeed(node.getPid(ID))
    print ("    PID    : {}".format(pid))

Most of this is done by rosnode as well, so I used that as a reference. See ros_comm/rosnode/src/rosnode/init.py.


Originally posted by gvdhoorn with karma: 86574 on 2017-09-28

This answer was ACCEPTED on the original site

Post score: 3


Original comments

Comment by thinwybk on 2017-09-28:
Thanks for that hint. Do you know about an example where the Slave API is used and where I can have a "quick start" into how to use the API?

Comment by gvdhoorn on 2017-09-29:
The Master API page provides a short snippet that shows how this works.

Comment by gvdhoorn on 2017-09-29:
But note that it's all XMLRPC, so any info you can find on XMLRPC should apply here. It's not ROS specific.

Comment by thinwybk on 2017-09-29:
I had a quick look at the APIs. I am interested in getting the process IDs of ROS nodes which are running in another machine. There shouldn't be the need for the "requested" machine to know about the requesting machine. I am not sure if the Slave API is suitable then...

Comment by thinwybk on 2017-09-29:
...to make it more clear what I am interested in: I thought about ssh login into the requested machine, execute pgrep for the ROS node of interest, capturing the process ID from stdout, and sending the information to the requesting machine.

Comment by gvdhoorn on 2017-09-29:
As long as the "[an]other machine" is using the same ROS master as the one that wants to know the PIDs, the Slave and Master API can be used. Using the same ROS master as the "other machine" could even be done temporarily (on the requesting machine).

If pgrep works for you, then by all means use it.

I just wanted to point out that the ROS master keeps track of all nodes -- which you could then interrogate as to what their PID is. pgrep-ing will require you know the names of the processes already, and is - I believe - less robust (ie: anything can match).

Comment by gvdhoorn on 2017-09-29:\

There shouldn't be the need for the "requested" machine to know about the requesting machine

As far as I know, that is also not required. The XMLRPC API is client-server: you are the client, nodes and master are the servers.

Comment by thinwybk on 2017-09-29:
I would prefer the Slave APi over pgrep due to a better robustness. (I would prefer to avoid to "modify" the "requested" machines ROS system in any way as well... means prefering of pgrep.) Can you guide me to more info about how to use the same ROS master for nodes on a different machine?

Comment by gvdhoorn on 2017-09-29:
There is no need to change anything, anywhere. See the small bit of Python I put together.

Comment by thinwybk on 2017-09-29:
Ok, now I understand. Thanks a lot for the Python example. (I prefer a solution which doesn't depend on rosnode and rosgraph.)

Comment by timwheeler on 2019-02-14:
Is this rospy-only? I'm having trouble finding roscpp resources for this. In the c++ version I seem to be getting the process id of master whenever I call ros::master::execute("getPid", args, result, payload, true).

Comment by gvdhoorn on 2019-02-15:
I would be surprised if that would be the case, but I honestly have no idea.


Edit: the ROS Master API is just XML-RPC and the master maintains registrations of all nodes. There cannot be anything client-library specific to it.

$\endgroup$
0
$\begingroup$

Rosanswers logo

With rosnode list you have the list of nodes.

If you want the PID of the node /rosout, for example, you can use:

rosnode info /rosout 2>/dev/null | grep Pid| cut -d' ' -f2

If a node named /rosout exists, the PID (like 5027) will be shown. Otherwise, nothing will be printed because we are redirecting the error to /dev/null


Originally posted by Ruben Alves with karma: 1038 on 2017-09-29

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by Robomaker on 2022-03-08:
Using this command in program will take time instead of this you should use "pgrep nodename" or use Slave API in py.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.