Manifest Field Reference

Every field of the dataset manifest, generated from its JSON Schema. The prose chapter The Dataset Manifest explains how the pieces fit together; this page is the exhaustive list. The schema itself is app/src/schemas/dataset_spec.json in the repository, and the desktop app builds its manifest form from it.

Paths in a manifest are relative to the directory that holds it unless they are absolute. A field marked required has no default and must be present; an optional field may be omitted.

DatasetSpec

Top-level dataset manifest. Authoritative description of where the user's calibration data lives and how to interpret it.

FieldTypeRequiredDefaultDescription
camerasarray of CameraSourceyesPer-camera image sources. Length must match the topology's expected camera count (a single-camera topology requires exactly one entry, a rig topology at least two, rig_handeye_laserline at least one).
targetTargetSpecyesCalibration-target specification. Tagged enum on kind.
topologyTopologyyesCalibration topology — selects which problem type the runner will dispatch to.
_unresolvedarray of stringnoField paths the manifest generator could not determine. Validated to be empty before the runner accepts the manifest. Populated as e.g. ["pose_convention.transform"].
descriptionstringnoFree-form human-readable description.
detectorDetectorSpecnoDetector-stage overrides shared by target families. Defaults preserve the detector's built-in behavior.
laserLaserExtractionSpecnoLaser-line extraction parameters for the laser topologies. None means defaults — extraction tuning has safe defaults and is not a fail-fast ambiguity. Rejected on non-laser topologies.
pose_conventionPoseConventionnoFrame conventions for robot poses. No defaults — every component is required when robot_poses is set.
pose_pairingPosePairingnoHow per-camera images are paired across views (and optionally with robot poses). None is permitted only where pairing is irrelevant: a single camera without robot poses.
robot_posesRobotPoseSourcenoRobot-pose source for hand-eye topologies. None for pure-intrinsics calibrations.
upstream_calibrationstringnoPath to a frozen upstream RigHandeyeExport JSON, relative to the manifest directory unless absolute. Required for Topology::RigLaserlineDevice, rejected elsewhere. Joint hand-eye laserline calibration computes its own hand-eye warm start and does not use this field.
versionintegerno1Format-version sentinel. Always 1 for now; bumped on breaking schema revisions.

Unknown fields are rejected.

CameraSource

Per-camera image source.

FieldTypeRequiredDescription
idstringyesStable camera identifier (e.g. "cam0"). Used as a key in pose pairings and downstream exports.
imagesImagePatternyesGlob pattern (e.g. "cam0/*.png") or explicit list of image paths, relative to the manifest's directory unless absolute.
laser_imagesImagePatternnoLaser-frame image source for the laser topologies. One laser image per view, captured by the same sensor with the line projector on; roi_xywh applies to laser frames too. Laser images pair with target views through pose_pairing.
roi_xywharray of 4 integernoOptional rectangular ROI in source-image pixels — [x, y, w, h]. When set, only the cropped region is fed to the detector and stored in the export's image manifest.

Unknown fields are rejected.

ImagePattern

How image paths for a camera are listed.

Tagged on kind; the fields depend on the variant.

kind = "glob": Single shell-glob pattern, evaluated relative to the manifest directory. Example: "cam0/*.png".

FieldTypeRequiredDescription
patternstringyesThe glob pattern.

kind = "list": Explicit ordered list of paths.

FieldTypeRequiredDescription
pathsarray of stringyesPaths relative to the manifest directory unless absolute.

TargetSpec

Calibration-target metadata. Tagged on kind.

Tagged on kind; the fields depend on the variant.

kind = "chessboard": Standard checkerboard. Counts are interior corners (i.e. 9x6 ⇒ a 10×7 black-and-white square grid).

A plain chessboard has no markers: each view is labelled from the detection's own top-left corner. Where views share one target frame (single-camera hand-eye and every rig topology) the runner therefore keeps a view only when its corners reach every edge of the board. In a rig, each camera's labels are turned to agree with the other cameras of the view, so a board seen turned is kept. Where the target is fixed through the views (hand-eye), the board must appear the same way up in every image of camera 0 (cols across and rows down); a board seen turned by 90° is dropped, and one seen upside down, or a square board seen turned by 90°, cannot be told apart. Use a ChArUco or PuzzleBoard target to calibrate a shared frame from partial views.

