# trackerPHD

Multi-sensor, multi-object PHD tracker

## Description

The `trackerPHD` System object™ is a tracker capable of processing detections of multiple targets from multiple sensors. The tracker uses a multi-target probability hypothesis density (PHD) filter to estimate the states of point targets and extended objects. PHD is a function defined over the state-space of the tracking system, and its value at a state is defined as the expected number of targets per unit state-space volume. The PHD is represented by a weighted summation (mixture) of probability density functions, and peaks in the PHD correspond to possible targets. For an overview of how the tracker functions, see Algorithms.

By default, the `trackerPHD` can track extended objects using the `ggiwphd` filter, which models detections from an extended object as a parse points cloud. You can also use `trackerPHD` with the `gmphd` filters, which tracks point targets and extended objects with designated shapes. Inputs to the tracker are detection reports generated by `objectDetection`, `radarSensor`, `monostaticRadarSensor`, `irSensor`, or `sonarSensor` objects. The tracker outputs all maintained tracks and their analysis information.

To track targets using this object:

1. Create the `trackerPHD` object and set its properties.

2. Call the object with arguments, as if it were a function.

## Creation

### Syntax

``tracker = trackerPHD``
``tracker = trackerPHD(Name,Value)``

### Description

````tracker = trackerPHD` creates a `trackerPHD` System object with default property values.```

example

````tracker = trackerPHD(Name,Value)` sets properties for the tracker using one or more name-value pairs. For example, `trackerPHD('MaxNumTracks',100)` creates a PHD tracker that allows a maximum of 100 tracks. Enclose each property name in quotes.```

## Properties

expand all

Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and the `release` function unlocks them.

If a property is tunable, you can change its value at any time.

Unique tracker identifier, specified as a nonnegative integer. This property is used as the `SourceIndex` in the tracker outputs, and distinguishes tracks that come from different trackers in a multiple-tracker system. You must specify this property as a positive integer to use the track outputs as inputs to a track fuser.

Example: `1`

Configuration of tracking sensors, specified as a cell array of `trackingSensorConfiguration` objects. This property provides the tracking sensor configuration information, such as sensor detection limits and sensor resolution, to the tracker. Note that there are no default values for the `SensorConfigurations` property, and you must specify the `SensorConfigurations` property before using the tracker. However, you can update the configuration by setting the `HasSensorConfigurationsInput` property to `true` and specifying the configuration input, `config`. If you set the `MaxDetsPerObject` property of the `trackingSensorConfiguration` object to 1, the tracker creates only one partition, such that at most one detection can be assigned to each target.

Function to partition detections into detection cells, specified as a function handle or as a character vector. When each sensor can report more than one detection per object, a partition function is required. The partition function reports all possible partitions of the detections from a sensor. In each partition, the detections are separated into mutually exclusive detection cells, assuming that each detection cell belongs to one extended object.

You can also specify your own detections partition function. For guidance in writing this function, you can examine the details of the default partitioning function, `partitionDetections`, using the `type` command as:

`type partitionDetections`

Example: `@myfunction` or `'myfunction'`

Data Types: `function_handle` | `char`

Birth rate of new targets in the density, specified as a scalar. Birth rate indicates the expected number of targets added in the density per unit time. The birth density is created by using the `FilterInitializationFcn` of the `trackingSensorConfiguration` used with the tracker. In general, the tracker adds components to the density function in two ways:

1. Predictive birth density – density initialized by `FilterInitializationFcn` function when called with no inputs.

2. Adaptive birth density – density initialized by `FilterInitializationFcn` function when called with detections inputs. The detections are chosen by the tracker based on their log-likelihood of association with the current estimates of the targets.

Note that the value for the `BirthRate` property represents the summation of both predictive birth density and adaptive birth density for each time step.

Example: `0.01`

Data Types: `single` | `double`

Death rate of components in the density, specified as a scalar. Death rate indicates the rate at which a component vanishes in the density after one time step. Death rate relates to the survival probability (Ps) of a component between successive time steps by

`${P}_{\text{s}}={\left(1-\text{DeathRate}\right)}^{\Delta T}$`

where ΔT is the time step.

Example: `1e-4`

Data Types: `single` | `double`

Threshold of selecting detections for component initialization, specified as a positive scalar. During correction, the tracker calculates the likelihood of association between existing tracks and detection cells. If the association likelihood (given by negative log-likelihood) of a detection cell to all existing tracks is higher than the threshold (which means the detection cell has low likelihood of association to existing tracks), the detection cell is used to initialize new components in the adaptive birth density.

Example: `18.1`

Data Types: `single` | `double`

Threshold for initializing a tentative track, specified as a scalar. If the weight of a component is higher than the threshold specified by the `ExtractionThreshold` property, the component is labeled as a `'Tentative'` track and given a `TrackID`.

Example: `0.45`

Data Types: `single` | `double`

Threshold for track confirmation, specified as a scalar. In a `trackerPHD` object, a track can have multiple components sharing the same `TrackID`. If the weight summation of a tentative track's components is higher than the threshold specified by the `ConfirmationThreshold` property, the track's status is marked as `'Confirmed'`.

Example: `0.85`

Data Types: `single` | `double`

Threshold for component deletion, specified as a scalar. In the PHD tracker, if the weight of a component is lower than the value specified by the `DeletionThreshold` property, the component is deleted.

Example: `0.01`

Data Types: `single` | `double`

Threshold for components merging, specified as a real positive scalar. In the PHD tracker, if the Kullback-Leibler distance between components with the same `TrackID` is smaller than the value specified by the `MergingThreshold` property, then these components are merged into one component. The merged weight of the new component is equal to the summation of the weights of the pre-merged components. Moreover, if the merged weight is higher than the first threshold specified in the `LabelingThresholds` property, the merged weight is truncated to the first threshold. Note that components with `TrackID` equal to `0` can also be merged with each other.

Example: 30

Data Types: `single` | `double`

Labeling thresholds, specified as an 1-by-3 vector of decreasing positive values, [C1, C2, C3]. Based on the `LabelingThresholds` property, the tracker manages components in the density using these rules:

1. The weight of any component that is higher than the first threshold C1 is reduced to C1.

2. For all components with the same `TrackID`, if the largest weight among these components is greater than C2, then the component with the largest weight is preserved to retain the `TrackID`, while all other components are deleted.

3. For all components with the same `TrackID`, if the ratio of the largest weight to the weight summation of all these components is greater than C3, then the component with the largest weight is preserved to retain the `TrackID`, while all other components are deleted.

4. If neither condition 2 nor condition 3 is satisfied, then the component with the largest weight retains the `TrackID`, while the labels of all other components are set to 0. When this occurs, it essentially means that some components may represent other objects. This treatment keeps the possibility for these unreserved components to be extracted again in the future.

Data Types: `single` | `double`

Enable updating sensor configurations with time, specified as `false` or `true`. Set this property to `true` if you want the configurations of the sensor updated with time. Also, when this property is set to `true`, the tracker must be called with the configuration input, `config`, as shown in the usage syntax.

Data Types: `logical`

Parameters of the track state reference frame, specified as a struct or a struct array. Use this property to define the track state reference frame and how to transform the track from the tracker (called source) coordinate system to the fuser coordinate system.

This property is tunable.

Data Types: `struct`

Number of tracks maintained by the tracker, returned as a nonnegative integer.

Data Types: `double`

Number of confirmed tracks, returned as a nonnegative integer. If the `IsConfirmed` field of an output track structure is `true`, the track is confirmed.

Data Types: `double`

Maximum number of sensors that can be connected to the tracker, specified as a positive integer. `MaxNumSensors` must be greater than or equal to the largest value of `SensorIndex` found in all the detections used to update the tracker. `SensorIndex` is a property of an `objectDetection` object.

Data Types: `single` | `double`

Maximum number of tracks that the tracker can maintain, specified as a positive integer.

Data Types: `single` | `double`

## Usage

To process detections and update tracks, call the tracker with arguments, as if it were a function (described here).

### Syntax

``confirmedTracks = tracker(detections,time)``
``confirmedTracks = tracker(detections,config,time)``
``[confirmedTracks,tentativeTracks,allTracks] = tracker(___)``
``[confirmedTracks,tentativeTracks,allTracks,analysisInformation] = tracker(___)``

### Description

