def _process_listeners(self, name, exit_code):
        '''
          This is usually run as a post-executing function to the interaction and so will do the
          cleanup when the user's side of the interaction has terminated.

          Note that there are other means of stopping & cleanup for interactions:

          - via the remocon stop buttons (self.stop_interaction, self.stop_all_interactions)
          - via a rapp manager status callback when it is a pairing interaction

          There is some common code (namely del launched_interactions element, check pairing, publish remocon) so
          if changing that flow, be sure to check the code in self.stop_interaction()

          @param str name : name of the launched process stored in the interactions launch_list dict.
          @param int exit_code : could be utilised from roslaunched processes but not currently used.
        '''
        terminated = False
        for interaction in self.interactions_table.interactions:
            if self.launched_interactions.remove(interaction.hash, name):
                # toggle the pairing indicator if it was a pairing interaction
                if interaction.is_paired_type() and interaction.hash in self.active_paired_interaction_hashes:
                    self.active_paired_interaction_hashes = [interaction_hash for interaction_hash in self.active_paired_interaction_hashes if interaction_hash != interaction.hash]
                if not self.launched_interactions.get_launch_details(interaction.hash):
                    # inform the gui to update
                    self.signal_updated.emit()
                # update the rocon interactions handler
                self._publish_remocon_status()
                terminated = True
                break
        if not terminated:
            console.logwarn("A process listener detected a terminating interaction, but nothing to do.")
            console.logwarn("Probably mopped up by gui or independently terminating pairing requirement. [%s]" % name)
        else:
            console.logdebug("A process listener detected a terminating interaction & mopped up appropriately [%s]" % name)
Beispiel #2
0
 def _stop_all_interactions(self):
     """
     Stopping all running interactions. If no interactions is running, stop interactions button is disables.
     """
     console.logdebug("Role Chooser : stopping all running interactions")
     self.interactive_client_interface.stop_all_interactions()
     self.roles_widget.stop_all_interactions_button.setEnabled(False)
Beispiel #3
0
    def _start_global_executable_interaction(self, interaction, filename):
        """
        @param str filename: not really a filename, but the command to run

        The filename could be something like:

        @code
        /opt/ros/indigo/bin/rqt_plot
        rqt_plot
        rqt_plot -t
        @endcode
        """
        console.logdebug(
            "Interactive Client : starting global executable [%s]" %
            interaction.command)
        name = os.path.basename(filename).replace('.', '_')
        anonymous_name = name + "_" + uuid.uuid4().hex
        process_listener = functools.partial(self._process_listeners,
                                             anonymous_name, 1)
        cmd = shlex.split(filename)
        remapping_args = []
        for remap in interaction.remappings:
            remapping_args.append(remap.remap_from + ":=" + remap.remap_to)
        cmd.extend(remapping_args)
        cmd.extend(
            self._prepare_command_line_parameters(interaction.parameters))

        console.logdebug("Global executable command: '%s'" % cmd)
        process = rocon_python_utils.system.Popen(cmd,
                                                  postexec_fn=process_listener)
        self.launched_interactions.add(
            interaction.hash, anonymous_name,
            launch.LaunchInfo(anonymous_name, True, process))
        return True
Beispiel #4
0
    def __init__(self, interactive_client_interface=None):
        self.binded_function = {}
        self.cur_selected_role = ''
        self.cur_selected_interaction = None
        self.interactions = {}
        self.interactive_client_interface = interactive_client_interface
        self.interactions_widget = QWidget()
        # load ui
        rospack = rospkg.RosPack()
        path = os.path.join(rospack.get_path('rocon_remocon'), 'ui',
                            'interactions_list.ui')
        loadUi(path, self.interactions_widget)

        # interactions list widget
        self.interactions_widget.interactions_list_widget.setIconSize(
            QSize(50, 50))
        self.interactions_widget.interactions_list_widget.itemDoubleClicked.connect(
            self._start_interaction)
        self.interactions_widget.back_btn.pressed.connect(self._back)
        self.interactions_widget.interactions_list_widget.itemClicked.connect(
            self._display_interaction_info)  # rocon master item click event
        self.interactions_widget.stop_interactions_button.pressed.connect(
            self._stop_interaction)
        self.interactions_widget.stop_interactions_button.setDisabled(True)
        self.interactions_widget.closeEvent = self._close_event

        console.logdebug('init QInteractionsChooser')
