rospy unload to reconnect python node

asked 2016-06-29 16:42:24 -0600

updated 2020-02-14 12:47:12 -0600

Essentially what I need here is to reconnect a python node without restarting the process. Ideally this should work:

#!/usr/bin/python
import rosgraph
import time
import os
import rospy
import std_msgs

m = os.environ['ROS_MASTER_URI']
firstime = True
def msg_callback(msg):
    rospy.loginfo(msg)

while True:
    connected = rosgraph.is_master_online(m)
    time.sleep(1)
    print("waiting master ...")

    if connected:
        rospy.init_node("test_node")
        sub = rospy.Subscriber("/chatter", std_msgs.msg.String, msg_callback)
        r = rospy.Rate(1)
        while not rospy.is_shutdown() and rosgraph.is_master_online(m):
            rospy.loginfo("alive")
            r.sleep()

    print("master lost ...")

It does not work, until the moment the only solution I found is restarting the process. My current idea is that I could "clean" the internal state of rospy to "mimic" that "process restarting".

However I do not find the way to execute the rospy.init_node a second time like it were a clean node initialization.

I have tested several approaches:

  • Using the rospy.shutdown_signal method

  • using the python imp.reload method to reload the rospy package

With these approaches I am able to execute again the rospy.init_node method without any error, however when I use some other method from rospy I get errors. For instance using rospy.set_param method I get this error:

 rospy.set_param("myparamname", myparamvalue)
 File "/opt/ros/indigo/lib/python2.7/dist-packages/rospy/client.py", line 502, in set_param
_param_server[param_name] = param_value #MasterProxy does all the magic for us
File "/opt/ros/indigo/lib/python2.7/dist-packages/rospy/msproxy.py", line 148, in __setitem__
self.target.setParam(rospy.names.get_caller_id(), rospy.names.resolve_name(key), val)
File "/usr/lib/python2.7/xmlrpclib.py", line 1224, in __call__
return self.__send(self.__name, args)
File "/usr/lib/python2.7/xmlrpclib.py", line 1578, in __request
verbose=self.__verbose
File "/usr/lib/python2.7/xmlrpclib.py", line 1264, in request
return self.single_request(host, handler, request_body, verbose)
File "/usr/lib/python2.7/xmlrpclib.py", line 1292, in single_request
self.send_content(h, request_body)
File "/usr/lib/python2.7/xmlrpclib.py", line 1439, in send_content
connection.endheaders(request_body)
File "/usr/lib/python2.7/httplib.py", line 958, in endheaders
self._send_output(message_body)
File "/usr/lib/python2.7/httplib.py", line 818, in _send_output
self.send(msg)
File "/usr/lib/python2.7/httplib.py", line 780, in send
self.connect()
File "/usr/lib/python2.7/httplib.py", line 761, in connect
self.timeout, self.source_address)
File "/usr/lib/python2.7/socket.py", line 571, in create_connection
raise err
error: [Errno 97] Address family not supported by protocol
edit retag flag offensive close merge delete

Comments

This is not supported. I've seen one or two other questions asking the same thing, and they've generally gone un-answered.

ahendrix gravatar imageahendrix ( 2016-06-29 16:54:02 -0600 )edit

I see. :-(

Pablo Iñigo Blasco gravatar imagePablo Iñigo Blasco ( 2016-06-29 16:59:12 -0600 )edit

Perhaps if you tell us why you think you "have to relaunch a node without killing the whole process", we could see whether there is an alternative approach that could work (just to avoid an xy-problem).

gvdhoorn gravatar imagegvdhoorn ( 2016-06-30 03:41:28 -0600 )edit

Some years after, again with the same issue :-) the idea is essentially being able to reconnect without restarting the python process. I edited the question so the goals may be now clear.

Pablo Iñigo Blasco gravatar imagePablo Iñigo Blasco ( 2020-02-14 12:21:20 -0600 )edit
1

It would still help if you could tell us why you want to do this. You've only clarified what you want to do.

gvdhoorn gravatar imagegvdhoorn ( 2020-02-15 06:08:51 -0600 )edit

In this case I have a graphic interface developed in pyside that is the main interface of the whole robotic system. It is GUI is designed to be used by non-expert people and it should be able to work standalone (ie: even without the rosmaster working or any network issue)

Pablo Iñigo Blasco gravatar imagePablo Iñigo Blasco ( 2020-02-16 17:15:57 -0600 )edit

Ignoring the question whether this is possible or not: ROS 1's networking code was (initially, and mostly) written with "perfect networks" in mind. Whether that is a valid assumption or not is a different question, but this means that dealing with lost connections is not something which is built-in at every level.

There is also an (implicit) assumption about process==single node and that restarting the node means restarting the process. In ROS 2, this is all different, but you appear to be using ROS 1.

As such, I'm afraid this (ie: reinitialising a node) is simply not supported at the moment (or at least not with the regular rospy, roscpp over the TCPROS and UDPROS transports).

Using a transport or client library that does know how to deal with this may be a lot easier than trying to shoe-horn a solution on-top of rospy. One of the ...(more)

gvdhoorn gravatar imagegvdhoorn ( 2020-02-17 02:47:05 -0600 )edit

You could of course also try to track down where this error is being thrown. Could be it's a simple fix.

gvdhoorn gravatar imagegvdhoorn ( 2020-02-17 03:16:57 -0600 )edit