Skip to content

Divide IMU derivatives by the real sample interval, not one frame's deltaTime - #215

Open
hijimasa wants to merge 1 commit into
Field-Robotics-Japan:masterfrom
hijimasa:fix/ImuDerivativesUseRealElapsedTime
Open

Divide IMU derivatives by the real sample interval, not one frame's deltaTime#215
hijimasa wants to merge 1 commit into
Field-Robotics-Japan:masterfrom
hijimasa:fix/ImuDerivativesUseRealElapsedTime

Conversation

@hijimasa

Copy link
Copy Markdown
Contributor

Fixes #156

Symptom

With the Frequency parameter set to 100 Hz or more, the reported
velocity and angular velocity become larger than the true values and
unstable.

Root cause

UpdateSensorOnce() differentiates position and rotation across the
whole interval since the previous sensor update, but divides by a
single frame's Time.deltaTime (the //FIXME in the code marks the
spot). The two only agree when the sensor happens to update exactly
once per frame:

  • Frequency at or above the frame rate (this issue's condition): the
    scheduler spaces samples one-to-two frames apart, so the readings
    jitter between 1× and 2× the true value.
  • Frequency below the frame rate: every sample spans several frames,
    and all derivatives come out scaled by (sample spacing / frame time).
    Measured on a robot simulator, a 20 Hz IMU rendered at 30 FPS
    reported ~2× the true angular velocity.

Fix

Record the time of the previous update in the until-now unused
_time_last field and divide by that real elapsed time. The first
update, and any degenerate non-positive interval, falls back to
Time.deltaTime.

Note the effective sample rate is still capped by the frame rate; this
change guarantees the values are correct at whatever spacing the
scheduler actually achieves.

Tests (PlayMode: Tests/Runtime/ImuDerivativeTimingTests.cs)

An IMU set to 4 Hz — so every sample necessarily spans several frames —
is attached to a GameObject rotating / translating at a known constant
rate, and the median of the reported magnitudes must land within ±30 %
of the truth (updates are detected via the public sensor.time).

Test Before fix After fix
AngularVelocity_MatchesConstantRotationRate (constant 30 deg/s) Fail (several × too large) Pass
Velocity_MatchesConstantSpeed (constant 0.8 m/s) Fail Pass

Verified with the Unity Test Runner (6000.3.21f1, batchmode, PlayMode):
2/2 pass with the fix, 2/2 fail with the old dt = Time.deltaTime.

Note

Independent of the #155 fix (full-turn angular velocity spike): both
touch the same method but on disjoint lines, and the branches merge
cleanly in either order.

Fixes the unstable, too-large velocity and angular velocity readings
reported in Field-Robotics-Japan#156 (Frequency set to
100 Hz or more).

UpdateSensorOnce differentiates position and rotation across the whole
interval since the previous sensor update, but divided by a single
frame's Time.deltaTime. The two only agree when the sensor happens to
update exactly once per frame; whenever the actual sample spacing is
longer -- several frames at low frame rates, or one-to-two frames
jittering with the scheduler when the requested frequency is at or
above the frame rate -- every derivative comes out scaled by
(actual sample spacing / frame time). That is exactly the reported
symptom: values larger than reality and fluctuating, getting worse as
the Frequency setting rises past the frame rate. Measured on a robot
simulator: a 20 Hz IMU rendered at 30 FPS reported ~2x the true
angular velocity.

Track the time of the previous update (the until-now unused _time_last)
and divide by that real elapsed time. The first update falls back to
Time.deltaTime, as does a degenerate non-positive interval. Note the
effective sample rate is still capped by the frame rate; this change
makes the reported values correct at whatever spacing the scheduler
actually achieves.

ImuDerivativeTimingTests (play mode) drives a 4 Hz sensor -- so every
sample spans several frames -- on an object rotating and translating
at known constant rates, and asserts the reported magnitudes match the
truth; before the fix they read several times too large.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

[IMU]Frequencyを上げると値が不安定になる

1 participant