-
Notifications
You must be signed in to change notification settings - Fork 131
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
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this 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.
docs/examples/PF_OOSM_example.py
Outdated
# 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# update the distribution while the latter updates only the filtered distribution. | |
# update the distribution, while the latter updates only the filtered distribution. |
docs/examples/PF_OOSM_example.py
Outdated
# | ||
# 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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. |
docs/examples/PF_OOSM_example.py
Outdated
# 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. |
There was a problem hiding this comment.
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?
docs/examples/PF_OOSM_example.py
Outdated
# :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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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 |
docs/examples/PF_OOSM_example.py
Outdated
# 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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 |
docs/examples/PF_OOSM_example.py
Outdated
# 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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. |
docs/examples/PF_OOSM_example.py
Outdated
# 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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. |
# The algorithm is applied only when the detection timestamp (:math:`t_{k}`) is not | ||
# greater than the previous recorded timestamp (:math:`t_{k-1}`). |
There was a problem hiding this comment.
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)
docs/examples/PF_OOSM_example.py
Outdated
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
docs/examples/PF_OOSM_example.py
Outdated
# 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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. |
There was a problem hiding this 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
# 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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
# | ||
# 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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 |
There was a problem hiding this 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!
b393113
to
c2ade1f
Compare
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.