# Specify a reference coordinate system for Cartesian movements

> Learn why Cartesian movements always target the world coordinate system. Discover how to plan one relative to a different coordinate system instead.

For PTP, LINE, and CIRC motions, the planner always expects the target pose in the
[world coordinate system](/nova/26.8/nova-api/core-concepts/robotics-basics#coordinate-systems).
This guide shows how to plan relative to a different coordinate system instead.

A robot controller can carry its own named coordinate systems, e.g., a base, a tool, and a
workpiece frame taught on the original robot control panel. NOVA lists them read-only through
[`GET /cells/{cell}/controllers/{controller}/coordinate-systems`](/nova/26.8/api-reference/rest),
but never applies one to a motion target automatically. The `PlanTrajectoryRequest` body takes
only a `target_pose` (and `via_pose` for a circle), with no `frame` or `reference_frame` field.
Convert a pose to world yourself before planning with it, as shown below.

### Step 1: Define the coordinate system as a pose

A `Pose` plays two roles: a place, and a transform between coordinate systems. The Python SDK has
no separate coordinate-system type; define one the same way you define any other pose:

```python
from nova.types import Pose

pallet = Pose((1000, 500, 300, 0, 0, 0))
```

### Step 2: Express the target relative to that coordinate system

Teach or compute the target as if the coordinate system were the origin:

```python
slot_in_pallet = Pose((200, 100, 0, 0, 0, 0))
```

### Step 3: Convert the pose to world

Use the `@` operator to compose two poses: `a @ b` applies `b` inside `a`'s coordinate system and
returns a new pose in `a`'s parent system. Order matters; `@` is not commutative.

```python
slot_in_world = pallet @ slot_in_pallet
```

Pass the result directly as a motion target:

```python
from nova.actions import linear

actions = [linear(slot_in_world)]
```

Chain `@` to go through more than one coordinate system, e.g., from one named frame, through a
second, and into world: `pose_in_world = cs2 @ cs1 @ pose_in_cs1`.

### Step 4: Convert a world pose back, if you need it

Use `~` to invert a pose. `~a` undoes `a`, so `~a @ world_pose` converts a world pose back into
`a`'s frame:

```python
assert ~pallet @ slot_in_world == slot_in_pallet
```

## Reposition a taught sequence when the frame moves

Teach positions once, relative to a frame, then re-apply them wherever that frame is. This is
useful when a pallet, fixture, or workpiece is not always in the same spot: only the one frame
pose changes between cycles, not every taught position.

```python
nominal_pallet = Pose((1000, 500, 300, 0, 0, 0))
slots = [
    Pose((0, 0, 0, 0, 0, 0)),
    Pose((150, 0, 0, 0, 0, 0)),
    Pose((300, 0, 0, 0, 0, 0)),
]

# A sensor or vision system measures the pallet 5 mm further out and rotated by 90°:
measured_pallet = Pose((1005, 500, 300, 0, 0, 1.5708))

# Re-apply every taught slot against the measured pose instead of the nominal one:
slots_in_world = [measured_pallet @ slot for slot in slots]
```

If a slot is only known in world coordinates from the nominal setup, localize it first, then
re-apply it against the measured pose:

```python
taught_in_world = nominal_pallet @ slots[1]
slot_in_world = measured_pallet @ (~nominal_pallet @ taught_in_world)
```

See the SDK's
[`pose_transformations.py`](https://github.com/wandelbotsgmbh/wandelbots-nova/blob/main/examples/pose_transformations.py)
example for more cases, including approach and retreat motions along a tool's axis.

## Dataset frames

See [Datasets](/nova/26.8/nova-api/core-concepts/datasets) if your poses already live in a
dataset: you do not need to compose transforms. A dataset frame's `reference_frame` chains up to
`world`, and its `resolve` and `localize` endpoints perform that conversion server-side, across
the whole chain, in one request.

## See also

- [Robotics basics](/nova/26.8/nova-api/core-concepts/robotics-basics): world, base, and tool
  coordinate system definitions
- [Datasets](/nova/26.8/nova-api/core-concepts/datasets): persisting frames and resolving or
  localizing dataset poses
- [Plan collision-free trajectories](/nova/26.8/guides/collision-free-paths): tool shapes use
  the flange coordinate system
