Stephen Kanti Mahanty

Abyss · Underwater robotics

Underwater navigation

I built this simulation to look at a problem that matters in underwater robotics: knowing where the vehicle is when its sensors are noisy, missing, or just wrong.

Built by Stephen Kanti Mahanty

Survey runSeed 42
—Position RMSE 120-second simulation

So I combine four sensor streams to estimate position and velocity, then compare that estimate with the simulated path.

120sMission length
10HzFilter updates
4Sensor streams

Mission replay

Simulated data · Repeatable results
ABYSS/ AUV—01
Loading
Coordinates in metersSeafloor survey
Extended Kalman filter
AUV—01 Estimated position
East / North / Depth
Fused trajectory Ground truthDrag to orbit · Scroll to zoom
026.0 / 120.0 s

I keep the true path separate from the estimator so I can check how well it works. The filter receives only sensor data. The ellipsoid shows its model-based 95% joint position uncertainty.

Sensor traces

Move over a chart to inspect the replay

Position error

Meters
Gated EKF Ungated EKF—

Depth profile

Meters · Depth increases downward
Estimate Reference—

Simulation results

3D position RMSE over the full mission
Multipath test—×

Rejecting reflected ranges

I compare the same sensor packets with and without statistical outlier rejection.

View this scenario ↗
120-second simulated missions / seed 42
ConditionsGated EKFUngated EKFInertial only
Computing mission results…

I use identical data for each comparison, and your browser computes the results. The inertial-only estimate integrates acceleration with a fixed sensor bias, so its error builds over time. Simulation results, not deployed vehicle measurements.

How the filter works

Read the numerical core ↗
↗Inertial acceleration10 Hz · Global frame
≋Doppler velocity2 Hz · Three axes
◉Acoustic ranging1 Hz · Four beacons
↓Pressure depth5 Hz · Depth reading
Extended Kalman filter6×6[ x y z vₓ vᵧ v_z ]Predict → Check → Update
013D position & velocity

The sensors report at different times, so I update the navigation state as each reading arrives.

02Covariance & diagnostics

I track the uncertainty and rejected readings alongside the estimate so I can see how it responds.

Updating covariance

Each correction changes the covariance as well as the position estimate. I use Joseph form to preserve its structure after each scalar measurement.

Acoustic ranges

The beacons report distance, while the filter estimates coordinates. So I linearize that distance at the predicted position and apply each reading at its sensor's cadence.

Checking the results

I wanted the comparison to reflect the filter itself. Every version receives the same seeded observations, and you can export each mission step to check the results.

Model specification & references

120 s mission; 0.1 s propagation; six states in east/north/depth coordinates. Continuous white acceleration with spectral density q = 0.02 m²/s³. Acoustic σ = 0.5 m; pressure σ = 0.08 m; Doppler σ = 0.045 m/s. Scalar normalized innovation squared above 9 is rejected. The 95% ellipsoid uses the three-dimensional χ² threshold 7.8147 and the full position covariance eigensystem.

Known attitude and global-frame inertial acceleration are assumed. IMU noise has σ = 0.025 m/s² and fixed bias [0.006, −0.004, 0.0015] m/s². Orientation and sensor bias are not estimated. Beacon positions are known, noise streams are independent, and updates have no latency. Cross-current changes actual acceleration and is observed by the inertial sensor. The vehicle and seabed are procedural; this is a portfolio simulation inspired by underwater robotics.

Welch & Bishop / Kalman filtering · Three.js · uPlot · Motion

Other projects

About me ↗Explore more projects ↗