Exemplo n.º 1
0
    def dump(self):
        """
        Dump the rocon masters to a cache file.
        """
        try:
            cache_rocon_master_info_list = open(rocon_masters_cache_path(),
                                                'w')
        except:
            console.logerror("Remocon : no directory or file: %s" %
                             rocon_masters_cache_path())
            return
        for rocon_master in self.rocon_masters.values():
            rocon_master_elem = '['
            rocon_master_elem += 'index=' + str(rocon_master.index) + ','
            rocon_master_elem += 'name=' + str(rocon_master.name) + ','
            rocon_master_elem += 'master_uri=' + str(rocon_master.uri) + ','
            rocon_master_elem += 'host_name=' + str(
                rocon_master.host_name) + ','
            rocon_master_elem += 'description=' + str(
                rocon_master.description) + ','
            rocon_master_elem += 'icon=' + rocon_master.icon + ','
            rocon_master_elem += 'flag=' + rocon_master.flag
            rocon_master_elem += ']\n'

            cache_rocon_master_info_list.write(rocon_master_elem)
        cache_rocon_master_info_list.close()
Exemplo n.º 2
0
 def start_interaction(self, interaction_hash):
     interaction = self.interactions_table.find(interaction_hash)
     if interaction is None:
         console.logerror("Couldn't find interaction with hash '%s'" % interaction_hash)
         return (False, "interaction key %s not found in interactions table" % interaction_hash)
     print("\nInteraction: %s" % interaction)
     console.logdebug("  - requesting permission to start interaction")
     response = self.service_proxies.request_interaction(remocon=self.name, hash=interaction_hash)
     if response.result == interaction_msgs.ErrorCodes.SUCCESS:
         console.logdebug("  - request granted")
         try:
             (app_executable, start_app_handler) = self._determine_interaction_type(interaction)
         except rocon_interactions.InvalidInteraction as e:
             return (False, ("invalid interaction specified [%s]" % str(e)))
         result = start_app_handler(interaction, app_executable)
         if result:
             if interaction.is_paired_type():
                 console.logdebug("  - setting an active pairing with %s" % interaction_hash)
                 self.active_paired_interaction_hashes.append(interaction_hash)
             self.signal_updated.emit()
             self._publish_remocon_status()
             return (result, "success")
         else:
             console.logerror("Result unknown")
             return (result, "unknown")
     else:
         console.logwarn("Request rejected [%s]" % response.message)
         return False, ("interaction request rejected [%s]" % response.message)
Exemplo n.º 3
0
 def relayed_invitation(self, req):
     '''
       Provides a relayed invitation from a client (e.g. android remocon).
       This relay fills in the gateway name to pass on to the app manager,
       which makes life much simpler for the clients.
     '''
     if self.auto_invite and req.cancel:
         # Don't cancel, just ignore it and send back a true response (not broken).
         return rocon_app_manager_srvs.SimpleInviteResponse(True)
     try:
         rospy.loginfo(
             "Pairing Master : inviting the private master's application manager."
         )
         remote_response = self.remote_invite_service(
             rocon_app_manager_srvs.InviteRequest(
                 remote_target_name=self.local_gateway_name,
                 application_namespace='',
                 cancel=req.cancel))
     except rospy.service.ServiceException:  # service call failed
         console.logerror(
             "Pairing Master: remote invitation failed to connect.")
     except rospy.exceptions.ROSInterruptException:  # shutdown exception
         sys.exit(0)
     return rocon_app_manager_srvs.SimpleInviteResponse(
         remote_response.result)
