Unable to see topic published from subprocess
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.
Is this behaviour intentional, or is this a bug? Is the mechanism between publishing and subscribing somehow based on process IDs?
Asked by heuristicus on 2015-07-26 22:21:14 UTC
Answers
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.
Asked by heuristicus on 2015-07-29 01:37:07 UTC
Comments