Waveforms
The Fmcw, Ofdm and Pulsed waveform records, their fields, units, defaults and derived properties, and Fmcw.from_ti for vendor units.
A waveform record sets the timing of one frame and the slow-time and fast-time axes of the cube. All three are frozen dataclasses in SI units and are passed to Radar(waveform=...).
from witwin.radar import Fmcw, Ofdm, PulsedThe physics behind each waveform is on Radar and waveforms.
| Record | kind | Cube axes after frame |
|---|---|---|
Fmcw | "fmcw" | tx, rx, chirp, range_bin or sample |
Ofdm | "ofdm" | tx, rx, symbol, subcarrier |
Pulsed | "pulsed" | tx, rx, pulse, sample |
Fmcw#
class Fmcw(slope, sample_rate, samples_per_chirp, chirps_per_frame, adc_start, idle, ramp_end, output='spectrum')One FMCW chirp and its ADC window. With several transmitters, the chirps are shared in time-division multiplexing.
Chirp slope, Hz/s. 60.012e12 is 60.012 MHz/µs.
ADC sample rate, samples/s.
ADC samples per chirp. The length of the fast axis.
Chirps per frame. The length of the slow axis.
ADC start time after the ramp starts, s.
Idle time before each ramp, s.
Ramp duration, s.
'spectrum'"spectrum" returns the normalized range spectrum (fast axis range_bin). "beat" returns the time-domain ADC samples (fast axis sample).
Raises ValueError if sample_rate or ramp_end is not positive, samples_per_chirp or chirps_per_frame is not a positive int, slope or adc_start is not finite, idle is negative, or output is not "spectrum" or "beat".
| Property | Returns |
|---|---|
kind | "fmcw" (class attribute). |
chirp_period | idle + ramp_end, s. |
bandwidth | Sampling bandwidth a thermal-noise stage integrates over, Hz. Equal to sample_rate. |
fmcw = Fmcw(slope=60.012e12, sample_rate=4.4e6, samples_per_chirp=256, chirps_per_frame=128,
adc_start=6e-6, idle=7e-6, ramp_end=65e-6)
print(fmcw.chirp_period) # 7.2e-05Fmcw.from_ti#
Fmcw.from_ti(*, slope_mhz_per_us, sample_rate_ksps, samples_per_chirp, chirps_per_frame,
adc_start_us, idle_us, ramp_end_us, output='spectrum') -> FmcwBuild from the units a TI-style configuration file uses. Each argument name carries its unit.
fmcw = Fmcw.from_ti(slope_mhz_per_us=60.012, sample_rate_ksps=4400, samples_per_chirp=256,
chirps_per_frame=128, adc_start_us=6, idle_us=7, ramp_end_us=65)Returns Fmcw in SI units.
Fmcw.to_spec#
Fmcw.to_spec(*, carrier, num_tx=1, num_rx=1, offset=0.0) -> FmcwSpecThe SI synthesis spec. You rarely need it; Radar.waveform_spec() calls it with the radar's own carrier and array. See Synthesis.
Ofdm#
class Ofdm(subcarrier_spacing, num_subcarriers, cyclic_prefix, num_symbols, max_expected_delay,
subcarrier_origin='f_ref_at_n0')One OFDM symbol grid. The cube is the channel frequency response per symbol and subcarrier.
Subcarrier spacing, Hz.
Number of subcarriers. The length of the fast axis.
Cyclic prefix duration, s.
Symbols per frame. The length of the slow axis.
Longest round-trip delay the radar is configured for, s. Must be shorter than cyclic_prefix.
'f_ref_at_n0'Where subcarrier 0 sits. The only value pins subcarrier 0 to the carrier, so subcarrier n is at carrier + n · subcarrier_spacing.
| Property | Returns |
|---|---|
kind | "ofdm" (class attribute). |
bandwidth | Occupied band, num_subcarriers · subcarrier_spacing, Hz. |
sample_rate | Sample rate of the symbol grid, Hz. Equal to bandwidth. |
Raises ValueError if subcarrier_spacing or cyclic_prefix is not positive, num_subcarriers or num_symbols is not a positive int, or max_expected_delay is negative.
ofdm = Ofdm(subcarrier_spacing=120e3, num_subcarriers=256, cyclic_prefix=0.6e-6,
num_symbols=32, max_expected_delay=0.1e-6)Ofdm.to_spec(*, carrier, offset=0.0) -> OfdmSpec returns the SI synthesis spec.
Pulsed#
class Pulsed(pulse_kind, pulse_width, bandwidth, pri, num_pulses, sample_rate, num_samples,
range_gate_start, max_expected_delay_rate=0.0, pulse_normalization='unit_energy')One pulse train and its range gate. The cube is the received baseband train, which is the matched-filter input.
"rect" for a rectangular pulse or "lfm" for a linear frequency-modulated pulse.
Pulse duration, s.
LFM sweep bandwidth, Hz. For "rect", set it to 1 / pulse_width.
Pulse repetition interval, s.
Pulses per frame. The length of the slow axis.
Receiver sample rate, samples/s.
Samples in the range gate. The length of the fast axis.
Delay at which the range gate opens, s.
0.0Configured bound on the round-trip delay rate, s/s. Used to check that the echo does not migrate more than one range cell over the frame.
'unit_energy'Pulse energy normalization. The only value is unit energy.
| Property | Returns |
|---|---|
kind | "pulsed" (class attribute). |
Raises ValueError if pulse_width, bandwidth, pri or sample_rate is not positive, num_pulses or num_samples is not a positive int, or range_gate_start or max_expected_delay_rate is negative.
pulsed = Pulsed(pulse_kind="lfm", pulse_width=1e-6, bandwidth=150e6, pri=50e-6, num_pulses=16,
sample_rate=300e6, num_samples=512, range_gate_start=0.0)Pulsed.to_spec(*, carrier, offset=0.0) -> PulsedSpec returns the SI synthesis spec. The spec checks the pulse against the PRI and the range gate; see Use OFDM and pulsed waveforms.