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


foreign_relay
Author(s): Blaise Gassend
autogenerated on Mon Dec 2 2013 13:03:53