Exemplo n.º 4
0
 def stop_interaction(self, interaction_hash):
     """
     This stops all launches for an interaction of a particular type.
     """
     interaction = self.interactions_table.find(interaction_hash)
     if interaction is None:
         console.logerror("Couldn't find interaction with hash '%s'" % interaction_hash)
         return (False, "interaction key %s not found in interactions table" % interaction_hash)
     console.loginfo("Stopping all instances of '%s'" % interaction.name)
     try:
         for unused_launch_name, launch_info in self.launched_interactions.get_launch_details(interaction.hash).iteritems():
             if launch_info.running:
                 launch_info.shutdown()
                 console.loginfo("  instance stopped [%s]" % (launch_info.name))
             elif launch_info.process is None:
                 launch_info.running = False
                 console.loginfo("  no attached interaction process to stop [%s]" % (launch_info.name))
             else:
                 console.loginfo("  instance is already stopped [%s]" % (launch_info.name))
         self.launched_interactions.clear_launch_details(interaction.hash)
     except Exception as e:
         console.logerror("Error trying to stop all instances of an interaction [%s][%s]" % (type(e), str(e)))
         # this is bad...should not create bottomless exception buckets.
         return (False, "unknown failure - (%s)(%s)" % (type(e), str(e)))
     if interaction.is_paired_type():
         self.active_paired_interaction_hashes = [h for h in self.active_paired_interaction_hashes if h != interaction_hash]
     self.signal_updated.emit()
     self._publish_remocon_status()
     return (True, "success")
Exemplo n.º 5
0
    def _connect(self, rocon_master_name="", ros_master_uri="http://localhost:11311", host_name='localhost'):
        # remocon name would be good as a persistant configuration variable by the user
        # so they can set something like 'Bob'.
        remocon_name = 'rqt_remocon'
        unique_name = remocon_name + "_" + self.key.hex

        # uri is obtained from the user, stored in ros_master_uri
        os.environ["ROS_MASTER_URI"] = ros_master_uri
        os.environ["ROS_HOSTNAME"] = host_name

        print "[remocon_info] connect RemoconInfo "
        print "[remocon_info] ROS_MASTER_URI: " + str(os.environ["ROS_MASTER_URI"])
        print "[remocon_info] Node Name: " + str(unique_name)
        # Need to make sure we give it a unique node name and we need a unique uuid
        # for the remocon-role manager interaction anyway:

        rospy.init_node(unique_name, disable_signals=True)

        try:
            rocon_master_info_topic_name = rocon_python_comms.find_topic('rocon_std_msgs/MasterInfo', timeout=rospy.rostime.Duration(5.0), unique=True)
            get_interactions_service_name = rocon_python_comms.find_service('rocon_interaction_msgs/GetInteractions', timeout=rospy.rostime.Duration(5.0), unique=True)
            request_interaction_service_name = rocon_python_comms.find_service('rocon_interaction_msgs/RequestInteraction', timeout=rospy.rostime.Duration(5.0), unique=True)
        except rocon_python_comms.NotFoundException as e:
            console.logerror("RemoconInfo : failed to find either rocon master info or interactions topics and services' [%s]" % str(e))
            return False

        self.info_sub = rospy.Subscriber(rocon_master_info_topic_name, rocon_std_msgs.MasterInfo, self._info_callback)
        self.get_interactions_service_proxy = rospy.ServiceProxy(get_interactions_service_name, rocon_interaction_srvs.GetInteractions)
        self.request_interaction_service_proxy = rospy.ServiceProxy(request_interaction_service_name, rocon_interaction_srvs.RequestInteraction)
        self.remocon_status_pub = rospy.Publisher("remocons/" + unique_name, rocon_interaction_msgs.RemoconStatus, latch=True)

        self._pub_remocon_status(0, False)
        self.is_connect = True
        self.is_valid_info = False
        return True
Exemplo n.º 6
0
    def __init__(self, context):
        self._context = context
        super(RqtRemocon, self).__init__(context)
        self.rocon_master_uri = None
        self.host_name = None

        ##############################
        # Environment Variables
        ##############################
        try:
            self.rocon_master_uri = os.environ["ROS_MASTER_URI"]
        except KeyError as unused_e:
            console.logerror("ROS_MASTER_URI not set, aborting")
            sys.exit(1)

        try:
            self.host_name = os.environ["ROS_HOSTNAME"]
        except KeyError as unused_e:
            console.logwarn("ROS_HOSTNAME not set, you may drop comms across a network connection.")
            self.host_name = 'localhost'

        ##############################
        # Launch User Interface
        ##############################

        self.setObjectName('Rqt Remocon')
        self.rqt_remocon = InteractionsChooserUI(self.rocon_master_uri, self.host_name, True)
        # self._rqt_remocon = InteractiveClientUI(None, "Rqt remocon", None, self.rocon_master_uri, self.host_name, True)
        context.add_widget(self.rqt_remocon.widget)
