Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding an example showing Particle filter algorithm with OOSM #965

Merged
merged 4 commits into from
Apr 18, 2024

Conversation

A-acuto
Copy link
Contributor

@A-acuto A-acuto commented Mar 1, 2024

This PR adds an example that implements an algorithm [1] that allows to deal with Out-of-sequence measurements (OOSM) while running a particle filter.

The algorithm works by "injecting" the delayed measurement into the particle track history and re-evaluate the particle weights. We compare as well a tracker where we ignore the OOSM and we see that the difference can be significant.

Other papers referenced are [2] and [3].

[1] M. Orton and A. Marrs, 2001, A Bayesian approach to multi-target tracking and data fusion with out-of-sequence measurements, IEE Target Tracking: Algorithms and Applications.
[2] M. Orton and A. Marrs, 2005, Particle filters for tracking with out-of-sequence measurements, IEEE Transactions on Aerospace and Electronic Systems.
[3] S. R. Maskell, R. G. Everitt, R. Wright, M. Briers, 2005, Multi-target out-of-sequence data association: Tracking using graphical models, Information Fusion.

@A-acuto A-acuto requested a review from a team as a code owner March 1, 2024 14:02
@A-acuto A-acuto requested review from jswright-dstl and orosoman-dstl and removed request for a team March 1, 2024 14:02
Copy link

codecov bot commented Mar 1, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 93.52%. Comparing base (10e26e0) to head (dca99c7).
Report is 39 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #965   +/-   ##
=======================================
  Coverage   93.52%   93.52%           
=======================================
  Files         201      201           
  Lines       12835    12835           
  Branches     2629     2629           
=======================================
  Hits        12004    12004           
  Misses        587      587           
  Partials      244      244           
Flag Coverage Δ
integration 66.27% <ø> (ø)
unittests 89.12% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@spike-dstl spike-dstl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see comments on line 25 and line 197. The example would benefit from a better explanation of when the OOSM algorithm is used/not used.

Other than that, just a few grammatical changes.

# case of Particle filters (the algorithm implementation can be found here [#]_).
#
# Particle filters (PF) work in a different manner compared to the Kalman filters because they sequentially
# update the distribution while the latter updates only the filtered distribution.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# update the distribution while the latter updates only the filtered distribution.
# update the distribution, while the latter updates only the filtered distribution.

#
# Particle filters (PF) work in a different manner compared to the Kalman filters because they sequentially
# update the distribution while the latter updates only the filtered distribution.
# In the PF application we have each trajectory, defined as particles, have an associated weight.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# In the PF application we have each trajectory, defined as particles, have an associated weight.
# In the PF application, we have each trajectory defined as a particle, where each have an associated weight.

Comment on lines 25 to 30
# The algorithm presented follows this logic: a measurement arrives at a time :math:`t_{k}`, if
# :math:`t_{k} > t_{k-1}` we apply the stadard particle filter tracking method.
# If :math:`t_{k} < t_{k-1}`, so it is a delayed measurement, then we look
# in the list of measurements where :math:`t_{k}` belongs. In detail, we look for two indices, :math:`a` and
# :math:`b`, such that :math:`t_{a} > t_{k} > t_{b}`. In this manner, we are able to insert the measurement in each
# particle tracjectory history.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph could do with slightly better explanation. You define t_{k}, and then compare it to t_{k-1}. Explanation of what t_{k-1} is denoting would be helpful to understand these comparisons. t_{k-1} would usually be used to denote the previous timestep in the algorithm - in this case, is it being used to denote previous measurement?

# :math:`b`, such that :math:`t_{a} > t_{k} > t_{b}`. In this manner, we are able to insert the measurement in each
# particle tracjectory history.
#
# We have obtained a time location for the new measurement, then we sample the particles from the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# We have obtained a time location for the new measurement, then we sample the particles from the
# We have obtained a time location for the new measurement. We then sample the particles from the

Comment on lines 33 to 34
# state at :math:`t_{b}` with new weights (un-normalised), then we apply the prediction and update steps with the
# delayed measurement :math:`t_{k}`, normalising the particle weights. To finalise the track we
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# state at :math:`t_{b}` with new weights (un-normalised), then we apply the prediction and update steps with the
# delayed measurement :math:`t_{k}`, normalising the particle weights. To finalise the track we
# state at :math:`t_{b}` with new weights (un-normalised), before applying the prediction and update steps with the
# delayed measurement :math:`t_{k}`, normalising the particle weights. To finalise the track, we

Comment on lines 92 to 94
# The detections are stored in scans, which contain also the time of arrival,
# when a delayed measurement appears, the timestamp of arrival will be modified, but not the
# timestamp attached to the measurement.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# The detections are stored in scans, which contain also the time of arrival,
# when a delayed measurement appears, the timestamp of arrival will be modified, but not the
# timestamp attached to the measurement.
# The detections are stored in scans, which contain also the time of arrival.
# When a delayed measurement appears, the timestamp of arrival will be modified, but not the
# timestamp attached to the measurement.

Comment on lines 152 to 154
# resampler we consider :class:`~.ESSResampler`. Then, to initialise the
# tracks we start defining a :class:`~.GaussianState`, we sample
# the particles using a Multivariate Normal distribution around the prior state.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# resampler we consider :class:`~.ESSResampler`. Then, to initialise the
# tracks we start defining a :class:`~.GaussianState`, we sample
# the particles using a Multivariate Normal distribution around the prior state.
# resampler we consider :class:`~.ESSResampler`, which calls :class:`~.SystematicResampler` by default.
# Then, to initialise the tracks, we start defining a :class:`~.GaussianState`. We sample
# the particles using a Multivariate Normal distribution around the prior state.

Comment on lines +197 to +198
# The algorithm is applied only when the detection timestamp (:math:`t_{k}`) is not
# greater than the previous recorded timestamp (:math:`t_{k-1}`).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This explanation would help explain the use of t_{k} and t_{k-1} above. (See comment on line 25)

Comment on lines 298 to 302
plotter.plot_measurements(scans_detections, [0, 2])
plotter.plot_tracks(track, [0, 2], track_label='Track with OOSM',
line= dict(color='blue'))
plotter.plot_tracks(track2, [0, 2], track_label='Track without OOSM')
plotter.fig
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
plotter.plot_measurements(scans_detections, [0, 2])
plotter.plot_tracks(track, [0, 2], track_label='Track with OOSM',
line= dict(color='blue'))
plotter.plot_tracks(track2, [0, 2], track_label='Track without OOSM')
plotter.fig
plotter.plot_measurements(scans_detections, [0, 2])
plotter.plot_tracks(track, [0, 2], track_label='Track dealing with OOSM',
line= dict(color='blue'))
plotter.plot_tracks(track2, [0, 2], track_label='Track ignoring OOSM')
plotter.fig

The track labels here are not easy distinguish between. I think these make it easier to clarify which is which.

Comment on lines 309 to 310
# to have better tracking performances and not discard any information from the sensors, to validate that
# we made a 1-to-1 comparison with a tracker which systematically ignores OOSM.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# to have better tracking performances and not discard any information from the sensors, to validate that
# we made a 1-to-1 comparison with a tracker which systematically ignores OOSM.
# to have better tracking performances and not discard any information from the sensors. To validate that,
# we made a 1-to-1 comparison with a tracker which systematically ignores OOSM.

Copy link
Contributor

@nperree-dstl nperree-dstl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some suggestions to improve structure and readability but otherwise looks good

docs/examples/PF_OOSM_example.py Outdated Show resolved Hide resolved
# delayed measurement :math:`t_{k}`, normalising the particle weights. To finalise the track we
# re-order the existing data such that :math:`t_{n} > t_{m}, \forall (n, m)`.
#
# However, it is important to note that there is the risk of accumulating some disparity over time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# However, it is important to note that there is the risk of accumulating some disparity over time.
# It is important to note that there is the risk of accumulating some disparity over time.

docs/examples/PF_OOSM_example.py Outdated Show resolved Hide resolved
docs/examples/PF_OOSM_example.py Outdated Show resolved Hide resolved
docs/examples/PF_OOSM_example.py Outdated Show resolved Hide resolved
docs/examples/PF_OOSM_example.py Outdated Show resolved Hide resolved
docs/examples/PF_OOSM_example.py Outdated Show resolved Hide resolved
#
# We have a series of measurements that arrive to the detector at different consecutive timesteps,
# :math:`k=0,1,2...`, with detection time defined as :math:`t_{k}`.
# If :math:`t_{k} > t_{k-1}`, meaning :math:`t_{k}` is consecutive to :math:`t_{k-1}`, we apply the stadard
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# If :math:`t_{k} > t_{k-1}`, meaning :math:`t_{k}` is consecutive to :math:`t_{k-1}`, we apply the stadard
# If :math:`t_{k} > t_{k-1}`, meaning :math:`t_{k}` is consecutive to :math:`t_{k-1}`, we apply the standard

Copy link
Contributor

@nperree-dstl nperree-dstl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spotted one last typo but otherwise looks good!

@A-acuto A-acuto requested a review from spike-dstl April 8, 2024 16:00
@sdhiscocks sdhiscocks merged commit 44c693a into dstl:main Apr 18, 2024
10 checks passed
@A-acuto A-acuto deleted the PF_oosm branch May 30, 2024 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants