Implementation:Haosulab ManiSkill Kinematics
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Simulation |
| Last Updated | 2026-02-15 08:00 GMT |
Overview
Concrete kinematics solver for computing inverse kinematics on both CPU and GPU, powering end-effector pose controllers in ManiSkill.
Description
The Kinematics class provides the core computational engine for task-space (Cartesian) control. It parses the URDF to identify the kinematic chain from the root to a specified end-effector link, filtering out joints not present in the kinematic chain (e.g., dummy joints in the Fetch robot). On CPU, it uses SAPIEN's PinocchioModel for IK via compute_inverse_kinematics(). On GPU, it uses the pytorch_kinematics library to build a serial chain, compute Jacobians, and solve IK via either the Levenberg-Marquardt method (solving J^T * J + lambda * I) or pseudo-inverse. Delta poses are converted from Pose objects to 6D tensors (translation + euler angles). A qmask boolean tensor identifies which joints in the ancestor kinematic chain are actually controlled by the current controller.
Usage
Kinematics is instantiated internally by PDEEPosController and PDEEPoseController during joint initialization. Users do not typically instantiate it directly. It requires a URDF path, end-effector link name, articulation, and active joint indices. The compute_ik() method is called each time the EE pose controller processes an action.
Code Reference
Source Location
- Repository: Haosulab_ManiSkill
- File: mani_skill/agents/controllers/utils/kinematics.py
- Lines: 1-274
Signature
class Kinematics:
def __init__(
self,
urdf_path: str,
end_link_name: str,
articulation: Articulation,
active_joint_indices: torch.Tensor,
):
def compute_ik(
self,
pose: Union[Pose, torch.Tensor],
q0: torch.Tensor,
is_delta_pose: bool = False,
current_pose: Optional[Pose] = None,
solver_config: dict = dict(
type="levenberg_marquardt", solver_iterations=1, alpha=1.0
),
):
Import
from mani_skill.agents.controllers.utils.kinematics import Kinematics
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| urdf_path | str | Yes | Path to the URDF file defining the robot kinematic chain. |
| end_link_name | str | Yes | Name of the end-effector link in the articulation. |
| articulation | Articulation | Yes | The robot articulation object. |
| active_joint_indices | torch.Tensor | Yes | Indices of the active joints that can be controlled. |
| pose | Pose or torch.Tensor | Yes | Target pose for IK. Can be a Pose object or a tensor of shape (N, 6) with translation + euler angles.
|
| q0 | torch.Tensor | Yes | Initial joint positions for the IK solve; shape (batch, num_active_joints). |
| is_delta_pose | bool | No | If True, pose is treated as a delta from the current pose. Defaults to False.
|
| current_pose | Pose or None | No | Current EE pose; used to avoid recomputation when is_delta_pose=False.
|
| solver_config | dict | No | IK solver configuration: type ("levenberg_marquardt" or "pseudo_inverse") and alpha (scaling). Default: Levenberg-Marquardt with alpha=1.0.
|
Outputs
| Name | Type | Description |
|---|---|---|
| return | torch.Tensor or None | Target joint positions for the controlled joints (shape: batch x num_controlled_joints). Returns None on CPU if IK fails. |
Usage Examples
Basic Usage
from mani_skill.agents.controllers.utils.kinematics import Kinematics
from mani_skill.utils.structs.pose import Pose
import torch
# Typically instantiated internally by PDEEPosController:
kinematics = Kinematics(
urdf_path="path/to/robot.urdf",
end_link_name="ee_link",
articulation=robot_articulation,
active_joint_indices=torch.tensor([0, 1, 2, 3, 4, 5, 6]),
)
# Compute IK for a target pose
target_pose = Pose.create_from_pq(
torch.tensor([[0.5, 0.0, 0.5]]),
torch.tensor([[1.0, 0.0, 0.0, 0.0]]),
)
q0 = robot_articulation.get_qpos()
target_qpos = kinematics.compute_ik(
pose=target_pose,
q0=q0,
solver_config=dict(type="levenberg_marquardt", alpha=1.0),
)