def create_terminal(name=None): """ Creates a manager for the terminal with supporting methods and variables. If name is None, it will try to auto-detect the user's terminal. We're currently using ubuntu's x-terminal-emulator to choose the shell. :param str name: name of the terminal manager to create (None to auto-detect). :returns: one of the suported terminal classes :rtype: one of the children of :class:.`.Terminal` :raises :exc:`.UnsupportedTerminal` if the name is not in the supported terminals list. :raises :exc:`rocon_python_comms.NotFoundException` if the specified/auto-detected terminal is not found on the system. """ if name is not None and name not in supported_terminals.keys(): raise UnsupportedTerminal("%s is not a supported terminal type [%s]" % (name, supported_terminals.keys())) if name == konsole: if not rocon_python_utils.system.which('konsole'): msg = "cannot find 'konsole' (hint: try --gnome for gnome-terminal instead)" raise rocon_python_comms.NotFoundException(msg) elif name == gnome_terminal or name == gnome_terminal_wrapper: if not rocon_python_utils.system.which('konsole'): msg = "cannot find 'gnome' (hint: try --konsole for konsole instead)" raise rocon_python_comms.NotFoundException(msg) # elif name is active: # nothing to do elif name is None: # auto-detect if not rocon_python_utils.system.which('x-terminal-emulator'): msg = "tried to auto-detect, but cannot find 'x-terminal-emulator' (hint: try --gnome or --konsole instead)" raise rocon_python_comms.NotFoundException(msg) p = subprocess.Popen([ rocon_python_utils.system.which('update-alternatives'), '--query', 'x-terminal-emulator' ], stdout=subprocess.PIPE) for line in p.stdout: if line.startswith("Value:"): auto_detected_name = os.path.basename(line.split()[1]) break if auto_detected_name not in supported_terminals.keys(): msg = "you are %s, an esoteric and unsupported terminal" % ( auto_detected_name) console.warning(msg.capitalize()) fallbacks = [konsole, gnome_terminal] for terminal_name in fallbacks: if rocon_python_utils.system.which(terminal_name): name = terminal_name console.warning(" --> falling back to '%s'" % terminal_name) if name is None: raise UnsupportedTerminal( msg + " (hint: try --gnome or --konsole instead)[%s]" % supported_terminals.keys()) else: name = auto_detected_name return supported_terminals[name]()
def resolve_local_gateway(timeout=rospy.rostime.Duration(1.0)): ''' @param timeout : timeout on checking for the gateway. @type rospy.rostime.Duration @raise rocon_python_comms.NotFoundException: if no remote gateways or no matching gateways available. ''' master = rosgraph.Master(rospy.get_name()) gateway_namespace = None timeout_time = time.time() + timeout.to_sec() while not rospy.is_shutdown() and time.time() < timeout_time: unused_publishers, unused_subscribers, services = master.getSystemState( ) for service in services: service_name = service[0] # second part is the node name if re.search(r'remote_gateway_info', service_name): if service_name == '/remote_gateway_info': gateway_namespace = "/" break else: gateway_namespace = re.sub(r'/remote_gateway_info', '', service_name) break if gateway_namespace is not None: break else: rospy.rostime.wallsleep(0.1) if not gateway_namespace: raise rocon_python_comms.NotFoundException( "could not find a local gateway - did you start it?") #console.debug("Found a local gateway at %s"%gateway_namespace) return gateway_namespace
def resolve_local_gateway(timeout=None): ''' @param timeout : timeout on checking for the gateway, if None, it just makes a single attempt. @type rospy.rostime.Duration @raise rocon_python_comms.NotFoundException: if no remote gateways or no matching gateways available. ''' #master = rosgraph.Master(rospy.get_name()) gateway_namespace = None service_names = [] timeout_time = time.time() + timeout.to_sec( ) if timeout is not None else None while not rospy.is_shutdown(): if timeout_time is not None and time.time() > timeout_time: break service_names = rosservice.rosservice_find( "gateway_msgs/RemoteGatewayInfo") if not service_names or len(service_names) > 1: gateway_namespace = None elif service_names[0] == '/remote_gateway_info': gateway_namespace = "/" else: gateway_namespace = re.sub(r'/remote_gateway_info', '', service_names[0]) if gateway_namespace is not None or timeout is None: break else: rospy.rostime.wallsleep(0.1) if not gateway_namespace: if not service_names: raise rocon_python_comms.NotFoundException( "no gateway found attached to this local master - did you start it?" ) else: raise rocon_python_comms.NotFoundException( "found more than one gateway connected to this master, this is an invalid configuration." ) #console.debug("Found a local gateway at %s"%gateway_namespace) return gateway_namespace
def resolve_connection_cache(timeout=None): """ @param timeout : timeout on checking for the connection_cache, if None, it just makes a single attempt. @type rospy.rostime.Duration @raise rocon_python_comms.NotFoundException: if no connection_cache available. """ connection_cache_namespace = None topic_names = [] timeout_time = time.time() + timeout.to_sec( ) if timeout is not None else None while not rospy.is_shutdown(): if timeout_time is not None and time.time() > timeout_time: break # CAREFUL : This will still return a topic name if it was there once and has disappeared since. topic_names = rostopic.find_by_type("rocon_std_msgs/ConnectionsList") if not topic_names or len(topic_names) > 1: connection_cache_namespace = None elif topic_names[0] == '/connection_cache/list': connection_cache_namespace = "/" else: connection_cache_namespace = re.sub(r'/connection_cache/list', '', topic_names[0]) if connection_cache_namespace is not None or timeout is None: break else: rospy.rostime.wallsleep(0.1) if not connection_cache_namespace: if not topic_names: raise rocon_python_comms.NotFoundException( "no connection_cache found attached to this local master - did you start it?" ) else: raise rocon_python_comms.NotFoundException( "found more than one connection_cache connected to this master, this is an invalid configuration." ) #console.debug("Found a connection_cache at %s"%connection_cache_namespace) return connection_cache_namespace
def __init__(self): ''' Don't do any loading here, just set up infrastructure and overrides from the solution. :raises: rocon_python_comms.NotFoundException, rospy.exceptions.ROSException, rospy.exceptions.ROSInterruptException ''' try: service_name = rocon_python_comms.find_service('rocon_interaction_msgs/SetInteractions', timeout=rospy.rostime.Duration(15.0), unique=True) except rocon_python_comms.NotFoundException as e: raise rocon_python_comms.NotFoundException( "failed to find unique service of type 'rocon_interaction_msgs/SetInteractions' [%s]" % str(e)) self._set_interactions_proxy = rospy.ServiceProxy(service_name, interaction_srvs.SetInteractions)
def set_topic_for_resource(self, msg): ''' Set a topic for resource @param msg : incoming message @type msg: scheduler_msgs.ServiceMsg ''' topic_name = "/services/adapter/required_resources" # rostopic find topic_name try: # assuming all topics here come in as /x/y/z/topicname or /x/y/z/topicname_355af31d topic_names = rocon_python_comms.find_topic( 'scheduler_msgs/SchedulerRequests', timeout=rospy.rostime.Duration(5.0), unique=False) topic_name = min(topic_names, key=len) except rocon_python_comms.NotFoundException: raise rocon_python_comms.NotFoundException( "couldn't find the concert scheduler topics, aborting")
def _setup_ros_services(self): """ :raises: :exc:`.rocon_python_comms.NotFoundException` if services couldn't be found. """ services = {} services['pull'] = rospy.ServiceProxy( '~gateway_pull', gateway_srvs.Remote, persistent=True) # @IgnorePep8 noqa services['remote_gateway_info'] = rospy.ServiceProxy( "~remote_gateway_info", gateway_srvs.RemoteGatewayInfo, persistent=True) try: for service in services.values(): service.wait_for_service( 10.0) # can throw rospy.ServiceException except rospy.ServiceException: raise rocon_python_comms.NotFoundException( "couldn't find the local gateway services") return services
def _get_gateway_info(self): gateway_info_proxy = rocon_python_comms.SubscriberProxy( "~gateway_info", gateway_msgs.GatewayInfo) # This needs to be in a loop, since it must not only check for a response, but that the gateway # is connected to the hub. If it isn't connected, it needs to try again. start_time = rospy.get_rostime() while not rospy.is_shutdown(): gateway_info = gateway_info_proxy(rospy.Duration(0.1)) if gateway_info: if gateway_info.connected: name = gateway_info.name ip = gateway_info.ip break else: rospy.loginfo( "Conductor : no hub yet available, spinning...") rospy.rostime.wallsleep(0.1) if rospy.get_rostime() - start_time > rospy.Duration(15.0): raise rocon_python_comms.NotFoundException( "couldn't retrieve gateway information") gateway_info_proxy.unregister() return (name, ip)
def find_scheduler_requests_topic(timeout=rospy.rostime.Duration(5.0)): ''' Do a lookup to find the scheduler requests topic. :param timeout: raise an exception if nothing is found before this timeout occurs. :type timeout: rospy.rostime.Duration :returns: the fully resolved name of the topic :rtype: str :raises rocon_python_comms.NotFoundException: if no topic is found within the timeout ''' try: # assuming all topics here come in as /x/y/z/topicname or /x/y/z/topicname_355af31d topic_names = rocon_python_comms.find_topic( 'scheduler_msgs/SchedulerRequests', timeout=rospy.rostime.Duration(5.0), unique=False) topic_name = min(topic_names, key=len) except rocon_python_comms.NotFoundException: raise rocon_python_comms.NotFoundException( "couldn't find the concert scheduler topics, aborting") return topic_name
def _set_remocon_services(self, interactions_namespace): """ setting up remocon-interaction manager apis. and check if the services are available :param str interactions_namespace : namespace to contact interaction manager :returns: remocon service apis :rtype: dict """ remocon_services = {} remocon_services[ 'get_interactions'] = interactions_namespace + '/' + 'get_interactions' remocon_services[ 'get_roles'] = interactions_namespace + '/' + 'get_roles' remocon_services[ 'request_interaction'] = interactions_namespace + '/' + 'request_interaction' for service_name in remocon_services.keys(): if not rocon_python_comms.service_is_available( remocon_services[service_name]): raise rocon_python_comms.NotFoundException( "'%s' service is not validated" % service_name) return remocon_services