Exemplo n.º 7
0
 def spawn_roslaunch_window(self, roslaunch_configuration, postexec_fn=None, env = {}):
     """
     :param roslaunch_configuration: required roslaunch info
     :type roslaunch_configuration: :class:`.RosLaunchConfiguration`
     :param func postexec_fn: run this after the subprocess finishes
     :param dict env: a additional customised environment to run ros launcher, {key : value}
     :returns: the subprocess and temp roslaunch file handles
     :rtype: (:class:`subprocess.Popen`, :class:`tempfile.NamedTemporaryFile`
     """
     if self.__class__ is Terminal:
         console.logerror("Do not use 'Terminal' directly, it is an abstract base class")
         sys.exit(1)
     if 'prepare_command' not in vars(self.__class__):
         console.logerror("The method _prepare_command must be implemented in children of rocon_launch.terminals.Terminal")
         sys.exit(1)
     meta_roslauncher = self._prepare_meta_roslauncher(roslaunch_configuration)
     cmd = self.prepare_command(roslaunch_configuration, meta_roslauncher.name)  # must be implemented in children
     # ROS_NAMESPACE is typically set since we often call this from inside a node
     # itself. Got to get rid of this otherwise it pushes things down
     roslaunch_env = os.environ.copy()
     if len(env) != 0:
         for key in env.keys():
             roslaunch_env[key] = env[key]
     try:
         roslaunch_env['ROS_MASTER_URI'] = roslaunch_env['ROS_MASTER_URI'].replace(str(urlparse(roslaunch_env['ROS_MASTER_URI']).port),str(roslaunch_configuration.port))
         del roslaunch_env['ROS_NAMESPACE']
     except KeyError:
         pass
     return (rocon_python_utils.system.Popen(cmd, postexec_fn=postexec_fn, env=roslaunch_env), meta_roslauncher)
Exemplo n.º 8
0
 def spawn_executable_window(self,
                             title,
                             command,
                             postexec_fn=None,
                             env={}):
     if self.__class__ is Terminal:
         console.logerror(
             "Do not use 'Terminal' directly, it is an abstract base class")
         sys.exit(1)
     if 'prepare_roslaunch_command' not in vars(self.__class__):
         console.logerror(
             "The method _prepare_roslaunch_command must be implemented in children of rocon_launch.terminals.Terminal"
         )
         sys.exit(1)
     cmd = self.prepare_command(title,
                                command)  # must be implemented in children
     our_env = os.environ.copy()
     if len(env) != 0:
         for key in env.keys():
             our_env[key] = env[key]
     # ROS_NAMESPACE is typically set since we often call this from inside a node
     # itself. Got to get rid of this otherwise it pushes things down
     try:
         del our_env['ROS_NAMESPACE']
     except KeyError:
         pass
     return rocon_python_utils.system.Popen(cmd,
                                            postexec_fn=postexec_fn,
                                            env=our_env)
    def _connect(self,
                 ros_master_uri="http://localhost:11311",
                 host_name='localhost'):

        self._ros_master_port = urlparse(os.environ["ROS_MASTER_URI"]).port
        console.logdebug("Interactive Client : Connection Details")
        console.logdebug("Interactive Client :   Node Name: " + self.name)
        console.logdebug("Interactive Client :   ROS_MASTER_URI: " +
                         ros_master_uri)
        console.logdebug("Interactive Client :   ROS_HOSTNAME: " + host_name)
        console.logdebug("Interactive Client :   ROS_MASTER_PORT: %s" %
                         self._ros_master_port)

        # Need to make sure we give init a unique node name and we need a unique uuid
        # for the remocon-role manager interaction anyway:

        try:
            console.logdebug(
                "Interactive Client : Get interactions service Handle")
            interactions_namespace = rocon_python_comms.find_service_namespace(
                'get_interactions',
                'rocon_interaction_msgs/GetInteractions',
                unique=True)
            remocon_services = self._set_remocon_services(
                interactions_namespace)
        except rocon_python_comms.MultipleFoundException as e:
            message = "multiple interactions' publications and services [%s] are found. Please check services" % str(
                e)
            console.logerror("InteractiveClientInterface : %s" % message)
            return (False, message)
        except rocon_python_comms.NotFoundException as e:
            message = "failed to find all of the interactions' publications and services for [%s]" % str(
                e)
            console.logerror("InteractiveClientInterface : %s" % message)
            return (False, message)

        self.get_interactions_service_proxy = rospy.ServiceProxy(
            remocon_services['get_interactions'],
            rocon_interaction_srvs.GetInteractions)
        self.get_roles_service_proxy = rospy.ServiceProxy(
            remocon_services['get_roles'], rocon_interaction_srvs.GetRoles)
        self.request_interaction_service_proxy = rospy.ServiceProxy(
            remocon_services['request_interaction'],
            rocon_interaction_srvs.RequestInteraction)
        self.remocon_status_pub = rospy.Publisher(
            "remocons/" + self.name,
            rocon_interaction_msgs.RemoconStatus,
            latch=True,
            queue_size=10)

        self.subscribers = rocon_python_comms.utils.Subscribers([
            (interactions_namespace + "/pairing_status",
             rocon_interaction_msgs.PairingStatus,
             self._subscribe_pairing_status_callback)
        ])

        self._publish_remocon_status()
        self.is_connect = True
        return (True, "success")
