Skip to main content

Tracking-scenario simulator and replay visualizer over a shared JSONL stream contract

Project description

GeoSol Research Logo

TrackSim (Tracking-Scenario Simulation)

Tracking-scenario simulator and replay visualizer over a shared JSONL stream contract. Generate labeled truth, degrade it into observables across fidelity tiers, replay it through a reference estimator, and scrub the result on a timeline. Requires Python 3.12+.

gri-tracksim is two paired tools joined by one file contract: a simulator that emits truth / input / output streams, and a Dash/Plotly replay viewer that reads them. The boundary is the JSONL contract alone, so the viewer renders the output of any contract-conformant tracker, not just this package's.

The viewer is a 2D replay tool. The 3D analyst app ("Crucible") is a separate, closed product and is not part of this repository.

Key Features

  • Scenario simulator: leg-based truth (straight / turn / climb / hold), degraded observables (geo / TDOA / FDOA / AOA / altitude), and a four-tier fidelity ladder (T0..T3) driven from one physical scene.
  • Declarative scenarios: author scenarios in YAML from the shipped vocabulary - no source checkout required.
  • Reference replay: a single-target IMM replay produces the output stream with forward-prediction horizons.
  • Replay viewer: a 2D top-down ENU map plus linked time-series panes, with a play/scrub timeline.
  • Self-contained contract: a language-agnostic JSONL wire format you can emit from your own tracker and render here.

Capability Tiers

gri-tracksim is built around three ways to use it:

  1. Viz-only consumer - you already have a tracker. Emit the JSONL contract and run gri-tracksim-viz to scrub it.
  2. Scenario author - write scenario YAML from the shipped vocabulary (emitters, legs, tiers, collector presets, noise) and generate the truth / input / output triple. Needs the package; no source.
  3. Vocabulary developer - add new leg primitives, collector geometries, fidelity tiers, or parametric sweeps. These live in registries in the source and require a checkout (see AGENTS.md).

Installation

pip install gri-tracksim          # simulator + replay viewer

Quick Start

Generate a scenario (CLI)

gri-tracksim --list                  # list bundled example scenarios
gri-tracksim air_racetrack           # render a bundled scenario
gri-tracksim air_racetrack --tier T3 # same scene, harder tier
gri-tracksim air_racetrack --seed 7  # same scene, new realization
gri-tracksim my_scenario.yaml        # render your own YAML

The scene name (air_racetrack) describes the physical scenario; --tier (T0-T3) and --seed are orthogonal run knobs layered over it. Each defaults to the scene's own value (a --seed-less scene with no seed: draws a random one), and the effective tier and seed are folded into the output directory so sweeps never clobber: streams land in _scratch/<name>_<tier>_s<seed>/. The output root defaults to _scratch/ (a gitignored scratch dir); override it with -o <dir>.

Scrub a run (viewer)

gri-tracksim-viz _scratch/air_racetrack_T2_s3

Author a scenario in Python

from gri_tracksim.sim import load_scenario, write_scenario_streams

scenario = load_scenario("my_scenario.yaml")
n_truth, n_input, n_output = write_scenario_streams(
    scenario, "_scratch/my_scenario", predict_horizons_s=(10.0, 30.0),
)

Read the contract from your own tracker

from gri_tracksim.contract import Header, load_stream, write_jsonl

header, records = load_stream("output.jsonl")   # parsed Header + event records

You only need gri_tracksim.contract to emit or read the streams - it has no dependency on the simulator or the viewer.

Scenario YAML

A scenario is a single declarative file. All keys but name, origin_lla, dt, and emitters are optional:

name: air_racetrack
origin_lla: [38.0, -77.0, 0.0]   # ENU anchor [lat_deg, lon_deg, alt_m]
dt: 2.0                          # grid step (s)
seed: 3                          # default realization (--seed overrides; random if omitted)
tier: T2                         # default tier (--tier overrides): T0 | T1 | T2 | T3
collectors: diverse              # good | weak | diverse | null
motion: air                      # level (cruise) | air (climb-aware IMM)
noise:
  altitude_std_m: 200.0
emitters:
  E1:
    start_enu: [0.0, 0.0, 1000.0]
    azimuth_deg: 90.0
    speed_mps: 120.0
    legs:
      - {type: straight, duration_s: 30.0}
      - {type: climb, duration_s: 20.0, climb_rate_mps: 10.0}
      - {type: turn, delta_azimuth_deg: 180.0, radius_m: 2000.0}

The leg types (straight, turn, climb, hold), fidelity tiers (T0..T3), collector presets (good, weak, diverse), and replay motion banks (level, level_fx, air) are fixed vocabularies; adding to them is the source-only developer path.

Reference Replay Options

The replay tracker has three orthogonal knobs (defaults are the validated configuration; legacy values remain available for comparison runs):

  • Motion bank (motion: in the YAML): level (cv / turn / static), air (adds a climb mode so altitude changes read as a mode), level_fx (adds a fixed +/- nominal-rate turn pair -- instant turn discrimination when the platform's maneuver-rate class is known; harmful off-nominal).
  • Segmentation (segmentation=): mode_sequence (default) -- a retrospective MAP decode over the whole track, recomputed each scan, which also emits settled (fixed-lag smoothed) mode probabilities per scan; or locked, the online residual-trigger segmenter.
  • Prediction (prediction=): locked (default) -- predict under the current settled segment's model (settle-gated, speed-guarded); evolved or blend for comparison.

Evaluation Harness

Two console scripts score tracker configurations against truth, corpus-wide:

# render + score scenario x seed runs (metrics.json per run, summary.json per sweep)
gri-tracksim-eval --seeds 10 --tier T2 -o _scratch/eval_new
gri-tracksim-eval --seeds 10 --tier T2 --segmentation locked --prediction blend \
    --model-selection mean_ll -o _scratch/eval_legacy   # the legacy stack

# paired (scenario, seed) comparison: median delta, bootstrap CI, sign test
gri-tracksim-compare _scratch/eval_legacy _scratch/eval_new
gri-tracksim-compare _scratch/eval_legacy _scratch/eval_new --scenario boat_racetrack

Per-run metrics cover segmentation (count, boundary error, label accuracy), characterization (instant and settled mode agreement, lock latency, thrash), smoothing (RMS and straight-leg bow, with a truth-boundary oracle bound), and prediction (per-horizon RMS plus the phantom-curve ratio vs a CV extrapolation).

The Stream Contract

Each stream is JSON Lines: a self-describing header record followed by one record per event.

  • truth - {"t", "emitter_id", "pos_enu", "vel_enu", "leg_mode"}
  • input - {"t", "id", "type", ...} where type is one of geo | tdoa | fdoa | aoa | altitude; the stable id (obs_0000...) is what the output's association references.
  • output - the estimator replay (estimate / association / predicted), association keyed back to the input id. Mode-sequence replays also carry settled_t / settled_mode_probabilities: the fixed-lag smoothed mode mix a few scans behind the playhead (the "settled" complement to the instant mode_probabilities); each predicted entry names the model that produced it.
  • smoothed (optional) - one retrospective snapshot per scan: the smoothed trajectory the tracker had settled on by that playhead, plus segments ({model, t_start, t_end}) naming the motion model the smoother used per leg. Segments revise as data accrues, so scrubbing replays the boundary back-dating.

The wire format is plain JSON (no gri types on the wire), so any tracker, in any language, can emit a stream the viewer will render.

Dependencies

A top-tier package in the GRI FOSS ecosystem; a sibling consumer of the same mid-tier libraries as gri-multitrack.

  • gri-geosim (iterative locate), gri-kalman (reference IMM replay), gri-trajectory (legs), gri-obs, gri-pos, gri-ell, gri-utils
  • gri-plot, dash, plotly (the replay viewer)
  • numpy, scipy, pyyaml

Other Projects

Current list of other GRI FOSS Projects we are building and maintaining.

License

MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gri_tracksim-0.3.0.tar.gz (164.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gri_tracksim-0.3.0-py3-none-any.whl (135.7 kB view details)

Uploaded Python 3

File details

Details for the file gri_tracksim-0.3.0.tar.gz.

File metadata

  • Download URL: gri_tracksim-0.3.0.tar.gz
  • Upload date:
  • Size: 164.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for gri_tracksim-0.3.0.tar.gz
Algorithm Hash digest
SHA256 27feea25fe755f6dc28bf3d14d6f6984b38e5628c26413cbf35da41fb54a9cb1
MD5 6d1f10b2da9626257e035087ca0e1e4d
BLAKE2b-256 a8b435472510288cb7e61212b09710d218cc58b707995b1bf99a95948ab553a4

See more details on using hashes here.

File details

Details for the file gri_tracksim-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: gri_tracksim-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 135.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for gri_tracksim-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6fdb39f02c193fc91507d8c81f5fa1010034ed6a662ba5d5a0169f9931eb330d
MD5 90fa6c38eca137e217a51fe1168cdd13
BLAKE2b-256 87c9653a420a156580bda7fa5378e0e7442224c0b5368eb70919411ac811f842

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page