Load a radar configuration file
Build a Radar from the flat FMCW configuration format with Radar.from_dict or Radar.from_json, and add a receiver chain, pose or pattern in the same call.
Many mmWave tools describe an FMCW radar as one flat mapping in the units a TI radar configuration file uses. Radar.from_dict reads that mapping, and Radar.from_json reads it from a JSON file. Use this page to load such a file and to know exactly which keys it accepts.
Load a mapping#
from witwin.radar import Noise, Radar
CONFIG = {
"num_tx": 3, "num_rx": 4, "fc": 77e9, "slope": 60.012, "adc_samples": 256,
"adc_start_time": 6, "sample_rate": 4400, "idle_time": 7, "ramp_end_time": 65,
"chirp_per_frame": 128, "power": 15,
"tx_loc": [[0, 0, 0], [4, 0, 0], [2, 1, 0]],
"rx_loc": [[-6, 0, 0], [-5, 0, 0], [-4, 0, 0], [-3, 0, 0]],
}
radar = Radar.from_dict(CONFIG, noise=Noise(figure=10.0), seed=1, position=(0.0, 1.0, 0.0), look_at=(0.0, 1.0, -1.0))Keyword arguments after the mapping are Radar fields in SI units. They override what the mapping produced, so you attach a receiver chain, a pose, a seed or a device without editing the file.
To read the same mapping from a file:
radar = Radar.from_json("configs/iwr1843.json", noise=Noise(figure=10.0))Required keys#
| Key | Unit | Becomes |
|---|---|---|
num_tx | count | Must equal the length of tx_loc |
num_rx | count | Must equal the length of rx_loc |
fc | Hz | Radar.carrier |
slope | MHz/µs | Fmcw.slope (Hz/s) |
adc_samples | count | Fmcw.samples_per_chirp |
adc_start_time | µs | Fmcw.adc_start (s) |
sample_rate | ksps | Fmcw.sample_rate (Hz) |
idle_time | µs | Fmcw.idle (s) |
ramp_end_time | µs | Fmcw.ramp_end (s) |
chirp_per_frame | count | Fmcw.chirps_per_frame |
power | dBm | Radar.power |
tx_loc | half wavelengths | Radar.tx, with antenna_unit="half_wavelength" |
rx_loc | half wavelengths | Radar.rx |
Optional keys#
| Key | Meaning |
|---|---|
output_domain | "spectrum" (default) or "beat". Becomes Fmcw.output |
antenna_pattern | An element pattern, in one of the two forms below |
A separable pattern gives one cut per axis:
"antenna_pattern": {
"kind": "separable",
"x_angles_deg": [-90, -45, 0, 45, 90], "x_values": [0.0, 0.6, 1.0, 0.6, 0.0],
"y_angles_deg": [-90, -45, 0, 45, 90], "y_values": [0.0, 0.7, 1.0, 0.7, 0.0]
}A map gives the gain on a full grid. values holds one row per y_angles_deg sample, and each row holds one value per x_angles_deg sample:
"antenna_pattern": {
"kind": "map",
"x_angles_deg": [-60, 0, 60], "y_angles_deg": [-60, 0, 60],
"values": [[0.2, 0.5, 0.2], [0.5, 1.0, 0.5], [0.2, 0.5, 0.2]]
}If kind is missing, a block with values is read as a map and any other block as separable. Gains are linear power gains normalized to at most 1, and angles are in degrees; see Use antenna patterns.
Refused keys#
Any other key raises ValueError that names it. This includes processing settings that older configuration files carried, such as frame_per_second, num_doppler_bins, num_range_bins and num_angle_bins. Frame times are the times argument of simulate, and bin counts follow from the waveform. Remove those keys before loading.
Non-FMCW radars#
The flat format describes FMCW only. For an OFDM or pulsed radar, build the Radar directly, or pass waveform=Ofdm(...) as an override. See Use OFDM and pulsed waveforms.
Typed construction#
The same radar without a mapping, using Fmcw.from_ti for the vendor units and metres for the antennas:
from witwin.radar import Fmcw, Radar
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)
radar = Radar(
carrier=77e9, waveform=fmcw, power=15.0, antenna_unit="half_wavelength",
tx=[(0, 0, 0), (4, 0, 0), (2, 1, 0)],
rx=[(-6, 0, 0), (-5, 0, 0), (-4, 0, 0), (-3, 0, 0)],
)