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


openrtm_tools
Author(s): Kei Okada
autogenerated on Thu Sep 21 2017 03:17:16