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

Comparing Multiple Trackers On Manoeuvring Targets, adding Kalman Filter, AttributeError: 'CartesianToBearingRange' object has no attribute 'matrix' #911

Open apiszcz opened 6 months ago

apiszcz commented 6 months ago

The example Comparing Multiple Trackers On Manoeuvring Targets is a great reference for learning and evaluation.

When I try to add Kalman Filter at the cell with "Now we run the trackers and store in sets for plotting:". The following error is generated. All prior cells added the hypothesor, updaters, data_associator for the KF.

KF addition:

kalman_tracker_KF = MultiTargetTracker(  # Runs the tracker
    initiator=initiator_KF,
    deleter=deleter,
    detector=detectors[4],
    data_associator=data_associator_KF,
    updater=updater_KF,
)

tracks_KF = set()
for step, (time, current_tracks) in enumerate(kalman_tracker_KF, 1):
    tracks_KF.update(current_tracks)

The following stack trace

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[102], line 13
      4 kalman_tracker_KF = MultiTargetTracker(  # Runs the tracker
      5     initiator=initiator_KF,
      6     deleter=deleter,
   (...)
      9     updater=updater_KF,
     10 )
     12 tracks_KF = set()
---> 13 for step, (time, current_tracks) in enumerate(kalman_tracker_KF, 1):
     14     tracks_KF.update(current_tracks)
     17 # #######################################################################

File test\lib\_venvwin\Lib\site-packages\stonesoup\tracker\simple.py:228, in MultiTargetTracker.__next__(self)
    225         track.append(hypothesis.prediction)
    227 self._tracks -= self.deleter.delete_tracks(self.tracks)
--> 228 self._tracks |= self.initiator.initiate(
    229     detections - associated_detections, time)
    231 return time, self.tracks

File test\lib\_venvwin\Lib\site-packages\stonesoup\initiator\simple.py:200, in MultiMeasurementInitiator.initiate(self, detections, timestamp, **kwargs)
    197 associated_detections = set()
    199 if self.holding_tracks:
--> 200     associations = self.data_associator.associate(
    201         self.holding_tracks, detections, timestamp)
    203     for track, hypothesis in associations.items():
    204         if hypothesis:

File test\lib\_venvwin\Lib\site-packages\stonesoup\dataassociator\neighbour.py:167, in GNNWith2DAssignment.associate(self, tracks, detections, timestamp, **kwargs)
    149 """Associate a set of detections with predicted states.
    150 
    151 Parameters
   (...)
    163     Key value pair of tracks with associated detection
    164 """
    166 # Generate a set of hypotheses for each track on each detection
--> 167 hypotheses = self.generate_hypotheses(tracks, detections, timestamp, **kwargs)
    169 # Create dictionary for associations
    170 associations = {}

File test\lib\_venvwin\Lib\site-packages\stonesoup\dataassociator\base.py:25, in DataAssociator.generate_hypotheses(self, tracks, detections, timestamp, **kwargs)
     24 def generate_hypotheses(self, tracks, detections, timestamp, **kwargs):
---> 25     return {track: self.hypothesiser.hypothesise(
     26                 track, detections, timestamp, **kwargs)
     27             for track in tracks}

File test\lib\_venvwin\Lib\site-packages\stonesoup\dataassociator\base.py:25, in <dictcomp>(.0)
     24 def generate_hypotheses(self, tracks, detections, timestamp, **kwargs):
---> 25     return {track: self.hypothesiser.hypothesise(
     26                 track, detections, timestamp, **kwargs)
     27             for track in tracks}

File test\lib\_venvwin\Lib\site-packages\stonesoup\hypothesiser\distance.py:75, in DistanceHypothesiser.hypothesise(self, track, detections, timestamp, **kwargs)
     71 prediction = self.predictor.predict(
     72     track, timestamp=detection.timestamp, **kwargs)
     74 # Compute measurement prediction and distance measure
---> 75 measurement_prediction = self.updater.predict_measurement(
     76     prediction, detection.measurement_model, **kwargs)
     77 distance = self.measure(measurement_prediction, detection)
     79 if self.include_all or distance < self.missed_distance:
     80     # True detection hypothesis

File test\lib\_venvwin\Lib\site-packages\stonesoup\updater\kalman.py:219, in KalmanUpdater.predict_measurement(self, predicted_state, measurement_model, **kwargs)
    215 measurement_model = self._check_measurement_model(measurement_model)
    217 pred_meas = measurement_model.function(predicted_state, **kwargs)
--> 219 hh = self._measurement_matrix(predicted_state=predicted_state,
    220                               measurement_model=measurement_model,
    221                               **kwargs)
    223 # The measurement cross covariance and innovation covariance
    224 meas_cross_cov = self._measurement_cross_covariance(predicted_state, hh)

File test\lib\_venvwin\Lib\site-packages\stonesoup\updater\kalman.py:96, in KalmanUpdater._measurement_matrix(self, predicted_state, measurement_model, **kwargs)
     74 def _measurement_matrix(self, predicted_state=None, measurement_model=None,
     75                         **kwargs):
     76     r"""This is straightforward Kalman so just get the Matrix from the
     77     measurement model.
     78 
   (...)
     93 
     94     """
     95     return self._check_measurement_model(
---> 96         measurement_model).matrix(**kwargs)

AttributeError: 'CartesianToBearingRange' object has no attribute 'matrix'
jswright-dstl commented 6 months ago

The Comparing Multiple Trackers On Manoeuvring Targets example has detections from a Bearing Range sensor so the measurements in the example are non linear (i.e., a non linear measurement model is used to transform between measurement space and state space). The standard Kalman filter expects the measurements to be linear (i.e., a linear measurement model). The Kalman filter variants for dealing with non linear measurement models are the extended Kalman filter and the unscented Kalman filter which are two of the filters compared in the example.

If you want to use a Kalman filter, a sensor with a linear measurement model will have to be used which will give detections in, for example, x and y, rather than bearing and range.

apiszcz commented 6 months ago

Thank you, will review source and documentation for cartesian approach.