fix(gui): align radar parameters to FPGA truth (radar_scene.py)

- Bandwidth 500 MHz -> 20 MHz, sample rate 4 MHz -> 100 MHz (DDC output)
- Range formula: deramped FMCW -> matched-filter c/(2*Fs)*decimation
- Velocity formula: use PRI (167 us) and chirps_per_subframe (16)
- Carrier frequency: 10.525 GHz -> 10.5 GHz per radar_scene.py
- Range per bin: 4.8 m -> 24 m, max range: 307 m -> 1536 m
- Fix simulator target spawn range to match new coverage (50-1400 m)
- Remove dead BANDWIDTH constant, add SAMPLE_RATE to V65 Tk
- All 174 tests pass, ruff clean
This commit is contained in:
Jason
2026-04-16 21:35:01 +05:45
parent 161e9a66e4
commit 76cfc71b19
5 changed files with 58 additions and 49 deletions
+10 -10
View File
@@ -98,9 +98,10 @@ class DemoTarget:
__slots__ = ("azimuth", "classification", "id", "range_m", "snr", "velocity")
# Physical range grid: 64 bins x ~4.8 m/bin = ~307 m max
_RANGE_PER_BIN: float = (3e8 / (2 * 500e6)) * 16 # ~4.8 m
_MAX_RANGE: float = _RANGE_PER_BIN * NUM_RANGE_BINS # ~307 m
# Physical range grid: 64 bins x ~24 m/bin = ~1536 m max
# Bin spacing = c / (2 * Fs) * decimation, where Fs = 100 MHz DDC output.
_RANGE_PER_BIN: float = (3e8 / (2 * 100e6)) * 16 # ~24 m
_MAX_RANGE: float = _RANGE_PER_BIN * NUM_RANGE_BINS # ~1536 m
def __init__(self, tid: int):
self.id = tid
@@ -187,10 +188,10 @@ class DemoSimulator:
mag = np.zeros((NUM_RANGE_BINS, NUM_DOPPLER_BINS), dtype=np.float64)
det = np.zeros((NUM_RANGE_BINS, NUM_DOPPLER_BINS), dtype=np.uint8)
# Range/Doppler scaling (approximate)
range_per_bin = (3e8 / (2 * 500e6)) * 16 # ~4.8 m/bin
# Range/Doppler scaling: bin spacing = c/(2*Fs)*decimation
range_per_bin = (3e8 / (2 * 100e6)) * 16 # ~24 m/bin
max_range = range_per_bin * NUM_RANGE_BINS
vel_per_bin = 1.484 # m/s per Doppler bin (from WaveformConfig)
vel_per_bin = 5.34 # m/s per Doppler bin (radar_scene.py: lam/(2*16*PRI))
for t in targets:
if t.range_m > max_range or t.range_m < 0:
@@ -385,7 +386,7 @@ class RadarDashboard:
UPDATE_INTERVAL_MS = 100 # 10 Hz display refresh
# Radar parameters used for range-axis scaling.
BANDWIDTH = 500e6 # Hz — chirp bandwidth
SAMPLE_RATE = 100e6 # Hz — DDC output I/Q rate (matched filter input)
C = 3e8 # m/s — speed of light
def __init__(self, root: tk.Tk, mock: bool,
@@ -526,9 +527,8 @@ class RadarDashboard:
def _build_display_tab(self, parent):
# Compute physical axis limits
range_res = self.C / (2.0 * self.BANDWIDTH) # ~0.3 m per FFT bin
# After decimation 1024→64, each range bin = 16 FFT bins
range_per_bin = range_res * 16
# Bin spacing = c / (2 * Fs_ddc) for matched-filter processing.
range_per_bin = self.C / (2.0 * self.SAMPLE_RATE) * 16 # ~24 m
max_range = range_per_bin * NUM_RANGE_BINS
doppler_bin_lo = 0