Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

NavState Autonomous Surface Vessel IMU EKF

This notebook rewrites parts of NavStateImuExample to make it work with the data found in gazebo_data.csv

This tutorial shows how to use GTSAM’s NavState-specific EKF (NavStateImuEKF) with synthetic IMU data and occasional position measurements. You’ll learn:

  • How the predict step integrates IMU into a NavState increment and propagates covariance.

  • How to write a position measurement in the EKF’s local coordinates (the correct H = [0, R, 0]).

  • How to interpret the results with ±2σ uncertainty bands for yaw/pitch/roll, velocity, and position.

We simulate a simple motion and run the EKF end-to-end, then visualize estimates vs. ground truth along with uncertainty.

Authors: Derek Benham & Frank Dellaert

Open In Colab
Source

Background and setup

State: NavState X = (R, p, v) with rotation R ∈ SO(3), position p ∈ R^3, velocity v ∈ R^3.

  • EKF local coordinates are [δθ, δp_body, δv_body], i.e., position/velocity increments are expressed in the body frame.

  • For a world-position measurement z ≈ p_world, the linearized measurement Jacobian is H = [0, R, 0].

We’ll now define a simple scenario that provides ground truth and noise-free IMU to drive the predict step.

Source
Number of IMU measurements: 988
Number of time steps (N): 988
Shape of position ground truth: (989, 3)
Shape of velocity ground truth: (989, 3)
Shape of yaw/pitch/roll ground truth: (989, 3)
Min/Max delta t: 0.01000 -> 0.03000
Initial NavState: ypr (deg) = [-176.68, -0.56, 0.14], pos = [220.43, -1.49, 0.03], vel = [-2.04, -0.14, 0.26]

Simulation issues

It appears that my simulation data is not perfect and that there are some dropped messages. See the chart below for all occurrences of time steps that are greater than 0.01

Source
Loading...
Indices of deltas greater than 0.01: [221 391 512 513 514 648]
The maximum delta between consecutive timestamps is: 0.03000000000000025

Create Parameters

Run the EKF

We integrate IMU in the predict step and occasionally update with a position measurement. The position Jacobian must be H = [0, R, 0] because EKF local coordinates use body-frame increments for p and v.

Plot Yaw/Pitch/Roll (degrees)

We show estimated angles with ±2σ bands and dashed ground truth. Ideally, the truth lies mostly within the shaded bands if covariances are well tuned.

Source
Loading...

Plot Velocity (m/s)

Velocity often benefits from frequent updates (e.g., GPS Doppler). Here we only have occasional position updates; expect velocity uncertainty to grow between updates and shrink slightly after them.

Source
Loading...

Plot Position (m)

Position updates should pull the estimate toward truth and reduce the ±2σ band. If divergence occurs, check:

  • H matches EKF local coords ([0, R, 0] for world-position).

  • Measurement noise R reflects your sensor.

  • Process noise (IMU) is not overconfident.

Source
Loading...

Conclusion

This notebook demonstrated the use of GTSAM’s NavStateImuEKF for fusing IMU and position measurements in an autonomous surface vessel scenario. We visualized the EKF’s estimates and uncertainty for orientation, velocity, and position, comparing them to ground truth. The results show that the EKF tracks the true state well, with uncertainty growing between updates and shrinking after position corrections. Careful tuning of process and measurement noise is essential for reliable performance. This workflow provides a foundation for integrating additional sensors and handling real-world data imperfections.