00001
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()
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
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
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(")")
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(")")
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
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'
00097 if sub_type == 'new':
00098 push_policy = 'all'
00099
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
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:
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:
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
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(")")
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(")")
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
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:
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(")")
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(")")
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:
00236 return True if 'true' in a.split("=")[1] else False
00237
00238
00239
00240