Exemplo n.º 10
0
 def _init_icon_paths(self):
     self.icon_paths = {}
     try:
         self.icon_paths[
             'unknown'] = rocon_python_utils.ros.find_resource_from_string(
                 'rocon_icons/unknown', extension='png')
     except (rospkg.ResourceNotFound, ValueError):
         console.logerror(
             "Remocon : couldn't find icons on the ros package path (install rocon_icons and rocon_bubble_icons"
         )
         sys.exit(1)
Exemplo n.º 11
0
    def __init__(self, parent, title, application):
        self._context = parent

        super(RemoconMain, self).__init__()
        self.initialised = False
        self.setObjectName('Remocon')

        self.host_name = "localhost"
        self.master_uri = "http://%s:11311" % (self.host_name)

        self.env_host_name = os.getenv("ROS_HOSTNAME")
        self.env_master_uri = os.getenv("ROS_MASTER_URI")
        if self.env_host_name == None:
            self.env_host_name = 'localhost'
        if self.env_master_uri == None:
            self.env_master_uri = "http://%s:11311" % (self.env_host_name)

        self.application = application
        self._widget_main = QWidget()

        self.rocon_master_list = {}
        self.cur_selected_rocon_master = None
        self.is_init = False

        path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../ui/remocon.ui")
        uic.loadUi(path, self._widget_main)

        utils.setup_home_dirs()
        self.rocon_master_list_cache_path = os.path.join(utils.get_settings_cache_home(), "rocon_master.cache")

        self.icon_paths = {}
        try:
            self.icon_paths['unknown'] = rocon_python_utils.ros.find_resource_from_string('rocon_icons/unknown', extension='png')
        except (rospkg.ResourceNotFound, ValueError):
            console.logerror("Remocon : couldn't find icons on the ros package path (install rocon_icons and rocon_bubble_icons")
            sys.exit(1)
        self.scripts_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../scripts/")

        #main widget
        self._widget_main.list_widget.setIconSize(QSize(50, 50))
        self._widget_main.list_widget.itemDoubleClicked.connect(self._connect_rocon_master)  # list item double click event
        self._widget_main.list_widget.itemClicked.connect(self._select_rocon_master)  # list item double click event

        self._widget_main.add_concert_btn.pressed.connect(self._set_add_rocon_master)  # add button event
        self._widget_main.delete_btn.pressed.connect(self._delete_rocon_master)  # delete button event
        self._widget_main.delete_all_btn.pressed.connect(self._delete_all_rocon_masters)  # delete all button event
        self._widget_main.refresh_btn.pressed.connect(self._refresh_rocon_master_list)  # refresh all button event

        #init
        self._init()
        self._widget_main.show()
        self._widget_main.activateWindow()  # give it the focus
        self._widget_main.raise_()          # make sure it is on top
 def stop_interaction(self, interaction_hash):
     """
     This stops all launches for an interaction of a particular type.
     """
     interaction = self._interactions_table.find(interaction_hash)
     if interaction is None:
         error_message = "interaction key %s not found in interactions table" % interaction_hash
         console.logwarn(
             "Interactive Client : could not stop interactions of this kind [%s]"
             % error_message)
         return (False, "%s" % error_message)
     else:
         console.logdebug(
             "Interactive Client : stopping all '%s' interactions" %
             interaction.display_name)
     try:
         for launch_info in interaction.launch_list.values():
             if launch_info.running:
                 launch_info.shutdown()
                 console.loginfo(
                     "Interactive Client : interaction stopped [%s]" %
                     (launch_info.name))
                 del interaction.launch_list[launch_info.name]
             elif launch_info.process is None:
                 launch_info.running = False
                 console.loginfo(
                     "Interactive Client : no attached interaction process to stop [%s]"
                     % (launch_info.name))
                 del interaction.launch_list.launch_list[launch_info.name]
             else:
                 console.loginfo(
                     "Interactive Client : interaction is already stopped [%s]"
                     % (launch_info.name))
                 del interaction.launch_list.launch_list[launch_info.name]
     except Exception as e:
         console.logerror(
             "Interactive Client : error trying to stop an interaction [%s][%s]"
             % (type(e), str(e)))
         # this is bad...should not create bottomless exception buckets.
         return (False, "unknown failure - (%s)(%s)" % (type(e), str(e)))
     # console.logdebug("Interactive Client : interaction's updated launch list- %s" % str(interaction.launch_list))
     if interaction.is_paired_type():
         self.currently_pairing_interaction_hashes = [
             h for h in self.currently_pairing_interaction_hashes
             if h != interaction_hash
         ]
     self._publish_remocon_status()
     return (True, "success")
