예제 #1
0
 def shutdown_roslaunch_windows(self, processes, hold):
     """
     Shuts down a roslaunch window cleanly, i.e. it first kills the roslaunch
     processes, then kills the terminal itself.
     """
     roslaunch_pids = []
     for process in processes:
         roslaunch_pids.extend(utils.get_roslaunch_pids(process.pid))
     # kill roslaunch's
     for pid in roslaunch_pids:
         try:
             os.kill(pid, signal.SIGHUP)
         except OSError:
             continue
     for pid in roslaunch_pids:
         console.pretty_println("Terminating roslaunch [pid: %d]" % pid, console.bold)
         rocon_python_utils.system.wait_pid(pid)
         #console.pretty_println("Terminated roslaunch [pid: %d]" % pid, console.bold)
     time.sleep(1)
     if hold:
         try:
             raw_input("Press <Enter> to close terminals...")
         except RuntimeError:
             pass  # this happens when you ctrl-c again instead of enter
     # now kill the terminal itself
     for process in processes:
         try:
             os.killpg(process.pid, signal.SIGTERM)
         except OSError:
             console.warning("Kill signal failed to reach the terminal - typically this means the terminal has already shut down.")
         except TypeError as e:
             console.error("Invalid pid value [%s][%s]" % (str(process.pid), str(e)))
예제 #2
0
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]()
예제 #3
0
    def __init__(self, ros_master_uri, host_name):
        super(InteractionsRemocon, self).__init__()
        self.key = uuid.uuid4()
        self.ros_master_uri = ros_master_uri
        self.ros_master_port = urlparse(self.ros_master_uri).port
        self.host_name = host_name
        self.name = "rqt_remocon_" + self.key.hex
        console.loginfo("Connection Details")
        console.loginfo("   Node Name: " + self.name)
        console.loginfo("   ROS_MASTER_URI: " + self.ros_master_uri)
        console.loginfo("   ROS_HOSTNAME: " + self.host_name)
        self.launched_interactions = LaunchedInteractions()

        # terminal for roslaunchers and other shell executables
        try:
            self.roslaunch_terminal = rocon_launch.create_terminal()
        except (rocon_launch.UnsupportedTerminal,
                rocon_python_comms.NotFoundException) as e:
            console.warning(
                "Cannot find a suitable terminal, falling back to the current terminal [%s]"
                % str(e))
            self.roslaunch_terminal = rocon_launch.create_terminal(
                rocon_launch.terminals.active)

        self.namespaces = []
        self.active_namespace = None
        self.rocon_uri = "rocon:/"
        self.active_pairing = None
        self.active_paired_interaction_hashes = []
        # TODO a configurable icon...with a default
        self.platform_info = rocon_std_msgs.MasterInfo(
            version=rocon_std_msgs.Strings.ROCON_VERSION,
            rocon_uri=str(self.rocon_uri),
            icon=rocon_std_msgs.Icon(),
            description="")
        self.service_proxies = None
        self.subscribers = None
        self.pairings_table = get_pairings(self.active_namespace)
        self.interactions_table = get_interactions(self.active_namespace,
                                                   "rocon:/")

        self.namespace_scanner = NamespaceScanner()
        self.namespace_scanner.signal_updated.connect(self.interactions_found,
                                                      Qt.QueuedConnection)
        # self.namespace_scanner.busy_dialog.show()
        self.namespace_scanner.start()

        self.remocon_status_publisher = rospy.Publisher(
            "/remocons/" + self.name,
            interaction_msgs.RemoconStatus,
            latch=True,
            queue_size=5)
        self._publish_remocon_status()
예제 #4
0
파일: utils.py 프로젝트: javierdiazp/myros
def get_roslaunch_pids(parent_pid):
    '''
      Search the pstree of the specified pid for roslaunch processes. We use this to
      aid in gracefully terminating any roslaunch processes running in terminals before
      closing down the terminals themselves.

      :param str parent_pid: the pid of the parent process.
      :returns: list of pids
      :rtype: str[]

    '''
    if parent_pid is None:
        console.warning(
            "aborting call to find child roslaunches of a non-existant parent pid (can happen if cancelling spawned processes while they are still establishing)."
        )
        return []
    ps_command = subprocess.Popen("ps -o pid -o comm --ppid %d --noheaders" %
                                  parent_pid,
                                  shell=True,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.STDOUT)
    ps_output = ps_command.stdout.read()

    retcode = ps_command.wait()
    pids = []
    if retcode == 0:
        for pair in ps_output.split("\n")[:-1]:
            try:
                [pid, command] = pair.lstrip(' ').split(" ")
            except ValueError:  # when we can't unpack the output into two pieces
                # ignore, it's not a roslaunch
                console.warning(
                    "Rocon Launch : bad pair while scanning for roslaunch pids [%s]"
                    % pair)
                continue
            if command == 'roslaunch':
                pids.append(int(pid))
            else:
                pids.extend(get_roslaunch_pids(int(pid)))
    else:
        # Presume this roslaunch was killed by ctrl-c or terminated already.
        # Am not worrying about classifying between the above presumption and real errors for now
        pass
    return pids
예제 #5
0
    def __init__(self, stop_interaction_postexec_fn):
        '''
          @param stop_app_postexec_fn : callback to fire when a listener detects an app getting stopped.
          @type method with no args
        '''
        self._interactions_table = InteractionsTable()
        self._stop_interaction_postexec_fn = stop_interaction_postexec_fn
        self.is_connect = False
        self.key = uuid.uuid4()
        self._ros_master_port = None
        try:
            self._roslaunch_terminal = rocon_launch.create_terminal()
        except (rocon_launch.UnsupportedTerminal,
                rocon_python_comms.NotFoundException) as e:
            console.warning(
                "Cannot find a suitable terminal, falling back to the current terminal [%s]"
                % str(e))
            self._roslaunch_terminal = rocon_launch.create_terminal(
                rocon_launch.terminals.active)

        # this might be naive and only work well on ubuntu...
        os_codename = OsDetect().get_codename()
        webbrowser_codename = utils.get_web_browser_codename()
        # this would be good as a persistant variable so the user can set something like 'Bob'
        self.name = "rqt_remocon_" + self.key.hex
        self.rocon_uri = rocon_uri.parse("rocon:/pc/" + self.name + "/" +
                                         rocon_std_msgs.Strings.URI_WILDCARD +
                                         "/" + os_codename + "|" +
                                         webbrowser_codename)
        # be also great to have a configurable icon...with a default
        self.platform_info = rocon_std_msgs.PlatformInfo(
            version=rocon_std_msgs.Strings.ROCON_VERSION,
            uri=str(self.rocon_uri),
            icon=rocon_std_msgs.Icon())
        console.logdebug("Interactive Client : initialised")
        self.pairing = None  # if an interaction is currently pairing, this will store its hash

        # expose underlying functionality higher up
        self.interactions = self._interactions_table.generate_role_view
        """Get a dictionary of interactions belonging to the specified role."""
    def __init__(self, stop_interaction_postexec_fn):
        '''
          @param stop_app_postexec_fn : callback to fire when a listener detects an app getting stopped.
          @type method with no args
        '''
        self._interactions_table = InteractionsTable()
        self._stop_interaction_postexec_fn = stop_interaction_postexec_fn
        self.is_connect = False
        self.key = uuid.uuid4()
        self._ros_master_port = None
        try:
            self._roslaunch_terminal = rocon_launch.create_terminal()
        except (rocon_launch.UnsupportedTerminal,
                rocon_python_comms.NotFoundException) as e:
            console.warning(
                "Cannot find a suitable terminal, falling back to the current terminal [%s]"
                % str(e))
            self._roslaunch_terminal = rocon_launch.create_terminal(
                rocon_launch.terminals.active)

        # this would be good as a persistant variable so the user can set something like 'Bob'
        self.name = "rqt_remocon_" + self.key.hex
        self.rocon_uri = rocon_uri.parse(
            rocon_uri.generate_platform_rocon_uri('pc', self.name) + "|" +
            utils.get_web_browser_codename())
        # be also great to have a configurable icon...with a default
        self.platform_info = rocon_std_msgs.MasterInfo(
            version=rocon_std_msgs.Strings.ROCON_VERSION,
            rocon_uri=str(self.rocon_uri),
            icon=rocon_std_msgs.Icon(),
            description="")
        self.currently_pairing_interaction_hashes = []
        self.active_one_sided_interaction = None

        # expose underlying functionality higher up
        self.interactions = self._interactions_table.generate_role_view
        """Get a dictionary of interactions belonging to the specified role."""
예제 #7
0
def choose_terminal(gnome_flag, konsole_flag):
    '''
      Use ubuntu's x-terminal-emulator to choose the shell, or over-ride if it there is a flag.
    '''
    if konsole_flag:
        if not rocon_python_utils.system.which('konsole'):
            console.error(
                "Cannot find 'konsole' [hint: try --gnome for gnome-terminal instead]"
            )
            sys.exit(1)
        return 'konsole'
    elif gnome_flag:
        if not rocon_python_utils.system.which('gnome-terminal'):
            console.error(
                "Cannot find 'gnome' [hint: try --konsole for konsole instead]"
            )
            sys.exit(1)
        return 'gnome-terminal'
    else:
        if not rocon_python_utils.system.which('x-terminal-emulator'):
            console.error(
                "Cannot find 'x-terminal-emulator' [hint: try --gnome or --konsole instead]"
            )
            sys.exit(1)
        p = subprocess.Popen([
            rocon_python_utils.system.which('update-alternatives'), '--query',
            'x-terminal-emulator'
        ],
                             stdout=subprocess.PIPE)
        terminal = None
        for line in p.stdout:
            if line.startswith("Value:"):
                terminal = os.path.basename(line.split()[1])
                break
        if terminal not in [
                "gnome-terminal", "gnome-terminal.wrapper", "konsole"
        ]:
            console.warning(
                "You are using an esoteric unsupported terminal [%s]" %
                terminal)
            if rocon_python_utils.system.which('konsole'):
                terminal = 'konsole'
                console.warning(" --> falling back to 'konsole'")
            elif rocon_python_utils.system.which('gnome-terminal'):
                console.warning(" --> falling back to 'gnome-terminal'")
                terminal = 'gnome-terminal'
            else:
                console.error(
                    "Unsupported terminal set for 'x-terminal-emulator' [%s][hint: try --gnome or --konsole instead]"
                    % terminal)
                sys.exit(1)
        return terminal