Fix UKF negative variance issue (#133)#134
Conversation
The standard UKF covariance update P = P - K*S*K' is numerically unstable and can produce negative eigenvalues due to floating-point rounding errors, causing the health monitor to fail with "Negative variance on diagonal" errors. This fix adds gentle diagonal regularization (eps = 1e-9) after the covariance update to prevent negative eigenvalues without drastically affecting filter behavior. The approach uses symmetrize() followed by small diagonal additions, which is more stable than aggressive eigenvalue flooring that can cause filter divergence. Fixes #133 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Summary of ChangesHello @jbrodovsky, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the robustness and numerical stability of the Unscented Kalman Filter (UKF) implementation. By introducing a gentle regularization technique during the covariance update, it effectively prevents the occurrence of negative variance values, which were previously causing test failures and could lead to filter instability. The change ensures the filter maintains a positive semi-definite covariance matrix, crucial for accurate state estimation. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request addresses a numerical instability issue in the Unscented Kalman Filter's covariance update by introducing diagonal regularization. The approach is sound and correctly fixes the problem of negative variance. The code change is clear and well-targeted. I have one suggestion to improve the implementation by using a named constant for the regularization value and a more idiomatic nalgebra function to modify the matrix, which will improve readability and maintainability.
| let eps = 1e-9; | ||
| for i in 0..self.state_size { | ||
| self.covariance[(i, i)] += eps; | ||
| } |
There was a problem hiding this comment.
The value 1e-9 is a magic number. It's better to define it as a constant with a descriptive name (e.g., COVARIANCE_REGULARIZATION) to improve readability and maintainability. This makes the purpose of the value explicit and easier to change if needed.
Additionally, the loop for adding the regularization term to the diagonal can be expressed more idiomatically and potentially more efficiently using nalgebra's diagonal_mut() and add_scalar_mut() methods.
const COVARIANCE_REGULARIZATION: f64 = 1e-9;
self.covariance.diagonal_mut().add_scalar_mut(COVARIANCE_REGULARIZATION);
Summary
Fixes #133 - UKF test failure due to negative variance on diagonal
Problem
The
test_ukf_with_degraded_gnssintegration test was failing with the error:The root cause is that the standard UKF covariance update formula
P = P - K*S*K'is numerically unstable and can produce negative eigenvalues due to floating-point rounding errors.Solution
Added gentle diagonal regularization in the UKF update step (
kalman.rs:303-309):symmetrize()for robust covariance symmetrizationeps = 1e-9) to prevent negative eigenvaluesThis approach is more stable than aggressive eigenvalue flooring, which can cause the filter to become overconfident and diverge.
Test plan
test_ukf_with_degraded_gnssnow passes🤖 Generated with Claude Code