Esempio n. 1
0
def validate(xml_dict):
    '''
    If we make assumptions elsewhere in XML processing, then they should be
        enforced here.
    '''
    # Assumption: radians for angles, "xyz" euler angle sequence, etc.

    values = {'@coordinate': 'local', '@angle': 'radian', '@eulerseq': 'xyz'}
    for key, value in values.items():
        if key in xml_dict:
            assert value == xml_dict[
                key], 'Invalid value for \"%s\". We support only \"%s\"' % (
                    key, value)

    # Assumption: all meshes have name
    if "asset" in xml_dict and "mesh" in xml_dict["asset"]:
        for mesh in xml_dict["asset"]["mesh"]:
            assert "@name" in mesh, "%s is missing name" % mesh

    # Assumption: none all the default classes is global.
    if "default" in xml_dict:
        for key, value in xml_dict["default"].items():
            assert key == "default", "Dont use global variables in default %s %s" % (
                key, value)

    # Assumption: all joints have name.
    def assert_joint_names(node):
        if "joint" in node:
            for joint in node["joint"]:
                assert "@name" in joint, "Missing name for %s" % joint

    if "worldbody" in xml_dict:
        closure_transform(assert_joint_names)(xml_dict["worldbody"])
Esempio n. 2
0
def extract_includes(xml_dict, root_xml_path, enforce_validation=True):
    '''
    extracts "include" xmls and substitutes them.
    '''
    def transform_include(node):
        if "include" in node:
            if isinstance(node["include"], OrderedDict):
                node["include"] = [node["include"]]
            include_xmls = []
            for include_dict in node["include"]:
                include_path = include_dict["@file"]
                if not exists(include_path):
                    include_path = join(dirname(abspath(root_xml_path)),
                                        include_path)
                assert exists(
                    include_path), "Cannot include file: %s" % include_path
                with open(include_path) as f:
                    include_string = f.read()
                include_xml = xmltodict.parse(include_string.strip())
                closure_transform(transform_include)(include_xml)
                assert "mujocoinclude" in include_xml, "Missing <mujocoinclude>."
                include_xmls.append(include_xml["mujocoinclude"])
            del node["include"]
            for include_xml in include_xmls:
                preprocess(include_xml,
                           root_xml_path,
                           enforce_validation=enforce_validation)
                update_mujoco_dict(node, include_xml)

    closure_transform(transform_include)(xml_dict)
Esempio n. 3
0
    def fun(xml_dict):
        def closure(node):
            if 'joint' in node:
                node["joint"] = [
                    j for j in node["joint"]
                    if j["@type"] != "hinge" or np.linalg.norm(j["@axis"] -
                                                               axis) >= 1e-5
                ]

        return closure_transform(closure)(xml_dict)
Esempio n. 4
0
def set_joint_damping_transform(damping, joint_name):
    ''' Set joints damping to a single value.
        Args:
            damping (float): damping to set
            joint_name (string): partial name of joint. Any joint with joint_name
                as a substring will be affected.
    '''
    def closure(node):
        for joint in node.get('joint', []):
            if joint_name in joint['@name']:
                joint['@damping'] = damping

    return closure_transform(closure)
Esempio n. 5
0
    def to_xml_dict(self):
        '''
        Generates XML for this object and all of its children.
            see generate_xml() for parameter documentation
        Returns merged xml_dict
        '''
        full_xml_dict = OrderedDict()
        # First add all of our own xml
        self.xml_dict = self.generate_xml_dict()

        # Removed joints marked to be static. We set positions in XML instead of using qpos.
        for body in self.xml_dict.get("worldbody", {}).get("body", []):
            remaining_joints = []
            for jnt in body.get("joint", []):
                if jnt["@type"] == "slide":
                    axis_idx = get_axis_index(jnt["@axis"])
                    if self._keep_slide_joint[axis_idx]:
                        remaining_joints.append(jnt)
                    else:
                        body["@pos"][axis_idx] = float(
                            body["@pos"]
                            [axis_idx]) + self.absolute_position[axis_idx]
                elif jnt["@type"] == "hinge":
                    axis_idx = get_axis_index(jnt["@axis"])
                    if self._keep_hinge_joint[axis_idx]:
                        remaining_joints.append(jnt)
                elif jnt["@type"] == "ball":
                    remaining_joints.append(jnt)
            body["joint"] = remaining_joints

        if len(self.markers) > 0:
            bodies = [
                body for body in self.xml_dict["worldbody"]["body"]
                if "annotation" not in body["@name"] and (
                    "@mocap" not in body or not body["@mocap"])
            ]
            assert len(bodies) == 1, ("Object %s should have only one body " % self) + \
                                     "to attach markers to. Otherwise mark() is" + \
                                     "ambiguous."
            body = bodies[0]
            if "site" not in body:
                body["site"] = []
            for marker in self.markers:
                site = OrderedDict()
                site['@name'] = marker['name']
                site['@pos'] = marker['position']
                site['@size'] = marker['size']
                site['@rgba'] = marker['rgba']
                site['@type'] = marker['type']
                body['site'].append(site)

        # Adding material influences nodes of the parent.
        if self._material is not None:
            update_mujoco_dict(self.xml_dict,
                               self._material.generate_xml_dict())

            def assign_material(node):
                if "geom" in node:
                    for g in node["geom"]:
                        g["@material"] = self._material.name

            closure_transform(assign_material)(self.xml_dict)

        update_mujoco_dict(full_xml_dict, self.xml_dict)
        for transform in self.transforms:
            transform(full_xml_dict)
        # Then add the xml of all of our children
        for children in self.children.values():
            for child, _ in children:
                child_dict = child.to_xml_dict()
                update_mujoco_dict(full_xml_dict, child_dict)

        return full_xml_dict