Exemplo n.º 13
0
    def check(self):
        '''
        Given the uri and hostname, this proceeds to try and ping the rocon master to detect if it is available and
        if available, find the information on the other fields that fully describe a rocon master.
        '''
        print("Checking")
        if not (self.uri and self.host_name):
            console.logerror(
                "Rocon Master : both uri and host_name should be configured before calling RoconMaster.check()"
            )
            return
        print("POpen: %s" % [
            RoconMaster.rocon_remocon_check_up_script, self.uri, self.host_name
        ])
        # should check that uri and host name have been set
        output = subprocess.Popen([
            RoconMaster.rocon_remocon_check_up_script, self.uri, self.host_name
        ],
                                  stdout=subprocess.PIPE)
        time_out_cnt = 0
        while True:
            result = output.poll()
            if time_out_cnt > 30:
                console.logdebug("timeout: %s" % self.uri)
                try:
                    output.terminate()
                except:
                    console.logdebug("Error: output.terminate()")
                self.set_unknown()
                break
            elif result == 0:
                args = output.communicate()[0]
                print("Got args: %s" % args)
                self.name = args.split('\n')[0]
                self.description = args.split('\n')[1]
                self.icon = args.split('\n')[2]

                if self.name == "Unknown":
                    self.flag = '0'
                elif self.name == "Uncommunicable":
                    self.flag = '1'
                else:
                    self.flag = '2'
                break

            time.sleep(0.1)
            time_out_cnt += 1
Exemplo n.º 14
0
    def __init__(self, context):
        self._context = context
        super(RqtRemocon, self).__init__(context)
        # Process standalone plugin command-line arguments
        self.rocon_master_uri = 'localhost'
        self.host_name = 'localhost'

        try:
            self.rocon_master_uri = os.environ["ROS_MASTER_URI"]
            self.host_name = os.environ["ROS_HOSTNAME"]
        except KeyError as e:
            console.logerror("Rqt Remocon: %s " % str(e))

        self.setObjectName('Rqt Remocon')
        self._rqt_remocon = InteractiveClientUI(None, "Rqt remocon", None,
                                                self.rocon_master_uri,
                                                self.host_name, True)
        context.add_widget(self._rqt_remocon.get_main_ui_handle())
