fix: align all range/carrier/velocity values to PLFM hardware + FPGA bug fixes
- Correct carrier from 10.525/10 GHz to 10.5 GHz (verified ADF4382 config) - Correct range-per-bin from 4.8/5.6/781.25 m to 24.0 m (matched-filter) - Correct velocity resolution from 1.484 to 2.67 m/s/bin (PRI-based) - Correct processing rate from 4 MSPS to 100 MSPS (post-DDC) - Correct max range from 307/5000/50000 m to 1536 m (64 bins x 24 m) - Add WaveformConfig.pri_s field (167 us PRI for velocity calculation) - Fix short chirp chirp_complete deadlock (Bug A) - Remove dead short_chirp ports, rename long_chirp to ref_chirp (Bug B) - Fix stale latency comment 2159 -> 3187 cycles (Bug C) - Create radar_params.vh as single source of truth for FPGA parameters - Lower RadarSettings.cpp map_size validation bound from 1000 to 100 - Add PLFM hardware constants to golden_reference.py - Update all GUI versions, tests, and cross-layer contracts All 244 tests passing (167 Python + 21 MCU + 29 cross-layer + 27 FPGA)
This commit is contained in:
@@ -108,12 +108,12 @@ class RadarSettings:
|
||||
range_resolution and velocity_resolution should be calibrated to
|
||||
the actual waveform parameters.
|
||||
"""
|
||||
system_frequency: float = 10e9 # Hz (carrier, used for velocity calc)
|
||||
range_resolution: float = 781.25 # Meters per range bin (default: 50km/64)
|
||||
velocity_resolution: float = 1.0 # m/s per Doppler bin (calibrate to waveform)
|
||||
max_distance: float = 50000 # Max detection range (m)
|
||||
map_size: float = 50000 # Map display size (m)
|
||||
coverage_radius: float = 50000 # Map coverage radius (m)
|
||||
system_frequency: float = 10.5e9 # Hz (PLFM TX LO, verified from ADF4382 config)
|
||||
range_resolution: float = 24.0 # Meters per decimated range bin (c/(2*100MSPS)*16)
|
||||
velocity_resolution: float = 2.67 # m/s per Doppler bin (lam/(2*32*167us))
|
||||
max_distance: float = 1536 # Max detection range (m) -- 64 bins x 24 m (3 km mode)
|
||||
map_size: float = 1536 # Map display size (m)
|
||||
coverage_radius: float = 1536 # Map coverage radius (m)
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -196,42 +196,44 @@ class TileServer(Enum):
|
||||
class WaveformConfig:
|
||||
"""Physical waveform parameters for converting bins to SI units.
|
||||
|
||||
Encapsulates the radar waveform so that range/velocity resolution
|
||||
Encapsulates the PLFM radar waveform so that range/velocity resolution
|
||||
can be derived automatically instead of hardcoded in RadarSettings.
|
||||
|
||||
Defaults match the ADI CN0566 Phaser capture parameters used in
|
||||
the golden_reference cosim (4 MSPS, 500 MHz BW, 300 us chirp).
|
||||
Defaults match the PLFM hardware: 100 MSPS post-DDC processing rate,
|
||||
20 MHz chirp bandwidth, 30 us long chirp, 167 us PRI, 10.5 GHz carrier.
|
||||
The receiver uses matched-filter pulse compression (NOT deramped FMCW),
|
||||
so range-per-bin = c / (2 * fs_processing) * decimation_factor.
|
||||
"""
|
||||
|
||||
sample_rate_hz: float = 4e6 # ADC sample rate
|
||||
bandwidth_hz: float = 500e6 # Chirp bandwidth
|
||||
chirp_duration_s: float = 300e-6 # Chirp ramp time
|
||||
center_freq_hz: float = 10.525e9 # Carrier frequency
|
||||
n_range_bins: int = 64 # After decimation
|
||||
sample_rate_hz: float = 100e6 # Post-DDC processing rate (400 MSPS / 4)
|
||||
bandwidth_hz: float = 20e6 # Chirp bandwidth (Phase 1 target: 30 MHz)
|
||||
chirp_duration_s: float = 30e-6 # Long chirp ramp (informational only)
|
||||
pri_s: float = 167e-6 # Pulse repetition interval (chirp + listen)
|
||||
center_freq_hz: float = 10.5e9 # TX LO carrier (verified: ADF4382 config)
|
||||
n_range_bins: int = 64 # After decimation (3 km mode)
|
||||
n_doppler_bins: int = 32 # After Doppler FFT
|
||||
fft_size: int = 1024 # Pre-decimation FFT length
|
||||
decimation_factor: int = 16 # 1024 → 64
|
||||
|
||||
@property
|
||||
def range_resolution_m(self) -> float:
|
||||
"""Meters per decimated range bin (FMCW deramped baseband).
|
||||
"""Meters per decimated range bin (matched-filter receiver).
|
||||
|
||||
For deramped FMCW: bin spacing = c * Fs * T / (2 * N_FFT * BW).
|
||||
For matched-filter pulse compression: bin spacing = c / (2 * fs).
|
||||
After decimation the bin spacing grows by *decimation_factor*.
|
||||
This is independent of chirp bandwidth (BW affects resolution, not
|
||||
bin spacing).
|
||||
"""
|
||||
c = 299_792_458.0
|
||||
raw_bin = (
|
||||
c * self.sample_rate_hz * self.chirp_duration_s
|
||||
/ (2.0 * self.fft_size * self.bandwidth_hz)
|
||||
)
|
||||
raw_bin = c / (2.0 * self.sample_rate_hz)
|
||||
return raw_bin * self.decimation_factor
|
||||
|
||||
@property
|
||||
def velocity_resolution_mps(self) -> float:
|
||||
"""m/s per Doppler bin. lambda / (2 * n_doppler * chirp_duration)."""
|
||||
"""m/s per Doppler bin. lambda / (2 * n_doppler * PRI)."""
|
||||
c = 299_792_458.0
|
||||
wavelength = c / self.center_freq_hz
|
||||
return wavelength / (2.0 * self.n_doppler_bins * self.chirp_duration_s)
|
||||
return wavelength / (2.0 * self.n_doppler_bins * self.pri_s)
|
||||
|
||||
@property
|
||||
def max_range_m(self) -> float:
|
||||
|
||||
Reference in New Issue
Block a user