Skip to content

Reuse the covariance ellipse helper in all localizers - #137

Open
dchaudhari7177 wants to merge 1 commit into
ShisatoYano:mainfrom
dchaudhari7177:refactor/124-covariance-ellipse-helper
Open

dchaudhari7177 wants to merge 1 commit into
ShisatoYano:mainfrom
dchaudhari7177:refactor/124-covariance-ellipse-helper

Conversation

@dchaudhari7177

@dchaudhari7177 dchaudhari7177 commented Oct 4, 2026 •

Copy link
Copy Markdown

Closes #124

Overview

The EKF, UKF and particle filter localizers each computed and drew their error ellipse by hand. They now call draw_covariance_ellipse() from plot_lib.py, and the helper is tidied as the issue asks:

  • np.linalg.eigh instead of eig: a covariance matrix is symmetric, so the eigenvalues are real and come back sorted, which removes the big/small index juggling. Eigenvalues that rounding pushes slightly below zero are clipped to 0.
  • The points are computed with numpy (a * np.cos(t), b * np.sin(t)) instead of list comprehensions.
  • The scale factor 3.0 is explained in a comment. The ellipse is the set where the squared Mahalanobis distance from the centre is 3: its half-axes are √3 standard deviations, and it contains 1 − e^(−3/2) ≈ 78 % of a 2D Gaussian. The particle filter's old comment called it a "3-sigma ellipse (99.7% confidence)", which it isn't, so that comment is gone.
  • Extra keyword arguments go through to axes.plot, so the particle filter keeps its linewidth=1.5. Colour is passed by keyword now. ndt_map.py, the existing user, is unaffected.

One behaviour fix comes with it. The EKF ran eig on its whole 4×4 state covariance and used the first two eigenpairs, so yaw and speed variances (and their correlation with x and y) leaked into the position ellipse. The UKF and the particle filter already used the x-y block; all three now pass cov_mat[:2, :2]. With an x-y block rotated by 30° plus some x–yaw correlation, the old EKF ellipse put its points at squared Mahalanobis distances from 6.6 to 132 instead of 3.

The now-unused XYArray and math imports are removed from the three localizers.

How I confirmed it works

New test/test_plot_lib.py:

  • the drawn points lie at squared Mahalanobis distance 3 for a rotated covariance;
  • plot keyword arguments (color, linewidth) reach axes.plot;
  • a rank-1 covariance draws a finite line along its axis;
  • the EKF draws the ellipse of its x-y block (this one fails on main).

Three of the four fail on main: the EKF one, and the two that read color from the plot keyword arguments, which main passes positionally. All four pass here. The localization simulations still run: test_ekf_localization_path_tracking, test_ukf_localization_path_tracking, test_pf_localization_path_tracking, test_ekf_vs_ukf_comparison, test_ekf_ukf_pf_comparison and test_ndt_map_construction all pass.

I didn't update the demo GIFs. I regenerated the EKF localization GIF on main and on this branch: at the demo's zoom the ellipse is a few pixels either way, and frames from the two only differ in the random sensor noise. The committed GIF predates other changes on main (it has no course line, for example), so regenerating it here would mostly show those.

The EKF, UKF and particle filter localizers each computed and drew their
error ellipse by hand. Use draw_covariance_ellipse() instead, and in the
helper use eigh (covariance matrices are symmetric), compute the points with
numpy, pass extra plot options through, and explain the scale factor 3.0.

The EKF used to run eig on its whole 4x4 state covariance, so yaw and speed
terms leaked into the position ellipse; it now draws the x-y block like the
UKF and the particle filter.

Closes ShisatoYano#124
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.

Reuse the covariance ellipse helper in all localizers

1 participant