rtmlaunch.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import roslib
00004 roslib.load_manifest('openrtm_tools')
00005 
00006 import sys
00007 import os
00008 import time
00009 import optparse
00010 
00011 from xml.dom.minidom import parse
00012 
00013 import rtctree
00014 from rtshell import rtcon
00015 from rtshell import path
00016 from rtshell import state_control_base
00017 from rtshell import rts_exceptions
00018 
00019 def alive_component(path):
00020     tree=rtctree.tree.RTCTree()
00021     if tree.has_path(path) and tree.is_component(path):
00022         node = tree.get_node(path)
00023         return node.plain_state_string
00024     else:
00025         return False
00026 
00027 def wait_component(cmd_path):
00028     count=0
00029     path = rtctree.path.parse_path(cmd_path)[0]
00030     node = alive_component(path)
00031     while not node and count < 30:
00032         node = alive_component(path)
00033         print >>sys.stderr, "\033[33m[rtmlaunch] Wait for ",cmd_path," ",count,"/30\033[0m"
00034         count += 1
00035         time.sleep(1)
00036     if not node:
00037         raise rts_exceptions.NoSuchObjectError(cmd_path)
00038     return node
00039 
00040 def check_connect(src_path, dest_path):
00041     tree=rtctree.tree.RTCTree()
00042     src_path, src_port = rtctree.path.parse_path(src_path)
00043     dest_path, dest_port = rtctree.path.parse_path(dest_path)
00044     src_node = tree.get_node(src_path)
00045     dest_node = tree.get_node(dest_path)
00046     port = src_node.get_port_by_name(src_port)
00047     for conn in port.connections:
00048         for name, p in conn.ports:
00049             tmp_dest_path, tmp_dest_port = rtctree.path.parse_path(name)
00050             if dest_path[-1] == tmp_dest_path[-1] and dest_port == tmp_dest_port:
00051                 return True
00052     return False
00053 
00054 def rtconnect(nameserver, tags):
00055     import re
00056     for tag in tags:
00057 
00058         # check if/unless attribute in rtconnect tags
00059         exec_flag = True
00060         if tag.attributes.get(u'if'):
00061             val = tag.attributes.get(u'if').value
00062             arg = val.split(" ")[1].strip(")") # To "USE_WALKING"
00063             exec_flag =  get_flag_from_argv(arg)
00064         if tag.attributes.get(u'unless'):
00065             val = tag.attributes.get(u'unless').value
00066             arg = val.split(" ")[1].strip(")") # To "USE_WALKING"
00067             exec_flag = not get_flag_from_argv(arg)
00068         if not exec_flag:
00069             continue
00070 
00071         source_path = nameserver+"/"+tag.attributes.get("from").value
00072         dest_path   = nameserver+"/"+tag.attributes.get("to").value
00073         source_path = re.sub("\$\(arg SIMULATOR_NAME\)",simulator,source_path);
00074         dest_path = re.sub("\$\(arg SIMULATOR_NAME\)",simulator,dest_path);
00075         # print >>sys.stderr, "[rtmlaunch] Connecting from %s to %s"%(source_path,dest_path)
00076         source_full_path = path.cmd_path_to_full_path(source_path)
00077         dest_full_path = path.cmd_path_to_full_path(dest_path)
00078         if tag.attributes.get("subscription_type") != None:
00079             sub_type = tag.attributes.get("subscription_type").value
00080             if not sub_type in ['flush','new','periodic']:
00081                 print >>sys.stderr, sub_type+' is not a subscription type'
00082                 continue
00083         else:
00084             sub_type = 'flush' # this is default value
00085         if sub_type == 'new':
00086             push_policy = 'all'
00087         # wait for proess
00088         try:
00089             wait_component(source_full_path)
00090             wait_component(dest_full_path)
00091             if check_connect(source_full_path,dest_full_path):
00092                 continue
00093         except Exception, e:
00094             print >>sys.stderr, '\033[31m[rtmlaunch] [ERROR] Could not Connect (', source_full_path, ',', dest_full_path, '): ', e,'\033[0m'
00095             return 1
00096         #print source_path, source_full_path, dest_path, dest_full_path;
00097         try:
00098             sub_type = str(sub_type)
00099             props = {'dataport.subscription_type': sub_type}
00100             if sub_type == 'new':
00101                 props['dataport.publisher.push_policy'] = 'all'
00102             elif sub_type == 'periodic':
00103                 props['dataport.publisher.push_policy'] = 'all'
00104                 if tag.attributes.get("push_rate") != None:
00105                     props['dataport.push_rate'] = str(tag.attributes.get("push_rate").value)
00106                 else:
00107                     props['dataport.push_rate'] = str('50.0')
00108             options = optparse.Values({'verbose': False, 'id': '', 'name': None, 'properties': props})
00109             print >>sys.stderr, "[rtmlaunch] Connected from",source_path
00110             print >>sys.stderr, "[rtmlaunch]             to",dest_path
00111             print >>sys.stderr, "[rtmlaunch]           with",options
00112             try :
00113                 rtcon.connect_ports(source_path, source_full_path, dest_path, dest_full_path, options, tree=None)
00114             except Exception, e_1_1_0: # openrtm 1.1.0
00115                 try:
00116                     rtcon.connect_ports([(source_path,source_full_path), (dest_path, dest_full_path)], options, tree=None)
00117                 except Exception, e_1_0_0: # openrtm 1.0.0
00118                     print >>sys.stderr, '\033[31m[rtmlaunch] {0} did not work on both OpenRTM 1.0.0 and 1.1.0'.format(os.path.basename(sys.argv[1])),'\033[0m'
00119                     print >>sys.stderr, '\033[31m[rtmlaunch]    OpenRTM 1.0.0 {0}'.format(e_1_0_0),'\033[0m'
00120                     print >>sys.stderr, '\033[31m[rtmlaunch]    OpenRTM 1.1.0 {0}'.format(e_1_1_0),'\033[0m'
00121                     print >>sys.stderr, '\033[31m[rtmlaunch]  This is very weird situation, Please check your network\033[0m'
00122                     print >>sys.stderr, '\033[31m[rtmlaunch] configuration with `ifconfig` on both robot and client side. \033[0m'
00123                     print >>sys.stderr, '\033[31m[rtmlaunch]  Having multiple network interface sometimes causes problem, \033[0m'
00124                     print >>sys.stderr, '\033[31m[rtmlaunch] please see FAQ site http://www.openrtm.org/OpenRTM-aist/html/FAQ2FE38388E383A9E38396E383ABE382B7E383A5E383BCE38386E382A3E383B3E382B0.html#f2bc375d\033[0m'
00125                     print >>sys.stderr, '\033[31m[rtmlaunch]            Issue related to this https://github.com/start-jsk/rtmros_hironx/issues/33\033[0m'
00126                     print >>sys.stderr, '\033[31m[rtmlaunch]            ~/.ros/log may contains usefully informations\033[0m'
00127         except Exception, e:
00128             print >>sys.stderr, '\033[31m[rtmlaunch] {0}: {1}'.format(os.path.basename(sys.argv[1]), e),'\033[0m'
00129     return 0
00130 
00131 def rtactivate(nameserver, tags):
00132     def activate_action(object, ec_index):
00133         object.activate_in_ec(ec_index)
00134     for tag in tags:
00135         
00136         # check if/unless attribute in rtactivate tags
00137         exec_flag = True
00138         if tag.attributes.get(u'if'):
00139             val = tag.attributes.get(u'if').value
00140             arg = val.split(" ")[1].strip(")") # To "USE_WALKING"
00141             exec_flag =  get_flag_from_argv(arg)
00142         if tag.attributes.get(u'unless'):
00143             val = tag.attributes.get(u'unless').value
00144             arg = val.split(" ")[1].strip(")") # To "USE_WALKING"
00145             exec_flag = not get_flag_from_argv(arg)
00146         if not exec_flag:
00147             continue
00148 
00149         cmd_path  = nameserver+"/"+tag.attributes.get("component").value
00150         full_path = path.cmd_path_to_full_path(cmd_path)
00151         # print >>sys.stderr, "[rtmlaunch] activate %s"%(full_path)
00152         try:
00153             state = wait_component(full_path)
00154             if state == 'Active':
00155                 continue
00156             else:
00157                 print >>sys.stderr, "[rtmlaunch] Activate <-",state,full_path
00158         except Exception, e:
00159             print >>sys.stderr, '\033[31m[rtmlaunch] Could not Activate (', cmd_path, ') : ', e,'\033[0m'
00160             return 1
00161         try:
00162             options = optparse.Values({"ec_index": 0, 'verbose': False})
00163             try :
00164                 state_control_base.alter_component_state(activate_action, cmd_path, full_path, options, None)
00165             except Exception, e: # openrtm 1.1.0
00166                 state_control_base.alter_component_states(activate_action, [(cmd_path, full_path)], options, None)
00167         except Exception, e:
00168             print >>sys.stderr, '[rtmlaunch] {0}: {1}'.format(os.path.basename(sys.argv[0]), e)
00169             return 1
00170     return 0
00171 
00172 def main():
00173     global simulator
00174     usage = '''Usage: %prog [launchfile]'''
00175     if len(sys.argv) <= 1:
00176         print >>sys.stderr, usage
00177         return 1
00178     fullpathname = sys.argv[1]
00179     print >>sys.stderr, "[rtmlaunch] starting... ",fullpathname
00180     try:
00181         parser = parse(fullpathname)
00182         nodes = parser.getElementsByTagName("launch")[0].childNodes
00183         remove_nodes = []
00184         for node in nodes:
00185             if node.nodeName == u'group':
00186                 if node.attributes.get(u'if'):
00187                     val = node.getAttributeNode(u'if').value
00188                     arg = val.split(" ")[1].strip(")") # To "USE_WALKING"
00189                     if not get_flag_from_argv(arg):
00190                         remove_nodes.append(node)
00191                 if node.attributes.get(u'unless'):
00192                     val = node.getAttributeNode(u'unless').value
00193                     arg = val.split(" ")[1].strip(")") # To "USE_WALKING"
00194                     if get_flag_from_argv(arg):
00195                         remove_nodes.append(node)
00196                 
00197         for remove_node in remove_nodes:
00198             nodes.remove(remove_node)
00199     except Exception,e:
00200         print e
00201         return 1
00202 
00203     if os.getenv("RTCTREE_NAMESERVERS") == None:
00204         print >>sys.stderr, "[rtmlaunch] RTCTREE_NAMESERVERS is not set, use localhost:15005"
00205         nameserver = "localhost:15005"
00206         os.environ["RTCTREE_NAMESERVERS"] = nameserver
00207     else:
00208         nameserver = os.getenv("RTCTREE_NAMESERVERS")
00209 
00210     simulator = os.getenv("SIMULATOR_NAME","Simulator")
00211     print >>sys.stderr, "[rtmlaunch] RTCTREE_NAMESERVERS", nameserver,  os.getenv("RTCTREE_NAMESERVERS")
00212     print >>sys.stderr, "[rtmlaunch] SIMULATOR_NAME", simulator
00213     while 1:
00214         print >>sys.stderr, "[rtmlaunch] check connection/activation"
00215         rtconnect(nameserver, parser.getElementsByTagName("rtconnect"))
00216         rtactivate(nameserver, parser.getElementsByTagName("rtactivate"))
00217         time.sleep(10)
00218 
00219 def get_flag_from_argv(arg):
00220     for a in sys.argv:
00221         if arg in a: # If "USE_WALKING" is in argv
00222             return True if 'true' in a.split("=")[1] else False
00223 
00224 import signal
00225 def signal_handler(signum, frame):
00226     sigdict = dict((k, v) for v, k in signal.__dict__.iteritems() if v.startswith('SIG'))
00227     print >>sys.stderr, "\033[33m[rtmlaunch] Catch signal %r, exitting...\033[0m"%(sigdict[signum])
00228     sys.exit(0)
00229 
00230 if __name__ == '__main__':
00231     signal.signal(signal.SIGINT, signal_handler)
00232     main()
00233 
00234 
00235 
00236 


openrtm_tools
Author(s): Kei Okada
autogenerated on Mon Oct 6 2014 07:17:55