|Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.|
Target tracking from raw radar detectionsDescription: Guide to filtering raw detections into tracked object detections
Tutorial Level: INTERMEDIATE
Next Tutorial: Tracking object Cartesian pose
Most radar sensors designed for applications in autonomous systems output what are known informally as raw detections (or targets). These are the direct result of applying standard peak-finding algorithms like CFAR on returned signals converted to the frequency domain.
The "peaks" of this multidimensional data correspond to detected objects; depending on the algorithm used, the resolutions of the sensor and so on, there may be many such detections - for example, from the K79 imaging radar. In this case, we may not necessarily care about the geometry of an object inferred from the group of targets but rather seek a stable detection of the object over time for applications like collision avoidance. We refer to this as a tracked detection (target), and it involves additional processing either on or offboard the radar in order to aggregate information from the many individual returns.
The basic idea behind implementing a filter which outputs tracked targets from periodic scans of raw targets is to maintain the state of potential objects and update them with new data as it arrives, and publishing these objects only when they have been stably tracked for some time.
Consider the figure below. In the top row, the detections evolve over time as the objects move around; even as the cross one another's paths, assuming the framerate is high enough, it's not terribly difficult to "connect the dots" in range-doppler space to track them. The second row is much more realistic, however - there are many returns from each object, plus background noise, which make it difficult to tell where the objects move and even how many distinct objects are in the scene. The final row shows the solution we seek for the tracking problem.
Theory and Implementation
The tracking filter is essentially a bank of simple Kalman filters, each maintaining the state of a tracked object in spherical coordinates. The flowchart below describes roughly how the filter works.
Essentially, a main thread continually updates the filters in the bank using the process model, while new radar data triggers a callback in which detections (targets) are evaluated against the existing filters in the bank. If a target is consistent with a filter's state, it passes through that filter's validation gate and triggers a Kalman filter update. If a target is not consistent with any filter, it is pushed back as a new filter. If a filter has not been updated within a specified timeout, it is removed from the bank.
The state of each instance of the filter is
latex error! exitcode was 2 (signal 0), transscript follows: [Thu Dec 02 06:47:54.279390 2021] [:error] [pid 16960] failed to exec() latex
and the process model is simply
latex error! exitcode was 2 (signal 0), transscript follows: [Thu Dec 02 06:47:54.291338 2021] [:error] [pid 16961] failed to exec() latex
Or, in the matrix form
latex error! exitcode was 2 (signal 0), transscript follows: [Thu Dec 02 06:47:54.302437 2021] [:error] [pid 16962] failed to exec() latex
we can write
where F is the state transition matrix, L is the process noise matrix, and
latex error! exitcode was 2 (signal 0), transscript follows: [Thu Dec 02 06:47:54.315753 2021] [:error] [pid 16963] failed to exec() latex
is the process noise vector. The noise terms
latex error! exitcode was 2 (signal 0), transscript follows: [Thu Dec 02 06:47:54.327023 2021] [:error] [pid 16964] failed to exec() latex
are the process noise on speed, azimuth and elevation angles, respectively. These are each assumed to be normally distributed with specified standard deviations.
The measurement model simply measures the state exactly, plus additive noise:
latex error! exitcode was 2 (signal 0), transscript follows: [Thu Dec 02 06:47:54.339946 2021] [:error] [pid 16965] failed to exec() latex
Or, in the matrix form
latex error! exitcode was 2 (signal 0), transscript follows: [Thu Dec 02 06:47:54.351965 2021] [:error] [pid 16966] failed to exec() latex
we can write
where H is the measurement model matrix and
latex error! exitcode was 2 (signal 0), transscript follows: [Thu Dec 02 06:47:54.366131 2021] [:error] [pid 16967] failed to exec() latex
is the measurement noise vector. The noise terms
latex error! exitcode was 2 (signal 0), transscript follows: [Thu Dec 02 06:47:54.378094 2021] [:error] [pid 16968] failed to exec() latex
are the measurement noise on range, speed, azimuth and elevation angles, respectively. These are each assumed to be normally distributed with specified standard deviations.
As detailed on the ainstein_radar_filters documentation, the tracking filter node has the following structure:
Subscribed Topics~radar_in (ainstein_radar_msgs/RadarTargetArray)
- Radar detections (targets) to be used for outputting tracked targets.
Published Topics~tracked (ainstein_radar_msgs/RadarTargetArray)
- Tracked targets output after updating Kalman Filters.
- Bounding boxes corresponding to each tracked target, formed from all raw detections associated with that tracked target after the current update.
Parameters~filter_update_rate (int, default: 20)
- Rate at which the filter is run, in Hz.
- Minimum time a target must be tracked before being published, in seconds (DYNAMICALLY-RECONFIGURABLE).
- Maximum time a tracked target can not be updated before being dropped, in seconds (DYNAMICALLY-RECONFIGURABLE).
- Validation gate confidence threshold map - see here for options (DYNAMICALLY-RECONFIGURABLE).
In most cases, it should be sufficient to tune the four filter parameters above based on the application - see below for some guidance on tuning. Always rosrun rqt_reconfigure rqt_reconfigure to tune these parameters dynamically, then save your settings and load them using functionality from dynamic_reconfigure.
filter_update_rate: This is the fixed rate at which the tracking is run, allowing to fill in the gaps between radar scans and provide tracked object information continuously. When no radar data is available, the simple kinematic model is integrated using the current state estimate for each object, so the object could drift considerably before being dropped from the filter.
filter_min_time: This is the time, in seconds, an object must be tracked before it's published in the tracked targets array. For fast-moving objects (eg tracking cars) this time should be set lower, however lowering the minimum time can lead to noise appearing as tracked targets.
filter_timeout: This is the time, in seconds, an object can be tracked purely from the kinematic model before being dropped due to lack of radar measurement updates. This should be set according to the radar's actual output rate, with a longer timeout for slower output rates. Of course, a longer timeout also means that targets may be spuriously tracked even when they're not visible to the sensor.
filter_val_gate_thresh: This is the threshold which, roughly, controls how much measurement error to allow when updating a tracked target from raw detections. It's specified as a confidence level percentage on the radar data, with the idea being that a higher confidence level (up to 99.5%) means much stricter use of data in updating tracked targets than a low one (down to 25.0%). The implication is that high confidence allows multiple targets in the vicinity of one another to be tracked independently, while a low confidence might merge those targets. It's easier to keep a stable track on an object with a low confidence, but it also means that the estimate is easily corrupted by data which is far from the true position. Consider again the problem in the image below. In the final scan, three objects are still clearly visible, but they begin to overlap; with a low confidence, these objects may merge into a single tracked object. With a high confidence, we may preserve the three object tracks but also start tracking an object from the noise down in the bottom left, for example.
Kalman Filter Tuning
The default parameters for the underlying Kalman Filter which is run per tracked object were tuned for people tracking using the K79 imaging radar. For other radars and applications, it may be necessary to re-tune these parameters for better performance. The parameters and their descriptions are listed below.
Initial Uncertainty ParametersThese parameters describe the initial uncertainty when the filter is initialized. Since the filter is initialized from an actual radar measurement, this should be based on the radar resolution.
- Initial range standard deviation, in meters.
- Initial speed standard deviation, in meters per second.
- Initial azimuth angle standard deviation, in degrees.
- Initial elevation angle standard deviation, in degrees.
Process Model Noise ParametersThese parameters describe the additive process model uncertainties. These are functions of the accuracy of the process model; since we use random walks to model the dynamics of the angles, their uncertainty is set high.
- Speed process noise standard deviation, in meters per second.
- Azimuth angle process noise standard deviation, in degrees.
- Elevation angle process noise standard deviation, in degrees.
Measurement Model Noise ParametersThese parameters describe the additive measurement model uncertainties. These are again loosely based on the radar data resolution/accuracy, however they were tuned with considerably higher uncertainty than that of the radar data in order to promote smooth tracking specifically for the people tracking application.
- Range measurement noise standard deviation, in meters.
- Speed measurement noise standard deviation, in meters per second.
- Azimuth angle measurement noise standard deviation, in degrees.
- Elevation angle measurement noise standard deviation, in degrees.