Beispiel #5
0
    def _connect_rocon_master(self):
        rocon_master_name = str(
            self.rocon_masters[self.cur_selected_rocon_master].name)
        rocon_master_uri = str(
            self.rocon_masters[self.cur_selected_rocon_master].uri)
        rocon_master_host_name = str(
            self.rocon_masters[self.cur_selected_rocon_master].host_name)

        rocon_master_index = str(self.cur_selected_rocon_master)
        self.rocon_masters[rocon_master_index].check()
        # Todo this use of flags is spanky
        if self.rocon_masters[rocon_master_index].flag == '0':
            QMessageBox.warning(
                self, 'Rocon Master Connection Error',
                "Could not find a rocon master at %s" %
                self.rocon_masters[rocon_master_index].uri, QMessageBox.Ok)
            return
        if self.rocon_masters[rocon_master_index].flag == '1':
            QMessageBox.warning(
                self, 'Rocon Master Communication Error',
                "Found a rocon master at %s but cannot communicate with it (are ROS_IP/ROS_MASTER_URI correctly configured locally and remotely?)"
                % self.rocon_masters[rocon_master_index].uri, QMessageBox.Ok)
            return

        self._widget_main.hide()
        arguments = ["", rocon_master_uri, rocon_master_host_name]
        os.execv(QMasterChooser.rocon_remocon_sub_script, arguments)
        console.logdebug("Spawning: %s with args %s" %
                         (QMasterChooser.rocon_remocon_sub_script, arguments))
Beispiel #6
0
 def _back(self):
     if 'back' in self.binded_function.keys(
     ) and self.binded_function['back'] is not None:
         self.binded_function['back']()
     else:
         console.logdebug(
             "Interactions Chooser : None binded functione: shutdown")
Beispiel #7
0
    def _process_listeners(self, name, exit_code):
        '''
          Callback function used to catch terminating applications and cleanup appropriately.

          @param name : name of the launched process stored in the interactions index.
          @type str

          @param exit_code : could be utilised from roslaunched processes but not currently used.
          @type int
        '''
        console.logdebug(
            "Interactive Client : process_listener detected terminating interaction [%s]"
            % name)
        for interaction in self._interactions_table.interactions:
            if name in interaction.launch_list:
                del interaction.launch_list[name]
                # toggle the pairing indicator if it was a pairing interaction
                if interaction.is_paired_type():
                    self.pairing = None
                if not interaction.launch_list:
                    # inform the gui to update
                    self._stop_interaction_postexec_fn()
                # update the rocon interactions handler
                self._publish_remocon_status()
            else:
                console.logwarn(
                    "Interactive Client : process_listener detected unknown terminating interaction [%s]"
                    % name)
Beispiel #8
0
 def _start_rosrunnable_interaction(self, interaction,
                                    rosrunnable_filename):
     '''
       Launch a rosrunnable application. This does not apply any parameters
       or remappings (yet).
     '''
     # the following is guaranteed since we came back from find_resource calls earlier
     # note we're overriding the rosrunnable filename here - rosrun doesn't actually take the full path.
     package_name, rosrunnable_filename = interaction.name.split('/')
     name = os.path.basename(rosrunnable_filename).replace('.', '_')
     anonymous_name = name + "_" + uuid.uuid4().hex
     process_listener = partial(self._process_listeners, anonymous_name, 1)
     cmd = [
         'rosrun', package_name, rosrunnable_filename,
         '__name:=%s' % anonymous_name
     ]
     remapping_args = []
     for remap in interaction.remappings:
         remapping_args.append(remap.remap_from + ":=" + remap.remap_to)
     cmd.extend(remapping_args)
     cmd.extend(
         self._prepare_command_line_parameters(interaction.parameters))
     console.logdebug("Interactive Client : rosrunnable command %s" % cmd)
     process = rocon_python_utils.system.Popen(cmd,
                                               postexec_fn=process_listener)
     interaction.launch_list[anonymous_name] = LaunchInfo(
         anonymous_name, True, process)
     return True
