.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/plot_tracking.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_plot_tracking.py: Velocity-aware clustering and tracking ====================================== Track two synthetic radar targets through crossing trajectories. Each frame contains several noisy points per target; DBSCAN produces measurements for the stateful Kalman/EKF tracker. .. GENERATED FROM PYTHON SOURCE LINES 9-92 .. image-sg:: /auto_examples/images/sphx_glr_plot_tracking_001.png :alt: GNN tracks with radial-velocity EKF updates :srcset: /auto_examples/images/sphx_glr_plot_tracking_001.png :class: sphx-glr-single-img .. code-block:: Python from __future__ import annotations import numpy as np from matplotlib import pyplot as plt from pyradar.base import PointCloud, TrackingConfig from pyradar.rsp import MultiTargetTracker, dbscan rng = np.random.default_rng(4) tracker = MultiTargetTracker( TrackingConfig( enabled=True, dimensions=2, processNoise=0.8, measurementNoise=0.3, radialVelocityNoise=0.5, gatingThreshold=13.8, confirmationHits=2, deletionMisses=4, ) ) measurementHistory: list[np.ndarray] = [] trackHistory: dict[int, list[np.ndarray]] = {} for frameId in range(32): time = frameId * 0.1 centres = np.array( [ [7.0 + 0.7 * time, -2.0 + 1.1 * time, 0.0], [10.0 - 0.4 * time, 2.0 - 1.0 * time, 0.0], ] ) velocities = np.array([[0.7, 1.1, 0.0], [-0.4, -1.0, 0.0]]) xyz = np.vstack([centre + rng.normal(0, 0.09, size=(8, 3)) for centre in centres]) fullVelocity = np.repeat(velocities, 8, axis=0) unit = xyz / np.linalg.norm(xyz, axis=1, keepdims=True) radial = np.sum(fullVelocity * unit, axis=1) points = PointCloud( xyz=xyz, power=np.ones(xyz.shape[0]), snr=np.full(xyz.shape[0], 15.0), radialVelocity=radial, sourceBins=np.zeros((xyz.shape[0], 4), dtype=np.int64), timestamp=time, frameId=frameId, ) clusters = dbscan( points, eps=0.42, minSamples=3, velocityScale=0.25, dimensions=2, ) tracks = tracker.update(points, clusters=clusters, timestamp=time) measurementHistory.append(clusters.centroid.copy()) for index, trackId in enumerate(tracks.trackId): if tracks.status[index] != "deleted": trackHistory.setdefault(int(trackId), []).append( tracks.position[index].copy() ) figure, axis = plt.subplots(figsize=(6, 4.5), constrained_layout=True) measurements = np.vstack(measurementHistory) axis.scatter( measurements[:, 0], measurements[:, 1], s=10, alpha=0.35, color="0.35", label="cluster centroids", ) for trackId, positions in sorted(trackHistory.items()): path = np.asarray(positions) axis.plot(path[:, 0], path[:, 1], marker=".", label=f"track {trackId}") axis.set( xlabel="Forward x (m)", ylabel="Left y (m)", title="GNN tracks with radial-velocity EKF updates", ) axis.legend() axis.axis("equal") plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.164 seconds) .. _sphx_glr_download_auto_examples_plot_tracking.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_tracking.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_tracking.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_tracking.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_