00001
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
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
00036 type = None
00037 for t in topics:
00038 if t[0] == topic:
00039 type = t[1]
00040 break
00041
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
00050 dup = False
00051 for pp in publishers:
00052 if p.startswith(pp):
00053
00054 dup = True
00055 break
00056 if dup:
00057 continue
00058 code, msg, uri = server_sub.lookupNode('', p)
00059
00060 sp = urlparse.urlsplit(sub_uri)
00061 mangled_name = '%s_%s_%s'%(p,sp.hostname,sp.port)
00062 new_publishers[mangled_name] = uri
00063
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
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'])