$search
00001 #!/usr/bin/env python 00002 00003 import roslib 00004 roslib.load_manifest('foreign_relay') 00005 00006 import sys 00007 import os 00008 import time 00009 import xmlrpclib 00010 import urlparse 00011 00012 USAGE = 'foreign_relay.py {adv|sub} topic foreign_master_uri' 00013 00014 g_publishers = {} 00015 00016 # Clean up the stuff that we registered 00017 def shutdown(foreign_master_uri): 00018 server = xmlrpclib.ServerProxy(foreign_master_uri) 00019 for p in g_publishers: 00020 server.unregisterPublisher(p, topic, g_publishers[p]) 00021 print 'unregistering %s @ %s'%(p,g_publishers[p]) 00022 00023 def go(mode, topic, foreign_master_uri, update_period): 00024 publishers = {} 00025 if mode == 'sub': 00026 sub_uri = foreign_master_uri 00027 adv_uri = os.environ['ROS_MASTER_URI'] 00028 else: 00029 sub_uri = os.environ['ROS_MASTER_URI'] 00030 adv_uri = foreign_master_uri 00031 server_sub = xmlrpclib.ServerProxy(sub_uri) 00032 server_adv = xmlrpclib.ServerProxy(adv_uri) 00033 while 1: 00034 code, msg, topics = server_sub.getPublishedTopics('', '') 00035 # Determine the type of the topic 00036 type = None 00037 for t in topics: 00038 if t[0] == topic: 00039 type = t[1] 00040 break 00041 # Find publishers 00042 if type is not None: 00043 new_publishers = {} 00044 code, msg, state = server_sub.getSystemState('') 00045 pubs = state[0] 00046 for t in pubs: 00047 if t[0] == topic: 00048 for p in t[1]: 00049 # Hack to avoid circular re-subscription 00050 dup = False 00051 for pp in publishers: 00052 if p.startswith(pp): 00053 #print '%s is dup of %s; skipping'%(p,pp) 00054 dup = True 00055 break 00056 if dup: 00057 continue 00058 code, msg, uri = server_sub.lookupNode('', p) 00059 # Uniquify by master 00060 sp = urlparse.urlsplit(sub_uri) 00061 mangled_name = '%s_%s_%s'%(p,sp.hostname,sp.port) 00062 new_publishers[mangled_name] = uri 00063 # Update remote advertisements appropriately 00064 subtractions = set(publishers.keys()) - set(new_publishers.keys()) 00065 additions = set(new_publishers.keys()) - set(publishers.keys()) 00066 for s in subtractions: 00067 server_adv.unregisterPublisher(s, topic, publishers[s]) 00068 print 'unregistering %s @ %s'%(s,publishers[s]) 00069 for a in additions: 00070 server_adv.registerPublisher(a, topic, type, new_publishers[a]) 00071 print 'registering %s @ %s'%(a,new_publishers[a]) 00072 publishers = new_publishers 00073 global g_publishers 00074 g_publishers = publishers 00075 time.sleep(update_period) 00076 00077 def parse(argvin): 00078 argv = [] 00079 # Remove the ROS arguments. 00080 for arg in argvin: 00081 if arg.find(":=") == -1: 00082 argv.append(arg) 00083 if len(argv) != 4: 00084 print USAGE 00085 return None 00086 mode = argv[1] 00087 if mode != 'sub' and mode != 'adv': 00088 print USAGE 00089 return None 00090 topic = argv[2] 00091 foreign_master_uri = argv[3] 00092 return (mode, topic, foreign_master_uri) 00093 00094 if __name__ == '__main__': 00095 ret = parse(sys.argv) 00096 if ret is None: 00097 sys.exit(1) 00098 mode, topic, foreign_master_uri = ret 00099 update_period = 1.0 00100 try: 00101 go(mode, topic, foreign_master_uri, update_period) 00102 except KeyboardInterrupt, e: 00103 if mode == 'adv': 00104 shutdown(foreign_master_uri) 00105 else: 00106 shutdown(os.environ['ROS_MASTER_URI'])