````confirmedTracks = tracker(detections,time)` returns a list of confirmed tracks that are updated from a list of detections, `detections`, at the update time, `time`. Confirmed tracks are corrected and predicted to the update time.```
````confirmedTracks = tracker(detections,config,time)` also specifies a sensor configuration input, `config`. Use this syntax when the configurations of sensors are changing with time. To enable this syntax, set the `HasSensorConfigurationsInput` property to `true`.```
````[confirmedTracks,tentativeTracks,allTracks] = tracker(___)` also returns a list of tentative tracks, `tentativeTracks`, and a list of all tracks, `allTracks`. You can use this output syntax with any of the previous input syntaxes.```
````[confirmedTracks,tentativeTracks,allTracks,analysisInformation] = tracker(___)` also returns the analysis information, `analysisInformation`, which can be used for track analysis. You can use this output syntax with any of the previous input syntaxes.```

### Input Arguments

expand all

Detection list, specified as a cell array of `objectDetection` objects. The `Time` property value of each `objectDetection` object must be less than or equal to the current update time, `time`, and greater than the previous time value used to update the tracker. Also, the `Time` differences between different `objectDetection` objects in the cell array do not need to be equal.

Time of update, specified as a scalar. The tracker updates all tracks to this time. Units are in seconds.

`time` must be greater than or equal to the largest `Time` property value of the `objectDetection` objects in the input `detections` list. `time` must increase in value with each update to the tracker.

Data Types: `single` | `double`

Sensor configurations, specified as an array of structs, a cell array of structs, or a cell array of `trackingSensorConfiguration` objects. If you specify the value using an array of structs or a cell array of structs, you must include `SensorIndex` as a field for each struct. The other optional fields in each struct must have the same name as one of the properties of the `trackingSensorConfiguration` object. Note that you only need to specify sensor configurations that need to be updated. For example, if you only want to update the `IsValidTime` property for the fifth sensor, provide the value for `config` as `struct('SensorIndex',5,'IsValidTime',false)`.

#### Dependencies

To enable this argument, set the `HasSensorConfigurationsInput` property to `true`.

### Output Arguments

expand all

Confirmed tracks updated to the current time, returned as a structure or an array of structures. Each structure corresponds to a track. A track is confirmed if the weight summation of its components is above the threshold specified by the `ConfirmationThreshold` property. If a track is confirmed, the `IsConfirmed` field of the structure is `true`. The fields of the confirmed tracks structure are defined in Track Structure.

Data Types: `struct`

Tentative tracks, returned as a structure or an array of structures. Each structure corresponds to a track. A track is tentative if the weight summation of its components is above the threshold specified by the `ExtractionThreshold` property, but below the threshold specified by the `ConfirmationThreshold` property. In that case, the `IsConfirmed` field of the structure is `false`. The fields of the structure are defined in Track Structure.

Data Types: `struct`

All tracks, returned as a structure or an array of structures. Each structure corresponds to a track. The set of all tracks consists of confirmed and tentative tracks. The fields of the structure are defined in Track Structure.

Data Types: `struct`

Additional information for analyzing track updates, returned as a structure. The fields of this structure are:

 Field Description `CorrectionOrder` The order in which sensors are used for state estimate correction, returned as a row vector of `SensorIndex`. For example, [1 3 2 4]. `TrackIDsAtStepBeginning` Track IDs when step began. `DeletedTrackIDs` IDs of tracks deleted during the step. `TrackIDsAtStepEnd` Track IDs when the step ended. `SensorAnalysisInfo` Cell array of sensor analysis information.

The `SensorAnalysisInfo` field can include multiple sensor information reports. Each report is a structure containing:

 Field Description `SensorIndex` Sensor index. `DetectionCells` Detection cells, returned as a logical matrix. Each column of the matrix denotes a detection cell. In each column, if the ith element is 1, then the ith detection belongs to the detection cell denoted by that column. `DetectionLikelihoods` The association likelihoods between components in the density function and detection cells, returned as an N-by-P matrix. N is the number of components in the density function, and P is the number of detection cells. `IsBirthCells` Indicates if the detection cells listed in `DetectionCells` give birth to new tracks, returned as a 1-by-P logical vector, where P is the number of detection cells. `NumPartitions` Number of partitions. `DetectionProbability` Probability of existing tracks being detected by the sensor, specified as a 1-by-N row vector, where N is the number of components in the density function. `LabelsBeforeCorrection` Labels of components in the density function before correction, return as a 1-by-Mb row vector. Mb is the number of components maintained in the tracker before correction. Each element of the vector is a `TrackID`. For example, [1 1 2 0 0]. Note that multiple components can share the same `TrackID`. `LabelsAfterCorrection` Labels of components in the density function after correction, returned as a 1-by-Ma row vector. Ma is the number of components maintained in the tracker after correction. Each element of the vector is a `TrackID`. For example, [1 1 1 2 2 0 0]. Note that multiple components can share the same `TrackID`. `WeightsBeforeCorrection` Weights of components in the density function before correction, returned as a 1-by-Mb row vector. Mb is the number of components maintained in the tracker before correction. Each element of the vector is the weight of the corresponding component given in `LabelsBeforeCorrection`. For example, [0.1 0.5 0.7 0.3 0.2]. `WeightsAfterCorrection` Weights of components in the density function after correction, returned as a 1-by-Ma row vector. Ma is the number of components maintained in the tracker after correction. Each element of the vector is the weight of the corresponding component given in `LabelsAfterCorrection`. For example, [0.1 0.4 0.2 0.6 0.3 0.2 0.2].

