Exemplo n.º 1
0
def get_action_clients_and_servers(*, node, action_name):
    action_clients = []
    action_servers = []

    expanded_name = expand_topic_name(action_name, node.get_name(),
                                      node.get_namespace())
    validate_full_topic_name(expanded_name)

    node_names_and_ns = node.get_node_names_and_namespaces()
    for node_name, node_ns in node_names_and_ns:
        # Construct fully qualified name
        node_fqn = '/'.join(node_ns) + node_name

        # Get any action clients associated with the node
        client_names_and_types = rclpy.action.get_action_client_names_and_types_by_node(
            node,
            node_name,
            node_ns,
        )
        for client_name, client_types in client_names_and_types:
            if client_name == expanded_name:
                action_clients.append((node_fqn, client_types))

        # Get any action servers associated with the node
        server_names_and_types = rclpy.action.get_action_server_names_and_types_by_node(
            node,
            node_name,
            node_ns,
        )
        for server_name, server_types in server_names_and_types:
            if server_name == expanded_name:
                action_servers.append((node_fqn, server_types))

    return (action_clients, action_servers)
Exemplo n.º 2
0
def subscriber(node: Node, topic_name: str, message_type: MsgType,
               callback: Callable[[MsgType], Any],
               qos_profile: QoSProfile) -> Optional[str]:
    """Initialize a node with a single subscription and spin."""
    if message_type is None:
        topic_names_and_types = get_topic_names_and_types(
            node=node, include_hidden_topics=True)
        try:
            expanded_name = expand_topic_name(topic_name, node.get_name(),
                                              node.get_namespace())
        except ValueError as e:
            raise RuntimeError(e)
        try:
            validate_full_topic_name(expanded_name)
        except rclpy.exceptions.InvalidTopicNameException as e:
            raise RuntimeError(e)
        for n, t in topic_names_and_types:
            if n == expanded_name:
                if len(t) > 1:
                    raise RuntimeError(
                        "Cannot echo topic '%s', as it contains more than one type: [%s]"
                        % (topic_name, ', '.join(t)))
                message_type = t[0]
                break
        else:
            raise RuntimeError(
                'Could not determine the type for the passed topic')

    msg_module = get_message(message_type)

    node.create_subscription(msg_module, topic_name, callback, qos_profile)

    rclpy.spin(node)
Exemplo n.º 3
0
def _get_msg_class(node, topic, include_hidden_topics):
    """
    Get message module based on topic name.

    :param topic: topic name, ``list`` of ``str``
    """
    topic_names_and_types = get_topic_names_and_types(
        node=node, include_hidden_topics=include_hidden_topics)
    try:
        expanded_name = expand_topic_name(topic, node.get_name(),
                                          node.get_namespace())
    except ValueError as e:
        raise RuntimeError(e)
    try:
        validate_full_topic_name(expanded_name)
    except rclpy.exceptions.InvalidTopicNameException as e:
        raise RuntimeError(e)
    for n, t in topic_names_and_types:
        if n == expanded_name:
            if len(t) > 1:
                raise RuntimeError(
                    "Cannot echo topic '%s', as it contains more than one type: [%s]"
                    % (topic, ', '.join(t)))
            message_type = t[0]
            break
    else:
        # Could not determine the type for the passed topic
        return None

    return import_message_type(topic, message_type)
Exemplo n.º 4
0
def subscriber(node, topic_name, message_type, callback):
    if message_type is None:
        topic_names_and_types = get_topic_names_and_types(
            node=node, include_hidden_topics=True)
        try:
            expanded_name = expand_topic_name(topic_name, node.get_name(),
                                              node.get_namespace())
        except ValueError as e:
            raise RuntimeError(e)
        try:
            validate_full_topic_name(expanded_name)
        except rclpy.exceptions.InvalidTopicNameException as e:
            raise RuntimeError(e)
        for n, t in topic_names_and_types:
            if n == expanded_name:
                if len(t) > 1:
                    raise RuntimeError(
                        "Cannot echo topic '%s', as it contains more than one type: [%s]"
                        % (topic_name, ', '.join(t)))
                message_type = t[0]
                break
        else:
            raise RuntimeError(
                'Could not determine the type for the passed topic')

    msg_module = import_message_type(topic_name, message_type)

    node.create_subscription(msg_module, topic_name, callback,
                             qos_profile_sensor_data)

    while rclpy.ok():
        rclpy.spin_once(node)
