def generate_xinit(self): # MuJoCo uses center of geom as origin, while we use bottom corner if not self.placeable: return {} position = self.absolute_position position_xinit = {} # extracts names of three top level slide joints from # the body. for body in self.xml_dict["worldbody"]["body"]: for jnt in body.get("joint", []): if jnt["@type"] == "slide": idx = get_axis_index(jnt["@axis"]) position_xinit[jnt["@name"]] = position[idx] # Some people add transforms which remove joints. # Only generate xinit terms for joints that remain xinit = {} for body in self.xml_dict["worldbody"]["body"]: for joint in body.get('joint', []): joint_name = joint.get('@name', '') if joint_name in position_xinit: xinit[joint_name] = position_xinit[joint_name] if hasattr(self, "default_qpos") and self.default_qpos is not None: for joint, value in self.default_qpos.items(): if not joint.startswith(self.name + ':'): joint = self.name + ":" + joint xinit[joint] = value return xinit
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