Implementation:Haosulab ManiSkill Pose
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Simulation, 3D Geometry |
| Last Updated | 2026-02-15 08:00 GMT |
Overview
Concrete tool for managing batched 6-DOF poses (position + quaternion orientation) with flexible creation and arithmetic operations.
Description
The Pose dataclass is a batched wrapper around sapien.Pose that stores position (p) and quaternion (q) data as torch tensors. It is designed to seamlessly handle single and batched poses, supporting both CPU and GPU simulation.
Key features:
- Flexible creation:
Pose.create_from_pq(p, q)accepts torch tensors, numpy arrays, or lists for position and quaternion. Automatic broadcasting handles mismatched batch sizes (e.g., one p with many q's).Pose.create(x)accepts sapien.Pose, another Pose, or a raw (N, 7) tensor. - Batch dimension: Always maintains a batch dimension.
pose.preturns shape (N, 3),pose.qreturns shape (N, 4),pose.raw_posereturns shape (N, 7). - Arithmetic: Supports pose composition via
*(multiplication) andpose.inv()for inverse, implemented using batched quaternion operations. - Transformation matrices:
to_transformation_matrix()returns (N, 4, 4) homogeneous matrices. - SAPIEN interop:
pose.spreturns asapien.Pose(only valid for batch size 1). - Indexing: Supports numpy/torch-style indexing to select subsets of poses.
Helper functions:
vectorize_pose()-- Convert a sapien.Pose to a (1, 7) tensor.to_sapien_pose()-- Convert a Pose back to sapien.Pose.
Usage
The Pose class is used throughout ManiSkill for all pose-related operations. It is the return type of actor.pose, link.pose, and used as input for set_pose() methods.
Code Reference
Source Location
- Repository: Haosulab_ManiSkill
- File: mani_skill/utils/structs/pose.py
Signature
@dataclass
class Pose:
raw_pose: torch.Tensor # shape (N, 7): [p_x, p_y, p_z, q_w, q_x, q_y, q_z]
@classmethod
def create_from_pq(cls, p=None, q=None, device=None) -> "Pose": ...
@classmethod
def create(cls, pose) -> "Pose": ...
@property
def p(self) -> torch.Tensor: ... # (N, 3)
@property
def q(self) -> torch.Tensor: ... # (N, 4)
@property
def sp(self) -> sapien.Pose: ... # single sapien.Pose
def inv(self) -> "Pose": ...
def __mul__(self, other: "Pose") -> "Pose": ...
def to_transformation_matrix(self) -> torch.Tensor: ... # (N, 4, 4)
Import
from mani_skill.utils.structs.pose import Pose
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| p | Array or None | No | Position(s), shape (3,) or (N, 3). Defaults to zeros. |
| q | Array or None | No | Quaternion(s) [w,x,y,z], shape (4,) or (N, 4). Defaults to identity. |
| pose | Union[sapien.Pose, Pose, torch.Tensor] | Yes | Source pose for Pose.create() |
Outputs
| Name | Type | Description |
|---|---|---|
| Pose | Pose | Batched pose object |
| p | torch.Tensor | Position tensor of shape (N, 3) |
| q | torch.Tensor | Quaternion tensor of shape (N, 4) in [w,x,y,z] |
| raw_pose | torch.Tensor | Combined tensor of shape (N, 7) |
Usage Examples
Basic Usage
import torch
from mani_skill.utils.structs.pose import Pose
# Create from position and quaternion
pose = Pose.create_from_pq(
p=torch.tensor([[1.0, 2.0, 3.0]]),
q=torch.tensor([[1.0, 0.0, 0.0, 0.0]]) # identity rotation
)
# Compose two poses
pose_a = Pose.create_from_pq(p=torch.tensor([[1, 0, 0]]))
pose_b = Pose.create_from_pq(p=torch.tensor([[0, 1, 0]]))
composed = pose_a * pose_b
# Get inverse
inv_pose = pose.inv()
# Convert to transformation matrix
T = pose.to_transformation_matrix() # (1, 4, 4)