Beispiel #9
0
 def _close_event(self, event):
     """
     Re-implementation of close event handlers for the interaction chooser's children
     (i.e. role and interactions list widgets).
     """
     console.logdebug("Interactions Chooser : remocon shutting down.")
     self.shutdown()
    def _start_rosrunnable_interaction(self, interaction, rosrunnable_filename):
        '''
          Launch a rosrunnable application. This does not apply any parameters yet.
          :param str rosrunnable_filename: full path to the rosrunnable filename
        '''
        # the following is guaranteed since we came back from find_resource calls earlier
        # note we're overriding the rosrunnable filename here - rosrun doesn't actually take the full path.
        console.logdebug("rosrunnable_filename : %s" % rosrunnable_filename)

        unused_package_name, rosrunnable_command = interaction.command.split('/', 1)
        rosrunnable_name = rosrunnable_command.split(' ', 1)[0]
        rosrunnable_name_and_args = rosrunnable_command.split(' ', 1)
        rosrunnable_args = rosrunnable_name_and_args[1] if len(rosrunnable_name_and_args) > 1 else []
        if rosrunnable_args:
            rosrunnable_args = roslaunch.substitution_args.resolve_args(rosrunnable_args)
            rosrunnable_args = rosrunnable_args.split(' ')
        name = os.path.basename(rosrunnable_name).replace('.', '_')
        anonymous_name = name + "_" + uuid.uuid4().hex
        process_listener = functools.partial(self._process_listeners, anonymous_name, 1)
        cmd = [rosrunnable_filename, '__name:=%s' % anonymous_name]
        cmd.extend(rosrunnable_args)
        remapping_args = []
        for remap in interaction.remappings:
            remapping_args.append(remap.remap_from + ":=" + remap.remap_to)
        cmd.extend(remapping_args)
        cmd.extend(self._prepare_command_line_parameters(interaction.parameters))
        console.logdebug("Rosrunnable command: '%s'" % cmd)
        process = rocon_python_utils.system.Popen(cmd, postexec_fn=process_listener)
        self.launched_interactions.add(
            interaction.hash,
            anonymous_name,
            launch.LaunchInfo(anonymous_name, True, process)
        )
        return True
Beispiel #11
0
    def _read_cache(self):
        #read cache and display the rocon master list
        try:
            cache_rocon_master_info_list = open(self.rocon_master_list_cache_path, 'r')
        except:
            console.logdebug("Remocon : no cached settings found, moving on.")
            return
        lines = cache_rocon_master_info_list.readlines()
        for line in lines:
            if line.count("[index="):
                rocon_master_index = line[string.find(line, "[index=") + len("[index="):string.find(line, ",name=")]
                rocon_master_name = line[string.find(line, "name=") + len("name="):string.find(line, ",master_uri=")]
                rocon_master_uri = line[string.find(line, ",master_uri=") + len(",master_uri="):string.find(line, ",host_name=")]
                rocon_master_host_name = line[string.find(line, ",host_name=") + len(",host_name="):string.find(line, ",description=")]
                rocon_master_description = line[string.find(line, ",description=") + len(",description="):string.find(line, ",icon=")]
                rocon_master_icon = line[string.find(line, ",icon=") + len(",icon="):string.find(line, ",flag=")]
                rocon_master_flag = line[string.find(line, ",flag=") + len(",flag="):string.find(line, "]")]

                self.rocon_master_list[rocon_master_index] = {}
                self.rocon_master_list[rocon_master_index]['index'] = rocon_master_index
                self.rocon_master_list[rocon_master_index]['name'] = rocon_master_name
                self.rocon_master_list[rocon_master_index]['master_uri'] = rocon_master_uri
                self.rocon_master_list[rocon_master_index]['host_name'] = rocon_master_host_name
                self.rocon_master_list[rocon_master_index]['icon'] = rocon_master_icon
                self.rocon_master_list[rocon_master_index]['description'] = rocon_master_description
                self.rocon_master_list[rocon_master_index]['flag'] = rocon_master_flag
        cache_rocon_master_info_list.close()
Beispiel #12
0
 def shutdown(self):
     self._terminal_shutdown_hook(processes=[self.process], hold=False)
     for temporary_file in self.temporary_files:
         console.logdebug("  unlinking %s" % temporary_file.name)
         try:
             os.unlink(temporary_file.name)
         except OSError:
             pass
