decide op• Data kinds: signal → table
• Call: import fullseye as fs; fs.ledger.doppler_track(signal, fs, *, f_high: 'float' = 960.0, f_low: 'float' = 770.0, c: 'float' = 343.0, smooth: 'float' = 0.005, guard: 'float' = 0.01, edge: 'float' = 0.05, v_tol: 'float' = 1.0, verdict_window: 'float' = 0.5) -> 'Dict[str, object]' (to call the implementation directly, import drivedecide; drivedecide.doppler_track(signal, fs, *, f_high: 'float' = 960.0, f_low: 'float' = 770.0, c: 'float' = 343.0, smooth: 'float' = 0.005, guard: 'float' = 0.01, edge: 'float' = 0.05, v_tol: 'float' = 1.0, verdict_window: 'float' = 0.5) -> 'Dict[str, object]'; from the registry, opsdrive.get("doppler_track"))
• GPU: none (CPU reference implementation only)
Estimates the instantaneous frequency from the siren sound and determines whether it is approaching or receding.
1. Phase difference of the analytic signal (Hilbert transform via FFT) → instantaneous frequency f(t) = arg(z[n+1] z̄[n]) fs / 2π.
2. Moving median of width smooth seconds.
3. At each time, of the 2 nominal tones (f_high / f_low) the one with the closer ratio is taken as "the emitted tone"; Doppler factor D = f / f_nom, line-of-sight velocity v_r = c (1 − 1/D) (doppler_shift solved for v_r).
4. guard seconds before and after a tone switch (jump of the median > 20 Hz) and edge seconds at both ends are invalid (valid = False).
5. Verdict: median of the valid v_r over the last verdict_window seconds greater than +v_tol → "approaching", less than −v_tol → "receding", in between → "abeam". state is the same verdict at each time ("unknown" where invalid).
Limit of mistaking the nominal tone: the dividing line for assignment is the geometric mean √(f_h f_l). The low tone crosses it when approaching at v_r = c (1 − √(f_l/f_h)), the high tone crosses it when receding at v_r = −c (√(f_h/f_l) − 1). For 960/770 Hz these are +35.8 m/s (129 km/h) and −40.0 m/s. Faster line-of-sight velocities are misassigned (fixed in the tests).
• Sample-data catalog (download URLs / licences) — 2-D uses skimage.data (BSD/public domain) plus synthetic images; 3-D lists download URLs for real data sources (Stanford, PDS, …).
• Operator provenance and references — the sources of the research/methods this op family came from.
• The canonical algorithm (author, year) and its uses are named in the family usage guide above.
• poc_driving_decisions — py -3.11 examples/poc_driving_decisions.py
table as input)course_layout · course_occupancy · course_contains · world_build · world_camera · world_move · lidar_scan · rss_longitudinal_same
decide)mirror_reflection_matrix · mirror_virtual_camera · mirror_aim_normal · convex_mirror_fov · mirror_blind_zone · check_sequence_score · signal_phase_plan · signal_state
*Provenance: drivedecide.py — DRIVE operator registry. This per-op note is generated by tools/opdocs.py md (do not hand-edit).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.