dstl / Stone-Soup

A software project to provide the target tracking community with a framework for the development and testing of tracking algorithms.
https://stonesoup.rtfd.io
MIT License
384 stars 126 forks source link

GaussianMixtureInitiator not working with MFAHypothesiser #896

Open Carlson-J opened 7 months ago

Carlson-J commented 7 months ago

I am trying to use the MHT with the new initializer added in https://github.com/dstl/Stone-Soup/pull/873. However, when I try to do so I get the following error

Traceback (most recent call last):
  File "MHT_testing.py", line 109, in <module>
    for time, ctracks in tracker:
  File "~/Stone-Soup/stonesoup/tracker/simple.py", line 323, in __next__
    self._tracks |= self.initiator.initiate(
  File "~/Stone-Soup/stonesoup/initiator/simple.py", line 368, in initiate
    tracks = self.initiator.initiate(detections, timestamp, **kwargs)
  File "~/Stone-Soup/stonesoup/initiator/simple.py", line 211, in initiate
    associations = self.data_associator.associate(
  File "~/Stone-Soup/stonesoup/dataassociator/mfa/__init__.py", line 38, in associate
    self.generate_hypotheses(tracks, detections, timestamp,
  File "~Stone-Soup/stone/soup/dataassociator/base.py", line 26, in generate_hypotheses
    return {track: self.hypothesiser.hypothesise(
  File "~/Stone-Soup/stonesoup/dataassociator/base.py", line 26, in <dictcomp>
    return {track: self.hypothesiser.hypothesise(
  File "~/Stone-Soup/stonesoup/hypothesiser/mfa.py", line 53, in hypothesise
    for component in track.state.components:
AttributeError: 'GaussianStateUpdate' object has no attribute 'components'

Here is the relevant part of the code. Assume I have created some measurements and timestamps beforehand (I use real data which I cannot post here).


    from stonesoup.predictor.kalman import ExtendedKalmanPredictor
    predictor = ExtendedKalmanPredictor(transition_model)

    from stonesoup.updater.kalman import ExtendedKalmanUpdater
    updater = ExtendedKalmanUpdater(measurement_model)

    from stonesoup.dataassociator.mfa import MFADataAssociator
    from stonesoup.hypothesiser.mfa import MFAHypothesiser
    from stonesoup.hypothesiser.probability import PDAHypothesiser

    hypothesiser = PDAHypothesiser(predictor, updater, lambda_, prob_gate=prob_gate, prob_detect=prob_detect)
    hypothesiser = MFAHypothesiser(hypothesiser)
    data_associator = MFADataAssociator(hypothesiser, slide_window=slide_window)

    from stonesoup.deleter.error import CovarianceBasedDeleter
    covariance_limit_for_delete = 2
    deleter = CovarianceBasedDeleter(covar_trace_thresh=covariance_limit_for_delete)

    from stonesoup.types.mixture import GaussianMixture
    from stonesoup.types.state import WeightedGaussianState, TaggedWeightedGaussianState
    s_prior_state = GaussianMixture([WeightedGaussianState([[0], [0], [0], [0], [0], [0]], np.diag([0.5, 0, 0.5, 0, 0.5, 0]))])
    s_prior_state = GaussianMixture([TaggedWeightedGaussianState([[0], [1], [0], [1], [0], [1]],
                                                 np.diag([1.5, 0.5, 1.5, 0.5, 1.5, 0.5]),
                                                 weight=Probability(1), tag=[])])
    min_detections = 3
    from stonesoup.initiator.simple import GaussianMixtureInitiator
    from stonesoup.initiator.simple import MultiMeasurementInitiator

    initiator = GaussianMixtureInitiator(
        MultiMeasurementInitiator(
        prior_state=s_prior_state,
        measurement_model=measurement_model,
        deleter=deleter,
        data_associator=data_associator,
        updater=updater,
        min_points=min_detections
    ))

    from stonesoup.tracker.simple import MultiTargetMixtureTracker

    tracker = MultiTargetMixtureTracker(
        initiator=initiator,
        deleter=deleter,
        detector=zip(timestamps, measurements),
        data_associator=data_associator,
        updater=updater,
    )
    tracks = set()

    for time, ctracks in tracker:
        tracks.update(ctracks)
Carlson-J commented 7 months ago

It seems that the MultiMeasurementInitiator does not work with the MultiTargetMixtureTracker.

I used this instead and it seems to be running without the error.

initiator = GaussianMixtureInitiator(
        SimpleMeasurementInitiator(
        prior_state=s_prior_state,
        measurement_model=measurement_model,
    ))

Is this expected/desired behavior?

sdhiscocks commented 7 months ago

Yeah, this is unfortunately expected behaviour, but not desirable. There is an issue with the multi-measurement initiator which doesn't work well with different mixture types, due to logic based on hard-assignment. A work around is in the initiator, use a hard-assignment data associator with non-MFA hypothesiser (e.g. GNNWith2DAssignment).

A fix would be add mixture/MFA compatible versions of a multi-measurement initiator.

Another more general option would be to make a multi-measurement initiator, which can use any "Tracker" style class, which would offer some flexibility, to then use mixture trackers in it. There is a few complications in implementing this however (possibly blocking iteration call for example, so a thread may be required).

Also, you wont want to use the MultiTargetMixtureTracker with MFA, as you need to use tracking loop similar to that found in the Estimate section of MFA example.

A-acuto commented 5 months ago

Hi both, I saw this open issue because I am, as well, in the middle of creating an example for MHT using MFA components and Stone soup trackers I got stuck in the same problems.

Wrapping up: MFA data associator, as it is now, it can't be used using in the MultiTargetMixtureTracker because of GaussianMixtureUpdates are created, right? Also the MultiMeasurementInitiator cannot be wrapped in GaussianMixtureInitiator, which should be used instantiating tracks for MFA/MHT. I am getting these right?

So the only option available is to loop over the MFA data associations as shown in the example and instantiate the tracks by hand. Is this correct?