IMU model
CamCalib solves IMU intrinsics — scale and misalignment for gyroscope and accelerometer, optional g-sensitivity, and biases — rather than assuming a datasheet. Symbols follow Notation & glossary.
Measurement model
Section titled “Measurement model”Dw / Da carry scale and misalignment, Tg the g-sensitivity — how linear
acceleration leaks into the gyro reading — and b_g / b_a the biases.
Three conventions
Section titled “Three conventions”solve: imu_intrinsics_model: kalibr # kalibr | rpng | calyxThe nine entries of each D are not all identifiable — the frame must be
pinned to something, and what it is pinned to is the convention:
| Model | Pins the frame to | Notes |
|---|---|---|
kalibr | accelerometer triad | Matches Kalibr output |
rpng | gyroscope triad | RPNG lineage |
calyx | — | Gyro correction as a full 3×3, decomposed post-hoc into rotation × upper-triangular |
The matrices themselves are not numerically comparable across conventions. Before concluding that two calibrations disagree, check they used the same one.
t_ga — the gyro↔accel offset
Section titled “t_ga — the gyro↔accel offset”Many IMU drivers publish gyro and accelerometer on one timestamp even though the
two channels are sampled at different rates and instants. t_ga is that
internal offset: the combined stamp is taken as the gyro clock, and the accel
stored at t is modelled as physically sampled at t − t_ga.
solve: estimate_t_ga: true sigma_t_ga: 0.001It is estimated inside the ACI factor — one extra Jacobian column in the
preintegration (∂a/∂t_ga = ȧ from per-step finite differences, coupled into
the gyro row through Tg) plus an optional sixth factor key with a staged
prior. With the flag off, the five-key factor is untouched.
In simulation, injected offsets of −2, +1, and +5 ms recover with |z| ≤ 1.3
at σ = 0.024 ms, with no td / Dw / Da cross-contamination.
On real data, the T265’s Bosch BMI055 measures t_ga ≈ −6.2 ms, stable to
about 0.2 ms across bags — roughly 16σ. That number is a direct measurement of
the driver’s accel-interpolation artefact.
t_ga is reported in the result JSON, the calibration YAML, and the text
report; apply-calib corrects it by
re-interpolating the accel channel at t + t_ga, and
roundtrip checks that it collapses toward zero.
Gyro-only auxiliaries
Section titled “Gyro-only auxiliaries”The other answer to an untrustworthy accelerometer — skip it:
input: imus: - {} # base IMU - {gyro_only: true} # auxSolves extrinsic rotation, td, Dw, and gyro bias; lever arm, Da, and Tg
are pinned. Not permitted on the base IMU, which needs the accelerometer for
gravity and metric scale. The calibration self-documents with a gyro_only: true flag per IMU.
On the T265 this makes the td collapse in a correct→recalibrate round-trip
(+8.6 → −9.0 ms becomes +0.9 → +0.4 ms) and halves the residual lever drift.
Which to reach for
Section titled “Which to reach for”Both address the same defect. gyro_only avoids the bad accelerometer;
estimate_t_ga measures the offset causing it. Prefer estimate_t_ga on
the base IMU, where you have no choice but to use the accel — and where the
measured value is itself worth having. Prefer gyro_only for an auxiliary whose
accelerometer adds nothing you need.
What is actually observable
Section titled “What is actually observable”Scale and misalignment need excitation on every axis. G-sensitivity needs
simultaneous rotation and strong linear acceleration, which most hand-held
calibration motions do not produce — when Tg returns near its initial value
with a wide covariance, it was not observed. See
Degeneracy.