def _send_flip_rules_request(self, name, cancel): rules = [] rule = gateway_msgs.Rule() rule.node = '' rule.type = gateway_msgs.ConnectionType.SUBSCRIBER # could resolve this better by looking up the service info rule.name = "/services/turtlesim/%s/cmd_vel" % name rules.append(copy.deepcopy(rule)) rule.type = gateway_msgs.ConnectionType.PUBLISHER rule.name = "/services/turtlesim/%s/pose" % name rules.append(copy.deepcopy(rule)) # send the request request = gateway_srvs.RemoteRequest() request.cancel = cancel remote_rule = gateway_msgs.RemoteRule() remote_rule.gateway = name for rule in rules: remote_rule.rule = rule request.remotes.append(copy.deepcopy(remote_rule)) try: self._gateway_flip_service(request) except rospy.ServiceException: # communication failed rospy.logerr("TurtleHerder : failed to send flip rules") return except rospy.ROSInterruptException: rospy.loginfo("TurtleHerder : shutdown while contacting the gateway flip service") return
def flip_tutorials(remote_gateway_name=None, cancel=False, regex_patterns=False, ns=_gateway_namespace): rospy.wait_for_service(ns + '/flip') flip = rospy.ServiceProxy(ns + '/flip', gateway_srvs.Remote) if not remote_gateway_name: remote_gateway_name = find_first_remote_gateway() req = gateway_srvs.RemoteRequest() req.cancel = cancel if regex_patterns: names, nodes = create_tutorial_dictionaries(use_regex_patterns=True) else: names, nodes = create_tutorial_dictionaries(use_regex_patterns=False) req.remotes = [] for connection_type in connection_types: rule = gateway_msgs.Rule() rule.name = names[connection_type] rule.type = connection_type rule.node = nodes[connection_type] rospy.loginfo( "Flip : %s [%s,%s,%s][%s]." % (_action_text(cancel, 'requesting flip to gateway'), rule.type, rule.name, rule.node or 'None', remote_gateway_name)) req.remotes.append(gateway_msgs.RemoteRule(remote_gateway_name, rule)) resp = flip(req) if resp.result == gateway_msgs.ErrorCodes.FLIP_RULE_ALREADY_EXISTS: # already flipped all error is ignored. this call only has no effect. pass elif resp.result != 0: raise GatewaySampleRuntimeError("failed to flip %s [%s]" % (rule.name, resp.error_message))
def flip(gate, remote, local, topic, node): rospy.init_node('generic_flip_subscriber') remote_gateway = gate[0] flip_service = rospy.ServiceProxy('/gateway/flip', gateway_srvs.Remote) req = gateway_srvs.RemoteRequest() req.cancel = False req.remotes = [] rule = gateway_msgs.Rule() if topic[0][0] == '/': rule.name = topic[0] elif not remote: rule.name = '/' + topic[0] else: rule.name = '/' + remote[0] + '/' + topic[0] rule.type = gateway_msgs.ConnectionType.SUBSCRIBER if not node: rule.node = '' elif node[0][0] == '/': rule.node = node[0] elif not local: rule.node = '/' + node[0] else: rule.node = '/' + local[0] + '/' + node[0] req.remotes.append(gateway_msgs.RemoteRule(remote_gateway, rule)) rospy.loginfo("Flip : [%s,%s,%s,%s]." % (remote_gateway, rule.name, rule.type, rule.node)) resp = flip_service(req) if resp.result != 0: rospy.logerr("Flip : %s" % resp.error_message) rospy.loginfo("Finished flipping connection.")
def pull(gate, remote, local, topic, node): rospy.init_node('generic_puller') rospy.wait_for_service('/gateway/pull') remote_gateway = gate[0] pull_service = rospy.ServiceProxy('/gateway/pull', gateway_srvs.Remote) req = gateway_srvs.RemoteRequest() req.cancel = False req.remotes = [] rule = gateway_msgs.Rule() if topic[0][0] == '/': rule.name = topic[0] elif not remote: rule.name = '/' + topic[0] ; else: rule.name = '/' + remote[0] + '/' + topic[0] rule.type = gateway_msgs.ConnectionType.PUBLISHER if not node: rule.node = '' elif node[0][0] == '/': rule.node = node[0] elif not local: rule.node = '/' + node[0] else: rule.node = '/' + local[0] + '/' + node[0] req.remotes.append(gateway_msgs.RemoteRule(remote_gateway, rule)) rospy.loginfo("Pull : [%s,%s,%s,%s]."%(remote_gateway, rule.name, rule.type, rule.node)) resp = pull_service(req) if resp.result != 0: rospy.logerr("Pull : %s"%resp.error_message) rospy.loginfo("Finished pulling connection.")
def _flip_connections(self, remote_name, connection_names, connection_type, cancel_flag=False): ''' (Un)Flip a service to a remote gateway. @param remote_name : the name of the remote gateway to flip to. @type str @param connection_names : the topic/service/action_xxx names @type list of str @param connection_type : publisher, subscriber, service, action_client or action_server @type gateway_msgs.ConnectionType @param cancel_flag : whether or not we are flipping (false) or unflipping (true) @type bool ''' if len(connection_names) == 0: return req = gateway_srvs.RemoteRequest() req.cancel = cancel_flag req.remotes = [] for connection_name in connection_names: req.remotes.append(create_gateway_remote_rule(remote_name, create_gateway_rule(connection_name, connection_type))) try: resp = self._gateway_services['flip'](req) except rospy.service.ServiceException: # often disappears when the gateway shuts down just before the app manager, ignore silently. return if resp.result == 0: rospy.loginfo("App Manager : successfully flipped %s" % str([os.path.basename(name) for name in connection_names])) else: rospy.logerr("App Manager : failed to flip [%s]" % resp.error_message)
def pull_tutorials(remote_gateway_name=None, cancel=False, regex_patterns=False, ns=_gateway_namespace): rospy.wait_for_service(ns + '/pull') pull = rospy.ServiceProxy(ns + '/pull', gateway_srvs.Remote) if not remote_gateway_name: remote_gateway_name = find_first_remote_gateway() req = gateway_srvs.RemoteRequest() req.cancel = cancel if regex_patterns: names, nodes = create_tutorial_dictionaries(use_regex_patterns=True) else: names, nodes = create_tutorial_dictionaries(use_regex_patterns=False) req.remotes = [] for connection_type in connection_types: rule = gateway_msgs.Rule() rule.name = names[connection_type] rule.type = connection_type rule.node = nodes[connection_type] rospy.loginfo( "Pull : %s [%s,%s,%s][%s]." % (_action_text(cancel, 'sending pull rule to the gateway'), rule.type, rule.name, rule.node or 'None', remote_gateway_name)) req.remotes.append(gateway_msgs.RemoteRule(remote_gateway_name, rule)) resp = pull(req) if resp.result != 0: raise GatewaySampleRuntimeError("failed to pull %s [%s]" % (rule.name, resp.error_message))
def _pull_concert_client(self): ''' Pulls platform information from the advertised platform_info on another ros system. It is just a one-shot only used at construction time. It pulls platform_info and list_apps information. It also pulls the required handles in for further manipulation ('status' and 'invite') ''' rospy.loginfo("Conductor: retrieving client information [%s]" % self.name) pull_service = rospy.ServiceProxy('~pull', gateway_srvs.Remote) req = gateway_srvs.RemoteRequest() req.cancel = False req.remotes = [] for service_name in ['platform_info', 'list_apps', 'status', 'invite']: rule = gateway_msgs.Rule() rule.name = str('/' + self.gateway_name + '/' + service_name) rule.node = '' rule.type = gateway_msgs.ConnectionType.SERVICE req.remotes.append( gateway_msgs.RemoteRule(self.gateway_name.lstrip('/'), rule)) resp = pull_service(req) if resp.result != 0: rospy.logwarn( "Conductor: failed to pull the platform info service from the client." ) return None
def _send_flip_rules(self, robots, cancel): """ Flip rules from Gazebo to the robot's concert client. :param robot_names str[]: Names of robots to whom information needs to be flipped. :param cancel bool: Cancel existing flips. Used during shutdown. """ for robot in robots: rules = self._robot_managers[robot['type']].get_flip_rule_list( robot['name']) # send the request request = gateway_srvs.RemoteRequest() request.cancel = cancel remote_rule = gateway_msgs.RemoteRule() remote_rule.gateway = robot['name'] for rule in rules: remote_rule.rule = rule request.remotes.append(copy.deepcopy(remote_rule)) try: self._gateway_flip_service(request) except rospy.ServiceException: # communication failed self.logerr('failed to send flip rules') return except rospy.ROSInterruptException: self.loginfo( 'shutdown while contacting the gateway flip service') return
def __init__(self, gateway, cancel_flag, regex): self.gateway = gateway if cancel_flag: self.action_text = "cancelling" else: self.action_text = "pulling" self.pull_service = rospy.ServiceProxy('/gateway/pull', gateway_srvs.Remote) rospy.wait_for_service('/gateway/pull') self.req = gateway_srvs.RemoteRequest() self.req.cancel = cancel_flag self.req.remotes = [] self.names, self.nodes = rocon_gateway.samples.create_tutorial_dictionaries( use_regex_patterns=regex)
def _flip_connections(self, remote_name, connection_names, connection_type, cancel_flag=False): ''' (Un)Flip a service to a remote gateway. @param remote_name : the name of the remote gateway to flip to. @type str @param connection_names : the topic/service/action_xxx names @type list of str @param connection_type : publisher, subscriber, service, action_client or action_server @type gateway_msgs.ConnectionType @param cancel_flag : whether or not we are flipping (false) or unflipping (true) @type bool ''' if len(connection_names) == 0: return req = gateway_srvs.RemoteRequest() req.cancel = cancel_flag req.remotes = [] for connection_name in connection_names: req.remotes.append( create_gateway_remote_rule( remote_name, create_gateway_rule(connection_name, connection_type))) try: resp = self._gateway_services['flip'](req) except rospy.service.ServiceException: # often disappears when the gateway shuts down just before the app manager, ignore silently. return if resp.result == 0: rospy.loginfo( "App Manager : successfully flipped %s" % str([os.path.basename(name) for name in connection_names])) else: if resp.result == gateway_msgs.ErrorCodes.NO_HUB_CONNECTION and cancel_flag: # can often happen if a concert goes down and brings the hub down as as well # so just suppress this warning if it's a request to cancel rospy.logwarn( "App Manager : failed to cancel flips (probably remote hub intentionally went down as well) [%s, %s]" % (resp.result, resp.error_message)) else: rospy.logerr("App Manager : failed to flip [%s, %s]" % (resp.result, resp.error_message))
def cancel_pulls(self): ''' Cancel any pulls for a client which failed to construct (e.g. in the init() when the service calls fail. ''' pull_service = rospy.ServiceProxy('~pull', gateway_srvs.Remote) req = gateway_srvs.RemoteRequest() req.cancel = True req.remotes = [] for service_name in ['platform_info', 'list_apps', 'status', 'invite']: rule = gateway_msgs.Rule() rule.name = str('/' + self.gateway_name + '/' + service_name) rule.node = '' rule.type = gateway_msgs.ConnectionType.SERVICE req.remotes.append( gateway_msgs.RemoteRule(self.gateway_name.lstrip('/'), rule)) unused_resp = pull_service(req)
def _set_gateway_flip_rules(self, cancel_flag=False): """ Converts the concert whitelist into a set of remote gateway flip rules for the namespaces in which the rapp manager will drop 'to be shared' communications. """ req = gateway_srvs.RemoteRequest() req.cancel = cancel_flag flip_request_service = rospy.ServiceProxy('~flip', gateway_srvs.Remote) for connection_type in rocon_gateway.connection_types: concert_namespace_rule = rocon_gateway_utils.create_gateway_rule(name="/concert/.*", connection_type=connection_type) # self.parameters.application namespace always finishes with a trailing slash because of 'rosgraph.names.make_global_ns()' called on it. applications_namespace_rule = rocon_gateway_utils.create_gateway_rule(name=self.parameters.application_namespace + ".*", connection_type=connection_type) for concert_remote_gateway in self.concert_parameters.concert_whitelist: req.remotes.append(rocon_gateway_utils.create_gateway_remote_rule(concert_remote_gateway, concert_namespace_rule)) req.remotes.append(rocon_gateway_utils.create_gateway_remote_rule(concert_remote_gateway, applications_namespace_rule)) if not self.concert_parameters.concert_whitelist: req.remotes.append(rocon_gateway_utils.create_gateway_remote_rule(".*", concert_namespace_rule)) req.remotes.append(rocon_gateway_utils.create_gateway_remote_rule(".*", applications_namespace_rule)) warning_throttle_counter = 0 rate = rospy.Rate(10) # 10hz while not rospy.is_shutdown(): try: resp = flip_request_service(req) except rospy.service.ServiceException: raise GatewayNotFoundException() # often disappears when the gateway shuts down just before the app manager, ignore silently. if resp.result == gateway_msgs.ErrorCodes.SUCCESS: rospy.loginfo("Rapp Manager : set flip rules on the local gateway [remotes: %s]" % self.concert_parameters.concert_whitelist) break else: if resp.result == gateway_msgs.ErrorCodes.NO_HUB_CONNECTION and cancel_flag: # can often happen if a concert goes down and brings the hub down as as well # so just suppress this warning if it's a request to cancel rospy.logwarn("Rapp Manager : failed to cancel flips (probably remote hub intentionally went down as well) [%s, %s]" % (resp.result, resp.error_message)) raise GatewayNotFoundException() # often disappears when the gateway shuts down just before the app manager, ignore silently. else: warning_throttle_counter += 1 if warning_throttle_counter % 10 == 0: rospy.logerr("Rapp Manager : could not set flip rules on the local gateway") rate.sleep()
def flip(namespace, topic, node): rospy.init_node('flip_remote_publisher') remote_gateway = "Hub_Gateway" flip_service = rospy.ServiceProxy('/gateway/flip', gateway_srvs.Remote) req = gateway_srvs.RemoteRequest() req.cancel = False req.remotes = [] rule = gateway_msgs.Rule() rule.name = '/' + namespace + '/' + topic rule.type = gateway_msgs.ConnectionType.PUBLISHER rule.node = '/' + namespace + '/' + node req.remotes.append(gateway_msgs.RemoteRule(remote_gateway, rule)) rospy.loginfo("Flip : [%s,%s,%s,%s]." % (remote_gateway, rule.name, rule.type, rule.node)) resp = flip_service(req) if resp.result != 0: rospy.logerr("Flip : %s" % resp.error_message) rospy.loginfo("Finished flipping connection.")
def _send_flip_rules(self, remote_controller): request = gateway_srvs.RemoteRequest() request.cancel = True if remote_controller == rocon_app_manager_msgs.Constants.NO_REMOTE_CONTROLLER else False remote_rule = gateway_msgs.RemoteRule() if request.cancel: remote_rule.gateway = self.remote_controller else: remote_rule.gateway = remote_controller for rule in self._flip_rules(): remote_rule.rule = rule request.remotes.append(copy.deepcopy(remote_rule)) try: unused_response = self.gateway_flip_service(request) except rospy.ServiceException: # communication failed rospy.logerr("Hatchling : failed to send flip rules") return except rospy.ROSInterruptException: rospy.loginfo( "Hatchling : shutdown while contacting the gateway flip service" ) return
def request_pulls(self, remote_gateway_name, cancel=False, service_names=['platform_info', 'list_rapps', 'invite'], topic_names=['status']): """ Handles pull requests and cancels from request gateways for the conductor. Note this only applies to topics/services relevant for interacting with concert clients. :param str remote_gateway_name: name of a remote gateway to apply to all rules :param bool cancel: to register or unregister the pull requests """ req = gateway_srvs.RemoteRequest() req.cancel = cancel req.remotes = [] for service_name in service_names: rule = gateway_msgs.Rule() rule.name = str('/' + remote_gateway_name.lower().replace(' ', '_') + '/' + service_name) rule.node = '' rule.type = gateway_msgs.ConnectionType.SERVICE req.remotes.append( gateway_msgs.RemoteRule(remote_gateway_name.lstrip('/'), rule)) for publisher_name in topic_names: rule = gateway_msgs.Rule() rule.name = str('/' + remote_gateway_name.lower().replace(' ', '_') + '/' + publisher_name) rule.node = '' rule.type = gateway_msgs.ConnectionType.PUBLISHER req.remotes.append( gateway_msgs.RemoteRule(remote_gateway_name.lstrip('/'), rule)) # TODO : exception handling for this call response = self._services['pull'](req) if response.result != gateway_msgs.ErrorCodes.SUCCESS and not cancel: # don't worry about errors on cleanup rospy.logwarn( "Conductor: failed to register pull requests from the concert client [%s]%s" % (remote_gateway_name, service_names) ) # TODO : exceptions, but what kind of failures?
def pull(topic): rospy.init_node('pull_hub_publisher') rospy.wait_for_service('/gateway/pull') remote_gateway = "Hub_Gateway" pull_service = rospy.ServiceProxy('/gateway/pull', gateway_srvs.Remote) req = gateway_srvs.RemoteRequest() req.cancel = False req.remotes = [] rule = gateway_msgs.Rule() rule.name = '/' + topic rule.type = gateway_msgs.ConnectionType.PUBLISHER rule.node = "" req.remotes.append(gateway_msgs.RemoteRule(remote_gateway, rule)) rospy.loginfo("Pull : [%s,%s,%s,%s]." % (remote_gateway, rule.name, rule.type, rule.node)) resp = pull_service(req) if resp.result != 0: rospy.logerr("Pull : %s" % resp.error_message) rospy.loginfo("Finished pulling connection.")
def flip(namespace, topic, node, gate): rospy.init_node('flip_hub_subscriber') remote_gateway = gate + '_gateway' flip_service = rospy.ServiceProxy('/gateway/flip', gateway_srvs.Remote) req = gateway_srvs.RemoteRequest() req.cancel = False req.remotes = [] rule = gateway_msgs.Rule() if topic[0] == '/': rule.name = topic else: rule.name = '/' + namespace + '/' + topic rule.type = gateway_msgs.ConnectionType.SUBSCRIBER rule.node = '/' + node req.remotes.append(gateway_msgs.RemoteRule(remote_gateway, rule)) rospy.loginfo("Flip : [%s,%s,%s,%s]." % (remote_gateway, rule.name, rule.type, rule.node)) resp = flip_service(req) if resp.result != 0: rospy.logerr("Flip : %s" % resp.error_message) rospy.loginfo("Finished flipping connection.")
def _flip_all_connections(self, remote_name, connections, cancel_flag=False): ''' (Un)Flip connections to a remote gateway. :param remote_name: the name of the remote gateway to flip to. :type remote_name: str :param connections: the dict of connection types(topic/service/action_xxx) names :type connetions: dict :param cancel_flag: whether or not we are flipping (false) or unflipping (true) :type cancel_flag: bool :returns: success or not, message :rtype: bool, str ''' success = False message = "" req = gateway_srvs.RemoteRequest() req.cancel = cancel_flag req.remotes = [] # Create request for conn_type, conns in connections.items(): gateway_type = plurality_converter[conn_type] for conn_name in conns: remote_rule = create_gateway_remote_rule( remote_name, create_gateway_rule(conn_name, gateway_type)) req.remotes.append(remote_rule) # Send request attempts = 0 MAX_ATTEMPTS = 4 while not success and attempts < MAX_ATTEMPTS and not rospy.is_shutdown( ): try: resp = self._gateway_services['flip'](req) except rospy.service.ServiceException: # often disappears when the gateway shuts down just before the app manager, ignore silently. success = False message = "Flip service has disappeared" attempts = attempts + 1 continue if resp.result == gateway_msgs.ErrorCodes.SUCCESS: rospy.loginfo("Rapp Manager : successfully flipped %s" % str([(names) for names in connections.values()])) success = True else: if resp.result == gateway_msgs.ErrorCodes.NO_HUB_CONNECTION and cancel_flag: # can often happen if a concert goes down and brings the hub down as as well # so just suppress this warning if it's a request to cancel rospy.logwarn( "Rapp Manager : failed to cancel flips (probably remote hub intentionally went down as well) [%s, %s]" % (resp.result, resp.error_message)) else: message = "failed to flip [%s][%s, %s]" % ( str(connections), resp.result, resp.error_message) rospy.logerr("Rapp Manager : %s" % message) success = False attempts = attempts + 1 rospy.sleep(1.0) return success, message