poser_mpfit: skip non-finite optical angles instead of passing to solver#353
Open
rocketmark wants to merge 1 commit intocollabora:masterfrom
Open
poser_mpfit: skip non-finite optical angles instead of passing to solver#353rocketmark wants to merge 1 commit intocollabora:masterfrom
rocketmark wants to merge 1 commit intocollabora:masterfrom
Conversation
Corrupt optical angles (bad FPGA timestamps during USB disturbances) can reach construct_input_from_scene() as NaN or Inf. Passing a non-finite value into the MPFIT solver causes it to produce a garbage pose which then assert-crashes downstream (observed as assert(!isnan(lhs[lh].Rot[0]))). Add an isfinite() check before emplacing each measurement. Non-finite angles are skipped with a one-time stderr warning. One dropped measurement has negligible effect on the pose solve; crashing does not. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8b5e22c to
a9d9441
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
construct_input_from_sceneinposer_mpfit.cfeeds optical angles directly into the MPFIT solver without checking for non-finite values. When corrupt optical angle data reaches this function, the solver receives NaN or Inf as input, produces a garbage pose, and assert-crashes downstream (assert(!isnan(lhs[lh].Rot[0]))).Dropping one non-finite measurement has negligible effect on the pose solve. Crashing does not.
Demonstration
Hardware trigger: a USB disturbance (cable flex, port brown-out) causes the FPGA to emit bad timestamps. The driver produces a non-finite optical angle. That angle propagates into
construct_input_from_scene→ MPFIT solver:BEFORE fix:
a[axis] = NaN
meas->light.value = NaN ← passed directly to solver
MPFIT: produces garbage pose rotation
assert(!isnan(lhs[lh].Rot[0])) → fires
Process: SIGABRT
Result: crash, tracking lost
AFTER fix:
a[axis] = NaN
isfinite(NaN) == false → measurement skipped, continue
stderr: "[libsurvive WARN] poser_mpfit: NaN optical angle sensor N lh N axis N; suppressing further"
Process: continues normally
Result: one measurement dropped, pose solve unaffected
The missing check was presumably an oversight — the angles array is treated as valid whenever
isReadingValueis true, butisReadingValueonly checks the timestamp, not the angle value itself.Impact
Any hardware that experiences USB instability is exposed. The FPGA timestamp corruption that produces non-finite angles is triggered by cable flex or port brown-out — common on embedded deployments with moving hardware. The crash is not recoverable without a process restart.
Change
One file,
src/poser_mpfit.c. Anisfinite()check is added before emplacing each measurement inconstruct_input_from_scene. Non-finite angles are skipped with a one-time stderr warning (to avoid log spam). The measurement count and solver input are otherwise unchanged.Found via
Observed in production: tracker running on embedded hardware (Raspberry Pi, USB bus under load) would crash with
assert(!isnan(lhs[lh].Rot[0]))after a cable disturbance. Backtrace confirmed the NaN originated from a corrupted optical angle passed throughconstruct_input_from_scenewithout validation.