Skip to content

Camera calibration

The camera intrinsics tell ROS the lens geometry so it can undistort images and project pixels to rays. Mote resolves them at launch with a fallback:

  1. ~/.mote/camera_calibration.yaml — this robot's own calibration, if it exists. Per-robot and intentionally outside the repo.
  2. camera_info.default.yaml (this directory) — a representative default for the UGREEN webcam, committed so a fresh checkout / new robot works out of the box.

mote_launch.py uses the ~/.mote file when present, otherwise the packaged default (robot.yaml's camera.default_info_url).

Do you need to calibrate?

Usually no — intrinsics barely vary between identical camera units, so the committed default is fine for display and coarse perception. Calibrate your own (and save it to ~/.mote/camera_calibration.yaml) when:

  • you fitted a different camera than the UGREEN model the default was made for;
  • you need metric accuracy — e.g. the L1 obstacle/depth work that projects pixels onto the ground or into 3D, where small intrinsic errors bias range;
  • straight edges look curved in the rectified image, or /camera_info clearly doesn't match your lens;
  • you changed the capture resolution (the default is for 640x480).

Print checkerboard_a4_25mm_7x10.pdf on A4 — it is 7x10 squares of 25 mm (so 6x9 inner corners), with the calibrator parameters printed along the bottom edge.

The page is deliberately a little smaller than A4 so it fits inside the printable area of any A4 printer: most printers should print it unscaled, and the squares come out true-size without changing any print settings. Just print it on A4 and the board is centred with a white border.

  • Mount it dead flat on a clipboard, foamboard, or glass. A floppy sheet warps and wrecks the result.
  • The squares should measure 25 mm on each side however if they do not match exactly it should still calibrate correctly. The intrinsics are independent of the absolute square size — square size only affects metric scale, which this calibration does not rely on.

Running the calibration

This is bench prep (getting started): plug the camera into your workstation and run the calibrator there. cameracalibrator is an interactive GUI and a dev dependency, not installed on the robot, and the camera does not have to be on the robot for its intrinsics. Nothing joins the robot's graph: a camera node and the GUI run on this machine, on a ROS domain of their own, loopback only.

  1. Print and mount the target above.
  2. Plug the camera in. The tool opens /dev/mote_camera when the udev rules are installed here (pixi run setup udev), else /dev/video0; --device picks another.
  3. Run the calibrator:
pixi run camera-calibrate                        # -> ./camera_calibration.yaml
pixi run camera-calibrate --out mote-02-camera.yaml
  1. Move the board through the frame until the X/Y/Size/Skew bars are full, press CALIBRATE, then SAVE, then close the window. The saved result (camera matrix, distortion, rectification, projection) is extracted to --out in the camera_info format mote_launch.py loads.

  2. Install it. For a new robot, onto the card: pixi run provision … --camera-calibration camera_calibration.yaml. For a robot already running, copy it to ~/.mote/camera_calibration.yaml on the Pi.