Overview
Camera calibration finds where a fixed (external) camera sits relative to a robot’s base — thecamera_wrt_base transform that skills such as pick-and-place
read to turn what the camera sees into where the arm should move. It runs from
the grid CLI, lets you position the arm by hand or from the keyboard
(depending on the arm), and records the result on the robot’s camera
automatically.
This calibrates fixed cameras only — a camera mounted on a tripod or rig
looking at the workspace, not one riding the end-effector. The arm moves the
target through the camera’s view; the camera stays put.
Step 1: Print the calibration target
The calibration uses a 12×9 radon checkerboard with 16.5 mm squares. Generate it with OpenCV’sgen_pattern.py:
- Scale is exact — print at 100% (no “fit to page”), then measure a printed square; it must be 16.5 mm. Printer scaling silently shrinks the board and biases every result.
- There is a white border of at least one square-width on all sides.
- The surface is non-reflective, with no creases or unevenness.
- The mount is rigid (a 3D-printed mount is ideal; tape works). The board and camera must never wiggle during a run.
Step 2: Run the calibration
Calibration is offered at the end ofrobot add, from the grid CLI:
- Run
robot addand complete the setup for your robot. Calibration is offered only for robots whose arm can be positioned; see Positioning the arm. - At the final step the wizard flags any camera that has not been calibrated.
Press
cto calibrate now (or enter to skip and finish). If more than one camera is uncalibrated, pick the one to calibrate.
Move the arm to a variety of poses and collect a sample at each, by hand or
from the keyboard as described below. Hold the arm still at the instant you
press space, so the pose and the frame match. 15–20 well-distributed samples
generally suffice; more is better.
Positioning the arm
Each arm is positioned in one of two ways:- Hand-guide: you move the arm by hand. The run puts the arm in hand-guiding (free-drive) mode when it starts and takes it out when the run ends.
- Jog: you move the arm with keys in the calibration window.
Calibration is not offered for an arm that is not in this table. On a robot
with more than one arm, the wizard offers only the arms in the table, and skips
the arm question when only one remains.
When the run starts, the terminal prints one line that says how to position
the arm. If the arm cannot start in its default mode and it has a second mode,
the run starts in the second mode. The window shows the reason as a notice. If
the arm has only one mode, the run stops before the window opens and the
terminal shows the reason. A Fanuc that cannot start in jog starts in
hand-guide if free-hand teaching is on, and the window shows the reason
(Turn off free-hand teaching to jog). It stops only if it can start in
neither mode. A Fanuc refuses a switch to hand-guide with free-hand teaching
off (Turn on free-hand teaching to hand-guide), and a switch to jog with it
on (Turn off free-hand teaching to end hand-guiding).
The positioning card
On an arm that can jog, the panel shows a positioning card below theNext step card. Its title names the mode and the arm. While you jog, the title is
Jogging the right arm (or left arm), with the current step size at its top
right, and the card lists the jog keys. In a short window the card shows
only the move and rotate keys; the rest still work. While you hand-guide, the
card shows only its title.
The key strip along the bottom keeps SPACE, C, Q, P and F. On an arm
that supports both hand-guide and jog, the strip also shows T, with the mode
it switches to: T to jog while you hand-guide, T to hand-guide while
you jog.
An arm that can only be hand-guided shows no positioning card.
Jog keys
The video pauses briefly while each move completes, and keys pressed during a
move are ignored. If the arm cannot reach a pose, the window shows Move
refused and the arm stays where it was.
Galaxea R1 Pro
On the Galaxea R1 Pro you calibrate the head camera and jog the arm. When the wizard asks which camera to calibrate, pickhead_camera_left:
pick-and-place uses the left head camera as its reference. The wizard then asks
which arm holds the board, with the right arm preselected; press enter to
keep it or choose the left. Either arm works, because the result is the camera
relative to the torso, not to the arm. Attach the board to that arm’s
end-effector. The window’s subtitle names the arm in use.
Park the torso and the mobile base at the pose the robot will later look
from, and keep both there for the whole run. The result is only valid from
that pose.
Follow the next step
Let theNext step card drive the run. When you jog, it names the keys for the
move it asks for, such as (W / S) to move closer or farther, or (I/K,
J/L, U/O) to rotate about a different axis. Move the arm as it asks, wait
until the arm stops, then press SPACE, and repeat. Press C only once the
card says Coverage good.
Amber always means still needed, never a fault. Red is reserved for the two
things that need you to act: a consistency check that failed, and a sample
the run rejected or dropped.

The four meters
Each meter is a track: white ticks are the samples you captured, the blue dot is
the pose you are holding now, and the amber band is the range still missing. A
meter gets a green dot once its samples span enough range with no large gap in
the middle, so a cluster of similar poses leaves it an empty ring however many
samples you take. When the span is too narrow, an amber band sits at each end:
fill either one, or part of both, whichever side the camera can still see.
Scale needs a spread of 0.30, for example from 0.10 at your farthest sample to
0.40 at your nearest. To fill a gap, take a sample between two distances you have.
Axes decides whether the solve is well-posed at all. It needs the wrist to
turn about genuinely different axes between samples; if every move is a
variation on the same twist, the solve has nothing to pin the remaining
direction down. To fill it, between samples change at least two of these
three, by roughly 30–45° each — and move the board to a different part of the
frame as you go:
- tilt the board forward/back,
- tilt it sideways,
- twist it in its own plane (rotate it about the camera’s viewing direction — this is the one most people skip).
The live estimate
Est. erroris the reprojection error your current samples produce, re-solved after every capture and shown in px and mm. It is reported, not graded — see Step 3. It is badged preliminary until there are enough samples for it to mean anything. PressingCre-solves from exactly these samples, so the number you watched is the number that gets saved.Consistencyshows two checks that compare the data against itself and need no camera pose, so they are meaningful within the first few samples. Rotation red means the arm’s end-effector orientation is reported in a different convention than assumed, or the board is not rigidly fixed to the gripper. Scale red means a wrong printed square size, wrong units, or wrong camera intrinsics. Neither improves with more samples — stop and fix the cause.Next stepnames the single most useful next action. Follow it and ignore everything else.
Samples the run rejects for you
There is no undo key: bad samples are removed automatically, and every removal is announced in the panel.- Arm was moving when you pressed space — hold still and re-capture.
- Corners were not crisp (blur, or a mis-ordered detection) — steady the board and re-capture.
- Inconsistent sample dropped, once 8 or more samples exist — one sample disagreed with all the others. Re-capture at that pose if you want it back.
If the target isn’t detected, confirm it is non-reflective and that the board is
12×9 squares. OpenCV sometimes counts interior corners (one fewer per side).
Step 3: Read the result
PressC to solve. The reprojection error is the one you were already
watching on the Est. error tile — the solve runs over exactly the samples you
kept. The window closes and the terminal prints the final line only: the camera
name and the error, in pixels and in millimetres.
error_px × distance ÷ focal length). It is how far, per sample, the arm’s
reported pose and the camera’s view of the board disagree out in the world,
which is the number your task actually cares about.
The tool does not judge it. There is no good/bad threshold and no advice to
re-run, because only you know what your application tolerates — a few
millimetres is fine for one task and not another. What does flag a real problem
is the Consistency pills and the samples the run rejects for you; both catch
a wrong pose convention, scale or intrinsics without depending on the solve at
all. The CLI records the calibration on the robot’s camera and pushes it to the
robot’s config. Skills that need the extrinsic then read it over Nexus — no
copying by hand.
C is refused, with a notice and you left collecting, only when there is no
solution at all yet — too few samples, or a solve that degenerated. That is the
absence of a result, not a judgement on one.