FixTheRobot Explore Robotics / Systems Engineering / Engineering Guides / Module 10

Engineering Guides · Module 10

Validating LiDAR–IMU calibration

A stationary robot on flat ground gives a free check: the ground normal seen by the LiDAR and gravity seen by the IMU must agree.

  • Intermediate
  • Module 10: Visual-Inertial SLAM & LiDAR-Inertial Integration
  • Written for ROS 2 Jazzy where ROS 2 is used
  • Sources checked 2026-11-06

Assumptions: Numbers in the examples are illustrative and the code is executed by the site’s tests. Facts taken from a cited source are marked; other statements are general engineering knowledge and must be confirmed on the datasheet of the part you use.

1. Engineering problem

LiDAR-inertial estimators use the IMU to deskew and to propagate the pose. If the rotation between the two sensors is wrong, gravity points the wrong way in the LiDAR frame and the map tilts or the height drifts.

2. When is this needed?

  • After mounting or changing the LiDAR or IMU.
  • When maps tilt or height drifts.
  • Before a LIO deployment.

3. Selection and design decisions

The FAST-LIO README (read 2026-11-06) asks users to make sure the IMU and LiDAR are synchronised and recommends setting extrinsic estimation off if the extrinsic is known, pointing to a LiDAR–IMU initialisation package for estimating it. LIO-SAM’s README describes the IMU-to-LiDAR extrinsic rotation that must be configured. A quick roll and pitch check uses the ground plane on level floor.

Overview
CheckMethodWhat a fail means
Roll and pitchFit the ground plane in the LiDAR frame and compare its normal with the IMU gravity direction in the same frameWrong extrinsic rotation or a non-level floor
YawDrive straight and compare headings; needs motionWrong yaw extrinsic
Time offsetCorrelate angular rates as in the other calibration guidesErrors while turning
Translation (lever arm)Needs accelerating rotationSmall effect at low acceleration

4. Advantages and disadvantages

  • Known floor must be level; a ramp breaks the check.
  • Estimating the extrinsic online adapts and can hide errors.
  • Static tests do not check yaw or time offset.

5. Requirements and constraints

  • The floor is measured level (a spirit level or tilt sensor).
  • The IMU is static and averaged for several seconds.
  • Plane fit uses many points over a wide area.

6. Architecture

LiDAR ground points ─▶ plane fit ─▶ normal n
IMU static accel ─▶ extrinsic rotation ─▶ gravity direction g      angle(n, g) = roll/pitch error

7. Implementation

  1. Place the robot on level ground and record for 10 seconds.
  2. Fit the ground plane in the LiDAR frame and compute its normal.
  3. Rotate the averaged IMU acceleration into the LiDAR frame with the extrinsic.
  4. Compute the angle between the two (below).
  5. If it exceeds the requirement, correct the extrinsic and repeat; then check yaw and time offset in motion.
import numpy as np
rng = np.random.default_rng(2)
tilt = np.radians(2.0)                                # true tilt between lidar and gravity
n_true = np.array([np.sin(tilt), 0, np.cos(tilt)])
u = rng.uniform(-5, 5, (400, 2))
pts = np.column_stack([u, -(n_true[0] * u[:, 0]) / n_true[2]]) + rng.normal(0, 0.005, (400, 3))   # ground plane in lidar frame
c = pts - pts.mean(0)
n_fit = np.linalg.svd(c, full_matrices=False)[2][-1]
n_fit *= np.sign(n_fit[2])
g_imu = np.array([0.0, 0.0, 1.0])                      # gravity direction measured by the IMU after the extrinsic rotation
err = np.degrees(np.arccos(np.clip(n_fit @ g_imu, -1, 1)))
print(f"ground normal vs IMU gravity direction: {err:.2f} deg")
print("extrinsic roll/pitch error flagged" if err > 1.0 else "within 1 deg")

Printed (checked by the site’s tests):

ground normal vs IMU gravity direction: 2.00 deg
extrinsic roll/pitch error flagged

Reading it: with a synthetic 2° tilt between the ground normal and the IMU’s idea of gravity, the check reports 2.00° and flags the extrinsic. The data are synthetic.

8. Real examples

  • Handheld mapping rig: the 2° error visible as tilted floors in the map is removed by correcting the extrinsic roll.

9. Failure scenarios

  • Testing on a slope.
  • Using too few ground points.
  • Ignoring time offset and blaming the rotation.

10. Troubleshooting

  1. Repeat the check at several places.
  2. Rotate the robot 90° and repeat: a consistent error in the sensor frame points at the extrinsic.
  3. Check the IMU’s own calibration.

11. Validation

  • The example prints the lines shown (executed by the site tests).
  • The angle is below the requirement and repeatable.

12. Engineering checklist

13. Further references

Related on FixTheRobot