IMUs ‐ Tips and Lessons - slgrobotics/articubot_one GitHub Wiki

Back to Home

IMU, AHRS, and their role in ROS 2

Contents:


An IMU (Inertial Measurement Unit) is a sensor that provides data about a robot’s orientation, angular velocity, and linear acceleration—acting like the robot’s inner ear for balance and motion tracking. The three axes of the accelerometer and the three axes of the gyroscope together provide six measured values (six degrees of freedom, or 6DOF). This data is fused into a relatively stable orientation representation, typically expressed as a quaternion or as Euler angles (roll, pitch, yaw).

In ROS 2, an IMU driver node typically publishes data using the sensor_msgs/Imu message type on topics such as /imu/data_raw or /imu/data.

Many IMUs also include a built-in magnetometer - these are commonly referred to as 9DOF IMUs. A stable Earth magnetic field vector allows the orientation estimate to be further stabilized by providing heading (North) information, which helps correct gyro drift and long-term precession.

A 9DOF IMU paired with a good sensor-fusion algorithm becomes an AHRS (Attitude and Heading Reference System). An AHRS provides continuous, drift-free estimates of a robot’s 3D orientation: roll, pitch, and yaw (heading), expressed in a reference frame such as ENU.

The data published by a ROS 2 IMU driver node is essential for sensor fusion with other sources (such as wheel encoders) to improve localization and state estimation. An EKF (Extended Kalman Filter) node is commonly used to perform this fusion.

Below are some “Lessons Learned” while troubleshooting and debugging various ROS 2 IMU drivers.

To see setup instructions, follow the links:

  • BNO085 - recommended, has DMP, normally does not need calibration.
  • BNO055 - has DMP, normally does not need calibration, but may skip some data.
  • ICM20948 - Adafruit boards work fine when calibrated, generic ones may have issues.
  • MPU9250 - works fine when properly calibrated.

Note: My forks of these drivers include numerous bug fixes and optimizations and have been thoroughly tested. Feel free to use them and report any issues you encounter.

IMUs with and without DMP

Some modern IMUs come with a Digital Motion Processor.

"Raw" IMUs without DMP

  • Output raw sensor data only: accelerometer, gyroscope (and sometimes magnetometer).
  • Sensor fusion (Madgwick, Mahony, EKF, etc.) runs on the host CPU.
  • More flexible and transparent: you control filtering, frames, covariances, and ROS 2 conventions.
  • Requires more CPU and careful tuning, but ideal for robotics and research.

IMUs with DMP

  • Include an on-chip processor that performs sensor fusion internally.
  • Can output orientation (quaternion / RPY) directly, often at low power.
  • Less CPU load on the host, simpler integration.
  • Limited configurability, sometimes opaque behavior, and may not follow ROS frame conventions exactly.

In short: DMP IMUs are convenient and low-power, while non-DMP IMUs are more flexible and better suited for custom ROS 2 pipelines and precise control.

For practical reasons some ROS2 drivers do not use the available DMP, or can be configured by a parameter not to use it. A ROS2 driver node developer has a choice:

  1. Read device registers, convert data to SI units, rotate to ENU reference frame and output as /imu/data_raw and /imu/mag topics
  2. Do all the above, and call a fusing algorithm (usually Madgwick filter) to derive orientation. Output as /imu/data topic.

In the first case you have to run an additional node (usually a Madgwick filter from the imu_tools package) to derive orientation.

Measurement Units and Frame Conventions

In ROS 2, IMU data is standardized through the sensor_msgs/msg/Imu message type.

The conventions are set in REP 103:

  • Linear Acceleration: Measured in meters per second squared m/s^2.
  • Angular Velocity: Measured in radians per second rad/s.
  • Orientation: Represented as a Quaternion (x,y,z,w). This is a unitless representation.
  • Magnetic Field must be in tesla (T). Caution: some drivers report microTesla (µT).

Tips:

  • to find Earth magnetic field strength in your area use this link
  • to convert Quaternion to Euler (roll, pitch, yaw) use this calculator

Important Conventions Coordinate System:

  • ROS 2 uses a Right-Handed System. For IMUs, the standard is usually X-forward, Y-left, and Z-up.
  • Map reference frame is ENU (+X=East, +Y=North, +Z=Up)
  • RViz normally shows frames in X=Red, Y=Green, Z=Blue)

Covariance: The message includes covariance arrays for each data type, which are measured in the square of the base units (e.g., (m/s^2)^2 for acceleration). A "-1" in the array means "covariance (precision) unknown". Small numbers (e.g. 0.1) mean good precision. All zeroes are usually a bad sign.

Gravity: By convention, an IMU at rest on a flat surface should report a positive acceleration of approximately +9.81 m/s^2 on the Z-axis.

Calibration

Calibration is the process of calculating biases (also called offsets) for all measured values. These biases are then used during operation to compensate for the device’s inherent deviations—they are subtracted from measurements to produce corrected values.