FieldTypeRequiredDescription
colsintegeryesNumber of interior corners across the board (the image's columns axis when the board is seen as declared).
rowsintegeryesNumber of interior corners down the board (the image's rows axis when the board is seen as declared).
square_size_mnumberyesEdge length of one square in metres.

kind = "charuco": ChArUco board. Marker IDs and dictionary live here so detection is fully deterministic from the manifest.

FieldTypeRequiredDescription
colsintegeryesNumber of squares along the cols axis.
dictionarystringyesArUco dictionary identifier (e.g. "DICT_4X4_50"). The detector validates this against the supported set.
marker_size_mnumberyesEdge length of an embedded marker in metres.
rowsintegeryesNumber of squares along the rows axis (full grid, not interior corners).
square_size_mnumberyesEdge length of one square in metres.

kind = "puzzleboard": Puzzleboard target: a self-identifying chessboard. The layout name carries the board's dimensions, so the manifest fully determines detection.

FieldTypeRequiredDescription
cell_size_mnumberyesEdge length of one cell in metres.
layoutstringyesBoard dimensions as puzzle_<rows>x<cols> (e.g. "puzzle_12x12"; the puzzle_ prefix is optional).

kind = "ringgrid": Coded ring-grid target (the ringgrid crate). The board is a hex-lattice of self-identifying ring markers; its geometry mirrors ringgrid::BoardLayout so the manifest fully determines detection.

FieldTypeRequiredDescription
long_row_colsintegeryesNumber of columns in the longest (even-indexed) row. Shorter rows are derived by the hex-lattice layout.
marker_inner_radius_mnumberyesInner ring radius in metres.
marker_outer_radius_mnumberyesOuter ring radius in metres.
marker_ring_width_mnumberyesWidth of each ring band in metres.
pitch_mnumberyesCenter-to-center spacing between adjacent markers in metres.
rowsintegeryesNumber of marker rows.

Topology

Calibration topology — selects the problem-type dispatch.

A topology describes the data (how many cameras, robot poses, laser images), not the camera model: a tilted (Scheimpflug) single camera is a planar_intrinsics dataset whose calibration config names the sensor.

ValueDescription
planar_intrinsicsSingle camera, planar target — PlanarIntrinsicsProblem (any camera model, including a tilted sensor).
single_cam_handeyeSingle camera mounted on a robot — SingleCamHandeyeProblem.
laserline_deviceCamera + laser plane — LaserlineDeviceProblem.
rig_extrinsicsMulti-camera rig, target only — RigExtrinsicsProblem.
rig_handeyeMulti-camera rig + robot — RigHandeyeProblem.
rig_handeye_laserlineMulti-camera rig + robot + laser planes — joint hand-eye/laser BA.
rig_laserline_deviceMulti-camera rig + laser planes — RigLaserlineDeviceProblem.

DetectorSpec

Target-detector overrides. These options affect feature detection only; they are hashed into the detection-cache key by the runner.

FieldTypeRequiredDescription
chess_cornersChessCornersDetectorSpecnoChESS corner extractor options shared by chessboard-like detectors (plain chessboard and ChArUco).
min_features_per_viewintegernoMinimum detected features for a view (or a camera's slot in a rig view) to be kept, in every topology. None keeps the runner default (4, the homography minimum). Raise it for detectors whose sparse detections are unreliable — e.g. ring-grid decodes with < 8 markers are noisy enough to poison a solve. A plain chessboard needs no floor to stay consistent: where views share one target frame the runner already keeps only views that span the whole board.

Unknown fields are rejected.

ChessCornersDetectorSpec

ChESS corner extractor overrides.

FieldTypeRequiredDescription
covarianceCornerCovarianceSpecnoAttach the detector's per-corner position covariance to every observation. Absent (the default) = off.

The covariance is the image noise propagated through the corner localizer, plus the localizer's systematic-error model. When present, a calibration weights each corner by it (whitened residuals) and its report gives the unit-weight scale factor σ̂₀ instead of an RMS in pixels.

Off by default, and not recommended for calibration. On real chessboard and ChArUco images, weighting by it did not improve the accuracy on held-out views and made it slightly worse on some cameras; its stated uncertainty was no closer to the real scatter.

Supported by the chessboard and charuco targets only: the PuzzleBoard detector runs on an upscaled image, for which no covariance is reported, and ring grids have none. A manifest that sets it for another target is an error.
min_corner_strengthnumbernoMinimum corner strength for a detected corner to enter the grid builder. None keeps the detector default (33.0). The floor is on the strategy's response scale; under Radon the default never binds.

The default drops weakly-firing corners, which is the right trade whenever corners are plentiful. Set 0.0 to disable it on small or soft image tiles, where the floor can remove a third of the board and the resulting sparse view conditions worse than the weak corners did.
strategyCornerStrategySpecnoCorner detector. None keeps ChESS.
threshold_valuenumbernoAcceptance threshold on the corner response. None keeps the strategy's default.

Under ChESS it is an absolute floor on the raw response: a corner is kept when its response exceeds it. Under Radon it is a fraction in (0, 1] of the frame's maximum response.

A sibling threshold_mode key is rejected by deny_unknown_fields: the corner detector has no threshold mode.

Unknown fields are rejected.

CornerCovarianceSpec

Per-corner covariance options; see [ChessCornersDetectorSpec::covariance].

FieldTypeRequiredDefaultDescription
image_noiseImageNoiseSpecno"estimate"The image noise that the propagated covariance is expressed in. Defaults to estimate: the noise is estimated from each image, which is unreliable on JPEG or demosaiced images; give known for those.

Unknown fields are rejected.

ImageNoiseSpec

The pixel-noise level behind a corner covariance.

In JSON / TOML: "estimate" or { known = 2.0 }.

Tagged on kind; the fields depend on the variant.

kind = "": Estimate the noise from each image. Unreliable on JPEG or demosaiced images, where a corner then reports no covariance and the run fails.

kind = "": The standard deviation of the image's pixel noise, in gray levels of the 8-bit image (finite and >= 0), e.g. the standard deviation of the difference of two frames of a static scene divided by √2.

FieldTypeRequiredDescription
knownnumberyes

Unknown fields are rejected.

CornerStrategySpec

The corner detector a chessboard-like detector runs.

ValueDescription
chessThe ChESS response. Fast; the default.
radonThe whole-image Radon response. Several times slower than ChESS, and less biased at a corner's sub-pixel position on sharp, finely sampled boards (e.g. rendered ones).

LaserExtractionSpec

Laser-line extraction parameters. Consumed by the runner's injected LaserPixelExtractor; hashed (canonical JSON) into the detection-cache key so edits re-extract.

FieldTypeRequiredDefaultDescription
min_pointsintegerno20Minimum extracted points for a usable laser view. Views below the bar are dropped (single camera) or become gap slots (rig). Must be at least 2 (a line needs two points); 0/1 would let an empty extraction pass as usable and leave the plane unconstrained.
neg_threshnumberno4.0Negative-edge response threshold.
pos_threshnumberno4.0Positive-edge response threshold.
scan_axisLaserScanAxisno"cols"Scan direction. cols walks image columns (one point per column; for laser lines running mostly left-to-right), rows walks image rows.
sigmanumberno1.2Gaussian derivative sigma in pixels for the edge detector.

Unknown fields are rejected.

LaserScanAxis

Laser scan direction.

ValueDescription
colsOne detection per image column.
rowsOne detection per image row.

PoseConvention

Frame conventions for the robot pose stream.

All three components are required (no defaults). Each is a closed enum so the runtime supports a finite, validated set of conventions.

FieldTypeRequiredDescription
rotation_formatRotationFormatyesHow rotation is parameterised in the file.
transformTransformConventionyesWhich transform the pose row encodes.
translation_unitsTranslationUnitsyesTranslation units in the file.

Unknown fields are rejected.

RotationFormat

Rotation parameterisation in the file.

ValueDescription
quat_xyzwHamilton quaternion as [qx, qy, qz, qw].
quat_wxyzHamilton quaternion as [qw, qx, qy, qz].
euler_xyz_degIntrinsic XYZ Euler angles in degrees.
euler_xyz_radIntrinsic XYZ Euler angles in radians.
euler_zyx_degIntrinsic ZYX Euler angles in degrees.
euler_zyx_radIntrinsic ZYX Euler angles in radians.
axis_angle_radAxis-angle vector (length encodes magnitude, radians).
matrix4x4_row_majorRow-major 4×4 homogeneous matrix flattened across 16 columns.

TransformConvention

Which transform a pose row encodes.

ValueDescription
t_base_tcpT_base_tcp — gripper pose in the robot base frame (KUKA, UR default).
t_tcp_baseT_tcp_base — base pose in the gripper frame (some ABB exports).
t_world_tcpT_world_tcp — gripper pose in a fixed world frame (less common; some lab-frame setups).
t_tcp_worldT_tcp_world — world pose in the gripper frame.

TranslationUnits

Translation units in the file.

ValueDescription
mMetres (SI, preferred).
mmMillimetres (some ABB / Fanuc exports).

PosePairing

How per-camera image lists align across views and (optionally) align with robot poses.

Tagged on kind; the fields depend on the variant.

kind = "by_index": All cameras have the same number of images, paired by index (image[i] from cam0 ↔ image[i] from cam1 ↔ pose[i]).

kind = "shared_filename_token": A regex applied to filenames extracts a shared "view token" (e.g. timestamp or pose id). All cameras and the pose file must produce the same set of tokens.

FieldTypeRequiredDescription
groupstringyesName of the capture group whose value identifies the view.
regexstringyesRegex with at least one named capture group.

RobotPoseSource

Where and how robot poses are stored on disk.

FieldTypeRequiredDescription
formatRobotPoseFormatyesFile-format selector.
pathstringyesPath to the pose file, relative to the manifest directory unless absolute.
columnsPoseColumnMapnoColumn / field mapping from the user's file to the canonical fields the converter consumes. Required for the tabular formats (csv / json / jsonl) unless matrix_field is set; must be absent for rowmajor4x4 and counted4x4, whose matrix layout is fixed.
matrix_fieldstringnoFor json / jsonl files whose rows store the whole pose as a single nested 4×4 (or flat-16) array field, names that field (e.g. "tcp2base"). Mutually exclusive with columns; requires pose_convention.rotation_format = matrix4x4_row_major. Translation comes from the matrix's fourth column, scaled by translation_units. No pose_id ⇒ by_index pairing only.

Unknown fields are rejected.

RobotPoseFormat

Robot-pose file format.

ValueDescription
csvComma-separated values with a header row.
jsonJSON array of objects.
jsonlJSONL (one JSON object per line).
rowmajor4x4Headerless text: each non-empty line is 16 whitespace-separated floats forming a row-major 4×4 homogeneous transform (KUKA-style exports). Requires pose_convention.rotation_format = "matrix4x4_row_major" and no columns mapping.
counted4x4Headerless text: the matrix count, then that many row-major 4×4 homogeneous transforms as whitespace-separated floats on any number of lines (the layout of the robot-world hand-eye datasets of Tabb and Ahmad Yousef). Same requirements as rowmajor4x4.

PoseColumnMap

Mapping from user-defined column / field names to the canonical pose fields. All seven of tx, ty, tz, qx, qy, qz, qw are required when rotation_format is a quaternion; the runner rejects partial mappings as a fail-fast event.

FieldTypeRequiredDescription
rotationarray of stringyesRotation columns. Length and meaning depend on the pose_convention.rotation_format.
txstringyesTranslation x column.
tystringyesTranslation y column.
tzstringyesTranslation z column.
pose_idstringnoOptional view-id column (string or integer). When absent, the pose row index is used as the implicit pose id.

Unknown fields are rejected.