Exemplo n.º 5
0
 def test_validate_full_topic_name_failures_services(self):
     # service name may not contain '?'
     with self.assertRaisesRegex(InvalidServiceNameException, 'must not contain characters'):
         validate_full_topic_name('/invalid_service?', is_service=True)
     # service name must start with /
     with self.assertRaisesRegex(InvalidServiceNameException, 'must be absolute'):
         validate_full_topic_name('invalid_service', is_service=True)
Exemplo n.º 6
0
 def test_validate_full_topic_name_failures(self):
     # topic name may not contain '?'
     with self.assertRaisesRegex(InvalidTopicNameException, 'must not contain characters'):
         validate_full_topic_name('/invalid_topic?')
     # topic name must start with /
     with self.assertRaisesRegex(InvalidTopicNameException, 'must be absolute'):
         validate_full_topic_name('invalid_topic')
Exemplo n.º 7
0
 def _validate_topic_or_service_name(self, topic_or_service_name, *, is_service=False):
     name = self.get_name()
     namespace = self.get_namespace()
     validate_node_name(name)
     validate_namespace(namespace)
     validate_topic_name(topic_or_service_name, is_service=is_service)
     expanded_topic_or_service_name = expand_topic_name(topic_or_service_name, name, namespace)
     validate_full_topic_name(expanded_topic_or_service_name, is_service=is_service)
Exemplo n.º 8
0
 def test_validate_full_topic_name(self):
     tests = [
         '/chatter',
         '/node_name/chatter',
         '/ns/node_name/chatter',
     ]
     for topic in tests:
         # Will raise if invalid
         validate_full_topic_name(topic)
Exemplo n.º 9
0
def subscriber(node, topic_name, message_type, callback):
    if message_type is None:
        topic_names_and_types = get_topic_names_and_types(node=node)
        try:
            expanded_name = expand_topic_name(topic_name, node.get_name(),
                                              node.get_namespace())
        except ValueError as e:
            raise RuntimeError(e)
        try:
            validate_full_topic_name(expanded_name)
        except rclpy.exceptions.InvalidTopicNameException as e:
            raise RuntimeError(e)
        for n, t in topic_names_and_types:
            if n == expanded_name:
                if len(t) > 1:
                    raise RuntimeError(
                        "Cannot echo topic '%s', as it contains more than one type: [%s]"
                        % (topic_name, ', '.join(t)))
                message_type = t[0]
                break
        else:
            raise RuntimeError(
                'Could not determine the type for the passed topic')

    # TODO(dirk-thomas) this logic should come from a rosidl related package
    try:
        package_name, message_name = message_type.split('/', 2)
        if not package_name or not message_name:
            raise ValueError()
    except ValueError:
        raise RuntimeError('The passed message type is invalid')
    module = importlib.import_module(package_name + '.msg')
    msg_module = getattr(module, message_name)

    node.create_subscription(msg_module,
                             topic_name,
                             callback,
                             qos_profile=qos_profile_sensor_data)

    while rclpy.ok():
        rclpy.spin_once(node)
Exemplo n.º 10
0
def _get_msg_class(node, topic):
    """
    Get message module based on topic name.

    :param topic: topic name, ``list`` of ``str``
    """
    topic_names_and_types = get_topic_names_and_types(node=node)
    try:
        expanded_name = expand_topic_name(topic, node.get_name(),
                                          node.get_namespace())
    except ValueError as e:
        raise RuntimeError(e)
    try:
        validate_full_topic_name(expanded_name)
    except rclpy.exceptions.InvalidTopicNameException as e:
        raise RuntimeError(e)
    for n, t in topic_names_and_types:
        if n == expanded_name:
            if len(t) > 1:
                raise RuntimeError(
                    "Cannot echo topic '%s', as it contains more than one type: [%s]"
                    % (topic, ', '.join(t)))
            message_type = t[0]
            break
    else:
        # Could not determine the type for the passed topic
        return None

    # TODO(dirk-thomas) this logic should come from a rosidl related package
    try:
        package_name, message_name = message_type.split('/', 2)
        if not package_name or not message_name:
            raise ValueError()
    except ValueError:
        raise RuntimeError('The passed message type is invalid')
    module = importlib.import_module(package_name + '.msg')
    return getattr(module, message_name)