Skip to content

Pose3D

SUMMARY

A position and orientation in 3D space.

python
from telekinesis import datatypes
pose = datatypes.Pose3D([1.0, 2.0, 3.0, 0.0, 0.0, 90.0])
API Reference
Complete API documentation for Pose3D, including parameters, attributes, and methods.
View Reference →

Parameters

ParameterTypeDefaultDescription
datanp.ndarray | list | tupleRequired3D pose [x, y, z, roll, pitch, yaw] with shape (6,). Rotation uses Euler XYZ angles in degrees.

Raises

ExceptionCondition
TypeErrordata can't be converted to float32 (e.g. non-numeric elements)
ValueErrordata is not rank-1, or its shape isn't (6,)
ValueErrordata contains a non-finite value (NaN/Inf)

Attributes

AttributeTypeDescription
datanp.ndarrayDefensive copy of the underlying (6,) float32 array. Assigning a new value re-validates it the same way as construction.
shapetuple[int, ...]Always (6,).
ndimintAlways 1.
dtypenp.dtypeAlways float32.
sizeintAlways 6.
positionnp.ndarrayPosition [x, y, z] — a copy of data[0:3].
orientationnp.ndarrayEuler XYZ orientation [roll, pitch, yaw] in degrees — a copy of data[3:6].

Methods

MethodTypeDescription
Pose3D.coerce(value)Pose3DConverts array-like data into a Pose3D. Accepts a [x, y, z, roll, pitch, yaw] array-like of shape (6,), checked the same way as the constructor. If value is already a Pose3D, it is returned unchanged.
Pose3D.from_quat(pose)Pose3DBuilds a Pose3D from a quaternion-encoded pose [x, y, z, qw, qx, qy, qz] (shape (7,)) — position followed by a scalar-first quaternion — and stores it as the pose's native degree-based Euler orientation. The input must be a 1D array with a valid 4-element quaternion for the rotation part.
Pose3D.from_euler(pose, degrees=True)Pose3DBuilds a Pose3D from an Euler-XYZ-encoded pose [x, y, z, roll, pitch, yaw] (shape (6,)). degrees selects whether the input rotation is given in degrees (default) or radians; either way it's stored as degrees. The input must be a 1D array with a 3-element rotation part.
Pose3D.from_rotvec(pose)Pose3DBuilds a Pose3D from a rotation-vector-encoded pose [x, y, z, rx, ry, rz] (shape (6,)) — position followed by an axis-angle rotation vector whose magnitude is the angle in radians. The input must be a 1D array with a 3-element rotation part.
Pose3D.from_transformation_matrix(transformation_matrix)Pose3DBuilds a Pose3D from a (4, 4) homogeneous transformation matrix.
to_transform3d()Transform3DConverts this pose into the equivalent Transform3D, built from its position and degree-based Euler orientation.
to_numpy(copy=True)np.ndarrayReturns the pose's coordinates as a plain array. With the default copy=True you get an independent copy; pass copy=False to get a direct reference to the internal array instead, so mutating it also mutates the Pose3D.
copy()Pose3DReturns a new, independent Pose3D with the same data.

Representations

