> ## Documentation Index
> Fetch the complete documentation index at: https://docs.generalrobotics.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Transform

> A rigid transform that maps coordinates in ``source_frame`` into ``target_frame``

```python theme={null}
from grid_types import Transform
```

A rigid transform that maps coordinates in `source_frame` into `target_frame`.

Direction: a transform is the pose of the source frame, measured in the target
frame. Name it `&lt;source>_wrt_&lt;target>`: `camera_wrt_base` is
`Transform(..., source_frame="camera", target_frame="base")`, the transform that
`Camera.getExtrinsics()` returns as a 4x4 matrix. Its `translation` is the
camera origin in base coordinates, and its `rotation` is the camera axes
relative to the base axes.

Math: a point `p` in the source frame maps to `p' = R p + t` in the target
frame, where `R` is `rotation` and `t` is `translation`; with the 4x4
matrix `M = to_matrix()`, `p' = M p`. A Pose's orientation `q` becomes
`q_T * q`. `inverse()` has rotation `R^-1` and translation `-R^-1 t`, and
swaps the frames. `transform.T` is the transpose of the 4x4 matrix, as in
NumPy, for points stored as rows:
`points @ transform.T`. The transpose is not the inverse; use `inverse()`.

Order: `A @ B` composes in matrix order, so `B` applies first; read a chain
from right to left. At each `@`, the right side must map into the frame that
the left side maps from: `A.source_frame == B.target_frame`.

Frame checks: `T @ pose` needs `pose.frame_id == T.source_frame` and returns
a Pose with `frame_id == T.target_frame`. `A @ B` needs
`A.source_frame == B.target_frame`. `from_pose` needs the pose in
`target_frame`. A mismatch raises `FrameMismatchError`, a `ValueError`
whose message names both frames. A Pose without a `frame_id` is taken to be
in the source frame and is not checked. Frames are names that the caller
supplies; nothing is inferred.

## Fields

**translation** `Position`

The origin of the source frame in the target frame (meters).

**rotation** `Orientation`

The orientation of the source frame in the target frame.

**source\_frame** `str`

The frame that the transform maps from.

**target\_frame** `str`

The frame that the transform maps to.

## Constructor

```python Signature theme={null}
Transform(
    translation: Position,
    rotation: Orientation,
    source_frame: str,
    target_frame: str,
)
```

Initialize a Transform from its translation, rotation and frames.

**translation** *required*

The origin of the source frame in the target frame (meters).

**rotation** *required*

The orientation of the source frame in the target frame.

**source\_frame** *required*

The frame that the transform maps from.

**target\_frame** *required*

The frame that the transform maps to.

## Properties

**T** `np.ndarray`

The transpose of the 4x4 matrix, `to_matrix().T`, as in NumPy.

Use it for points stored as rows: `points @ transform.T` maps an (N, 4)
array of homogeneous points. It is not the inverse; use `inverse`.

## Methods

### `apply()`

```python Signature theme={null}
apply(pose: Pose) -> Pose
```

Map a Pose from `source_frame` into `target_frame`; the same as `self @ pose`.

A pose without a frame is taken to be in `source_frame`. The input pose does
not change.

**pose** *required*

The pose to map.

**Returns:**

Pose: The pose in `target_frame`, with `frame_id` set to `target_frame`.

**Raises:**

FrameMismatchError: If the pose has a frame and it is not `source_frame`.

### `compose()`

```python Signature theme={null}
compose(other: Transform) -> Transform
```

Apply `other` first, then this transform; the same as `self @ other`.

**other** *required*

A transform whose target frame is this transform's source frame.

**Returns:**

Transform: The transform from `other.source_frame` into `self.target_frame`.

**Raises:**

FrameMismatchError: If `other.target_frame` is not `self.source_frame`.

### `from_dict()`

```python Signature theme={null}
from_dict(data: dict) -> Transform
```

Deserialize from `&#123;"translation", "rotation", "source_frame", "target_frame"&#125;`

### `from_matrix()`

```python Signature theme={null}
from_matrix(
    matrix: Union[np.ndarray, list],
    source_frame: str,
    target_frame: str,
) -> Transform
```

Build a transform from a 4x4 homogeneous matrix.

**matrix** *required*

4x4 rigid transform; the bottom row must be `[0, 0, 0, 1]`.

**source\_frame** *required*

The frame that the matrix maps from.

**target\_frame** *required*

The frame that the matrix maps to.

**Returns:**

Transform: The transform with the matrix's rotation and translation.

**Raises:**

ValueError: If the matrix is not 4x4, its bottom row is wrong, or its
rotation part is not a rotation.

### `from_pose()`

```python Signature theme={null}
from_pose(pose: Pose, source_frame: str, target_frame: str) -> Transform
```

Build the transform of a frame whose origin and orientation are `pose`.

**pose** *required*

The pose of the source frame in the target frame.

**source\_frame** *required*

The frame located at `pose`.

**target\_frame** *required*

The frame that `pose` is in.

**Returns:**

Transform: The transform from `source_frame` into `target_frame`.

**Raises:**

FrameMismatchError: If the pose has a frame and it is not `target_frame`.

### `identity()`

```python Signature theme={null}
identity(frame: str) -> Transform
```

The transform that maps `frame` onto itself and changes no coordinates.

**frame** *required*

The source and target frame.

**Returns:**

Transform: The identity transform in `frame`.

### `inverse()`

```python Signature theme={null}
inverse() -> Transform
```

The transform in the opposite direction, from `target_frame` into `source_frame`.

**Returns:**

Transform: The inverse transform, with the frames swapped.

### `to_dict()`

```python Signature theme={null}
to_dict() -> dict
```

Serialize for JSON transfer: `&#123;"translation", "rotation", "source_frame", "target_frame"&#125;`

### `to_matrix()`

```python Signature theme={null}
to_matrix() -> np.ndarray
```

Convert to a 4x4 homogeneous matrix.

**Returns:**

np.ndarray: 4x4 matrix that maps source-frame coordinates into the target frame.

## Example

```python theme={null}
camera_wrt_base = Transform.from_matrix(camera.getExtrinsics(), source_frame="camera", target_frame="base")
object_in_base = camera_wrt_base @ Pose(0.1, 0.2, 0.5, frame_id="camera")  # camera -> base
object_in_base.frame_id  # 'base'
base_wrt_camera = camera_wrt_base.inverse()  # base -> camera
# (base -> camera) @ (gripper -> base) @ (target -> gripper) = target -> camera
target_wrt_camera = base_wrt_camera @ gripper_wrt_base @ target_wrt_gripper
camera_wrt_base @ Pose(0.1, 0.2, 0.5, frame_id="gripper")  # raises FrameMismatchError:
# the pose is in frame 'gripper', but the transform maps from frame 'camera'
```


## Related topics

- [RealsenseCamera](https://docs.generalrobotics.dev/python-api/cameras/realsensecamera.md)
- [ZedCamera](https://docs.generalrobotics.dev/python-api/cameras/zedcamera.md)
- [OrbbecCamera](https://docs.generalrobotics.dev/python-api/cameras/orbbeccamera.md)
- [ZedUSBCamera](https://docs.generalrobotics.dev/python-api/cameras/zedusbcamera.md)
- [FrameMismatchError](https://docs.generalrobotics.dev/python-api/grid-types/framemismatcherror.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.