In [1]:
import radarsimpy
radarsimpy.__version__
Out[1]:
'10.0.0'

FMCW Radar with a Plate¶



This is an example of using RadarSimPy to simulate an FMCW radar with a plate.


Setup FMCW radar¶

Transmitter¶

Setup the basic transmitter parameters through Transmitter module.

The following table lists the parameters in this example.

Parameter Variable in Transmitter Value
Frequency ($f$) f [1e9-50e6, 1e9+50e6] GHz
Time ($T$) t 80e-6 s
Transmitted power ($P_t$) tx_power 15 dBm
Pulse repetition period ($PRP$) prp 0.5 s
Number of pulses pulses 180

Receiver¶

Setup the receiver parameters through Receiver module.

The parameters of the receiver are listed in the table below.

Parameter Variable in Receiver Value
Sampling rate ($f_s$) fs 2 Msps
Noise figure ($NF$) noise_figure 8 dB
RF gain/loss ($G_{rf}$) rf_gain 20 dB
Load resistor ($R_L$) load_resistor 500 $\Omega$
Baseband voltage gain ($G_{BB}$) baseband_gain 30 dB
In [2]:
import numpy as np
from radarsimpy import Radar, Transmitter, Receiver

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 = Radar(transmitter=tx, receiver=rx)

Plate model¶

The plate model is with .stl. It can be imported by using meshio module.

In [3]:
target_1 = {
    'model': '../models/plate5x5.stl',
    'location': (200, 0, 0),
    'speed': (0, 0, 0),
    'rotation_rate': (1, 0, 0),
}

targets = [target_1]

Plot the 3D mesh of the plate

In [4]:
import meshio

import plotly.graph_objs as go
from IPython.display import SVG, display

mesh_data = meshio.read('../models/plate5x5.stl')

fig = go.Figure()

fig.add_trace(go.Mesh3d(x=mesh_data.points[:, 0],
                        y=mesh_data.points[:, 1],
                        z=mesh_data.points[:, 2],
                        i=mesh_data.cells[0].data[:, 0],
                        j=mesh_data.cells[0].data[:, 1],
                        k=mesh_data.cells[0].data[:, 2],
                        intensity=mesh_data.points[:, 2],
                        colorscale='Viridis'
                        ))

# fig.show()
display(SVG(fig.to_image(format='svg', scale=1)))
−2−1012

Raytracing¶

In [5]:
from radarsimpy.rt import scene
import time

tic = time.time()
data = scene(radar, targets, density=1, noise=False, level='pulse')

baseband = data['baseband']
toc = time.time()

print('Exec time:', toc-tic, 's')
Exec time: 0.6394860744476318 s

Radar signal processing¶

Range processing¶

In [6]:
from scipy import signal
import radarsimpy.processing as proc

range_window = signal.chebwin(radar.samples_per_pulse, at=60)
range_profile = proc.range_fft(baseband, range_window)

Plot range profiles

In [7]:
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')
display(SVG(fig.to_image(format='svg', scale=1)))
050100150160140120100806040200−80−70−60−50−40−30−20−10010Range binChirp index

Peak amplitude versus observation angle

In [8]:
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)')
display(SVG(fig.to_image(format='svg', scale=1)))
020406080−80−60−40−200Observation angle (deg)Peak amplitude (dB)
In [ ]: