ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
2

Unable to see topic published from subprocess

asked 2015-07-26 22:21:14 -0600

heuristicus gravatar image

updated 2015-07-27 20:27:19 -0600

I'm trying to use subprocesses spawned by a rospy node to provide information about topics in a distributed fashion, but am unable to see any messages published by the subprocess. The following is a short piece of code that can be used to illustrate the problem:

#!/usr/bin/env python
import rospy
import sys
from std_msgs.msg import String
from multiprocessing import Process
from threading import Thread

def talker():
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rate = rospy.Rate(10)
    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

def talkerprocess():
    pub = rospy.Publisher('process', String, queue_size=10)
    rospy.init_node('process', anonymous=True)

    t1 = Process(target=talker)
    t1.start()

    while not rospy.is_shutdown():
        rate = rospy.Rate(10)
        pub.publish("process string %s" % rospy.get_time())
        rate.sleep()

def talkerthread():
    pub = rospy.Publisher('thread', String, queue_size=10)
    rospy.init_node('thread', anonymous=True)

    t1 = Thread(target=talker)
    t1.start()

    while not rospy.is_shutdown():
        rate = rospy.Rate(10)
        pub.publish("thread string %s" % rospy.get_time())
        rate.sleep()

if __name__ == '__main__':
    args = rospy.myargv(argv=sys.argv)
    try:
        if (len(args) < 2):
            method = 'process'
        else:
            method = args[1]

        if (method == 'process'):
            print("Publishing hello world from subprocess.")
            talkerprocess()
        elif (method == 'thread'):
            print("Publishing hello world from thread.")
            talkerthread()
        else:
            print("Unknown method %s." % method)
    except rospy.ROSInterruptException:
        pass

Running this node using rosrun [package] [filename] thread will run the talker function in a thread, while passing process as an argument instead will spawn a subprocess using the multiprocessing module. In the first case, using rostopic echo /chatter and rostopic echo /thread will show the messages from both the spawned thread and the original thread. However, if we spawn a subprocess instead, we do not see the messages on /chatter published from the subprocess, while the messages on the /process topic are visible.

I've looked at the logs from a run of the node when spawning a subprocess. The chatter topic never seems to be registered, but this is the same for when running with a spawned thread instead. In both cases the topic is visible using rostopic list, but messages are only received when spawning threads.

edit: I think this is probably because things are running in a different thread/process, so they don't go into the log, but I can't find them elsewhere in the log directory either.

Here's the rqt_graph of the program. The main process is 20486, and the spawned process, 20504, is nowhere to be seen.

rqt_graph of process

Is this behaviour intentional, or is this a bug? Is the mechanism between publishing and subscribing somehow based on process IDs?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2015-07-29 01:37:07 -0600

heuristicus gravatar image

updated 2015-07-29 01:37:31 -0600

I had a look in the rospy code. I think that the problem is that the publisher in the subprocess does not have a QueuedConnection object added to its connections list. The connections are added in a separate thread which is spawned by the main process when the node is initialised.

Specifically, client.py::init_node line 337 starts the TCPROS server, calling tcpros_base::start which launches a thread to run the run function which accepts connections. Connections are then created on line 165, via the route inbound_handler->tcpros_base::_tcp_server_callback->self.topic_connection_handler->tcpros_pubsub::TCPROSHandler::topic_connection_handler->topics::add_connection->tcpros_pubsub::QueuedConnection . It seems that this does not modify the topic that exists in the subprocess, and so the publisher never gets any connections in the subprocess, whereas if it were in the main process things would be OK.

edit flag offensive delete link more

Question Tools

3 followers

Stats

Asked: 2015-07-26 22:21:14 -0600

Seen: 1,075 times

Last updated: Jul 29 '15