RepresentationMethodResult
Quaternionas_quat()(7,) float32 [x, y, z, qw, qx, qy, qz] — this pose's position, followed by a scalar-first quaternion equivalent to its Euler XYZ orientation.
Euler XYZas_euler(degrees=True)(6,) float32 [x, y, z, roll, pitch, yaw]. degrees=True (default, this pose's native representation) or degrees=False for radians. Always an independent copy.
Rotation vectoras_rotvec()(6,) float32 [x, y, z, rx, ry, rz] — position, followed by a rotation vector (axis-angle, magnitude = angle in radians).
Transformation matrixas_transformation_matrix()(4, 4) float32 homogeneous transform matrix encoding this pose's position and Euler XYZ orientation.

Operators

OperationBehavior
p == otherTrue only if other is also a Pose3D with element-equal data. False for anything else.
len(p)Always 6.
np.asarray(p) / np.reshape(p, ...)Returns a copy of data as an np.ndarray; NumPy functions accept a Pose3D directly.

Visualization

python
import rerun as rr

# Your code block
# ....

rr.init("pose3d_example", spawn=True)
datatypes.visualize(pose, entity_path="/pose", label="Pose3D")

Example

python
"""Demonstrates the Telekinesis Pose3D datatype."""

import time

import numpy as np
import rerun as rr
from loguru import logger

from telekinesis import datatypes


def pose3d_example():
    """Demonstrate creation, inspection, operations, visualization, and serialization."""

    # ======================= Create ============================================
    pose_data = [0.5, 0.2, 0.5, 0.0, 60.0, 90.0]
    pose3d = datatypes.Pose3D(pose_data)
    logger.info(f"Created Pose3D: {pose3d}")

    pose3d_from_quat = datatypes.Pose3D.from_quat(
        [0.5, 0.2, 0.8, 0.0, 0.0, 0.3826834, 0.9238795]
    )
    logger.info(f"Pose3D created from quaternion: {pose3d_from_quat}")

    pose3d_from_euler = datatypes.Pose3D.from_euler(
        [0.5, 0.2, 0.8, np.radians(30), np.radians(45), np.radians(60)],
        degrees=False,
    )
    logger.info(f"Pose3D created from radians: {pose3d_from_euler}")

    pose3d_from_rotvec = datatypes.Pose3D.from_rotvec([0.5, 0.2, 0.8, 0.0, 0.0, np.pi / 2])
    logger.info(f"Pose3D created from rotation vector: {pose3d_from_rotvec}")

    pose3d_from_matrix = datatypes.Pose3D.from_transformation_matrix(
        np.eye(4, dtype=np.float32)
    )
    logger.info(f"Pose3D created from transformation matrix: {pose3d_from_matrix}")

    # ======================= Inspect ===========================================
    logger.info(f"data={pose3d.data}")
    logger.info(f"shape={pose3d.shape}")
    logger.info(f"ndim={pose3d.ndim}")
    logger.info(f"dtype={pose3d.dtype}")
    logger.info(f"size={pose3d.size}")
    logger.info(f"position={pose3d.position}")
    logger.info(f"orientation={pose3d.orientation}")

    # ======================= Operations =========================================
    pose3d.data = [0.1, 0.2, 0.3, 0.0, 0.0, 90.0]
    logger.info(f"Updated Pose3D: {pose3d}")

    pose3d_copy = pose3d.copy()
    logger.info(f"Copied Pose3D: {pose3d_copy}")

    pose3d_numpy = pose3d.to_numpy(copy=True)
    logger.info(f"NumPy Pose3D: {pose3d_numpy}")

    pose3d_quat = pose3d.as_quat()
    logger.info(f"Pose3D as quaternion: {pose3d_quat}")

    pose3d_euler_deg = pose3d.as_euler(degrees=True)
    logger.info(f"Pose3D as Euler degrees: {pose3d_euler_deg}")

    pose3d_euler_rad = pose3d.as_euler(degrees=False)
    logger.info(f"Pose3D as Euler radians: {pose3d_euler_rad}")

    pose3d_rotvec = pose3d.as_rotvec()
    logger.info(f"Pose3D as rotation vector: {pose3d_rotvec}")

    transformation_matrix = pose3d.as_transformation_matrix()
    logger.info(f"Pose3D as transformation matrix:\n{transformation_matrix}")

    transform3d = pose3d.to_transform3d()
    logger.info(f"Pose3D as Transform3D: {transform3d}")

    reshaped = np.reshape(pose3d, (6,))
    logger.info(f"Pose3D with np.reshape: {reshaped}")

    # ======================= Visualize =========================================
    rr.init("pose3d_example", spawn=True)
    datatypes.visualize(pose3d, entity_path="/pose3d", label="Pose3D")
    datatypes.visualize(
        transform3d, entity_path="/pose3d/transform3d", label="Pose3D As Transform3D"
    )

    # ======================= Serialize / Deserialize ===========================
    start = time.perf_counter()
    serialized = datatypes.serialize(pose3d)
    serialization_ms = (time.perf_counter() - start) * 1000

    start = time.perf_counter()
    deserialized = datatypes.deserialize(serialized)["param_0"]
    deserialization_ms = (time.perf_counter() - start) * 1000

    logger.info(f"Deserialized Pose3D: {deserialized}")
    logger.info(f"Round-trip successful: {pose3d == deserialized}")
    logger.info(f"Serialization time: {serialization_ms:.3f} ms")
    logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")


if __name__ == "__main__":
    pose3d_example()