Skip to content

Modular Python package for multi-target tracking with aerial robots, supporting JPDA, distributed tracking, and flexible algorithm combinations.

License

Notifications You must be signed in to change notification settings

robot-perception-group/multi_target_tracking

Repository files navigation

Multi-Target Tracking from Multiple Aerial Robots

A comprehensive Python package for multi-target tracking algorithms, designed with a modular architecture that separates tracking components for flexibility and extensibility.

Overview

The MTT package implements a modular framework for multi-target tracking algorithms. The tracking problem is decomposed into distinct, interchangeable components:

  • Gating: Filters out unlikely measurement-to-track associations
  • Association: Assigns measurements to existing tracks using different algorithms
  • Filtering: Provides single target state estimation (Kalman filters)
  • Track Management: Handles track creation, confirmation, and deletion logic

This modular design allows for easy experimentation with different combinations of algorithms and makes the codebase highly maintainable and extensible. This project was developed as part of the WildCap project.

ROS Integration: For ROS integration and deployment as ROS nodes for real-time multi-target tracking in robotic systems, please see the separate ROS wrapper repository: ROS MTT Repository

Requirements

  • Python 3.8+
  • NumPy ≥ 1.24.0
  • Pandas ≥ 2.0.0
  • SciPy ≥ 1.10.0
  • pyehm ≥ 2.0a1 (for EHM algorithm)

Optional dependencies:

Installation

Standard Installation

# Clone the multi_target_tracking repository from GitHub
git clone https://github.com/robot-perception-group/multi_target_tracking.git

# Change directory to the cloned repository
cd multi_target_tracking

# Install the package (recommended for most users)
pip install .

Development Installation (Editable Mode)

If you want to make changes to the code and have them reflected without reinstalling, use editable mode:

# Install the package in editable mode (for development)
pip install -e .

Installing Murty Algorithm (Optional)

To enable the Multi-Hypothesis Tracker (MHT), you need to install the Murty algorithm package in the root folder:

# Navigate to the root directory
cd path/to/multi_target_tracking

# Clone the murty repository
git clone https://github.com/robot-perception-group/murty.git

# Navigate to the murty directory
cd murty

# Install the murty package
pip install -e .

Note: The Murty algorithm is only required for MultiHypothesisTracker. Other trackers (SingleTargetTracker, JPDATracker) work without this dependency.

Installation Verification

# Test basic installation
from multi_target_tracking.trackers import SingleTargetTracker, JPDATracker
print("✓ Basic tracking functionality available")

# Test Murty algorithm (if installed)
try:
    from multi_target_tracking.trackers import MultiHypothesisTracker
    print("✓ Murty algorithm and MHT available (Note: MHT currently not working)")
except ImportError:
    print("ℹ Murty algorithm not installed")

Quick Start

Basic JPDA Multi-Target Tracking

from multi_target_tracking.trackers import JPDATracker
from multi_target_tracking.filters import KFTrack
from multi_target_tracking.gaters import MahalanobisGater
from multi_target_tracking.likelihoods import MahalanobisLikelihood
from multi_target_tracking.track import MNLogic

# Initialize JPDA tracker
tracker = JPDATracker(
    filter_obj=KFTrack(),
    gater=MahalanobisGater(),
    likelihood=MahalanobisLikelihood(),
    track_logic=MNLogic(),
)

# Process measurements
for timestamp, measurements, source_id in measurement_data:
    tracker.evaluate((timestamp, measurements, source_id))

# Get confirmed tracks
from multi_target_tracking.track import TrackStage
confirmed_tracks = [track for track in tracker.tracks 
                   if track.stage == TrackStage.CONFIRMED]

Package Structure

multi_target_tracking/
├── cfg/mtt_config.yaml     # Configuration parameters
├── distributed_trackers/   # Distributed tracking algorithms
├── filters/                # State estimation filters (Kalman filters)
├── gaters/                 # Measurement gating algorithms
├── likelihoods/            # Likelihood calculation methods
├── track/                  # Track management and scoring logic
├── trackers/               # Single and multi-target trackers
├── measurement.py          # Measurement data structures
└── parameterManager.py     # Parameter management

Key Components

Trackers

  • SingleTargetTracker: Basic single-target tracker for testing
  • JPDATracker: Joint Probabilistic Data Association tracker
  • MultiHypothesisTracker: Multi-Hypothesis Tracker (⚠️ Currently not working)

Distributed Trackers

The package provides two different approaches for multi-robot tracking:

  • DistributedJPDA: Reprocessing approach - Uses a specialized distributed implementation of JPDA that reprocesses measurements when out-of-sequence measurements (OOSMs) arrive. This approach is specific to JPDA and handles temporal synchronization by recomputing association probabilities when late measurements are received.

  • SynchronizedDistributedTracker: Buffering approach - A generic wrapper that can work with any single-robot tracker (JPDA, MHT, etc.). It buffers measurements from multiple drones until all expected measurements for a time window arrive, then processes them synchronously. This approach is compatible with all tracker types but may introduce latency.