Beispiel #13
0
    def _set_add_rocon_master(self):
        if self._connect_dlg:
            console.logdebug("Dialog is live!!")
            self._connect_dlg.done(0)

        self._connect_dlg = self._create_add_rocon_master_dialog()
        self._connect_dlg.setVisible(True)
        self._connect_dlg.finished.connect(self._destroy_connect_dlg)
 def _switch_to_role_list(self):
     """
     Switch to role chooser from interactions chooser.
     """
     self._interactive_client_ui_widget.setWindowTitle('Role Chooser')
     console.logdebug("InteractiveClientUI : switching to the role list")
     self._role_chooser.show(
         self._interactions_chooser.interactions_widget.pos())
     self._interactions_chooser.hide()
 def _switch_to_master_chooser(self):
     """
     Switch to master chooser from role chooser. If it was launced by rqt or rqt standalone, It is just shutdown.
     """
     self.shutdown()
     if not self.with_rqt:
         console.logdebug(
             "InteractiveClientUI : switching back to the master chooser")
         os.execv(QMasterChooser.rocon_remocon_script, ['', self.host_name])
Beispiel #16
0
 def _back(self):
     """
     Public method to enable shutdown of the script - this function is primarily for
     shutting down the Role chooser from external signals (e.g. CTRL-C on the command
     line).
     """
     console.logdebug("Role Chooser : Back")
     if 'back' in self.binded_function.keys() and self.binded_function['back'] is not None:
         self.binded_function['back']()
 def _start_dummy_interaction(self, interaction, unused_filename):
     console.logdebug("Starting a dummy interaction [%s]" % interaction.command)
     anonymous_name = interaction.name.lower().replace(' ', '_') + "_" + uuid.uuid4().hex
     # process_listener = partial(self._process_listeners, anonymous_name, 1)
     # process = rocon_python_utils.system.Popen([rosrunnable_filename], postexec_fn=process_listener)
     self.launched_interactions.add(interaction.hash,
                                    anonymous_name,
                                    launch.LaunchInfo(anonymous_name, True, None)
                                    )  # empty shutdown function
     return True
Beispiel #18
0
 def _stop_interaction(self):
     console.logdebug("Interactions Chooser : stopping interaction %s " % str(self.cur_selected_interaction.name))
     (result, message) = self.interactive_client.stop_interaction(self.cur_selected_interaction.hash)
     if result:
         if self.cur_selected_interaction.is_paired_type():
             self._refresh_interactions_list()  # make sure the highlight is disabled
         self._set_stop_interactions_button()
         #self.interactions_widget.stop_interactions_button.setDisabled(True)
     else:
         QMessageBox.warning(self, 'Stop Interaction Failed', "%s." % message.capitalize(), QMessageBox.Ok)
         console.logwarn("Interactions Chooser : stop interaction failed [%s]" % message)
    def append(self, interaction):
        """
        Append an interaction to the table.

        :param :class:`.Interaction` interaction:
        """
        matches = [i for i in self.interactions if i.hash == interaction.hash]
        if not matches:
            self.interactions.append(interaction)
        else:
            console.logdebug("Interactions Table : interaction already stored, not appending to the table [%s]" % interaction.hash)
Beispiel #20
0
    def _select_role(self, item):
        """
        Take the selected role to switch interactions viewer as it.

        :param item: qt list widget item of selected role. The user does double click on item wanted to launch
        :type item: python_qt_binding.QtGui.QListWidgetItem
        """
        console.logdebug("Role Chooser : switching to the interactions list")
        self.cur_selected_role = str(item.text())
        if 'select_role' in self.binded_function.keys() and self.binded_function['select_role'] is not None:
            self.binded_function['select_role']()
Beispiel #21
0
 def _switch_to_interactions_list(self, Item):
     """
     Take the selected role and switch to an interactions view of that role.
     """
     console.logdebug("Interactions Chooser : switching to the interactions list")
     self.cur_selected_role = str(Item.text())
     self.interactive_client.select_role(self.cur_selected_role)
     self.interactions_widget.show()
     self.interactions_widget.move(self.roles_widget.pos())
     self.roles_widget.hide()
     self._refresh_interactions_list()
Beispiel #22
0
 def _publish_remocon_status(self):
     remocon_status = interaction_msgs.RemoconStatus()
     remocon_status.platform_info = self.platform_info
     remocon_status.uuid = str(self.key.hex)
     remocon_status.version = rocon_std_msgs.Strings.ROCON_VERSION
     running_interactions = []
     for interaction_hash in self.launched_interactions.active():
         running_interactions.append(interaction_hash)
     remocon_status.running_interactions = running_interactions
     console.logdebug("Remocon : publishing remocon status")
     self.remocon_status_publisher.publish(remocon_status)
 def stop_all_interactions(self):
     """
     This is the big showstopper - stop them all!
     """
     console.logdebug("Interactive client : stopping all interactions")
     running_interactions = []
     for interaction in self._interactions_table.interactions:
         for unused_process_name in interaction.launch_list.keys():
             running_interactions.append(interaction.hash)
     for interaction_hash in running_interactions:
         self.stop_interaction(interaction_hash)
Beispiel #24
0
 def _publish_remocon_status(self):
     remocon_status = rocon_interaction_msgs.RemoconStatus()
     remocon_status.platform_info = self.platform_info
     remocon_status.uuid = str(self.key.hex)
     remocon_status.version = rocon_std_msgs.Strings.ROCON_VERSION
     running_interactions = []
     for interaction in self._interactions_table.interactions:
         for unused_process_name in interaction.launch_list.keys():
             running_interactions.append(interaction.hash)
     remocon_status.running_interactions = running_interactions
     console.logdebug("Interactive Client : publishing remocon status")
     self.remocon_status_pub.publish(remocon_status)
Beispiel #25
0
 def _close_event(self, event):
     """
     Re-implementation of close event handlers for the interaction chooser's children
     (i.e. role and interactions list widgets).
     """
     console.logdebug("Interactions Chooser : remocon shutting down.")
     if 'shutdown' in self.binded_function.keys(
     ) and self.binded_function['shutdown'] is not None:
         self.binded_function['shutdown']()
     else:
         console.logdebug(
             "Interactions Chooser : None binded functione: shutdown")
 def _switch_to_interactions_list(self):
     """
     Take the selected role and switch to an interactions view of that role.
     """
     console.logdebug(
         "InteractiveClientUI : switching to the interactions list")
     self._interactive_client_ui_widget.setWindowTitle(
         'Interactions Chooser')
     self._interactions_chooser.select_role(
         self._role_chooser.cur_selected_role)
     self._interactions_chooser.show(self._role_chooser.pos())
     self._role_chooser.hide()
Beispiel #27
0
 def get_rocon_master_info(self):
     console.logdebug("RemoconInfo : retrieving rocon master information")
     time_out_cnt = 0
     while not rospy.is_shutdown():
         if len(self.rocon_master_info) != 0:
             break
         else:
             rospy.sleep(rospy.Duration(0.2))
         time_out_cnt += 1
         if time_out_cnt > 5:
             console.logwarn("RemoconInfo : timed out waiting for rocon master information")
             break
     return self.rocon_master_info
Beispiel #28
0
 def _subscribe_pairing_status_callback(self, msg):
     console.logdebug(
         "Interactive Client : pairing status callback [%s][%s]" %
         (msg.rapp, msg.remocon))
     if self.pairing:
         if not msg.rapp and msg.remocon == self.name:
             console.logdebug(
                 "Interactive Client : the rapp in this paired interaction terminated"
             )
             # there will only ever be one allowed instance of a paired interaction, so ok to call a stop to all instances of this interaction type
             self.stop_interaction(self.pairing)
             # updat the gui
             self._stop_interaction_postexec_fn()
Beispiel #29
0
 def _set_stop_interactions_button(self):
     '''
       Disable or enable the stop button depending on whether the
       selected interaction has any currently launched processes,
     '''
     if not self.interactions:
         console.logwarn("No interactions")
         return
     if self.cur_selected_interaction.launch_list:
         console.logdebug("Interactions Chooser : enabling stop interactions button [%s]" % self.cur_selected_interaction.display_name)
         self.interactions_widget.stop_interactions_button.setEnabled(True)
     else:
         console.logdebug("Interactions Chooser : disabling stop interactions button [%s]" % self.cur_selected_interaction.display_name)
         self.interactions_widget.stop_interactions_button.setEnabled(False)
Beispiel #30
0
    def _switch_to_role_list(self):
        console.logdebug("Interactions Chooser : switching to the role list")

        # show the roles widget
        if self.interactive_client.has_running_interactions():
            self.roles_widget.stop_all_interactions_button.setEnabled(True)
        else:
            self.roles_widget.stop_all_interactions_button.setEnabled(False)
        self.roles_widget.show()
        self.roles_widget.move(self.interactions_widget.pos())

        # show the interactions widget
        self.interactions_widget.stop_interactions_button.setEnabled(False)
        self.interactions_widget.hide()