Engineering Guides · Module 10
Configuring an IMU for VIO
Most VIO failures from the IMU are mundane: wrong units, too low a rate, wrong axes. Check them with a stationary recording first.
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
VIO fuses image motion with integrated IMU measurements. An IMU in the wrong units, at too low a rate or with axes mismatched to the camera makes the fusion fail from the first second, and the symptom looks like a tracking problem.
2. When is this needed?
- Setting up a new VIO pipeline.
- After replacing an IMU or driver.
- When initialisation fails.
3. Selection and design decisions
The ROS 2 sensor_msgs/Imu message defines accelerations in m/s² (not g) and angular velocity in rad/s; a covariance of all zeros means unknown, and a first element of −1 means no estimate for that quantity. VINS-Fusion’s README notes that VIO relies on hardware quality, and recommends global-shutter cameras and hardware-synchronised IMUs. LIO-SAM’s README says the IMU data must be in the LiDAR frame following the REP convention, and the same discipline applies to VIO.
| Item | Requirement | Check |
|---|---|---|
| Units | m/s² and rad/s | Static accelerometer magnitude ≈ 9.81 |
| Rate | Several IMU samples per image (commonly 100 to 400 Hz) | Count samples per frame |
| Axes and handedness | Right-handed, documented relative to the camera | Rotate the sensor about one axis and watch the gyro |
| Static bias | Small and stable | Mean gyro at rest |
| Time stamps | Capture time, monotonic | Plot sample intervals |
| Gravity | Point along a known axis at rest | Direction of mean acceleration |
4. Advantages and disadvantages
- Higher IMU rate improves preintegration and increases data and CPU.
- A better IMU costs more and relaxes calibration demands.
- Onboard filtering in the IMU reduces noise and adds a delay.
5. Requirements and constraints
- Units, frame and rate documented in the ICD.
- Time stamps are from the same clock as the camera (or the offset is calibrated).
- Noise parameters match the actual rate and filter settings.
6. Architecture
IMU (rate, units, filter) ─▶ driver ─▶ sensor_msgs/Imu ─▶ VIO (preintegration) ◀─ camera frames7. Implementation
- Record 30 seconds stationary.
- Check units, rate and static bias (below).
- Rotate by 90° about each axis and check signs.
- Check intervals and time stamps.
- Enter noise parameters from the datasheet or an Allan-variance run (see the next guide).
import math
def check_imu(accel_static, imu_rate, cam_rate, gyro_static):
mag = math.sqrt(sum(a * a for a in accel_static))
out = [f"static accel magnitude {mag:.2f}"]
if abs(mag - 9.81) < 0.5:
out.append("-> consistent with m/s^2")
elif abs(mag - 1.0) < 0.1:
out.append("-> looks like g, not m/s^2: convert")
else:
out.append("-> neither m/s^2 nor g: check units and scale")
ratio = imu_rate / cam_rate
out.append(f"{ratio:.1f} IMU samples per frame" + ("" if ratio >= 4 else " (low: preintegration will be coarse)"))
bias = max(abs(g) for g in gyro_static)
out.append(f"static gyro offset {bias:.4f} rad/s ({math.degrees(bias):.2f} deg/s)")
return out
for case in (((0.1, 0.2, 9.79), 200, 20, (0.002, -0.001, 0.003)), ((0.01, 0.02, 0.99), 100, 30, (0.05, 0.0, 0.0))):
print("\n".join(check_imu(*case)), end="\n\n")Printed (checked by the site’s tests):
static accel magnitude 9.79
-> consistent with m/s^2
10.0 IMU samples per frame
static gyro offset 0.0030 rad/s (0.17 deg/s)
static accel magnitude 0.99
-> looks like g, not m/s^2: convert
3.3 IMU samples per frame (low: preintegration will be coarse)
static gyro offset 0.0500 rad/s (2.86 deg/s)Reading it: the first IMU reports 9.79 m/s² (consistent with m/s²), 10 samples per frame and a 0.003 rad/s static offset; the second reports 0.99 which is gravity in g and needs conversion, only 3.3 samples per frame (low) and a 0.05 rad/s offset. Values are illustrative.
8. Real examples
- 200 Hz IMU with a 20 Hz camera: 10 IMU samples per frame for preintegration.
9. Failure scenarios
- IMU in g fed to an estimator that expects m/s².
- Axis signs wrong in the extrinsic, so the estimator fights the data.
- IMU stamped at arrival with variable delay.
10. Troubleshooting
- If initialisation fails, check units and gravity first.
- If the trajectory flips at the start, check handedness.
- If drift appears when turning, check time offset.
11. Validation
- The checker prints the lines shown (executed by the site tests).
- A stationary recording gives gravity ≈ 9.81 m/s² and a small stable gyro offset.
12. Engineering checklist
13. Further references
- ROS 2
sensor_msgs/Imu(Jazzy): Imu.msg, read 2026-11-05 (acceleration in m/s², angular velocity in rad/s). - VINS-Fusion README, read 2026-11-06: HKUST-Aerial-Robotics/VINS-Fusion.
- FAST-LIO and LIO-SAM READMEs, read 2026-11-06: FAST_LIO, LIO-SAM.