Exemplo n.º 15
0
                    cancel=req.cancel))
        except rospy.service.ServiceException:  # service call failed
            console.logerror(
                "Pairing Master: remote invitation failed to connect.")
        except rospy.exceptions.ROSInterruptException:  # shutdown exception
            sys.exit(0)
        return rocon_app_manager_srvs.SimpleInviteResponse(
            remote_response.result)


##############################################################################
# Main
##############################################################################

if __name__ == '__main__':
    rospy.init_node('pairing_master')
    auto_invite = rospy.get_param("~auto_invite", "false")
    rospy.loginfo("Pairing Master : auto-inviting %s" % auto_invite)
    local_gateway_name = local_gateway_name()
    if local_gateway_name is None:
        console.logerror("Pairing Master : shutting down.")
        sys.exit(1)
    rospy.loginfo("Pairing Master : local gateway name [%s]" %
                  local_gateway_name)
    remote_gateway_name = remote_gateway_name()
    rospy.loginfo("Pairing Master : remote gateway name [%s]" %
                  remote_gateway_name)
    invitation_handler = InvitationHandler(local_gateway_name,
                                           remote_gateway_name, auto_invite)
    invitation_handler.spin()
Exemplo n.º 16
0
    def _connect(self,
                 rocon_master_name="",
                 ros_master_uri="http://localhost:11311",
                 host_name='localhost'):

        # uri is obtained from the user, stored in ros_master_uri
        os.environ["ROS_MASTER_URI"] = ros_master_uri
        os.environ["ROS_HOSTNAME"] = host_name
        self._ros_master_port = urlparse(os.environ["ROS_MASTER_URI"]).port

        console.logdebug("Interactive Client : Connection Details")
        console.logdebug("Interactive Client :   Node Name: " + self.name)
        console.logdebug("Interactive Client :   ROS_MASTER_URI: " +
                         ros_master_uri)
        console.logdebug("Interactive Client :   ROS_HOSTNAME: " + host_name)
        console.logdebug("Interactive Client :   ROS_MASTER_PORT: %s" %
                         self._ros_master_port)

        # Need to make sure we give init a unique node name and we need a unique uuid
        # for the remocon-role manager interaction anyway:
        rospy.init_node(self.name, disable_signals=True)
        try:
            get_interactions_service_name = rocon_python_comms.find_service(
                'rocon_interaction_msgs/GetInteractions',
                timeout=rospy.rostime.Duration(5.0),
                unique=True)
            get_roles_service_name = rocon_python_comms.find_service(
                'rocon_interaction_msgs/GetRoles',
                timeout=rospy.rostime.Duration(5.0),
                unique=True)
            request_interaction_service_name = rocon_python_comms.find_service(
                'rocon_interaction_msgs/RequestInteraction',
                timeout=rospy.rostime.Duration(5.0),
                unique=True)
        except rocon_python_comms.NotFoundException as e:
            message = "failed to find all of the interactions' publications and services [%s]" % str(
                e)
            console.logerror("InteractiveClient : %s" % message)
            return (False, message)

        self.get_interactions_service_proxy = rospy.ServiceProxy(
            get_interactions_service_name,
            rocon_interaction_srvs.GetInteractions)
        self.get_roles_service_proxy = rospy.ServiceProxy(
            get_roles_service_name, rocon_interaction_srvs.GetRoles)
        self.request_interaction_service_proxy = rospy.ServiceProxy(
            request_interaction_service_name,
            rocon_interaction_srvs.RequestInteraction)
        self.remocon_status_pub = rospy.Publisher(
            "remocons/" + self.name,
            rocon_interaction_msgs.RemoconStatus,
            latch=True,
            queue_size=10)

        try:
            # if its available, should be quick to find this one since we found the others...
            pairing_topic_name = rocon_python_comms.find_topic(
                'rocon_interaction_msgs/Pair',
                timeout=rospy.rostime.Duration(0.5),
                unique=True)
            self.pairing_status_subscriber = rospy.Subscriber(
                pairing_topic_name, rocon_interaction_msgs.Pair,
                self._subscribe_pairing_status_callback)
        except rocon_python_comms.NotFoundException as e:
            console.logdebug(
                "Interactive Client : support for paired interactions disabled [not found]"
            )

        self._publish_remocon_status()
        self.is_connect = True
        return (True, "success")