コード例 #1
0
ファイル: utils.py プロジェクト: xdiegool/ros2lc_bridge
def get_topic_types(tlist):
    """Query the master about topics and their types."""
    master = Master('/' + PROJ_NAME)
    ttdict = dict(master.getTopicTypes())
    want = set(tlist)
    have = set(ttdict.keys())
    missing = want - have
    if missing:
        raise GeneratorException("Unknown topic(s) referenced: %s" %
                                 ', '.join(missing))

    return {to: ttdict[to] for to in (set(ttdict.keys()) & set(tlist))}
コード例 #2
0
ファイル: proxy.py プロジェクト: roman-dvorak/rosbridge_suite
def get_topics():
    """ Returns a list of all the active topics in the ROS system """
    try:
        publishers, subscribers, services = Master('/rosbridge').getSystemState()
        return list(set([x for x, _ in publishers] + [x for x, _, in subscribers]))
    except:
        return []
コード例 #3
0
def get_topics(topics_glob):
    """ Returns a list of all the active topics in the ROS system """
    try:
        publishers, subscribers, services = Master('/rosbridge').getSystemState()
        # Filter the list of topics by whether they are public before returning.
        return filter_globs(topics_glob,
                            list(set([x for x, _ in publishers] + [x for x, _, in subscribers])))
    except:
        return []
コード例 #4
0
ファイル: topic_listener.py プロジェクト: fangzheng81/rhbp
 def __init__(self,
              include_regex_into_topic_names=True,
              prefix=DEFAULT_NAME):
     """
     :param include_regex_into_topic_names: Whether names of update topic should contain the pattern. Just for better debugging. Has no influence on functionality
     :param prefix: address of the topic listener. The address is used for the subscribe service and all update topics.
     """
     self.__handler = Master(rospy.get_name(
     ))  # get access to the ROS master to use the topic directoy
     self.__lock = Lock()
     self.__update_topics = {}
     self.__include_regex_into_topic_names = include_regex_into_topic_names
     self.__topic_counter = 0
     self.__subscribed_regular_expressions = []
     self.__prefix = prefix
     self.__subscribe_service = rospy.Service(
         self.__prefix + TopicListener.SUBSCRIBE_SERVICE_NAME_POSTFIX,
         TopicUpdateSubscribe, self.__subscribe_callback_thread_safe)
     self.__existing_topics = []
コード例 #5
0
def get_topics_and_types(topics_glob):
    """ Returns a list of all the active topics in the ROS system """
    try:
        # Function getTopicTypes also returns inactive topics and does not
        # return topics with unknown message types, so it must be compared
        # to results from getSystemState.
        master = Master('/rosbridge')
        topic_types = master.getTopicTypes()
        publishers, subscribers, services = master.getSystemState()
        topics = set([x for x, _ in publishers] + [x for x, _ in subscribers])

        # Filter the list of topics by whether they are public.
        topics = set(filter_globs(topics_glob, topics))
        topic_types = [x for x in topic_types if x[0] in topics]

        # Add topics with unknown type messages.
        unknown_type = topics.difference([x for x, _ in topic_types])
        return zip(*topic_types + [[x, ''] for x in unknown_type])
    except:
        return []
コード例 #6
0
def get_service_providers(queried_type, services_glob):
    """ Returns a list of node names that are advertising a service with the specified type """
    _, _, services = Master('/rosbridge').getSystemState()

    service_type_providers = []
    for service, providers in services:
        service_type = get_service_type(service, services_glob)

        if service_type == queried_type:
            service_type_providers += providers
    return service_type_providers
コード例 #7
0
ファイル: proxy.py プロジェクト: roman-dvorak/rosbridge_suite
def get_service_providers(servicetype):
    """ Returns a list of node names that are advertising a service with the specified type """
    try:
        publishers, subscribers, services = Master('/rosbridge').getSystemState()
        servdict = dict(services)
        if servicetype in servdict:
            return servdict[servicetype]
        else:
            return []
    except socket.error:
        return []
コード例 #8
0
ファイル: proxy.py プロジェクト: roman-dvorak/rosbridge_suite
def get_subscribers(topic):
    """ Returns a list of node names that are subscribing to the specified topic """
    try:
        publishers, subscribers, services = Master('/rosbridge').getSystemState()
        subdict = dict(subscribers)
        if topic in subdict:
            return subdict[topic]
        else:
            return []
    except socket.error:
        return []
コード例 #9
0
def get_node_publications(node):
    """ Returns a list of topic names that are been published by the specified node """
    try:
        publishers, subscribers, services = Master('/rosbridge').getSystemState()
        toReturn = []
        for i, v in publishers:
            if node in v:
                toReturn.append(i)
        toReturn.sort()
        return toReturn
    except socket.error:
        return []
コード例 #10
0
def get_publishers(topic, topics_glob):
    """ Returns a list of node names that are publishing the specified topic """
    try:
        if any_match(str(topic), topics_glob):
            publishers, subscribers, services = Master('/rosbridge').getSystemState()
            pubdict = dict(publishers)
            if topic in pubdict:
                return pubdict[topic]
            else:
                return []
        else:
            return []
    except socket.error:
        return []
コード例 #11
0
def get_topics_types(topics, topics_glob):
    try:
        # Get all types from master once
        topic_types = {
            topic: type
            for topic, type in Master('/rosbridge').getTopicTypes()
        }
        types = []
        for i in topics:
            # Make sure topic is public & published
            if any_match(str(i), topics_glob) and i in topic_types:
                types.append(topic_types[i])
            else:
                types.append("")
        return types
    except:
        return []
