This is an example of using RadarSimPy
to simulate an FMCW radar with a corner reflector model above the ground surface. Ray-Tracing/Shoot-and-Bounce-Rays method is used in RadarSimPy
. The ray-tracing engine RadarSimC
, which is built with C++, is integrated in RadarSimPy.
RadarSimPy
is a radar simulation package built with python. Contact me if you are interested in this module.
This notebook is available on my GitHub.
The following table lists the basic parameters of the radar transmitter.
Parameter | Variable in RadarSimPy |
Value |
---|---|---|
Center frequency ($f_c$) | fc | 77 GHz |
Bandwidth ($B$) | bandwidth | 100 MHz |
Transmitted power ($P_t$) | tx_power | 10 dBm |
Rising or falling chirp | slop_type | rising |
Chirp repetition period ($CRP$) | repetition_period | 100 us |
Chirp length ($T$) | pulse_length | 80 us |
Number of chirps | pulses | 256 |
Chirp start delay | delay | 0 s |
The parameters of the receiver are listed in the table below.
Parameter | Variable in RadarSimPy |
Value |
---|---|---|
Sampling rate ($f_s$) | fs | 2 Msps |
Noise figure ($NF$) | noise_figure | 12 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 |
import numpy as np
from radarsimpy import Radar, Transmitter, Receiver
angle = np.arange(-90, 91, 1)
pattern = 20 * np.log10(np.cos(angle / 180 * np.pi) + 0.01)
tx_channel = dict(
location=(0, 0, 0),
azimuth_angle=angle,
azimuth_pattern=pattern,
elevation_angle=angle,
elevation_pattern=pattern,
)
tx = Transmitter(f=[24e9-4000e6, 24e9+4000e6],
t=300e-6,
tx_power=15,
prp=0.0025,
pulses=1280,
channels=[tx_channel])
rx_channel = dict(
location=(0, 0, 0),
azimuth_angle=angle,
azimuth_pattern=pattern,
elevation_angle=angle,
elevation_pattern=pattern,
)
rx = Receiver(fs=2e6,
noise_figure=8,
rf_gain=20,
load_resistor=500,
baseband_gain=30,
channels=[rx_channel])
aperture = dict(
phi=0,
theta=90,
location=[0, 0, 0],
extension=[0.25, 0.25, 0.25, 0.25]
)
radar = Radar(transmitter=tx, receiver=rx, aperture=aperture)
target_1 = {
'model': '../models/fan_3blade.stl',
'location': (10, 0, 0),
'rotation': (0, 0, 0),
'rotation_rate': (0, 20, 0),
'speed': (0, 0, 0)
}
targets = [target_1]
from radarsimpy.rt import scene
import time
tic = time.time()
data = scene(radar, targets, correction=-42, density=0.5, level='pulse')
baseband = data['baseband']
toc = time.time()
print('Exection time:', toc-tic, 's')
Exection time: 11.700995922088623 s
from scipy import signal
import radarsimpy.processing as proc
range_window = signal.chebwin(radar.samples_per_pulse, at=60)
range_profile = proc.cal_range_profile(radar, baseband, range_window)
doppler_window = signal.chebwin(radar.transmitter.pulses, at=60)
range_doppler = proc.cal_range_doppler(
radar, range_profile, doppler_window, fft_shift=True)
import plotly.graph_objs as go
from plotly.offline import iplot
from IPython.display import SVG, display
temp = np.abs(range_doppler[0, :, :])
temp = 20 * np.log10(temp)
range_axis = np.linspace(
0, radar.max_range, radar.samples_per_pulse, endpoint=False)
rng_idx = np.where(np.logical_and(range_axis > 9.5, range_axis < 10.5))
doppler_axis = np.linspace(
-radar.unambiguous_speed/2, radar.unambiguous_speed/2, radar.transmitter.pulses, endpoint=False)
data = [go.Surface(x=range_axis[rng_idx[0]], y=doppler_axis,
z=temp[:, rng_idx[0]], colorscale='Rainbow')]
camera = dict(
up=dict(x=0, y=0, z=1),
center=dict(x=0, y=0, z=0),
eye=dict(x=1.4, y=1.4, z=1.4)
)
layout = go.Layout(
title='Range Doppler',
height=800,
scene=dict(
xaxis=dict(title='Range (m)', range=[9.5, 10.5]),
yaxis=dict(title='Velocity (m/s)'),
zaxis=dict(title='Amplitude (dB)'),
aspectmode='cube',
camera=camera,
),
margin=dict(l=0, r=0, b=60, t=100),
legend=dict(orientation='h'),
)
fig = go.Figure(data=data, layout=layout)
# iplot(fig)
display(SVG(fig.to_image(format='svg', scale=1)))