Skip to content

Add datasheet noise density settings for the IMU - #15

Merged
JaidenAGrimminck merged 2 commits into
mainfrom
imu-noise-density
Oct 16, 2026
Merged

JaidenAGrimminck merged 2 commits into
mainfrom
imu-noise-density

Conversation

@clmazzac

Copy link
Copy Markdown
Member

Problem

IMU white noise was a fixed standard deviation per sample (angularVelocityStdDev, linearAccelerationStdDev), whatever the rate. A real sensor is specified by noise density. Its per-sample noise grows with sample rate, and noise averaged over a fixed time does not change.

In the sim, raising the IMU from 100 Hz to 400 Hz kept 0.002 rad/s per sample, so the noise left after averaging halved. The simulated IMU got better at higher rates. A filter tuned from a datasheet would get the wrong noise level at any rate other than the one the per-sample values were picked for.

Change

  • New optional calibration settings angularVelocityNoiseDensity (rad/s/√Hz) and linearAccelerationNoiseDensity (m/s²/√Hz). Each is one number for all three axes.
  • With a density, each sample uses σ = density / √Δt. Δt is the time since the previous capture, so σ follows the actual capture rate after fixed-step rounding. The message covariance uses the same σ.
  • Without a density, the per-sample settings apply as before. Saved and default runs do not change.
  • The Config page shows both densities under the IMU advanced fields. The per-sample fields are relabelled as the fallback.
  • docs/run-manifests.md explains the model and gives conversions from datasheet units (°/s/√Hz, °/√h, µg/√Hz, m/s/√h).

Why the default run is unchanged

Setting densities on the default run would change its hash. That breaks the pinned golden in VIS-02 explicit-camera v11 identity vectors (tests/render-scene-provider.test.js). Making densities the default is a separate decision that needs that fixture regenerated. 0.0002 rad/s/√Hz and 0.002 m/s²/√Hz reproduce the current defaults exactly at 100 Hz.

Tests

Live sim, car parked, 2.5 ms step, about 20 s of sim time per run, IMU read back from the recorded SFLog. Units: rad/s for the gyro, m/s² for the accelerometer.

Run Gyro per sample Reported σ Gyro 0.1 s avg Accel 0.1 s avg
Density, 100 Hz 0.00195 0.00200 6.1e-4 6.6e-3
Density, 400 Hz 0.00402 0.00400 6.2e-4 5.8e-3
Per-sample, 100 Hz 0.00196 0.00200 6.1e-4 6.6e-3
Per-sample, 400 Hz 0.00201 0.00200 3.1e-4 2.9e-3
  • With densities, the 0.1 s averages match the predicted 6.3e-4 and 6.3e-3 at both rates.
  • At 100 Hz the density and per-sample runs give identical values.
  • Lag-1 autocorrelation of the gyro is about 0, so samples stay white.
  • npm test on a clean checkout: 1964 pass, 6 skipped, 1 fail. The failure is Python decodes retained RGB, depth, and CameraInfo SFLog messages, which also fails on main.
  • No unit test is added in this PR.

Noticed while testing, not changed here

The recorded logs are missing IMU messages. Only about half of the 0.1 s windows in each run had every sample. The averages above use complete windows only.

🤖 Generated with Claude Code

clmazzac and others added 2 commits October 15, 2026 19:04
IMU white noise was a fixed standard deviation per sample. A real sensor
is specified by noise density, so per-sample noise grows with sample rate
and noise averaged over a fixed time does not. In the sim, raising the
IMU from 100 Hz to 400 Hz halved the noise left after a 1 s average.

New optional settings angularVelocityNoiseDensity (rad/s/√Hz) and
linearAccelerationNoiseDensity (m/s²/√Hz) each take one number for all
axes. When set, each sample uses sigma = density / √dt, with dt the time
since the previous capture. The reported covariance uses the same sigma.
Without a density, the per-sample settings apply as before, so existing
and default runs do not change.

The Config page shows both densities. docs/run-manifests.md gives
datasheet unit conversions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JaidenAGrimminck
JaidenAGrimminck merged commit 113eef8 into main Oct 16, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants