Exemple #1
0
    def _param_tag(self, tag, context, ros_config, force_local=False, verbose=True):
        """
        @param force_local: if True, param must be added to context instead of ros_config
        @type  force_local: bool
        """
        try:
            self._check_attrs(tag, context, ros_config, XmlLoader.PARAM_ATTRS)

            # compute name and value
            ptype = (tag.getAttribute('type') or 'auto').lower().strip()
            
            vals = self.opt_attrs(tag, context, ('value', 'textfile', 'binfile', 'command'))
            if len([v for v in vals if v is not None]) != 1:
                raise XmlParseException(
                    "<param> tag must have one and only one of value/textfile/binfile.")

            # compute name. if name is a tilde name, it is placed in
            # the context. otherwise it is placed in the ros config.
            name = self.resolve_args(tag.attributes['name'].value.strip(), context)
            value = self.param_value(verbose, name, ptype, *vals)

            if is_private(name) or force_local:
                p = Param(name, value)
                context.add_param(p)
            else:
                p = Param(ns_join(context.ns, name), value)
                ros_config.add_param(Param(ns_join(context.ns, name), value), filename=context.filename, verbose=verbose)
            return p

        except KeyError, e:
            raise XmlParseException(
                "<param> tag is missing required attribute: %s. \n\nParam xml is %s"%(e, tag.toxml()))
Exemple #2
0
def test_Param():
    from roslaunch.core import Param
    p = Param('key/', 'value')

    assert p.key == 'key'
    assert p.value == 'value'
    assert p == Param('key', 'value')
    assert p != Param('key2', 'value')
    assert p != 1

    assert 'key' in str(p)
    assert 'key' in repr(p)
    assert 'value' in str(p)
    assert 'value' in repr(p)
Exemple #3
0
    def add_param(self, ros_config, param_name, param_value, verbose=True):
        """
        Add L{Param} instances to launch config. Dictionary values are
        unrolled into individual parameters.

        @param ros_config: launch configuration
        @type  ros_config: L{ROSLaunchConfig}
        @param param_name: name of parameter namespace to load values
            into. If param_name is '/', param_value must be a dictionary
        @type  param_name: str
        @param param_value: value to assign to param_name. If
            param_value is a dictionary, it's values will be unrolled
            into individual parameters.
        @type  param_value: str
        @raise ValueError: if parameters cannot be processed into valid Params
        """

        # shouldn't ever happen
        if not param_name:
            raise ValueError("no parameter name specified")

        if param_name == '/' and type(param_value) != dict:
            raise ValueError(
                "Cannot load non-dictionary types into global namespace '/'")

        if type(param_value) == dict:
            # unroll params
            for k, v in param_value.items():
                self.add_param(ros_config,
                               ns_join(param_name, k),
                               v,
                               verbose=verbose)
        else:
            ros_config.add_param(Param(param_name, param_value),
                                 verbose=verbose)
Exemple #4
0
    def _node_tag(self, tag, context, ros_config, default_machine, is_test=False, verbose=True):
        """
        Process XML <node> or <test> tag
        @param tag: DOM node
        @type  tag: Node
        @param context: namespace context
        @type  context: L{LoaderContext}
        @param params: ROS parameter list
        @type  params: [L{Param}]
        @param clear_params: list of ROS parameter names to clear before setting parameters
        @type  clear_params: [str]
        @param default_machine: default machine to assign to node
        @type  default_machine: str
        @param is_test: if set, will load as L{Test} object instead of L{Node} object
        @type  is_test: bool
        """
        try:
            if is_test:
                self._check_attrs(tag, context, ros_config, XmlLoader.TEST_ATTRS)
                (name,) = self.opt_attrs(tag, context, ('name',)) 
                test_name, time_limit, retry = self._test_attrs(tag, context)
                if not name:
                    name = test_name
            else:
                self._check_attrs(tag, context, ros_config, XmlLoader.NODE_ATTRS)
                (name,) = self.reqd_attrs(tag, context, ('name',))

            if not roslib.names.is_legal_name(name):
                ros_config.add_config_error("WARN: illegal <node> name '%s'.\nhttp://ros.org/wiki/Names\nThis will likely cause problems with other ROS tools.\nNode xml is %s"%(name, tag.toxml()))
                    
            child_ns = self._ns_clear_params_attr('node', tag, context, ros_config, node_name=name)
            param_ns = child_ns.child(name)
                
            # required attributes
            pkg, node_type = self.reqd_attrs(tag, context, ('pkg', 'type'))
            
            # optional attributes
            machine, args, output, respawn, cwd, launch_prefix, required = \
                     self.opt_attrs(tag, context, ('machine', 'args', 'output', 'respawn', 'cwd', 'launch-prefix', 'required'))
            if tag.hasAttribute('machine') and not len(machine.strip()):
                raise XmlParseException("<node> 'machine' must be non-empty: [%s]"%machine)
            if not machine and default_machine:
                machine = default_machine.name
            # validate respawn, required
            required, respawn = [_bool_attr(*rr) for rr in ((required, False, 'required'),\
                                                                (respawn, False, 'respawn'))]

            # each node gets its own copy of <remap> arguments, which
            # it inherits from its parent
            remap_context = context.child('')

            # nodes can have individual env args set in addition to
            # the ROS-specific ones.  
            for t in [c for c in tag.childNodes if c.nodeType == DomNode.ELEMENT_NODE]:
                tag_name = t.tagName.lower()
                if tag_name == 'remap':
                    r = self._remap_tag(t, context, ros_config)
                    if r is not None:
                        remap_context.add_remap(r)
                elif tag_name == 'param':
                    self._param_tag(t, param_ns, ros_config, force_local=True, verbose=verbose)
                elif tag_name == 'rosparam':
                    self._rosparam_tag(t, param_ns, ros_config, verbose=verbose)
                elif tag_name == 'env':
                    self._env_tag(t, context, ros_config)
                else:
                    ros_config.add_config_error("WARN: unrecognized '%s' tag in <node> tag. Node xml is %s"%(t.tagName, tag.toxml()))

            # #1036 evaluate all ~params in context
            # TODO: can we get rid of force_local (above), remove this for loop, and just rely on param_tag logic instead?
            for p in itertools.chain(context.params, param_ns.params):
                pkey = p.key
                if is_private(pkey):
                    # strip leading ~, which is optional/inferred
                    pkey = pkey[1:]
                pkey = param_ns.ns + pkey
                ros_config.add_param(Param(pkey, p.value), verbose=verbose)
                    
            if not is_test:
                return Node(pkg, node_type, name=name, namespace=child_ns.ns, machine_name=machine, 
                            args=args, respawn=respawn, 
                            remap_args=remap_context.remap_args(), env_args=context.env_args,
                            output=output, cwd=cwd, launch_prefix=launch_prefix,
                            required=required, filename=context.filename)
            else:
                return Test(test_name, pkg, node_type, name=name, namespace=child_ns.ns, 
                            machine_name=machine, args=args,
                            remap_args=remap_context.remap_args(), env_args=context.env_args,
                            time_limit=time_limit, cwd=cwd, launch_prefix=launch_prefix,
                            retry=retry, filename=context.filename)
        except KeyError, e:
            raise XmlParseException(
                "<%s> tag is missing required attribute: %s. Node xml is %s"%(tag.tagName, e, tag.toxml()))