Data Types: `struct`

## Object Functions

To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named `obj`, use this syntax:

`release(obj)`

expand all

 `predictTracksToTime` Predict track state `deleteTrack` Delete existing track `initializeTrack` Initialize new track
 `step` Run System object algorithm `release` Release resources and allow changes to System object property values and input characteristics `isLocked` Determine if System object is in use `clone` Create duplicate System object `reset` Reset internal states of System object

## Examples

collapse all

Set up the sensor configuration, create a PHD tracker, and feed the tracker with detections.

``` % Create sensor configuration. Specify clutter density of the sensor and % set the IsValidTime property to true. configuration = trackingSensorConfiguration(1); configuration.ClutterDensity = 1e-7; configuration.IsValidTime = true; % Create a PHD tracker. tracker = trackerPHD('SensorConfigurations',configuration); % Create detections near points [5;-5;0] and [-5;5;0] at t=0, and % update the tracker with these detections. detections = cell(20,1); for i = 1:10 detections{i} = objectDetection(0,[5;-5;0] + 0.2*randn(3,1)); end for j = 11:20 detections{j} = objectDetection(0,[-5;5;0] + 0.2*randn(3,1)); end tracker(detections,0);```

Update the tracker again after 0.1 seconds by assuming that targets move at a constant velocity of [1;2;0] unit per second.

``` dT = 0.1; for i = 1:20 detections{i}.Time = detections{i}.Time + dT; detections{i}.Measurement = detections{i}.Measurement + [1;2;0]*dT; end [confTracks,tentTracks,allTracks] = tracker(detections,dT);```

Visualize detections and confirmed tracks.

``` % Obtain measurements from detections. d = [detections{:}]; measurements = [d.Measurement]; % Extract positions of confirmed tracking using getTrackPositions function. % Note that we used the default sensor configuration % FilterInitializationFcn, initcvggiwphd, which uses a constant velocity % model and defines the states as [x;vx;y;vy;z;vy]. positionSelector = [1 0 0 0 0 0;0 0 1 0 0 0;0 0 0 0 1 0]; positions = getTrackPositions(confTracks,positionSelector); figure() plot(measurements(1,:),measurements(2,:),'x','MarkerSize',5,'MarkerEdgeColor','b'); hold on; plot(positions(1,1),positions(1,2),'v','MarkerSize',5,'MarkerEdgeColor','r' ); hold on; plot(positions(2,1),positions(2,2),'^','MarkerSize',5,'MarkerEdgeColor','r' ); legend('Detections','Track 1','Track 2') xlabel('x') ylabel('y')```

expand all

expand all

## References

[1] Granstorm, K., C. Lundquiest, and O. Orguner. " Extended target tracking using a Gaussian-mixture PHD filter." IEEE Transactions on Aerospace and Electronic Systems. Vol. 48, Number 4, 2012, pp. 3268-3286.

[2] Granstorm, K., and O. Orguner." A PHD filter for tracking multiple extended targets using random matrices." IEEE Transactions on Signal Processing. Vol. 60, Number 11, 2012, pp. 5657-5671.

[3] Granstorm, K., and A. Natale, P. Braca, G. Ludeno, and F. Serafino."Gamma Gaussian inverse Wishart probability hypothesis density for extended target tracking using X-band marine radar data." IEEE Transactions on Geoscience and Remote Sensing. Vol. 53, Number 12, 2015, pp. 6617-6631.