Pose2D
Represents a single 2D pose: a planar position plus a heading angle.
Parameters
| Field | Type | Description |
|---|---|---|
data | np.ndarray | list | tuple | Array-like input of shape (3,): [x, y, theta], converted to a contiguous float32 array. |
Raises
| Exception | Condition |
|---|---|
TypeError | data can't be converted to float32 (e.g. non-numeric elements) |
ValueError | data is not rank-1, or its shape isn't (3,) |
ValueError | data contains a non-finite value (NaN/Inf) |
Attributes
| Attribute | Type | Description |
|---|---|---|
data | np.ndarray | Defensive copy of the underlying (3,) float32 array. Assigning a new value re-validates it the same way as construction. |
shape | tuple[int, ...] | Always (3,). |
ndim | int | Always 1. |
dtype | np.dtype | Always float32. |
size | int | Always 3. |
Methods
| Method | Description |
|---|---|
to_numpy(copy=True) | Returns the pose as np.ndarray. Pass copy=False for a reference to the internal array instead — faster, but mutating it mutates the Pose2D too. |
copy() | Returns a new Pose2D with an independent copy of the data. |
Pose2D.coerce(value) | Returns value unchanged if it's already a Pose2D; otherwise wraps an array-like into one. Raises TypeError for any other input. |
Operators
| Operation | Behavior |
|---|---|
p == other | True only if other is also a Pose2D with element-equal data. False for anything else. |
len(p) | Always 3. |
np.asarray(p) | Works directly via __array__. Always returns a copy; use to_numpy(copy=False) for a zero-copy view. |
p + array | Not implemented on Pose2D — Python falls back to NumPy's array coercion (__array__), so e.g. p + np.array([1.0, 1.0, 0.0]) returns a plain np.ndarray, not a Pose2D. |
hash(p) | Not supported — mutable via the data setter. |
Visualization
datatypes.visualize(pose, entity_path=...) logs the pose's posed frame (X/Y axes rotated by theta, translated by [x, y]) alongside a labeled world-origin frame. Per-axis labels are omitted; only the world-origin frame is labeled "origin". Passing label="..." attaches a floating text label at the posed frame's translation.
Example
python
"""Demonstrates the Telekinesis Pose2D datatype."""
import time
import numpy as np
from loguru import logger
import rerun as rr
from telekinesis import datatypes
def pose2d_example():
"""Demonstrate creation, access, visualization, update, NumPy translation, and serialization."""
# ======================= Create ============================================
pose = [1.0, 2.0, 0.5]
pose2d = datatypes.Pose2D(pose)
logger.info(f"Original Pose2D: {pose2d}")
# ======================= Inspect ===========================================
data = pose2d.data
shape = pose2d.shape
size = pose2d.size
dtype = pose2d.dtype
ndim = pose2d.ndim
numpy_pose2d = pose2d.to_numpy()
pose2d_copy = pose2d.copy()
logger.info(f"shape={shape}, size={size}, ndim={ndim}, dtype={dtype}")
logger.info(f"Underlying data: {data}")
logger.info(f"NumPy array: {numpy_pose2d}")
logger.info(f"Copy: {pose2d_copy}")
# ======================= Visualize =========================================
rr.init("pose2d_example", spawn=True)
datatypes.visualize(pose2d, entity_path="/Pose2D", label="My Pose2D")
# ======================= Update ============================================
new_data = [3.0, 4.0, 1.0]
pose2d.data = new_data
logger.info(f"Updated Pose2D: {pose2d}")
datatypes.visualize(pose2d, entity_path="/Pose2D/updated", label="Updated Pose2D")
# ======================= Translate =========================================
translated = pose2d + np.array([1.0, 1.0, 0.0])
logger.info(f"Translated Pose2D: {translated}")
# ======================= Serialize / Deserialize ===========================
start = time.perf_counter()
serialized = datatypes.serialize(pose2d)
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 Pose2D: {deserialized}")
logger.info(f"Round-trip successful: {deserialized.data == new_data}")
logger.info(f"Serialization time: {serialization_ms:.3f} ms")
logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")
if __name__ == "__main__":
pose2d_example()
