IMU BIAS CALIBRATION.
A raw QMI8658A reads a small, steady offset even when the car is dead still, and the QMC6309 magnetometer reads a field warped by the metal around it. Two scripts measure those once and write the corrections to a pair of YAML files the driver loads at launch, so rc.physics gives you honest numbers.
THE TWO CALIBRATIONS.
The IMU node reads three sensors off one chip: accelerometer, gyroscope, and magnetometer. The first two are corrected by sitting still; the third needs you to turn the car through every direction so the script can map the field. They are two separate scripts and two separate YAML files.
Accel + gyro bias
accelerometer.bias and gyroscope.bias.Magnetometer fit
WHAT YOU'LL NEED.
The driver running
A level surface
Space to rotate
THE ACCEL + GYRO PASS.
bash# Driver running (teleop), car flat and motionless on a level surface. python3 ~/racecar_ws/src/racecar_neo/scripts/calibrate_imu.py # It connects to /imu, collects a window of samples, and averages them. # The mean is the bias: what the sensor reports when nothing is moving. # When it finishes, it writes imu_cal.yaml.
THE MAGNETOMETER FIT.
bash# Driver running. Pick the car up and be ready to rotate it. python3 ~/racecar_ws/src/racecar_neo/scripts/calibrate_mag.py # While it collects, slowly tumble the car through every orientation: # nose up and down, roll left and right, spin through a full yaw. # It fits a hard-iron offset and a soft-iron matrix to the cloud of # points, plots them as a sphere so you can see the coverage, and # writes mag_cal.yaml.
The goal is even coverage of the sphere. Gaps mean a direction the field was never sampled, which leaves the fit guessing there. Keep turning until the plotted points wrap the whole ball.
THE OUTPUT YAML.
This is the one calibration that is a real config file, not a source constant. The launch file hands both YAMLs to the IMU node as parameters, so the corrections apply the next time you bring the driver up. The parameter names are documented on the ROS 2 parameters page.
yaml# config/imu_cal.yaml, written by calibrate_imu.py imu_node: ros__parameters: accelerometer: bias: [0.013, -0.021, 0.004] # m/s^2, per axis gyroscope: bias: [0.0011, 0.0006, -0.0009] # rad/s, per axis # config/mag_cal.yaml, written by calibrate_mag.py imu_node: ros__parameters: magnetometer: hard_iron_bias: [1.2e-5, -8.0e-6, 3.1e-6] # T, offset soft_iron_matrix: data: [1.02, 0.01, 0.0, 0.01, 0.98, 0.0, 0.0, 0.0, 1.0] # row-major 3x3
- Relaunch the driver after calibrating so the IMU node reloads the files.
- The values above are an illustration; yours come out of the two scripts.
- Keep the YAMLs with your workspace so a re-image does not drop them back to identity.
