00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 import rospy
00011 import gateway_msgs.msg as gateway_msgs
00012 import gateway_msgs.srv as gateway_srvs
00013 import rocon_gateway_utils
00014 import rocon_python_comms
00015
00016 from .exceptions import GatewaySampleRuntimeError
00017 from .utils import connection_types
00018
00019
00020
00021
00022
00023 _gateway_namespace = '/gateway'
00024
00025
00026
00027
00028
00029
00030 def wait_for_gateway(ns=_gateway_namespace, timeout=rospy.Duration(5.0)):
00031 '''
00032 Slowly loop (and block) until the gateway is connected to a hub.
00033 '''
00034 gateway_info_service = rocon_python_comms.SubscriberProxy(ns + '/gateway_info', gateway_msgs.GatewayInfo)
00035 start_time = rospy.Time.now()
00036 while not rospy.is_shutdown():
00037 gateway_info = gateway_info_service()
00038 if gateway_info.connected:
00039 break
00040 if rospy.Time.now() - start_time > timeout:
00041 raise GatewaySampleRuntimeError("timed out waiting for the gateway to connect to a hub")
00042 rospy.sleep(0.5)
00043
00044
00045 def wait_for_remote_gateway(remote_gateway_name, ns=_gateway_namespace, timeout=rospy.Duration(5.0)):
00046 '''
00047 Slowly loop (and block) until remote the gateway is visible on our hub.
00048 '''
00049 rospy.wait_for_service(ns + '/remote_gateway_info')
00050 remote_gateway_info_service = rospy.ServiceProxy(ns + '/remote_gateway_info', gateway_srvs.RemoteGatewayInfo)
00051 req = gateway_srvs.RemoteGatewayInfoRequest()
00052 start_time = rospy.Time.now()
00053 while not rospy.is_shutdown():
00054 req = gateway_srvs.RemoteGatewayInfoRequest()
00055 req.gateways = []
00056 resp = remote_gateway_info_service(req)
00057 matched = False
00058 if rospy.Time.now() - start_time > timeout:
00059 raise GatewaySampleRuntimeError("timed out waiting for a remote gateway to appear")
00060 for gateway in resp.gateways:
00061 if remote_gateway_name == gateway.name:
00062 matched = True
00063 break
00064 remote_gateway_basename = rocon_gateway_utils.gateway_basename(gateway.name)
00065 print("Samples: gateway comparison [%s][%s]" % (remote_gateway_basename, remote_gateway_name))
00066 if remote_gateway_name == remote_gateway_basename:
00067 matched = True
00068 break
00069 if matched:
00070 break
00071
00072
00073 def find_first_remote_gateway(ns=_gateway_namespace, timeout=rospy.Duration(15.0)):
00074 '''
00075 Parses the remote gateway list to find a gateway to use for testing.
00076
00077 It's a dumb hack to make testing quite convenient.
00078
00079 @return gateway string name
00080 @rtype string
00081 '''
00082 rospy.wait_for_service(ns + '/remote_gateway_info')
00083 remote_gateway_info = rospy.ServiceProxy(ns + '/remote_gateway_info', gateway_srvs.RemoteGatewayInfo)
00084 start_time = rospy.Time.now()
00085 while not rospy.is_shutdown():
00086 req = gateway_srvs.RemoteGatewayInfoRequest()
00087 req.gateways = []
00088 resp = remote_gateway_info(req)
00089 if rospy.Time.now() - start_time > timeout:
00090 raise GatewaySampleRuntimeError("timed out waiting for a remote gateway to appear")
00091 if len(resp.gateways) > 0:
00092 break
00093 rospy.sleep(0.5)
00094 return resp.gateways[0].name
00095
00096
00097 def create_tutorial_dictionaries(use_regex_patterns=False):
00098 names = {}
00099 nodes = {}
00100 if use_regex_patterns:
00101 names = {
00102 gateway_msgs.ConnectionType.PUBLISHER: '.*ter',
00103 gateway_msgs.ConnectionType.SUBSCRIBER: '.*ter',
00104 gateway_msgs.ConnectionType.SERVICE: '/add_two_.*',
00105 gateway_msgs.ConnectionType.ACTION_CLIENT: '/fibonacci/cli.*',
00106 gateway_msgs.ConnectionType.ACTION_SERVER: '/fibonacci/ser.*'
00107 }
00108 nodes = {
00109 gateway_msgs.ConnectionType.PUBLISHER: '/t.*er',
00110 gateway_msgs.ConnectionType.SUBSCRIBER: '',
00111 gateway_msgs.ConnectionType.SERVICE: '',
00112 gateway_msgs.ConnectionType.ACTION_CLIENT: '',
00113 gateway_msgs.ConnectionType.ACTION_SERVER: ''
00114 }
00115 else:
00116 names = {
00117 gateway_msgs.ConnectionType.PUBLISHER: '/chatter',
00118 gateway_msgs.ConnectionType.SUBSCRIBER: '/chatter',
00119 gateway_msgs.ConnectionType.SERVICE: '/add_two_ints',
00120 gateway_msgs.ConnectionType.ACTION_CLIENT: '/fibonacci/client',
00121 gateway_msgs.ConnectionType.ACTION_SERVER: '/fibonacci/server'
00122 }
00123 nodes = {
00124 gateway_msgs.ConnectionType.PUBLISHER: '',
00125 gateway_msgs.ConnectionType.SUBSCRIBER: '',
00126 gateway_msgs.ConnectionType.SERVICE: '',
00127 gateway_msgs.ConnectionType.ACTION_CLIENT: '',
00128 gateway_msgs.ConnectionType.ACTION_SERVER: ''
00129 }
00130 return names, nodes
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 def _action_text(cancel=False, msg='acting'):
00144 text = "cancelling" if cancel else msg
00145 return text
00146
00147
00148 def advertise_all(cancel=False, ns=_gateway_namespace):
00149 '''
00150 Sends a rule for advertising everything except the default blacklist.
00151 '''
00152 rospy.wait_for_service(ns + '/advertise_all')
00153 advertise_all = rospy.ServiceProxy(ns + '/advertise_all', gateway_srvs.AdvertiseAll)
00154 req = gateway_srvs.AdvertiseAllRequest()
00155 req.cancel = cancel
00156 req.blacklist = []
00157 rospy.loginfo("Advertise All : %s all." % _action_text(cancel, 'advertising'))
00158 resp = advertise_all(req)
00159 if resp.result != 0:
00160 raise GatewaySampleRuntimeError("failed to advertise all (todo: no error message yet)")
00161
00162
00163 def advertise_tutorials(cancel=False, regex_patterns=False, ns=_gateway_namespace):
00164 rospy.wait_for_service(ns + '/advertise')
00165 advertise = rospy.ServiceProxy(ns + '/advertise', gateway_srvs.Advertise)
00166 req = gateway_srvs.AdvertiseRequest()
00167 req.cancel = cancel
00168 rule = gateway_msgs.Rule()
00169 if regex_patterns:
00170 names, nodes = create_tutorial_dictionaries(use_regex_patterns=True)
00171 else:
00172 names, nodes = create_tutorial_dictionaries(use_regex_patterns=False)
00173 for connection_type in connection_types:
00174 req.rules = []
00175 rule.name = names[connection_type]
00176 rule.type = connection_type
00177 rule.node = nodes[connection_type]
00178 rospy.loginfo("Advertise : %s [%s,%s,%s]." %
00179 (_action_text(cancel, 'advertising'), rule.type, rule.name, rule.node or 'None'))
00180 req.rules.append(rule)
00181 resp = advertise(req)
00182 if resp.result != 0:
00183 raise GatewaySampleRuntimeError("failed to advertise %s [%s]" % (rule.name, resp.error_message))
00184
00185
00186 def pull_all(remote_gateway_name=None, cancel=False, ns=_gateway_namespace):
00187 '''
00188 Sends a rule for pulling everything from the specified remote gateway.
00189 '''
00190 rospy.wait_for_service(ns + '/pull_all')
00191 pull_all = rospy.ServiceProxy(ns + '/pull_all', gateway_srvs.RemoteAll)
00192 if not remote_gateway_name:
00193 remote_gateway_name = find_first_remote_gateway()
00194 req = gateway_srvs.RemoteAllRequest()
00195 req.gateway = remote_gateway_name
00196 req.cancel = cancel
00197 req.blacklist = []
00198 rospy.loginfo("Pull All : %s." % _action_text(cancel, 'sending pull rule for all to the gateway'))
00199 resp = pull_all(req)
00200 if resp.result != 0:
00201 raise GatewaySampleRuntimeError("failed to pull all from %s [%s]" % (remote_gateway_name, resp.error_message))
00202
00203
00204 def pull_tutorials(remote_gateway_name=None, cancel=False, regex_patterns=False, ns=_gateway_namespace):
00205 rospy.wait_for_service(ns + '/pull')
00206 pull = rospy.ServiceProxy(ns + '/pull', gateway_srvs.Remote)
00207 if not remote_gateway_name:
00208 remote_gateway_name = find_first_remote_gateway()
00209 req = gateway_srvs.RemoteRequest()
00210 req.cancel = cancel
00211 if regex_patterns:
00212 names, nodes = create_tutorial_dictionaries(use_regex_patterns=True)
00213 else:
00214 names, nodes = create_tutorial_dictionaries(use_regex_patterns=False)
00215 req.remotes = []
00216 for connection_type in connection_types:
00217 rule = gateway_msgs.Rule()
00218 rule.name = names[connection_type]
00219 rule.type = connection_type
00220 rule.node = nodes[connection_type]
00221 rospy.loginfo(
00222 "Pull : %s [%s,%s,%s][%s]." %
00223 (_action_text(
00224 cancel,
00225 'sending pull rule to the gateway'),
00226 rule.type,
00227 rule.name,
00228 rule.node or 'None',
00229 remote_gateway_name))
00230 req.remotes.append(gateway_msgs.RemoteRule(remote_gateway_name, rule))
00231 resp = pull(req)
00232 if resp.result != 0:
00233 raise GatewaySampleRuntimeError("failed to pull %s [%s]" % (rule.name, resp.error_message))
00234
00235
00236 def flip_all(remote_gateway_name=None, cancel=False, ns=_gateway_namespace):
00237 '''
00238 Sends a rule for flipping everything to the specified remote gateway.
00239 '''
00240 rospy.wait_for_service(ns + '/flip_all')
00241 flip_all = rospy.ServiceProxy(ns + '/flip_all', gateway_srvs.RemoteAll)
00242 if not remote_gateway_name:
00243 remote_gateway_name = find_first_remote_gateway()
00244 req = gateway_srvs.RemoteAllRequest()
00245 req.gateway = remote_gateway_name
00246 req.cancel = cancel
00247 req.blacklist = []
00248 rospy.loginfo("Flip All : %s [%s]." %
00249 (_action_text(cancel, 'sending flip rule for all to the gateway'), remote_gateway_name))
00250 resp = flip_all(req)
00251 if resp.result != 0:
00252 raise GatewaySampleRuntimeError("failed to flip all to %s [%s]" % (remote_gateway_name, resp.error_message))
00253
00254
00255 def flip_tutorials(remote_gateway_name=None, cancel=False, regex_patterns=False, ns=_gateway_namespace):
00256 rospy.wait_for_service(ns + '/flip')
00257 flip = rospy.ServiceProxy(ns + '/flip', gateway_srvs.Remote)
00258 if not remote_gateway_name:
00259 remote_gateway_name = find_first_remote_gateway()
00260 req = gateway_srvs.RemoteRequest()
00261 req.cancel = cancel
00262 if regex_patterns:
00263 names, nodes = create_tutorial_dictionaries(use_regex_patterns=True)
00264 else:
00265 names, nodes = create_tutorial_dictionaries(use_regex_patterns=False)
00266 req.remotes = []
00267 for connection_type in connection_types:
00268 rule = gateway_msgs.Rule()
00269 rule.name = names[connection_type]
00270 rule.type = connection_type
00271 rule.node = nodes[connection_type]
00272 rospy.loginfo(
00273 "Flip : %s [%s,%s,%s][%s]." %
00274 (_action_text(
00275 cancel,
00276 'requesting flip to gateway'),
00277 rule.type,
00278 rule.name,
00279 rule.node or 'None',
00280 remote_gateway_name))
00281 req.remotes.append(gateway_msgs.RemoteRule(remote_gateway_name, rule))
00282 resp = flip(req)
00283 if resp.result != 0:
00284 raise GatewaySampleRuntimeError("failed to flip %s [%s]" % (rule.name, resp.error_message))
00285
00286
00287 def connect_hub_by_service(ns=_gateway_namespace, raise_exception=True):
00288 connect = rospy.ServiceProxy(ns + '/connect_hub', gateway_srvs.ConnectHub)
00289
00290 req = gateway_srvs.ConnectHubRequest()
00291 req.uri = "http://localhost:6380"
00292 rospy.loginfo("")
00293 rospy.loginfo("Request:\n\n%s\n" % req)
00294 rospy.loginfo("")
00295 resp = connect(req)
00296 rospy.loginfo("")
00297 rospy.loginfo("Response:\n\n%s\n" % resp)
00298 if raise_exception:
00299 if resp.result != gateway_msgs.ErrorCodes.SUCCESS:
00300 raise GatewaySampleRuntimeError("failed to connect to hub [%s][%s]" % (req.uri, resp.error_message))
00301 return resp.result, resp.error_message