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


openrtm_tools
Author(s): Kei Okada
autogenerated on Wed Sep 16 2015 10:51:26