imu-calib
Kalibr-compatible IMU intrinsic calibration for Rust: estimate the parameters, then apply them online.
Implements the model from Rehder et al., "Extending Kalibr: Calibrating the Extrinsics of Multiple IMUs and of Individual Axes", ICRA 2016, and reads and writes the YAML files Kalibr uses.
Workflow
Two independent parameter groups, from two different recordings.
long stationary recording static poses + rotations
│ │
▼ ▼
allan::AllanEstimator estimate::calibrate_recording
│ │
noise densities, random walks M_a, M_g, C_gyro_i, b_a, b_g
│ │
└───────────────► ImuIntrinsics ◄───────────┘
│
┌──────────────────┴──────────────────┐
▼ ▼
save_kalibr_input_yaml() ImuCorrector
feeds the Kalibr run corrects a live stream
Noise parameters
Record at least 3 hours with the IMU undisturbed, away from vibration.
use ;
let mut estimator = new;
// for every sample of the recording:
estimator.push;
let result = estimator.finish?;
let noise = result.noise?;
println!;
println!;
write?;
White noise is read off the −1/2 slope at τ = 1 s, bias random walk off the +1/2 slope at τ = 3 s. noise() returns an error if the recording is too short to show either region.
Intrinsics
Needs no camera and no target. Hold the IMU still in at least nine well-spread orientations, rotating about a different axis between each one. Start at rest: the first seconds set the noise floor that tells a hold from a move.
GuidedCalibration prompts through it live:
use ;
let mut session = new;
// for every incoming sample:
match session.push
For a finished recording, estimate::calibrate_recording finds the static
stretches itself. Both return a CalibrationReport; check its residuals.
With only the six axis-aligned faces, set
accel_parametrization: AccelParametrization::ScaleBias.
Apply
use ImuIntrinsics;
let intrinsics = from_kalibr_yaml?;
let corrector = intrinsics.corrector?; // build once
// per sample:
let = corrector.correct;
correct_msg and correct_msg_in_place take a ROS-shaped [ImuMsg].
ImuCorrector::gyro_bias_from_static re-estimates the gyro bias from a few
seconds of stationary data, which is worth doing at startup — bias moves with
temperature and between power cycles, scale and misalignment do not.
Kalibr interop
from_kalibr_yaml reads Kalibr's imu-<bagname>.yaml directly, including the
imu0: / imu1: nesting and every key of all three --imu-models:
let intrinsics = from_kalibr_yaml?;
let second = from_kalibr_yaml_named?;
let all = all_from_kalibr_yaml_str?;
Files written by this crate use Kalibr's layout, so the two are interchangeable.
To feed a Kalibr run, write the flat input file after the Allan step:
intrinsics.save_kalibr_input_yaml?;
For low-cost MEMS parts the Kalibr wiki suggests inflating the measured noise densities by 10× or more before using them in an estimator.
Command line
binnacle runs both estimators over an MCAP recording: record a bag, get a Kalibr YAML.