PoseLib Toolkit¶
Location: protomotions/components/pose_lib.py
PoseLib is a suite of utilities that bridges MJCF robot definitions to simulation state. It’s called throughout the codebase for FK/IK, motion processing, and coordinate conversions.
What PoseLib Does¶
Parse MJCF → KinematicInfo: Extract robot structure from MJCF files
Coordinate conversions: Transform between reduced (qpos) and maximal coordinates
Forward/Inverse Kinematics: Compute body poses from joint angles and vice versa
Velocity computation: Finite-difference velocities from pose sequences
MJCF Parsing¶
extract_kinematic_info() parses an MJCF file and returns a KinematicInfo
dataclass containing the robot’s kinematic structure:
from protomotions.components.pose_lib import extract_kinematic_info
kinematic_info = extract_kinematic_info(
"protomotions/data/assets/mjcf/g1_bm_no_mesh_box_feet.xml"
)
KinematicInfo fields:
@dataclass
class KinematicInfo:
body_names: List[str] # All body names in order
dof_names: List[str] # Joint names (excluding root)
parent_indices: List[int] # Parent body index for each body
local_pos: Tensor # Local position offsets
local_rot_ref_mat: Tensor # Reference local rotations
hinge_axes_map: Dict # Hinge joint axes
nq: int # Dimension of qpos
nv: int # Dimension of qvel
num_bodies: int
num_dofs: int
dof_limits_lower: Tensor
dof_limits_upper: Tensor
This is automatically populated when you create a robot config.
Coordinate Systems¶
Motion data and simulation use different coordinate representations:
Reduced Coordinates (qpos):
MuJoCo-style generalized coordinates:
qpos = [root_pos(3), root_quat_wxyz(4), joint_angles(...)]
Compact representation - one value per DOF.
Maximal Coordinates:
World-space position and rotation for each rigid body:
rigid_body_pos: Tensor[num_envs, num_bodies, 3]
rigid_body_rot: Tensor[num_envs, num_bodies, 4]
Easier for reward computation (distances in Cartesian space).
Coordinate Conversions¶
Reduced → Maximal (Forward Kinematics):
from protomotions.components.pose_lib import (
extract_transforms_from_qpos,
compute_forward_kinematics_from_transforms
)
# qpos → local transforms
root_pos, local_rot_mats = extract_transforms_from_qpos(
kinematic_info, qpos
)
# local transforms → world poses
world_pos, world_rot_mat = compute_forward_kinematics_from_transforms(
kinematic_info, root_pos, local_rot_mats
)
Maximal → Reduced (Inverse):
from protomotions.components.pose_lib import extract_qpos_from_transforms
qpos = extract_qpos_from_transforms(
kinematic_info, root_pos, local_rot_mats,
multi_dof_decomposition_method="exp_map"
)
Velocity Computation¶
Compute velocities from pose sequences via finite differences:
from protomotions.components.pose_lib import (
compute_cartesian_velocity,
compute_angular_velocity
)
# Linear velocity from position sequence
linear_vel = compute_cartesian_velocity(positions, fps=30)
# Angular velocity from rotation sequence
angular_vel = compute_angular_velocity(rotation_mats, fps=30)
High-Level Functions¶
For motion processing, use the high-level wrapper:
from protomotions.components.pose_lib import fk_from_transforms_with_velocities
# Compute full state (positions, rotations, velocities)
state = fk_from_transforms_with_velocities(
kinematic_info=kinematic_info,
root_pos=root_positions,
joint_rot_mats=local_rotations,
fps=30,
compute_velocities=True
)
# Returns RobotState with all fields populated
ControlInfo¶
PoseLib also defines ControlInfo for PD control parameters:
@dataclass
class ControlInfo:
stiffness: float # P gain
damping: float # D gain
armature: float # Motor inertia
friction: float # Joint friction
effort_limit: float # Max torque
velocity_limit: float # Max velocity
Used in robot configs to specify per-joint control properties.
Testing¶
Verify FK/IK against MuJoCo:
from protomotions.components.pose_lib import test_fk_against_mujoco
test_fk_against_mujoco("path/to/robot.xml")
This compares PoseLib’s FK output to MuJoCo’s internal FK.
Next Steps¶
Simulator State - How states are represented in simulation
Core Abstractions - Where PoseLib fits in the architecture