IMU/gyroscope yaw drift in /odometry/filtered while robot is stationary

Environment

  • Robot: Husarion Panther (ROS2 driver, jazzy-0.1.2-20250902 autonomy image)

  • ROS2 Jazzy, Ubuntu (Husarion OS)

Symptom

While the robot is completely stationary (motors idle, no cmd_vel published), the orientation reported on /panther/odometry/filtered drifts steadily and monotonically over time. Position (x, y) remains perfectly stable; only the orientation quaternion’s z component changes.

Reproduction data (example 1, before a Panther restart)

Sampled orientation.z every 20s, robot fully stationary:

-0.8199164438465193
-0.8243785040318643
-0.8287673412518860
-0.8331439936139190
-0.8374805137112821
-0.8417683472022925
-0.8461119044899703
-0.8503328145010635
-0.8544288145354818
-0.8585038050307093

Consistent, monotonic increase, ~0.004/20s.

Reproduction data (example 2, after restart, recurred later)

0.7681325992355065
0.7635192483793188
0.7589934700487009
0.7544824055507371
(still decreasing...)

Same pattern, opposite direction this time, ~0.0045/20s.

Notes

  • Restarting the Panther (not the whole Jetson, just the robot) appeared to temporarily resolve the issue once (orientation.z stayed within ~0.0005 of baseline over several minutes after restart), but the drift recurred in a later session.

  • No external process is republishing to /panther/initialpose or otherwise interfering (checked via ros2 topic info --verbose, only our own application node publishes there, subscribed only by amcl).

  • This looks like a gyroscope bias/calibration issue rather than a software bug in our own stack, since position stays rock-stable while only orientation drifts.

## Reproduction data (example 2, after restart, recurred a day later)
Same test, robot fully stationary, sampled every 20s:

0.7681325992355065
0.7635192483793188
0.7589934700487009
0.7544824055507371
0.7498738473629565
0.7452258336009627
0.7408654192311477
0.7363918656685432
0.7318642890077869
0.7272233586993572

Consistent, monotonic decrease over 180s, ~0.0045/20s (opposite direction
from example 1, same steady, systematic pattern).

Question

Is there an official gyroscope re-calibration procedure/service for Panther (beyond the automatic one at boot)? Is this a known issue? Any guidance on diagnosing/fixing IMU bias drift would be appreciated.

Hi @emilijas,

Thanks for the detailed report — this is a known limitation of the current hardware/firmware setup, not a bug.

The IMU’s magnetometer can’t be used for absolute yaw correction because it sits close to the drive motors, and the magnetic field from the motors distorts the readings too much to trust. Without a magnetometer, yaw has no absolute reference, so the EKF relies purely on gyroscope integration — and gyro bias (typical for MEMS IMUs, especially without temperature compensation) accumulates over time, including while the robot is standing still.

A few directions we’re considering to address this:

  1. External IMU mounted away from motor interference (with verification that it’s actually clean of magnetic/electrical noise from the drivetrain), fused into the existing EKF as an additional absolute yaw reference.
  2. Periodic small motion (e.g. every few minutes) so localization gets a chance to re-align against the map instead of relying purely on dead-reckoning while stationary.
  3. Zero angular rate update: a node subscribing to odometry and cmd_vel that detects when the robot is stationary and suppresses the orientation update during that time, so gyro bias doesn’t get integrated into yaw while not moving.