{"record":{"id":"5b74e4ebe964d98e","repo":"Genesis-Embodied-AI/genesis-world","slug":"compounding-joints-of-types-free-or-fixed-with","errorCode":null,"errorMessage":"Compounding joints of types 'FREE' or 'FIXED' with any other joint on the same body not supported","messagePattern":"Compounding joints of types 'FREE' or 'FIXED' with any other joint on the same body not supported","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"genesis/engine/entities/rigid_entity/rigid_entity.py","lineNumber":1188,"sourceCode":"                dofs_motion_ang=dofs_motion_ang,\n                dofs_motion_vel=dofs_motion_vel,\n                dofs_limit=j_info.get(\"dofs_limit\", np.tile([[-np.inf, np.inf]], [n_dofs, 1])),\n                dofs_invweight=j_info.get(\"dofs_invweight\", np.zeros(n_dofs)),\n                dofs_frictionloss=j_info.get(\"dofs_frictionloss\", np.zeros(n_dofs)),\n                dofs_stiffness=j_info.get(\"dofs_stiffness\", np.zeros(n_dofs)),\n                dofs_damping=j_info.get(\"dofs_damping\", np.zeros(n_dofs)),\n                dofs_armature=j_info.get(\"dofs_armature\", np.zeros(n_dofs)),\n                dofs_act_gain=j_info.get(\"dofs_act_gain\", np.zeros(n_dofs)),\n                dofs_act_bias=j_info.get(\"dofs_act_bias\", np.zeros((n_dofs, 3))),\n                dofs_force_range=j_info.get(\"dofs_force_range\", np.tile([[-np.inf, np.inf]], [n_dofs, 1])),\n            )\n            joints.append(joint)\n\n        return joints\n\n    def _add_by_info(self, l_info, j_infos, g_infos, morph, surface):\n        if len(j_infos) > 1 and any(j_info[\"type\"] in (gs.JOINT_TYPE.FREE, gs.JOINT_TYPE.FIXED) for j_info in j_infos):\n            raise ValueError(\n                \"Compounding joints of types 'FREE' or 'FIXED' with any other joint on the same body not supported\"\n            )\n\n        parent_idx = l_info[\"parent_idx\"]\n        if parent_idx >= 0:\n            parent_idx += self._link_start\n        root_idx = l_info.get(\"root_idx\")\n        if root_idx is not None and root_idx >= 0:\n            root_idx += self._link_start\n        link_idx = self.n_links + self._link_start\n        joint_start = self.n_joints + self._joint_start\n\n        cg_infos, vg_infos = self._postprocess_geoms_info(morph, g_infos, l_info.get(\"is_robot\", False))\n        self._align_link(l_info, j_infos, cg_infos, vg_infos, morph, link_idx)\n\n        joints = self._create_joints(j_infos, link_idx, joint_start)\n\n        # Add child link","sourceCodeStart":1170,"sourceCodeEnd":1206,"githubUrl":"https://github.com/Genesis-Embodied-AI/genesis-world/blob/56e4aa5d82bdb83f2e532e4cc364cb69527acb06/genesis/engine/entities/rigid_entity/rigid_entity.py#L1170-L1206","documentation":"RigidEntity._add_by_info rejects a link info carrying more than one joint when any of them is a FREE or FIXED joint. FREE and FIXED joints fully determine a link's 6-DoF attachment to its parent, so compounding them with hinge/slide joints on the same body is physically ill-defined and Genesis refuses it at build time.","triggerScenarios":"Loading a URDF/MJCF/morph whose body has multiple <joint> elements where at least one is 'free'/'floating' or 'fixed' (e.g. a URDF link with both a fixed joint and a revolute joint, or an MJCF body with a freejoint plus another joint). Also triggered by _load_primitive/_load_mesh/_load_terrain/_load_scene paths generating compound j_infos.","commonSituations":"Hand-authored or auto-generated URDF/MJCF files that attach several joints to one link; converting MuJoCo models where a freejoint coexists with hinge joints on the same body; merging links during model simplification.","solutions":["Edit the model so FREE/FIXED joints appear alone on their body: move the additional hinge/slide joints onto a child body/link.","If the fixed joint was meant to weld a decoration, put that geometry on the same link instead of adding a second fixed joint.","For a floating-base robot, keep exactly one free joint on the root body and no other joint on it."],"exampleFix":"<!-- before: URDF link with fixed + revolute joints -->\n<link name=\"base\"/>\n<joint name=\"fix\" type=\"fixed\" .../>\n<joint name=\"roll\" type=\"revolute\" .../>\n\n<!-- after: weld geometry onto one link, revolute on its own link -->\n<link name=\"base\"/>  <!-- fixed joint only, geometry merged here -->\n<joint name=\"roll\" type=\"revolute\" parent=\"base\" child=\"roll_link\"/>","handlingStrategy":"validation","validationCode":"import xml.etree.ElementTree as ET\n# reject bodies with multiple joints incl. free/fixed\nfor body in root.iter(\"body\"):\n    joints = body.findall(\"joint\") + body.findall(\"freejoint\")\n    if len(joints) > 1 and any(j.get(\"type\", \"free\" if j.tag == \"freejoint\" else None) in (\"free\", \"fixed\") for j in joints):\n        raise ValueError(f\"Body {body.get('name')} compounds FREE/FIXED with other joints\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never put a freejoint/fixed joint together with hinge/slide joints on the same body in MJCF/URDF.","Validate generated models with a lint pass before feeding them to Genesis.","Keep one joint per link in authored models."],"tags":["python","genesis","urdf","mjcf","kinematics","model-validation"],"backgroundTag":"model-schema-validation-failed","analyzedSha":"56e4aa5d82bdb83f2e532e4cc364cb69527acb06","analyzedAt":"2026-08-28T15:15:07.922Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}