Composition and InversesΒΆ
Use spatial operations to compose poses/transforms, apply poses to points, rotate free vectors, and convert transforms into frameless pose offsets.
In Python, * composes poses/transforms or applies them to points. In
TypeScript, use multiply() for composition and apply() for points.
Pose * Pose chains frameless poses; Transform * Pose re-expresses a
pose in a new frame; Transform * Transform chains stamped transforms when
frame ids match (empty ids act as wildcards). inverse() undoes a pose or
transform; for Transform the frame ids are swapped as
well. as_pose() / asPose() returns the equivalent frameless
Pose. Use rotate() for Vector
values when translation should not be applied.
from olo.spatial import Point, Pose, Transform, Vector
# Compose frameless poses.
p1 = Pose(Point(x=0.1, y=0.0, z=0.3))
p2 = Pose(Point(x=0.0, y=0.2, z=0.0))
composed = p1 * p2
print(f"{composed = }")
# Apply a pose to a point.
transformed = p1.apply(Point(x=0.05))
print(f"{transformed = }")
# Chain stamped transforms when frame ids match.
world_to_odom = Transform(
translation=Vector(x=1.0),
frame_id="world",
child_frame_id="odom",
)
odom_to_base = Transform(
translation=Vector(y=2.0),
frame_id="odom",
child_frame_id="base_link",
)
world_to_base = world_to_odom * odom_to_base
print(f"{world_to_base = }")
# Invert a transform; frame ids are swapped.
base_to_tool = Transform(
translation=Vector(z=0.12),
frame_id="base_link",
child_frame_id="tool0",
)
tool_to_base = base_to_tool.inverse()
print(f"{tool_to_base = }")
# Drop frame metadata for a frameless pose offset.
tool_offset = base_to_tool.as_pose()
print(f"{tool_offset = }")
import { Point, Pose, Transform, Vector } from "olo/spatial";
// Compose frameless poses.
const p1 = new Pose(new Point(0.1, 0.0, 0.3));
const p2 = new Pose(new Point(0.0, 0.2, 0.0));
const composed = p1.multiply(p2);
console.log(`composed = ${composed}`);
// Apply a pose to a point.
const transformed = p1.apply(new Point(0.05));
console.log(`transformed = ${transformed}`);
// Chain stamped transforms when frame ids match.
const worldToOdom = new Transform({
translation: new Vector(1.0),
frameId: "world",
childFrameId: "odom",
});
const odomToBase = new Transform({
translation: new Vector(0.0, 2.0),
frameId: "odom",
childFrameId: "base_link",
});
const worldToBase = worldToOdom.multiply(odomToBase);
console.log(`worldToBase = ${worldToBase}`);
// Invert a transform; frame ids are swapped.
const baseToTool = new Transform({
translation: new Vector(0.0, 0.0, 0.12),
frameId: "base_link",
childFrameId: "tool0",
});
const toolToBase = baseToTool.inverse();
console.log(`toolToBase = ${toolToBase}`);
// Drop frame metadata for a frameless pose offset.
const toolOffset = baseToTool.asPose();
console.log(`toolOffset = ${toolOffset}`);