There is not much involved in calibrating the accelerometer and gyroscope: an average computed over about 10 seconds while the device is resting in a level position becomes the bias. Most ROS2 drivers perform this automatically at startup.

Magnetometer bias is calculated by moving the device through as many orientations as possible, attempting to cover the full sphere. An ellipsoid fit algorithm is then applied to the collected samples, producing a bias (essentially the ellipsoid center) and a transform (a 3×3 matrix that maps the ellipsoid to a sphere). For most practical purposes, the bias alone is sufficient, and the transform is usually very close to the identity matrix. Some ROS 2 drivers accept only the magnetometer_bias parameter and ignore the transform entirely.

For ROS2 drivers that do not take advantage of the DMP, magnetometer calibration is not optional. Look for instructions and scripts (usually something like tests/calibrate_mag.py) in the driver’s repository. Drivers that rely on a DMP (e.g., BNO055, BNO085) typically output reasonably accurate values thanks to the DMP’s ability to self-calibrate.

Tip: The DMP does not reach a calibrated status immediately and may report incorrect orientation for some time after startup. Look for messages on /imu/calib_status (or similar indicators). You can accelerate the calibration process by moving the robot—ideally through a range of orientations.

Data validation.

It is not difficult to validate data coming from the IMU. Run the ROS 2 node and either monitor the values in RQT or use the ros2 topic echo command.

Note:

  • In ROS2, the magnetic field is normally reported in Tesla. For example, 1.20000e-05 corresponds to 12 µT, and 3.10000e-06 corresponds to 3.1 µT.
  • Earth field in the US typically has negative z (points down into Earth)
  • See this link - magnetic field by location (µT - microTesla, NED frame)

Here is a simple cheat sheet. Print it and fill in the table:

 Accelerometer raw values (ax, ay, az in /imu/data.linear_acceleration)
 - Flat on the floor        → ax and ay near zero, az is positive (~9.8)
 - Tilt nose down (forward) → ax turns negative, az decreases (with all tilts)
 - Tilt left side down      → ay turns negative

 ros2 topic echo /imu/data | grep -A 3 "angular_velocity:"|grep "  x:"|grep -v "0.0"

 Gyroscope raw values (gx, gy, gz in /imu/data.angular_velocity)
 - Tilt nose down (robot pitching forward)  → gy goes positive
 - Roll left (left side going down)         → gx goes negative
 - Turn left (CCW, viewed from above)       → gz goes positive

 Mag:
   Rotate the robot in place.
   The published values should roughly conform to the following matrix:

      ENU    |    x    |    y    |    z    |
    ----------------------------------------   When robot rotates in place:
      North  |   +20   |     0   |   -40   |     N -> S  x changes from + to - (y stays around 0)
      East   |     0   |   +20   |   -40   |     E -> W  y changes from + to - (x stays around 0)
      South  |   -20   |     0   |   -40   |     z axis is Up; 
      West   |     0   |   -20   |   -40   |     z shouldn't change much
    ----------------------------------------
    values are in microTesla (µT), Earth's field is about 25 to 65 µT depending on location

           |   x     |   y     |   z     |
  ----------------------------------------
    North  |         |         |         |
    East   |         |         |         |
    South  |         |         |         |
    West   |         |         |         |
  ----------------------------------------

To Raw or to Madgwick — that is the question

An IMU driver can run in raw mode (delivering only accel/gyro/mag values, typically converted to SI units and bias-compensated), or it can compute the orientation quaternion and publish it as well.

In the first case, you need to run an additional Madgwick filter node to estimate orientation.

Refer to the following launch files to see how this is done:

The BNO085 driver does not allow "raw" mode; it always uses DMP.

EKF filter configuration

IMU data is typically fused with wheel odometry and GPS data using an EKF filter. An example configuration is available here.

You can select which components of the /imu/data message contribute to the filter outputs (/odometry/local, /odometry/global) by configuring the corresponding EKF input masks.

The following parameter determines how the filter interprets the linear acceleration reported by the IMU:

imu0_remove_gravitational_acceleration: true | false
  • true — The filter assumes the IMU publishes raw accelerometer data that includes gravity and subtracts the gravity component internally.
  • false — The filter assumes the IMU driver already provides gravity-compensated (linear) acceleration, so no additional correction is applied.

Ensure this parameter matches the behavior of your IMU driver; otherwise, velocity and position estimates may drift due to incorrect acceleration interpretation.

Here is a quick field test:

  • Place the robot flat and stationary:
  • If accelerometer Z reads about +9.81 m/s², gravity is included → set true
  • If it reads about 0 m/s², gravity is already removed → set false

Review this guide for a detailed explanation.

Final words

An IMU can be a no-worry, almost invisible component—or a major source of problems—depending on your choice of device, ROS 2 driver, operating mode, parameter tuning, and the effort invested in calibration and data validation.

The data it publishes directly affects mapping (SLAM Toolbox, AMCL) and navigation (Nav2), making its correct configuration especially important.

Hopefully, the information provided here will help you make the right decisions.


Back to Home