import radarsimpy
print("`RadarSimPy` used in this example is version: " + str(radarsimpy.__version__))
`RadarSimPy` used in this example is version: 12.4.0
FMCW Radar with a Plate¶
Introduction¶
An FMCW (Frequency-Modulated Continuous Wave) radar is a type of radar system that uses frequency modulation to continuously transmit a signal with varying frequency. FMCW radar systems are commonly used in various applications, including automotive radar, weather monitoring, navigation, and industrial sensing. They offer several advantages over other radar types, such as pulsed radar.
Here's how FMCW radar works:
Frequency Modulation: In an FMCW radar, the radar transmitter emits a continuous waveform that changes frequency over time. This waveform is typically a sinusoidal signal. The frequency change occurs in a linear or ramp-like manner, hence the name "Frequency-Modulated Continuous Wave."
Transmit and Receive Phases: The radar emits the frequency-modulated signal, which travels towards the target. When the signal encounters an object, a portion of it gets reflected back towards the radar receiver.
Mixing and Beat Frequency: The reflected signal is mixed with the original transmitted signal in the radar receiver. Because the received signal has traveled a certain distance to the target and back, it experiences a frequency shift due to the Doppler effect and the frequency modulation of the transmitted signal. This frequency shift creates a beat frequency that is proportional to the distance and relative velocity of the target.
Signal Processing: By analyzing the beat frequency, the radar system can determine both the range (distance) and velocity of the target. The range is determined by the phase shift of the beat frequency, and the velocity is derived from the rate of change of the beat frequency over time.
Advantages of FMCW radar include:
Continuous Operation: FMCW radars operate continuously without interruptions, making them well-suited for tracking moving targets and providing real-time data.
Range and Velocity Information: FMCW radar can simultaneously provide information about the range and velocity of targets, making it useful for applications such as automotive collision avoidance and speed measurement.
High Range Resolution: FMCW radar systems can achieve high range resolution due to the continuous waveform and the use of frequency modulation.
Simplicity and Cost-Effectiveness: FMCW radar systems can be simpler and more cost-effective to implement compared to some other radar types, like pulsed radar.
Adaptability to Multiple Targets: FMCW radars can handle multiple targets within their field of view due to their continuous operation and the ability to separate different targets based on their individual beat frequencies.
Despite their advantages, FMCW radars also have limitations, such as reduced performance in certain cluttered environments and susceptibility to interference from other radar systems using similar frequencies. However, advancements in signal processing and technology have helped mitigate many of these challenges.
This illustration provides a simulation of an FMCW radar system with a rotating metal plate. This simulation is executed through the raytracing framework available in RadarSimPy
.
Create Radar Model¶
Firstly, import the required modules from radarsimpy
. numpy
will also be needed in this example.
import numpy as np
from radarsimpy import Radar, Transmitter, Receiver
Transmitter¶
Setup the basic transmitter parameters through Transmitter module.
Define a Radar Transmitter¶
As shown in the diagram below, f
and t
are used to define the waveform modulation. For a linear frequency-modulated continuous waveform (FMCW), it can be specified as f = [fstart, fend]
and t = [tstart, tend]
. If t
is a single number t = t0
, which is equivalent to t = [0, t0]
. The bandwidth of the FMCW is abs(fstart - fend)
. prp
is the pulse repetition period, and prp >= (tend - tstart)
.
| prp
| +-----------+
|
| +---f[1]---> / / /
| / / /
| / / /
| / / /
| / / / ...
| / / /
| / / /
| / / /
| +---f[0]--->/ / /
|
| +-------+
| t[0] t[1]
tx_channel = dict(
location=(0, 0, 0),
)
tx = Transmitter(
f=[1e9 - 50e6, 1e9 + 50e6],
t=[0, 80e-6],
tx_power=15,
prp=0.5,
pulses=180,
channels=[tx_channel],
)
rx_channel = dict(
location=(0, 0, 0),
)
rx = Receiver(
fs=2e6,
noise_figure=8,
rf_gain=20,
load_resistor=500,
baseband_gain=30,
channels=[rx_channel],
)
Radar System¶
Use the defined transmitter and receiver to create the radar system.
radar = Radar(transmitter=tx, receiver=rx)
Plate model¶
The plate model is with .stl
.
target_1 = {
"model": "../models/plate5x5.stl",
"unit": "m",
"location": (200, 0, 0),
"speed": (0, 0, 0),
"rotation_rate": (1, 0, 0),
}
targets = [target_1]
Plot the 3D mesh of the plate
import pymeshlab
import plotly.graph_objs as go
from IPython.display import Image
ms = pymeshlab.MeshSet()
ms.load_new_mesh(target_1["model"])
t_mesh = ms.current_mesh()
v_matrix = np.array(t_mesh.vertex_matrix())
f_matrix = np.array(t_mesh.face_matrix())
fig = go.Figure()
fig.add_trace(
go.Mesh3d(
x=v_matrix[:, 0],
y=v_matrix[:, 1],
z=v_matrix[:, 2],
i=f_matrix[:, 0],
j=f_matrix[:, 1],
k=f_matrix[:, 2],
intensity=v_matrix[:, 2],
colorscale="Viridis",
)
)
fig["layout"]["scene"]["aspectmode"] = "data"
fig["layout"]["height"] = 800
# uncomment this to display interactive plot
# fig.show()
# display static image to reduce size on radarsimx.com
img_bytes = fig.to_image(format="jpg", scale=2)
display(Image(img_bytes))
Radar Scene Simulation¶
Use the simulator.sim_radar
module to simulate the baseband samples from the defined radar system and targets.
The output baseband data is a dict including the timestamp and baseband. Both of them are 3-D matrix:
[channels, pulses, ADC samples]
from radarsimpy.simulator import sim_radar
import time
tic = time.time()
data = sim_radar(radar, targets, density=1, level="pulse")
baseband = data["baseband"]
toc = time.time()
print("Exec time:", toc - tic, "s")
Exec time: 9.267109632492065 s
from scipy import signal
import radarsimpy.processing as proc
range_window = signal.windows.chebwin(radar.sample_prop["samples_per_pulse"], at=60)
range_profile = proc.range_fft(baseband, range_window)
Plot range profiles
import plotly.express as px
fig = px.imshow(
20 * np.log10(np.abs(range_profile[0, :, :]) + 0.0001), color_continuous_scale="hot"
)
fig.update_xaxes(title="Range bin")
fig.update_yaxes(title="Chirp index")
# uncomment this to display interactive plot
# fig.show()
# display static image to reduce size on radarsimx.com
img_bytes = fig.to_image(format="jpg", scale=2)
display(Image(img_bytes))
Plot peak amplitude versus observation angle
obs_angle = np.arange(0, 90, 0.5)
fig = px.line(
x=obs_angle, y=20 * np.log10(np.abs(range_profile[0, :, :]) + 0.0001)[:, 133]
)
fig.update_xaxes(title="Observation angle (deg)")
fig.update_yaxes(title="Peak amplitude (dB)")
# uncomment this to display interactive plot
# fig.show()
# display static image to reduce size on radarsimx.com
img_bytes = fig.to_image(format="jpg", scale=2)
display(Image(img_bytes))