コード例 #12
0
ファイル: topic_listener.py プロジェクト: fangzheng81/rhbp
class TopicListener(object):
    """
    Service that allows subscribing for updates about added or removed topics
    Provides a method, which checks for new or removed topics and informs subscribers about.
    The topic listener is usually started as own node, see main below. The clients of this service
    register through a service interface and are updated by a topic of new topcis that match their pattern.
    """

    DEFAULT_NAME = 'TopicListenerNode'

    SUBSCRIBE_SERVICE_NAME_POSTFIX = '/Subscribe'

    def __init__(self,
                 include_regex_into_topic_names=True,
                 prefix=DEFAULT_NAME):
        """
        :param include_regex_into_topic_names: Whether names of update topic should contain the pattern. Just for better debugging. Has no influence on functionality
        :param prefix: address of the topic listener. The address is used for the subscribe service and all update topics.
        """
        self.__handler = Master(rospy.get_name(
        ))  # get access to the ROS master to use the topic directoy
        self.__lock = Lock()
        self.__update_topics = {}
        self.__include_regex_into_topic_names = include_regex_into_topic_names
        self.__topic_counter = 0
        self.__subscribed_regular_expressions = []
        self.__prefix = prefix
        self.__subscribe_service = rospy.Service(
            self.__prefix + TopicListener.SUBSCRIBE_SERVICE_NAME_POSTFIX,
            TopicUpdateSubscribe, self.__subscribe_callback_thread_safe)
        self.__existing_topics = []

    def __del__(self):
        """
            closes all services
        """
        self.__subscribe_service.shutdown()

    @staticmethod
    def generate_topic_name_for_pattern(pattern, regex, include_pattern,
                                        counter):
        """
        generates topic name for given regex
        :param prefix: prefix for topic names
        :param pattern: regex (type string)
        :param include_pattern: whether the regex should occur in the topic name
        :param counter: unique number for this topic name
        :return: topic name
        """
        topic_name = pattern + 'Topic' + str(counter)
        if include_pattern:
            topic_name += '_' + re.sub(r'[^a-zA-Z0-9]', '', str(regex))
        return topic_name

    def __find_matching_topcis(self, regex):
        """
        :param regex: (regular expression) regex for matching the topics
        :return: names of all existing topics, which match the regular expression
        """
        matching_topics = []
        for topic_name in self.__existing_topics:
            if (regex.match(topic_name)):
                matching_topics.append(topic_name)
        return tuple(matching_topics)

    def __subscribe_callback_thread_safe(self, request):
        """
        Creates topics for the requested pattern and returns all already existing topic names, matching the pattern
        :param request: (TopicUpdateSubscribe) subscribe request.
                        The pattern must be a regular expression, compatible to pythons regular expressions
        :return: service response
        """
        with self.__lock:
            pattern = request.regex
            regex = re.compile(pattern)
            if (regex in self.__update_topics):
                topic_names = self.__update_topics[regex]
                return TopicUpdateSubscribeResponse(
                    topicNameTopicAdded=topic_names[0].name,
                    topicNameTopicRemoved=topic_names[1].name,
                    existingTopics=self.__find_matching_topcis(regex))

            self.__subscribed_regular_expressions.append(regex)
            base_topic_name = TopicListener.generate_topic_name_for_pattern(
                self.__prefix + '/Topics/', pattern,
                self.__include_regex_into_topic_names, self.__topic_counter)
            self.__topic_counter += 1
            added_topic_name = base_topic_name + '/TopicAdded'
            added_topic = rospy.Publisher(added_topic_name,
                                          String,
                                          queue_size=10)
            removed_topic_name = base_topic_name + '/TopicRemoved'
            removed_topic = rospy.Publisher(removed_topic_name,
                                            String,
                                            queue_size=10)
            rospy.sleep(0.1)
            self.__update_topics[regex] = (added_topic, removed_topic)

            rhbplog.logdebug('subscribed for pattern: ' + pattern)
            return TopicUpdateSubscribeResponse(
                topicNameTopicAdded=added_topic_name,
                topicNameTopicRemoved=removed_topic_name,
                existingTopics=self.__find_matching_topcis(regex))

    def __inform_about_topic_change(self, changed_topics,
                                    inform_about_added_topics):
        """
        Informs all subscribed topics about the topic changes.
        Each client is only informed about changes of matching topics
        :param changed_topics: names of all changed topics
        :param inform_about_added_topics: whether the changed topics are added (or removed).
                                          Is used for decision about used topic
        """
        if (inform_about_added_topics):
            index_of_topic_in_pair = 0
        else:
            index_of_topic_in_pair = 1
        for regex in self.__subscribed_regular_expressions:
            for topic in changed_topics:
                if (regex.match(topic)):
                    self.__update_topics[regex][
                        index_of_topic_in_pair].publish(topic)

    def __inform_about_added_topics(self, added_topics):
        self.__inform_about_topic_change(added_topics, True)

    def __inform_about_removed_topics(self, removed_topics):
        self.__inform_about_topic_change(removed_topics, False)

    def check(self):
        """
        Update method that tracks known and new topics
        It triggers the pattern comparision in case of new
        available topics
        """
        with self.__lock:
            expected_topics = list(self.__existing_topics)
            self.__existing_topics = []
            added_topics = []
            topics = self.__handler.getPublishedTopics('')
            for topic in topics:
                topic_name = topic[0]
                # cache and update existing and new topics
                self.__existing_topics.append(topic_name)
                if (topic_name in expected_topics):
                    expected_topics.remove(topic_name)
                else:
                    added_topics.append(topic_name)
            self.__inform_about_added_topics(added_topics)
            if (added_topics):
                rhbplog.logdebug('New Topics: ' + str(added_topics))

            if (expected_topics):
                rhbplog.logdebug('Removed Topics: ' + str(expected_topics))
            self.__inform_about_removed_topics(expected_topics)