Filters

  • KFTrack: Kalman filter for track state estimation
  • KF3D_standalone: Standalone 3D Kalman filter implementation

Configuration

Configure tracking parameters in mtt_config.yaml:

# Detection probabilities
PD: 0.6      # Probability of detection
PG: 1        # Probability of gating
FAR: 0.01    # False alarm rate

# Gating parameters
thresholdMahalanobis: 1.5  # Threshold for Mahalanobis gating
thresholdID: 0.1           # Threshold for ID gating

# Filter parameters
velocityDecayTime: 20.0    # Time constant for velocity decay in filter
offsetDecayTime: 30.0      # Time constant for offset decay in filter

# Track management
maximumTrackLength: None   # Maximum track length kept (None = unlimited)
MN_del_tentative: 10       # Deletions to remove tentative track
MN_confirm_tentative: 15   # Detections to confirm tentative track
MN_del_confirmed: 18       # Deletions to remove confirmed track
MN_intervall: 20           # Total updates considered for M/N logic

# Score logic parameters
lambda: 0.90                    # Forgetting factor (0-1, closer to 1 = slower forgetting)
score_del_confirmed: 0.05       # Score threshold for deletion

Algorithm Comparison

Tracker Use Case Computational Cost Status
SingleTargetTracker Single target, testing Low ✅ Working
JPDATracker Multiple targets Medium ✅ Working
MultiHypothesisTracker Complex scenarios High ⚠️ Not working

Advanced Usage

Multi-Hypothesis Tracking

⚠️ Note: Multi-Hypothesis Tracking is currently not working and under development.

from multi_target_tracking.trackers import MultiHypothesisTracker
from multi_target_tracking.filters import KFTrack
from multi_target_tracking.gaters import MahalanobisGater
from multi_target_tracking.likelihoods import IdLikelihood
from multi_target_tracking.track import MNLogic

# Requires murty algorithm from: https://github.com/robot-perception-group/murty
# WARNING: Currently not functional
tracker = MultiHypothesisTracker(
    filter_obj=KFTrack(),
    gater=MahalanobisGater(),
    likelihood=IdLikelihood(),
    track_logic=MNLogic(),
    max_hypotheses=30,
    pruning_threshold=0.95
)

Distributed Tracking

Reprocessing Approach (JPDA-specific)

from multi_target_tracking.distributed_trackers import DistributedJPDA
from multi_target_tracking.filters import KFTrack
from multi_target_tracking.gaters import MahalanobisGater
from multi_target_tracking.likelihoods import MahalanobisLikelihood
from multi_target_tracking.track import MNLogic

# Reprocessing approach - handles OOSMs by recomputing associations
distributed_tracker = DistributedJPDA(
    filter_obj=KFTrack(),
    gater=MahalanobisGater(),
    likelihood=MahalanobisLikelihood(),
    track_logic=MNLogic(),
    drone_id=1
)

# Process measurements from multiple drones
for timestamp, measurements, drone_id in measurement_data:
    distributed_tracker.add_measurements(timestamp, measurements, drone_id)

tracks = distributed_tracker.tracks

Buffering Approach (Compatible with all trackers)

from multi_target_tracking.distributed_trackers import SynchronizedDistributedTracker
from multi_target_tracking.trackers import JPDATracker
from multi_target_tracking.filters import KFTrack
from multi_target_tracking.gaters import MahalanobisGater
from multi_target_tracking.likelihoods import MahalanobisLikelihood
from multi_target_tracking.track import MNLogic

# Create base tracker (can be any tracker type)
base_tracker = JPDATracker(
    filter_obj=KFTrack(),
    gater=MahalanobisGater(),
    likelihood=MahalanobisLikelihood(),
    track_logic=MNLogic(),
    drone_id=None  # No specific drone ID for multi-drone processing
)

# Buffering approach - waits for measurements from all drones
num_drones = 3
synchronized_tracker = SynchronizedDistributedTracker(base_tracker, num_drones)

# Process measurements (will buffer until all drones report for time window)
for timestamp, measurements, drone_id in measurement_data:
    synchronized_tracker.add_measurements(timestamp, measurements, drone_id)

tracks = synchronized_tracker.tracks

Custom Measurements

from multi_target_tracking import PosMeasurement
import numpy as np

# Position-only measurement
pos_meas = PosMeasurement(
    timestamp=time,
    position=np.array([x, y, z]),
    covariance=cov_matrix,
    id=measurement_id
)

Development

Adding New Components

Inherit from the appropriate base class:

  • Filter: BasicFilter in filters/basic_filter.py
  • Gater: BasicGater in gaters/basic_gater.py
  • Likelihood: BasicLikelihood in likelihoods/basic_likelihood.py
  • Tracker: BasicTracker in trackers/basic_tracker.py
  • Distributed Tracker: BasicDistributedTracker in distributed_trackers/basic_distributed_tracker.py

Acknowledgements

License

GNU General Public License v3.0 - see the LICENSE file for details.

Version

Current version: 0.1.0

About

Modular Python package for multi-target tracking with aerial robots, supporting JPDA, distributed tracking, and flexible algorithm combinations.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages