trackerJPDA
Joint probabilistic data association tracker
Description
The trackerJPDA
System object™ is a tracker capable of processing detections of multiple targets from multiple
sensors using the joint probabilistic data association (JPDA) assignment algorithm. The
tracker applies a soft assignment where multiple detections can contribute to each track. The
tracker initializes, confirms, corrects, predicts (performs coasting), and deletes tracks.
Inputs to the tracker are detection reports generated by objectDetection
, fusionRadarSensor
,
irSensor
, or
sonarSensor
objects. The tracker estimates the state vector and state estimate error covariance matrix for
each track. Each detection is assigned to at least one track. If the detection cannot be
assigned to any existing track, the tracker creates a new track.
Any new track starts in a tentative state. If enough detections are
assigned to a tentative track, its status changes to confirmed (see the
ConfirmationThreshold
property). If the detection already has a known
classification (i.e., the ObjectClassID
field of the returned track is
nonzero), that corresponding track is confirmed immediately. When a track is confirmed, the
tracker considers the track to represent a physical object. If detections are not assigned to
the track within a specifiable number of updates, the track is deleted.
You can enable different JPDA tracking modes by specifying the TrackLogic and MaxNumEvents properties.
Setting the TrackLogic property to
'Integrated'
to enable the joint integrated data association (JIPDA) tracker, in which track confirmation and deletion is based on the probability of track existence.Setting the MaxNumEvents property to a finite integer to enable the k-best joint integrated data association (k-best JPDA) tracker, which generates a maximum of k events per cluster.
Setting the ClassFusionMethod property to
"Bayes"
to enable detection class fusion.
To track targets using this object:
Create the
trackerJPDA
object and set its properties.Call the object with arguments, as if it were a function.
To learn more about how System objects work, see What Are System Objects?
Creation
Description
creates a
tracker
= trackerJPDAtrackerJPDA
System object with default property values.
sets properties for the tracker using one or more name-value pairs. For example,
tracker
= trackerJPDA(Name,Value
)trackerJPDA('FilterInitializationFcn',@initcvukf,'MaxNumTracks',100)
creates a multi-object tracker that uses a constant-velocity, unscented Kalman filter and
allows a maximum of 100 tracks. Enclose each property name in quotes.
Properties
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.
For more information on changing property values, see System Design in MATLAB Using System Objects.
TrackerIndex
— Unique tracker identifier
0
(default) | nonnegative integer
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
FilterInitializationFcn
— Filter initialization function
@initcvekf
(default) | function handle | character vector
Filter initialization function, specified as a function handle or as a character vector containing the name of a valid filter initialization function. The tracker uses a filter initialization function when creating new tracks.
Sensor Fusion and Tracking Toolbox™ supplies many initialization functions that you can use to specify
FilterInitializationFcn
for a trackerJPDA
object.
Initialization Function | Function Definition |
---|---|
initcvkf | Initialize constant-velocity linear Kalman filter. |
initcakf | Initialize constant-acceleration linear Kalman filter. |
initcvabf | Initialize constant-velocity alpha-beta filter |
initcaabf | Initialize constant-acceleration alpha-beta filter |
initcvekf | Initialize constant-velocity extended Kalman filter. |
initcaekf | Initialize constant-acceleration extended Kalman filter. |
initrpekf | Initialize constant-velocity range-parametrized extended Kalman filter. |
initapekf | Initialize constant-velocity angle-parametrized extended Kalman filter. |
initctekf | Initialize constant-turn-rate extended Kalman filter. |
initctrvekf | Initialize constant-turn-rate and velocity magnitude extended Kalman filter. |
initcackf | Initialize constant-acceleration cubature filter. |
initctckf | Initialize constant-turn-rate cubature filter. |
initcvckf | Initialize constant-velocity cubature filter. |
initcvukf | Initialize constant-velocity unscented Kalman filter. |
initcaukf | Initialize constant-acceleration unscented Kalman filter. |
initctukf | Initialize constant-turn-rate unscented Kalman filter. |
initctrvukf | Initialize constant-turn-rate and velocity magnitude unscented Kalman filter. |
initcvmscekf | Initialize constant-velocity extended Kalman filter in modified spherical coordinates. |
initekfimm | Initialize tracking IMM filter. |
initvisionbboxkf | Initialize constant-velocity linear Kalman filter for 2-D axis-aligned bounding box. |
You can also write your own initialization function using the following syntax:
filter = filterInitializationFcn(detection)
objectDetection
. The output of this function must be a filter object:
trackingKF
, trackingEKF
, trackingUKF
, trackingCKF
,
trackingGSF
,
trackingIMM
,
trackingMSCEKF
, or trackingABF
.
For guidance in writing this function, use the type
command to
examine the details of built-in MATLAB®
functions. For example:
type
initcvekf
Note
trackerJPDA
does not accept all filter initialization functions
in Sensor Fusion and Tracking Toolbox. The full list of filter initialization functions available in
Sensor Fusion and Tracking Toolbox are given in the Initialization section of Estimation Filters.
Data Types: function_handle
| char
MaxNumEvents
— Value of k for k-best JPDA
Inf
(default) | positive integer
Value of k for k-best JPDA, specified as a positive integer. This property defines the maximum number of feasible joint events for the track and detection association of each cluster. Setting this property to a finite value enables you to run a k-best JPDA tracker, which generates a maximum of k events per cluster.
Data Types: single
| double
EventGenerationFcn
— Feasible joint events generation function
@jpdaEvents
(default) | function handle | character vector
Feasible joint events generation function, specified as a function handle or as a
character vector containing the name of a feasible joint events generation function. A
generation function generates feasible joint event matrices from an association
likelihood matrix between tracks and detections. For details, see jpdaEvents
.
To write your own generation function, you must use this syntax.
[FJE,FJEProbs] = myfunction(likelihoodMatrix,k)
jpdaEvents
.
You can use the type
command to examine the details of
jpdaEvents
function.
type jpdaEvents
Example:
@myfunction
or 'myfunction'
Data Types: function_handle
| char
MaxNumTracks
— Maximum number of tracks
100
(default) | positive integer
Maximum number of tracks that the tracker can maintain, specified as a positive integer.
Data Types: single
| double
MaxNumSensors
— Maximum number of sensors
20
(default) | positive integer
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. The MaxNumSensors
property
determines how many sets of ObjectAttributes
each track can
have.
Data Types: single
| double
MaxNumDetections
— Maximum number of detections
Inf
(default) | positive integer
Maximum number of detections that the tracker can take as inputs, specified as a positive integer.
Data Types: single
| double
OOSMHandling
— Handle out-of-sequence measurement (OOSM)
'Terminate'
(default) | 'Neglect'
| 'Retrodiction'
Handling of out-of-sequence measurement (OOSM), specified as
'Terminate'
, 'Neglect'
, or
'Retrodiction'
. Each detection has an associated timestamp,
td, and the tracker has its own timestamp,
tt, which is updated in each call to the
tracker. The tracker considers a measurement as an OOSM if
td <
tt.
When you specify this property as:
'Terminate'
— The tracker stops running when it encounters an out-of-sequence measurement.'Neglect'
— The tracker neglects any out-of-sequence measurements and continues to run.'Retrodiction'
— The tracker uses a retrodiction algorithm to update the tracker by either neglecting the OOSMs, updating existing tracks, or creating new tracks using the OOSM. You must specify a filter initialization function that returns atrackingKF
,trackingEKF
, ortrackingIMM
object in theFilterInitializationFcn
property.
If you specify this property as 'Retrodiction'
, the
tracker follows these steps to handle the OOSMs:
If the OOSM timestamp is beyond the oldest correction timestamp (specified by the
MaxNumOOSMSteps
property) maintained by the tracker, the tracker discards the OOSMs.If the OOSM timestamp is within the oldest correction timestamp maintained by the tracker, the tracker first retrodicts all the existing tracks to the time of the OOSMs. Then, the tracker applies the joint probability data association algorithm to try to associate the OOSMs to the retrodicted tracks.
If the tracker successfully associates the OOSM to at least one of the retrodicted tracks, then the tracker updates the associated, retrodicted tracks using the OOSMs by applying the retro-correction algorithm to obtain current, corrected tracks.
If the tracker cannot associate an OOSM to any retrodicted track, then the tracker creates a new track based on the OOSM and predicts the track to the current time.
For more details on JPDA-based retrodiction, see JPDA-Based Retrodiction and Retro-Correction.To simulate
out-of-sequence detections, use objectDetectionDelay
.
Note
When you select
'Retrodiction'
, you cannot use the costMatrix input.The benefits of using retrodiction decreases as the number of targets that move in close proximity increases.
The tracker requires all input detections that share the same
SensorIndex
have theirTime
differences bounded by theTimeTolerance
property. Therefore, when you set the OOSMHandling property to'Neglect'
, you must make sure that the out-of-sequence detections have timestamps strictly less than the previous timestamp when running the tracker.
MaxNumOOSMSteps
— Maximum number of out-of-sequence measurement steps
3
(default) | positive integer
Maximum number of out-of-sequence measurement (OOSM) steps, specified as a positive integer.
Increasing the value of this property requires more memory, but enables you to call
the tracker with OOSMs that have a larger lag relative to the last timestamp. However,
as the lag increases, the impact of the OOSM on the current state of the track
diminishes. The recommended value for this property is 3
.
Dependencies
To enable this argument, set the OOSMHandling
property to
'Retrodiction'
.
StateParameters
— Parameters of track state reference frame
struct([])
(default) | struct array
Parameters of the track state reference frame, specified as a structure or a structure
array. The tracker passes its StateParameters
property values to
the StateParameters
property of the generated tracks. You can use
these parameters to define the reference frame in which the track is reported or other
desirable attributes of the generated tracks.
For example, you can use the following structure to define a rectangular reference
frame whose origin position is at [10 10 0]
meters and whose origin
velocity is [2 -2 0] meters per second with respect to the scenario frame.
Field Name | Value |
---|---|
Frame | "Rectangular" |
Position | [10 10 0] |
Velocity | [2 -2 0] |
Tunable: Yes
Data Types: struct
AssignmentThreshold
— Detection assignment threshold
30*[1 Inf]
(default) | positive scalar | 1-by-2 vector of positive values
Detection assignment threshold (or gating threshold), specified as a positive scalar
or 1-by-2 vector of
[C1,C2],
where C1 ≤
C2. If specified as a scalar, the specified
value, val, is expanded to [val,
Inf
].
Initially, the tracker executes a coarse estimation for the normalized distance between all the tracks and detections. The tracker only calculates the accurate normalized distance for the combinations whose coarse normalized distance is less than C2. Also, the tracker can only assign a detection to a track if the accurate normalized distance between them is less than C1. See Algorithms for an explanation of the normalized distance.
Increase the value of C2 if there are track and detection combinations that should be calculated for assignment but are not. Decrease this value if cost calculation takes too much time.
Increase the value of C1 if there are detections that should be assigned to tracks but are not. Decrease this value if there are detections that are assigned to tracks they should not be assigned to (too far away).
Note
If the value of C2 is finite, the state transition function and measurement function, specified in the tracking filter used in the tracker, must be able to take an M-by-N matrix of states as input and output N predicted states and N measurements, respectively. M is the size of the state. N, the number of states, is an arbitrary nonnegative integer.
Tunable: Yes
DetectionProbability
— Probability of detection
0.9
(default) | scalar in the range (0,1)
Probability of detection, specified as a scalar in the range (0,1). The object uses this property to evaluate the marginal posterior probabilities of association and the probability of track existence when initializing and updating a track.
Example: 0.85
Tunable: Yes
Data Types: single
| double
InitializationThreshold
— Threshold to initialize a track
0
(default) | scalar in the range [0,1)
The probability threshold to initialize a new track, specified as a
scalar in the range [0,1). If the probabilities of associating a
detection with any of the existing tracks are all smaller than
InitializationThreshold
, the
object uses the detection to initialize a new track. This allows
detections that are within the validation gate of a track but
have an association probability lower than the initialization
threshold to spawn a new track.
Example: 0.1
Tunable: Yes
Data Types: single
| double
TrackLogic
— Track confirmation and deletion logic type
'History'
(default) | 'Integrated'
Confirmation and deletion logic type, specified as:
'History'
– Track confirmation and deletion is based on the number of times the track has been assigned to a detection in the latest tracker updates.'Integrated'
– Track confirmation and deletion is based on the probability of track existence, which is integrated in the assignment function. Selecting this value enables the joint integrated data association (JIPDA) tracker.
ConfirmationThreshold
— Threshold for track confirmation
scalar | 1-by-2 vector
Threshold for track confirmation, specified as a scalar or a 1-by-2 vector. The
threshold depends on the type of track confirmation and deletion logic you set with the
TrackLogic
property:
'History'
– Specify the confirmation threshold as 1-by-2 vector [M N]. A track is confirmed if it recorded at least M hits in the last N updates. ThetrackerJPDA
registers a hit on a track’s history logic according to theHitMissThrehold
. The default value is[2 3]
.'Integrated'
– Specify the confirmation threshold as a scalar in the range (0,1). A track is confirmed if its probability of existence is greater than or equal to the confirmation threshold. The default value is0.95
.
Note
This property is tunable only when you set the TrackLogic
property to 'Integrated'
.
Tunable: Yes
Data Types: single
| double
DeletionThreshold
— Threshold for track deletion
scalar | real-valued 1-by-2 vector
Threshold for track deletion, specified as a scalar or a real-valued 1-by-2 vector.
The threshold depends on the type of track confirmation and deletion logic you set with
the TrackLogic
property:
'History'
– Specify the deletion threshold as [P R]. If, inP
of the lastR
tracker updates, a confirmed track is not assigned to any detection that has a likelihood greater than theHitMissThreshold
property, then that track is deleted. The default value is[5,5]
.'Integrated'
– Specify the deletion threshold as a scalar in the range (0,1). A track is deleted if its probability of existence drops below the threshold. The default value is0.1
.
Note
This property is tunable only when you set the TrackLogic
property to 'Integrated'
.
Example: 0.2
or [5,6]
Tunable: Yes
Data Types: single
| double
HitMissThreshold
— Threshold for registering hit or miss
0.2 (default) | scalar in the range [0,1]
Threshold for registering a hit or miss, specified as a scalar in the range [0,1].
The track history logic will register a miss and the track will be coasted if the sum of
the marginal probabilities of assignments is below the
HitMissThreshold
. Otherwise, the track history logic will
register a hit.
Example: 0.3
Dependencies
To enable this argument, set the TrackLogic
property to
'History'
.
Data Types: single
| double
ClutterDensity
— Spatial density of clutter measurements
1e-6
(default) | positive scalar
Spatial density of clutter measurements, specified as a positive scalar. The clutter
density describes the expected number of false positive detections per unit volume. It
is used as the parameter of a Poisson clutter model. When
TrackLogic
is set to 'Integrated'
,
ClutterDensity
is also used in calculating the initial
probability of track existence.
Example: 1e-5
Tunable: Yes
Data Types: single
| double
NewTargetDensity
— Spatial density of new targets
1e-5
(default) | positive scalar
Spatial density of new targets, specified as a positive scalar. The new target density describes the expected number of new tracks per unit volume in the measurement space. It is used in calculating the probability of track existence during track initialization.
Example: 1e-3
Tunable: Yes
Dependencies
To enable this argument, set the TrackLogic
property to
'Integrated'
.
Data Types: single
| double
DeathRate
— Time rate of target deaths
0.01
(default) | scalar in the range [0,1]
Time rate of target deaths, specified as a scalar in the range [0,1].
DeathRate
describes the probability with which true targets
disappear. It is related to the propagation of the probability of track existence
(PTE) :
where δt is the time interval since the previous update time t.
Tunable: Yes
Dependencies
To enable this argument, set the TrackLogic
property to
'Integrated'
.
Data Types: single
| double
InitialExistenceProbability
— Initial probability of track existence
0.9
(default) | scalar in the range [0,1]
This property is read-only.
Initial probability of track existence, specified as a scalar in the range [0,1] and
calculated as InitialExistenceProbability =
NewTargetDensity*DetectionProbability/(ClutterDensity +
NewTargetDensity*DetectionProbability)
.
Dependencies
To enable this property, set the TrackLogic
property to
'Integrated'
. When the TrackLogic
property
is set to 'History'
, this property is not available.
Data Types: single
| double
HasCostMatrixInput
— Enable cost matrix input
false
(default) | true
Enable a cost matrix, specified as false
or
true
. If true
, you can provide an assignment cost
matrix as an input argument when calling the object.
Data Types: logical
HasDetectableTrackIDsInput
— Enable input of detectable track IDs
false
(default) | true
Enable the input of detectable track IDs at each object update, specified as
false
or true
. Set this property to
true
if you want to provide a list of detectable track IDs. This
list informs the tracker of all tracks that the sensors are expected to detect and,
optionally, the probability of detection for each track.
Data Types: logical
NumTracks
— Number of tracks maintained by tracker
nonnegative integer
This property is read-only.
Number of tracks maintained by the tracker, returned as a nonnegative integer.
Data Types: single
| double
NumConfirmedTracks
— Number of confirmed tracks
nonnegative integer
This property is read-only.
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: single
| double
TimeTolerance
— Absolute time tolerance between detections
1e-5
(default) | positive scalar
Absolute time tolerance between detections of the same cluster from
the same sensor in seconds, specified as a positive scalar.
Ideally, trackerJPDA
expects detections from
the same cluster to have identical time stamps. However, if the
time stamp differences between detections from the same cluster
are within the margin specified by
TimeTolerance
, these detections
will be used to update the track estimate based on the average
time of these detections.
Data Types: double
EnableMemoryManagement
— Enable memory management properties
false
or 0
(default) | true
or 1
Enable memory management properties, specified as a logical 1
(true
) or false
(0
). Setting
this property to true
enables you to use these four properties to
specify bounds for certain variable-sized arrays in the tracker, as well as determine
how the tracker handles cluster-size violations:
MaxNumDetectionsPerSensor
MaxNumDetectionsPerCluster
MaxNumTracksPerCluster
ClusterViolationHandling
Specifying bounds for variable-sized arrays enables you to manage the memory footprint of the tracker in the generated C/C++ code.
Data Types: logical
MaxNumDetectionsPerSensor
— Maximum number of detections per sensor
100
(default) | positive integer
Maximum number of detections per sensor, specified as a positive integer. This property determines the maximum number of detections that each sensor can pass to the tracker during each call of the tracker.
Set this property to a finite value if you want the tracker to establish efficient
bounds on local variables for C/C++ code generation. Set this property to
Inf
if you do not want to bound the maximum number of detections
per sensor.
Dependencies
To enable this property, set the EnableMemoryManagement
property to true
.
Data Types: single
| double
MaxNumDetectionsPerCluster
— Maximum number of detections per cluster
5
(default) | positive integer
Maximum number of detections per cluster during the run-time of the tracker, specified as a positive integer.
Setting this property to a finite value allows the tracker to bound cluster sizes
and reduces the memory footprint of the tracker in generated C/C++ code. Set this
property to Inf
if you do not want to bound the maximum number of
detections per cluster.
If, during run-time, the number of detections in a cluster exceeds the specified
MaxNumDetectionsPerCluster
, the tracker reacts based on the
ClusterViolationHandling
property.
Dependencies
To enable this property, set the EnableMemoryManagement
property to true
.
Data Types: single
| double
MaxNumTracksPerCluster
— Maximum number of tracks per cluster
5
(default) | positive integer
Maximum number of tracks per cluster during the run-time of the tracker, specified as a positive integer.
Setting this property to a finite value enables the tracker to bound cluster sizes
and reduces the memory footprint of the tracker in generated C/C++ code. Set this
property to Inf
if you do not want to bound the maximum number of
tracks per cluster.
If, during run-time, the number of tracks in a cluster exceeds the specified
MaxNumTracksPerCluster
, the tracker reacts based on the
ClusterViolationHandling
property.
Dependencies
To enable this argument, set the EnableMemoryManagement
property to true
.
Data Types: single
| double
ClusterViolationHandling
— Handling of run-time violation of cluster bounds
'Split and warn'
(default) | 'Terminate'
| 'Split'
Handling of run-time violation of cluster bounds, specified as:
'Teminate'
— The tracker reports an error if, during run-time, any cluster violates the cluster bounds specified in theMaxNumDetectionsPerCluster
andMaxNumTracksPerCluster
properties.'Split and warn'
— The tracker splits the size-violating cluster into smaller clusters using a suboptimal approach. The tracker also reports a warning to indicate the violation.'Split'
— The tracker splits the size-violating cluster into smaller clusters by using a suboptimal approach. The tracker does not report a warning.
In the suboptimal approach, the tracker separates out detections or tacks that have
the smallest likelihood of association to other tracks or detections until the cluster
bounds are satisfied. These separated-out detections or tracks can form one or many new
clusters depends on their association likelihoods with each other and the
AssignmentThreshold
property.
Dependencies
To enable this property, set the EnableMemoryManagement
property to true
.
Data Types: char
| string
ClassFusionMethod
— Class fusion method
"None"
(default) | "Bayes"
Class fusion method, specified as one of these:
"None"
— The tracker does not fuse classification information from detections. When the tracker initializes a track from a detection that has a nonzero class ID, the tracker immediately confirms the track and assigns the class ID of the detection to the track. In the subsequent updates to the track, the tracker assigns only detections with the same class ID or a class ID of 0 to the track. As a result, the track classification cannot change once the tracker establishes it."Bayes"
— The tracker fuses classification information from detections. When the tracker initializes a tentative track from detections, the tracker determines the class probability of the track based on the a priori class distribution and the class information of the detections. In the subsequent updates to the track, the tracker considers all possible detections for association with the track regardless of their classifications. The tracker uses the kinematic state as well as class information of the detections to calculate the detection-track association likelihoods. The tracker updates the classification of a track by using the marginal probabilities and class information of relevant detections.
Data Types: char
| string
InitialClassProbabilities
— Prior class probability distribution for new tracks
1
(default) | N-element vector of nonnegative scalars that sum to
1
Prior class probability distribution for new tracks, specified as an
N-element vector of nonnegative scalars that sum to
1
. N must be equal to the total number of
classes.
For each objectDetection
object that you specify
through the detections
input, the ObjectClassID
property of the
objectDetection
object must be less than or equal to
N.
Example: [0.2 0.8]
Tunable: Yes
Data Types: single
| double
ClassFusionWeight
— Weight factor of class fusion
0.7
(default) | scalar in range [0,1]
Weight factor of class fusion, specified as a scalar in the range [0,1]. When you
set the ClassFusionMethod
property to "Bayes"
,
the tracker calculates the mixed likelihood of association between a detection
m and a track t as:
where
α — Weight factor of class fusion
Λk — Likelihood of assigning a detection to a track based on the kinematic states
Λc — Likelihood of assigning a classified detection to a track based on the class information
Using the mixed likelihoods between detections and tracks in each cluster, the tracker performs joint probabilistic data association between tracks and detections.
Tunable: Yes
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
Description
returns a list of confirmed tracks that are updated from a list of detections at the
update time. Confirmed tracks are corrected and predicted to the update time,
confirmedTracks
= tracker(detections
,time
)time
.
also specifies a cost matrix. confirmedTracks
= tracker(detections
,time
,costMatrix
)
To enable this syntax, set the HasCostMatrixInput
property to
true
.
also specifies a list of expected detectable tracks given by
confirmedTracks
= tracker(___,detectableTrackIDs
)detectableTrackIDs
. This argument can be used with any of the
previous input syntaxes.
To enable this syntax, set the HasDetectableTrackIDsInput
property to true
.
[
also returns a list of tentative tracks and a list of all tracks. You can use any of the
input arguments in the previous syntaxes.confirmedTracks
,tentativeTracks
,allTracks
] = tracker(___)
[
also returns analysis information that can be used for track analysis. You can use any of
the input arguments in the previous syntaxes.confirmedTracks
,tentativeTracks
,allTracks
,analysisInformation
] = tracker(___)
Input Arguments
detections
— Detection list
cell array of objectDetection
objects
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
— Time of update
scalar
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
costMatrix
— Cost matrix
real-valued M-by-N matrix
Cost matrix, specified as a real-valued
M-by-N matrix, where M is
the number of existing tracks in the previous update, and N is the
number of current detections. The cost matrix rows must be in the same order as the
list of tracks, and the columns must be in the same order as the list of detections.
Obtain the correct order of the list of tracks from the third output argument,
allTracks
, when the tracker is updated.
At the first update of the tracker or when the tracker has no previous tracks,
specify the cost matrix to be empty with a size of
[0,numDetections]
. Note that the cost must be given so that lower
costs indicate a higher likelihood of assigning a detection to a track. To prevent
certain detections from being assigned to certain tracks, you can set the appropriate
cost matrix entry to Inf
.
Dependencies
To enable this argument, set the HasCostMatrixInput
property to true
.
Data Types: double
| single
detectableTrackIDs
— Detectable track IDs
real-valued M-by-1 vector | real-valued M-by-2 matrix
Detectable track IDs, specified as a real-valued M-by-1 vector or M-by-2 matrix. Detectable tracks are tracks that the sensors expect to detect. The first column of the matrix contains a list of track IDs that the sensors report as detectable. The optional second column allows you to add the detection probability for each track.
Tracks whose identifiers are not included in
detectableTrackIDs
are considered undetectable. In this case,
the track deletion logic does not count the lack of detection for that track as a
missed detection for track deletion purposes.
Dependencies
To enable this input argument, set the detectableTrackIDs
property to true
.
Data Types: single
| double
Output Arguments
confirmedTracks
— Confirmed tracks
array of objectTrack
objects | array of structures
Confirmed tracks, returned as an array of objectTrack
objects in MATLAB or as an array of structures in code generation. In code
generation, the field names of the returned structure are identical to the
property names of objectTrack
.
The tracker confirms a track if it satisfies the confirmation threshold specified in the
ConfirmationThreshold
property. In that case,
the IsConfirmed
property of the object or field of the
structure is true
.
Data Types: struct
| object
tentativeTracks
— Tentative tracks
array of objectTrack
objects | array of structures
Tentative tracks, returned as an array of objectTrack
objects in
MATLAB or as an array of structures in code generation. In code generation, the
field names of the returned structure are identical to the property names of
objectTrack
.
A track is tentative if it does not satisfy the confirmation threshold specified in the
ConfirmationThreshold
property. In that case, the
IsConfirmed
property of the object or field of the structure is
false
.
Data Types: struct
| object
allTracks
— All tracks
array of objectTrack
objects | array of structures
All tracks, returned as an array of objectTrack
objects in
MATLAB or as an array of structures in code generation. In code generation, the
field names of the returned structure are identical to the property names of
objectTrack
. allTracks
consists of confirmed
and tentative tracks.
Data Types: struct
| object
analysisInformation
— Additional information for analyzing track updates
structure
Additional information for analyzing track updates, returned as a structure. The structure contains the following field.
Field | Description |
OOSMDetectionIndices | Indices of out-of-sequence measurements at the current step of the tracker. |
TrackIDsAtStepBeginning | Track IDs when the step began. |
UnassignedTracks | IDs of unassigned tracks. |
UnassignedDetections | Indices of unassigned detections in the
|
CostMatrix | Cost of kinematic assignment matrix, in which the (i, j) element denotes the cost of assigning track i to detection j. |
Clusters | Cell array of cluster reports. |
InitiatedTrackIDs | IDs of tracks initiated during the step. |
DeletedTrackIDs | IDs of tracks deleted during the step. |
TrackIDsAtStepEnd | Track IDs when the step ended. |
MaxNumDetectionsPerCluster | The maximum number of detections in all the clusters generated during the
step. only when you set the EnableMemoryManagement
property to 'on' . |
MaxNumTracksPerCluster | The maximum number of tracks in all the clusters generated during the
step. The field appears only when you set the
EnableMemoryManagement property to
'on' . |
OOSMHandling | Analysis information for out-of-sequence measurements handling,
returned as a structure. The field appears only when you set the
|
ClassCostMatrix | Cost matrix for classification assignment, in which the (i, j) elements denotes the classification cost of assigning track i to detection j. The field appears when you set the
|
The Clusters
field can include multiple cluster reports. Each
cluster report is a structure containing these fields.
Field | Description |
DetectionIndices | Indices of clustered detections, returned as an M-element vector. |
TrackIDs | Track IDs of clustered tracks, returned as an N-element vector. |
ValidationMatrix | Validation matrix of the cluster, returned as an
M-by-(N+1) matrix. See the
validationMatrix input of the jpdaEvents function
for more details. |
SensorIndex | Index of the originating sensor of detections in the cluster. |
TimeStamp | Mean time stamp of clustered detections. |
MarginalProbabilities | Matrix of marginal posterior joint association probabilities,
returned as an (M+1)-by-N matrix. In
the upper M-by-N matrix, the
(i,j) element represents the
probability that the i-th detection (specified in the
When the |
Likelihood | Individual association likelihoods based on kinematic
information, returned as an
(M+1)-by-(N+1) matrix. See the
|
ClassLikelihood | Individual association likelihoods based on classification
information, returned as an
(M+1)-by-(N+1) matrix. See the
The field appears when you set the
|
The OOSMHandling
structure contains these fields:
Field | Description |
---|---|
DiscardedDetections | Indices of discarded out-of-sequence detections. An OOSM is discarded
if it is not covered by the saved state history specified by the
MaxNumOOSMSteps property. |
CostMatrix | Cost of assignment matrix for the out-of-sequence detections. |
Clusters | Clusters that are related only to the out-of-sequence detections. |
UnassignedDetections | Indices of unassigned out-of-sequence detections. The tracker creates new tracks for unassigned out-of-sequence detections. |
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)
Specific to trackerJPDA
predictTracksToTime | Predict track state |
getTrackFilterProperties | Obtain track filter properties |
setTrackFilterProperties | Set track filter properties |
initializeTrack | Initialize new track |
confirmTrack | Confirm tentative track |
deleteTrack | Delete existing track |
generateCode | Generate code for tracker object and object functions |
exportToSimulink | Export tracker or track fuser to Simulink model |
Examples
Track Two Objects Using trackerJPDA
Construct a trackerJPDA object with a default constant velocity Extended Kalman Filter and 'History' track logic. Set AssignmentThreshold to 100 to allow tracks to be jointly associated.
tracker = trackerJPDA('TrackLogic','History', 'AssignmentThreshold',100,... 'ConfirmationThreshold', [4 5], ... 'DeletionThreshold', [10 10]);
Specify the true initial positions and velocities of the two objects.
pos_true = [0 0 ; 40 -40 ; 0 0]; V_true = 5*[cosd(-30) cosd(30) ; sind(-30) sind(30) ;0 0];
Create a theater plot to visualize tracks and detections.
tp = theaterPlot('XLimits',[-1 150],'YLimits',[-50 50]); trackP = trackPlotter(tp,'DisplayName','Tracks','MarkerFaceColor','g','HistoryDepth',0); detectionP = detectionPlotter(tp,'DisplayName','Detections','MarkerFaceColor','r');
To obtain the position and velocity, create position and velocity selectors.
positionSelector = [1 0 0 0 0 0; 0 0 1 0 0 0; 0 0 0 0 0 0]; % [x, y, 0] velocitySelector = [0 1 0 0 0 0; 0 0 0 1 0 0; 0 0 0 0 0 0 ]; % [vx, vy, 0]
Update the tracker with detections, display cost and marginal probability of association information, and visualize tracks with detections.
dt = 0.2; for time = 0:dt:30 % Update the true positions of objects. pos_true = pos_true + V_true*dt; % Create detections of the two objects with noise. detection(1) = objectDetection(time,pos_true(:,1)+1*randn(3,1)); detection(2) = objectDetection(time,pos_true(:,2)+1*randn(3,1)); % Step the tracker through time with the detections. [confirmed,tentative,alltracks,info] = tracker(detection,time); % Extract position, velocity and label info. [pos,cov] = getTrackPositions(confirmed,positionSelector); vel = getTrackVelocities(confirmed,velocitySelector); meas = cat(2,detection.Measurement); measCov = cat(3,detection.MeasurementNoise); % Update the plot if there are any tracks. if numel(confirmed)>0 labels = arrayfun(@(x)num2str([x.TrackID]),confirmed,'UniformOutput',false); trackP.plotTrack(pos,vel,cov,labels); end detectionP.plotDetection(meas',measCov); drawnow; % Display the cost and marginal probability of distribution every eight % seconds. if time>0 && mod(time,8) == 0 disp(['At time t = ' num2str(time) ' seconds,']); disp('The cost of assignment was: ') disp(info.CostMatrix); disp(['Number of clusters: ' num2str(numel(info.Clusters))]); if numel(info.Clusters) == 1 disp('The two tracks were in the same cluster.') disp('Marginal probabilities of association:') disp(info.Clusters{1}.MarginalProbabilities) end disp('-----------------------------') end end
At time t = 8 seconds,
The cost of assignment was:
1.0e+03 * 0.0020 1.1523 1.2277 0.0053
Number of clusters: 2
-----------------------------
At time t = 16 seconds,
The cost of assignment was:
1.3968 4.5123 2.0747 1.9558
Number of clusters: 1
The two tracks were in the same cluster.
Marginal probabilities of association:
0.8344 0.1656 0.1656 0.8344 0.0000 0.0000
-----------------------------
At time t = 24 seconds,
The cost of assignment was:
1.0e+03 * 0.0018 1.2962 1.2664 0.0013
Number of clusters: 2
-----------------------------
Detection Class Fusion Using trackerJPDA
Create two objectDetection
objects at time = 0 and = 1, respectively. The ObjectClassID
of the two detections is 1
. Specify the confusion matrix for each detection.
detection0 = objectDetection(0,[0 0 0],... ObjectClassID=1,... ObjectClassParameters=struct("ConfusionMatrix",[0.6 0.2 0.2; 0.2 0.6 0.2; 0.2 0.2 0.6])); detection1 = objectDetection(1,[0 0 0],... ObjectClassID=1,... ObjectClassParameters=struct("ConfusionMatrix",[0.5 0.3 0.2; 0.3 0.5 0.2; 0.2 0.2 0.6]));
Create a trackerJPDA
object. Set the class fusion method to "Bayes"
and specify the initial probability of each class as 1/3
.
tracker = trackerJPDA(ClassFusionMethod="Bayes",InitialClassProbabilities=[1/3 1/3 1/3])
tracker = trackerJPDA with properties: TrackerIndex: 0 FilterInitializationFcn: 'initcvekf' MaxNumEvents: Inf EventGenerationFcn: 'jpdaEvents' MaxNumTracks: 100 MaxNumDetections: Inf MaxNumSensors: 20 TimeTolerance: 1.0000e-05 AssignmentThreshold: [30 Inf] InitializationThreshold: 0 DetectionProbability: 0.9000 ClutterDensity: 1.0000e-06 OOSMHandling: 'Terminate' TrackLogic: 'History' ConfirmationThreshold: [2 3] DeletionThreshold: [5 5] HitMissThreshold: 0.2000 HasCostMatrixInput: false HasDetectableTrackIDsInput: false StateParameters: [1x1 struct] ClassFusionMethod: 'Bayes' InitialClassProbabilities: [0.3333 0.3333 0.3333] ClassFusionWeight: 0.7000 NumTracks: 0 NumConfirmedTracks: 0 EnableMemoryManagement: false
Update the track with the first and second detections sequentially.
tracker(detection0,0); [tracks,~,~,info] = tracker(detection1,1);
Show the maintained tracks and analysis information.
disp(tracks)
objectTrack with properties: TrackID: 1 BranchID: 0 SourceIndex: 0 UpdateTime: 1 Age: 2 State: [6x1 double] StateCovariance: [6x6 double] StateParameters: [1x1 struct] ObjectClassID: 1 ObjectClassProbabilities: [0.7409 0.1530 0.1060] TrackLogic: 'History' TrackLogicState: [1 1 0 0 0] IsConfirmed: 1 IsCoasted: 0 IsSelfReported: 1 ObjectAttributes: [1x1 struct]
disp(info)
OOSMDetectionIndices: [1x0 uint32] TrackIDsAtStepBeginning: 1 UnassignedTracks: [1x0 uint32] UnassignedDetections: [1x0 uint32] CostMatrix: 13.8823 Clusters: {[1x1 struct]} InitializedTrackIDs: [1x0 uint32] DeletedTrackIDs: [1x0 uint32] TrackIDsAtStepEnd: 1 ClassCostMatrix: -0.1823
Display the cluster information.
disp(info.Clusters{:})
DetectionIndices: 1 TrackIDs: 1 ValidationMatrix: [1 1] SensorIndex: 1 TimeStamp: 1 MarginalProbabilities: [2x1 double] Likelihood: [2x2 double] ClassLikelihood: [2x2 double]
Algorithms
Tracker Logic Flow
When a JPDA tracker processes detections, track creation and management follow these steps.
The tracker divides detections into multiple groups by originating sensor.
For each sensor:
The tracker calculates the distances from detections to existing tracks and forms a
costMatrix
.The tracker creates a validation matrix based on the assignment threshold (or gate threshold) of the existing tracks. A validation matrix is a binary matrix listing all possible detections-to-track associations. For details, see Feasible Joint Events.
Tracks and detections are then separated into clusters. A cluster can contain one track or multiple tracks if these tracks share common detections within their validation gates. A validation gate is a spatial boundary, in which the predicted detection of the track has a high likelihood to fall. For details, see Feasible Joint Events.
Update all clusters following the order of the mean detection time stamp within the cluster. For each cluster, the tracker:
Generates all feasible joint events. For details, see
jpdaEvents
.Calculates the posterior probability of each joint event.
Calculates the marginal probability of each individual detection-track pair in the cluster.
Reports weak detections. Weak detections are the detections that are within the validation gate of at least one track, but have probability association to all tracks less than the
IntitializationThreshold
.Updates tracks in the cluster using
correctjpda
.
Unassigned detections (these are not in any cluster) and weak detections spawn new tracks.
The tracker checks all tracks for deletion. Tracks are deleted based on the number of scans without association using
'History'
logic or based on their probability of existence using'Integrated'
track logic.All tracks are predicted to the latest time value (either the time input if provided, or the latest mean cluster time stamp).
Detection Class Fusion for trackerJPDA
Single Detection Class Probability Update
First, consider the class information association between one detection and one track. Assume the confusion matrix of the detection is
where cij denotes the likelihood that the classifier outputs the classification as j if the truth class of the target is i. Here, i, j = 1,…, N, and N is the total number of possible classes.
At time k-1, the probability distribution of a track is given as
where μi is the probability that the classification of the track is i.
If the tracker associates the detection to the track at time k, then the updated value of μi using Bayes' theorem is
Write this equation in a vector form for all possible classifications as
where cj is the j-th column of the confusion matrix and ⊗ represents element-wise multiplication. This equation represents the updated class probability of a track if the track is associated with the detection of classification j.
Mixed Association Likelihood in Cluster
The tracker performs gating and clustering by using only the kinematic information between detections and tracks as explained in the Tracker Logic Flow section. After that, in each cluster, the tracker calculates the mixed likelihood of association between a detection m and a track t as:
where
α — Weight factor of class likelihood
Λk — Likelihood of assigning a detection to a track based on the kinematic states
Λc — Likelihood of assigning a classified detection to a track based on the class information
In the equation, Λc takes one of these three forms based on the value of m and t.
m > 0 and t > 0 — A hypothesis that the measurement is associated with a track in the tracker. In this case,
where cj is the j-th column in the confusion matrix that detection m corresponds to, and μ(k-1) is the class probability vector of the track in the previous step.
m > 0 and t = 0 — A hypothesis that the measurement is not associated with any track in the tracker. In this case,
where cj is the j-th column in the confusion matrix that detection m corresponds to, and μ0 is the a priori class distribution vector of tracks.
m = 0 and t > 0 — A hypothesis that the track is not associated with any measurement in the tracker. In this case,
Using the mixed likelihoods of association between detections and tracks in a cluster, the tracker generates all the feasible events and then calculates the marginal probability of assigning each detection to each track in the cluster.
Update Track Class Probability
Suppose the marginal probabilities of M detections assigned to a track in the cluster are (β0, β1, …, βM), where β0 is the marginal probability that no measurements is associated with the track. Then the tracker updates the class probability of the track as
where cj(m) is the class probability vector of detection m, ⊗ represents element-wise multiplication, μ(k-1) is the class probability vector of the track in the k-1 step, and μ(k) is the class probability vector of the track in the k step.
The tracker updates the class properties of tracks cluster by cluster.
Feasible Joint Events
In the typical workflow for a tracking system, the tracker needs to determine if a detection can be associated with any of the existing tracks. If the tracker only maintains one track, the assignment can be done by evaluating the validation gate around the predicted measurement and deciding if the measurement falls within the validation gate. In the measurement space, the validation gate is a spatial boundary, such as a 2-D ellipse or a 3-D ellipsoid, centered at the predicted measurement. The validation gate is defined using the probability information (state estimation and covariance, for example) of the existing track, such that the correct or ideal detections have high likelihood (97% probability, for example) of falling within this validation gate.
However, if a tracker maintains multiple tracks, the data association process becomes more complicated, because one detection can fall within the validation gates of multiple tracks. For example, in the following figure, tracks T1 and T2 are actively maintained in the tracker, and each of them has its own validation gate. Since the detection D2 is in the intersection of the validation gates of both T1 and T2, the two tracks (T1 and T2) are connected and form a cluster. A cluster is a set of connected tracks and their associated detections.
To represent the association relationship in a cluster, the validation matrix is commonly used. Each row of the validation matrix corresponds to a detection while each column corresponds to a track. To account for the eventuality of each detection being clutter, a first column is added and usually referred to as "Track 0" or T0. If detection Di is inside the validation gate of track Tj, then the (i, j+1) entry of the validation matrix is 1. Otherwise, it is zero. For the cluster shown in the figure, the validation matrix Ω is
Note that all the elements in the first column of Ω are 1, because any detection can be clutter or false alarm. One important step in the logic of joint probabilistic data association (JPDA) is to obtain all the feasible independent joint events in a cluster. Two assumptions for the feasible joint events are:
A detection cannot be emitted by more than one track.
A track cannot be detected more than once by the sensor during a single scan.
Based on these two assumptions, feasible joint events (FJEs) can be formulated. Each FJE is mapped to an FJE matrix Ωp from the initial validation matrix Ω. For example, with the validation matrix Ω, eight FJE matrices can be obtained:
As a direct consequence of the two assumptions, the Ωp matrices have
exactly one "1" value per row. Also, except for the first column which maps to clutter,
there can be at most one "1" per column. When the number of connected tracks grows in a
cluster, the number of FJE increases rapidly. The jpdaEvents
function
uses an efficient depth-first search algorithm to generate all the feasible joint event
matrices.
References
[1] Fortmann, T., Y. Bar-Shalom, and M. Scheffe. "Sonar Tracking of Multiple Targets Using Joint Probabilistic Data Association." IEEE Journal of Ocean Engineering. Vol. 8, Number 3, 1983, pp. 173-184.
[2] Musicki, D., and R. Evans. "Joint Integrated Probabilistic Data Association: JIPDA." IEEE transactions on Aerospace and Electronic Systems. Vol. 40, Number 3, 2004, pp 1093-1099.
[3] Bar-Shalom, Y., et al. “Tracking with Classification-Aided Multiframe Data Association.” IEEE Transactions on Aerospace and Electronic Systems, vol. 41, no. 3, July 2005, pp. 868–78.
Extended Capabilities
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
Usage notes and limitations:
See System Objects in MATLAB Code Generation (MATLAB Coder).
All the detections used with a multi-object tracker must have properties with the same sizes and types.
If you use the
ObjectAttributes
field within anobjectDetection
object, you must specify this field as a cell containing a structure. The structure for all detections must have the same fields, and the values in these fields must always have the same size and type. The form of the structure cannot change during simulation.If
ObjectAttributes
are contained in the detection, theSensorIndex
value of the detection cannot be greater than 10.The first update to the multi-object tracker must contain at least one detection.
The tracker supports strict single-precision code generation with these restrictions:
You must specify the
MaxNumEvents
property as a finite positive integer.You must specify the filter initialization function to return a
trackingEKF
,trackingUKF
,trackingCKF
, ortrackingIMM
object configured with single-precision.
For details, see Generate Code with Strict Single-Precision and Non-Dynamic Memory Allocation.
The tracker supports non-dynamic memory allocation code generation with these restrictions:
You must specify the
MaxNumEvents
property as a finite positive integer.You must specify the filter initialization function to return a
trackingEKF
,trackingUKF
,trackingCKF
, ortrackingIMM
object.You must specify the
MaxNumDetections
property as a finite integer.You cannot specify the
ClassFuionMethod
property as"Bayes"
.
For details, see Generate Code with Strict Single-Precision and Non-Dynamic Memory Allocation.
After enabling non-dynamic memory allocation code generation, consider using these properties to set bounds on the local variables in the tracker:
EnableMemoryManagement
MaxNumDetectionsPerSensor
MaxNumDetectionsPerCluster
MaxNumTracksPerCluster
ClusterViolationHandling
Version History
Introduced in R2019aR2024a: Tune additional properties
You can tune the following properties:
AssignmentThreshold
ConfirmationThreshold
DeletionThreshold
DetectionProbability
InitializationThreshold
ClutterDensity
NewTargetDensity
DeathRate
InitialClassProbabilities
HitMissThreshold
R2024a: Generate code automatically
You can generate C/C++ code automatically by using the generateCode
object function.
R2023a: Fuse detection classification information
Using the trackerJPDA
System object, you can fuse detection
classification information by specifying the ClassFusionMethod
property
of the object as "Bayes"
. With this specification, the tracker uses the
detection classification information to assign tracks based on the Bayesian Product Class
Fusion algorithm.
Additionally, you can use these two properties to adjust the class fusion algorithm:
InitialClassProbabilities
— A priori class probability of new tracks.ClassFusionWeight
— The weight of class fusion likelihood in the mixed likelihood.
See Also
Functions
Objects
objectDetection
|trackingKF
|trackingUKF
|trackingEKF
|trackingCKF
|trackingIMM
|trackingABF
|trackHistoryLogic
|objectTrack
|staticDetectionFuser
|trackerTOMHT
|trackerGNN
Blocks
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)