Skip to content
PreciSim
concepts

Coordinate frames and sign conventions

The section that causes the most bugs and tolerates the least ambiguity. Fix the conventions, then write code.

This is the important one. In projects that combine vision and motion, more than half of the strange problems end up being "a sign was flipped" or "two people meant different things by the same frame". So the conventions are written down, fixed, and copied verbatim.

Four frames

World W        the stage, right-handed, mm
  ├── Machine M    each axis's mechanical zero (the origin after homing)
  ├── Part P       a datum on the part or carrier, usually defined by fiducials
  └── Image I      pixels, origin top-left, u right, v down
        └── Camera C   optical centre at the origin, Z along the optical axis

Conventions — copy these, do not improvise

Item Convention
Handedness Right-handed. X right, Y away from the operator, Z up
Positive rotation Counter-clockwise seen looking down the positive axis toward the origin
Image v axis Down is positive (every camera SDK does this; do not fight it)
Angles rad internally, degrees only in the UI
Lengths mm internally; pixel size quoted in µm but converted on input
Transform notation T_A_B maps points from B into A: p_A = T_A_B · p_B
Composition T_A_C = T_A_B · T_B_Csubscripts meet in the middle, so a wrong chain is visible at a glance

The trap in "v points down"

In the image v points down; in the world Y points away. Those directions are opposite, so the 2D similarity transform from image to world always carries a sign flip:

[x_W]   [ s·cosθ   s·sinθ ] [ u ]   [tx]
[y_W] = [ s·sinθ  -s·cosθ ] [ v ] + [ty]
                    ↑
              this minus sign is not a typo

Miss it and the calibration still "converges" with a small-looking residual, but Y motion is globally inverted. The symptom is: X tracks fine, Y drifts further away the more you move. When you see that, come back to this sign before you start suspecting the camera.

Hand-eye: two configurations

Configuration Camera mounting What you solve for Typical use
Eye-in-hand On the moving member T_Tool_Cam Camera rides the Z axis to find focus
Eye-to-hand Fixed to the frame T_World_Cam Fixed overhead station

The two have different solve formulations, and picking the wrong one does not raise an error — it hands you a small residual and a completely wrong result. The wizard asks you first for a reason; do not click past it.

The cheap way to check a sign

Do not re-derive the algebra. Run an experiment:

  1. Move X by +10 mm;
  2. See which way, and how far in pixels, a marker moved in the image;
  3. Convert that pixel displacement back to mm with your transform and check it says +10.

If it does not, a sign is flipped or an axis mapping is wrong. On the virtual rig this takes a minute. On real hardware it takes half an hour and risks a crash.

Naming rule

Variables carry their frame. Bare x or pos is not allowed:

var pTargetW   = new Point2d(120.5, 80.0);   // world, mm
var pTargetI   = new Point2d(1204.0, 768.0); // image, px
var tWorldCam  = calib.Get<Transform2d>("T_World_Cam");
var pMeasuredW = tWorldCam * pMeasuredI;     // subscripts visibly line up

It reads as fussy, and it is. It also moves "a sign got flipped" from a machine crash to a code review comment.

Last updated: Sep 21, 2026
Was this page helpful?