import radarsimpy
print("`RadarSimPy` used in this example is version: " + str(radarsimpy.__version__))
`RadarSimPy` used in this example is version: 13.1.0
FMCW Radar Link Budget (Mesh Target)ΒΆ
IntroductionΒΆ
This is the continue of previous post about FMCW radar link budget with point target. This example showcases the link budget analysis of an FMCW radar with a mesh target.
Radar Link Budget AnalysisΒΆ
Radar link budget analysis is a critical process for determining the power levels throughout the radar systemβs signal chain, from transmission, through propagation, to reception. The goal is to ensure that the radar can detect and track targets at the desired range. The analysis involves understanding how transmitted power is affected by various factors, such as antenna gains, propagation losses, and target characteristics, ultimately determining if the received signal is strong enough for detection.
The key equation used in radar link budget analysis is derived from the Radar Range Equation:
$$ P_r = \frac{P_t G_t G_r \lambda^2 \sigma}{(4\pi)^3 R^4 L_s} $$
Where:
- $( P_t )$ = Transmitted power (W)
- $( G_t )$ = Transmitting antenna gain
- $( G_r )$ = Receiving antenna gain
- $( \lambda )$ = Wavelength of the radar signal (m), $( \lambda = \frac{c}{f} )$ where $( c )$ is the speed of light (3Γ10βΈ m/s) and $( f )$ is the frequency (Hz)
- $( \sigma )$ = Radar cross-section (RCS) of the target (mΒ²)
- $( R )$ = Range to the target (m)
- $( L_s )$ = System losses, including propagation losses, hardware inefficiencies, and atmospheric attenuation
1. Transmitted Power $(P_t)$:ΒΆ
The radar system transmits a signal with power $( P_t )$ (in watts). This power is directed through the radar's transmitting antenna, which has a specific gain $( G_t )$, concentrating the energy into a particular direction.
$$ P_{\text{transmit}} = P_t G_t $$
2. Antenna Gain $(G_t)$ and $(G_r)$:ΒΆ
Antenna gain is a measure of how well the antenna focuses the transmitted (or received) energy in a specific direction. It is typically expressed as:
$$ G = \frac{4 \pi A_{\text{antenna}}}{\lambda^2} $$
Where $( A_{\text{antenna}} )$ is the effective area of the antenna, and $( \lambda )$ is the wavelength.
3. Free-Space Path Loss (FSPL):ΒΆ
As the signal propagates through space, it experiences free-space path loss (FSPL), which increases with the square of the distance from the radar and the square of the operating frequency. The FSPL is given by:
$$ L_{\text{fspl}} = \left( \frac{4 \pi R}{\lambda} \right)^2 = \frac{(4 \pi R f)^2}{c^2} $$
Where:
- $( R )$ is the distance to the target (m)
- $( f )$ is the radar frequency (Hz)
- $( c )$ is the speed of light (3Γ10βΈ m/s)
4. Radar Cross Section (RCS) $( \sigma )$:ΒΆ
The radar cross-section $( \sigma )$ represents how much of the transmitted signal is reflected back by the target. Larger or more reflective targets have a higher RCS, which increases the power of the reflected signal:
$$ P_{\text{return}} = P_{\text{transmit}} \frac{\sigma}{4 \pi R^2} $$
5. Received Power $(P_r)$:ΒΆ
The power received by the radar after the signal is reflected from the target is determined by the radar range equation:
$$ P_r = \frac{P_t G_t G_r \lambda^2 \sigma}{(4 \pi)^3 R^4 L_s} $$
- $( R^4 )$: The signal experiences two-way propagation, so the range term is raised to the fourth power β $( R^2 )$ for the transmission from radar to the target and another $( R^2 )$ for the return path.
- $( L_s )$: This term represents total system losses, which can include:
- Propagation losses (e.g., due to atmospheric absorption).
- Antenna losses (e.g., due to inefficiencies in the antenna design).
- Polarization mismatches and other hardware inefficiencies.
6. Noise Power $(P_{\text{noise}})$:ΒΆ
For the radar system to successfully detect a target, the received power ( Pr ) must exceed the minimum detectable signal (MDS), ( P{\text{min}} ), which is defined by the receiver sensitivity and the noise level in the system:
$$ P_{\text{noise}} = k T B F $$
Where:
- $( k )$ = Boltzmann's constant (1.38Γ10β»Β²Β³ J/K)
- $( T )$ = System temperature (Kelvin)
- $( B )$ = Receiver bandwidth (Hz)
- $( F )$ = Receiver noise figure
7. Signal-to-Noise Ratio $(SNR)$:ΒΆ
The signal-to-noise ratio $(SNR)$ is a key performance metric that determines whether the target can be detected reliably. A higher SNR means the signal is strong compared to the noise, making detection easier.
$$ SNR = \frac{P_r}{P_{\text{noise}}} $$
Simulation ExampleΒΆ
Radar System ParametersΒΆ
In this simulation, we are building a radar system based on the following parameters:
TransmitterΒΆ
- $P_t = 13$ dBm
- $G_t = 12$ dB
- $N_p = 512$ (number of pulses)
ReceiverΒΆ
- $f_s = 20 \times 10^6$ (samping rate)
- $N_s = 1024$ (number of samples per pulse)
- $G_r = 12$ dB
- $\lambda = 3e8/76.5e9$ m
- $F = 11$ dB
TargetΒΆ
- A trihedral corner reflector, 13.6 dBsm @ 76.5 GHz
- $R = 100$ m
Build Simulation ModelΒΆ
import numpy as np
from radarsimpy import Radar, Transmitter, Receiver
antenna_gain = 12
az_angle = np.arange(-80, 81, 1)
az_pattern = 20 * np.log10(np.cos(az_angle / 180 * np.pi) ** 4) + antenna_gain
el_angle = np.arange(-80, 81, 1)
el_pattern = 20 * np.log10((np.cos(el_angle / 180 * np.pi)) ** 20) + antenna_gain
Plot the antenna patterns
import plotly.graph_objs as go
from IPython.display import Image
fig = go.Figure()
fig.add_trace(
go.Scatter(
x=az_angle,
y=az_pattern,
name="Azimuth",
)
)
fig.add_trace(
go.Scatter(
x=el_angle,
y=el_pattern,
name="Elevation",
)
)
fig.update_layout(
title="Antenna Pattern",
yaxis=dict(title="Amplitude (dB)", range=[-20, 20]),
xaxis=dict(title="Angle (deg)"),
)
# 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))
Transmitter ChannelΒΆ
tx_channel = dict(
location=(0, 0, 0),
azimuth_angle=az_angle,
azimuth_pattern=az_pattern,
elevation_angle=el_angle,
elevation_pattern=el_pattern,
)
Radar TransmitterΒΆ
tx = Transmitter(
f=[76.3e9, 76.7e9],
t=5.12e-05,
tx_power=13,
prp=5.5e-05,
pulses=512,
channels=[tx_channel],
)
Receiver ChannelΒΆ
rx_channel = dict(
location=(0, 0, 0),
azimuth_angle=az_angle,
azimuth_pattern=az_pattern,
elevation_angle=el_angle,
elevation_pattern=el_pattern,
)
Radar ReceiverΒΆ
rx = Receiver(
fs=20e6,
noise_figure=11,
rf_gain=20,
load_resistor=500,
baseband_gain=30,
bb_type="real",
channels=[rx_channel],
)
Radar SystemΒΆ
radar = Radar(transmitter=tx, receiver=rx)
TargetsΒΆ
A trihedral corner reflector is used in this example. For the property of this corner reflector, please refer to: https://radarsimx.com/2021/05/10/corner-reflector-rcs/
target_1 = {
"model": "../models/cr.stl",
"unit": "m",
"location": (100, 0, 0),
"speed": (0, 0, 0),
}
targets = [target_1]
Simulate Baseband SignalsΒΆ
Utilize the simulator.sim_radar
module to simulate baseband samples from the defined radar system and its targets.
The output is a dictionary containing the timestamp, noise, and baseband data, each represented as a 3D matrix with the following structure:
[channels, pulses, ADC samples]
To provide greater flexibility, the noise and baseband data are kept separate. Users must combine these two datasets to generate the noisy baseband.
from radarsimpy.simulator import sim_radar
data = sim_radar(radar, targets)
timestamp = data["timestamp"]
baseband = data["baseband"]+data["noise"]
noise = data["noise"]
import radarsimpy.processing as proc
range_doppler = np.fft.fftshift(
proc.range_doppler_fft(baseband), axes=1
)
noise_range_doppler = np.fft.fftshift(
proc.range_doppler_fft(noise), axes=1
)
max_per_range_bin = np.max(np.abs(range_doppler), axis=1)
noise_mean = np.mean(np.abs(noise_range_doppler), axis=1)
valid_range_bins = int(radar.sample_prop["samples_per_pulse"]/2)
max_range = (
3e8
* radar.radar_prop["receiver"].bb_prop["fs"]
* radar.radar_prop["transmitter"].waveform_prop["pulse_length"]
/ radar.radar_prop["transmitter"].waveform_prop["bandwidth"]
/ 4
)
range_axis = np.linspace(
0, max_range, valid_range_bins, endpoint=False
)
fig = go.Figure()
fig.add_trace(
go.Scatter(
x=range_axis,
y=20*np.log10(max_per_range_bin[0, 0:valid_range_bins]),
name="Peak per Range Bin"
)
)
fig.add_trace(
go.Scatter(
x=range_axis,
y=20*np.log10(noise_mean[0, 0:valid_range_bins]),
name="Noise Floor"
)
)
fig.update_layout(
yaxis=dict(title="Amplitude (dB)"),
xaxis=dict(title="Range (m)"),
)
# 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))
Compare Simulated SNR with TheoryΒΆ
Based on the equations above, the calculated SNR from the theory is:
$$ SNR = P_r - P_{\text{noise}} \text{ in decibels} $$
While
$$ P_r = 13(P_t) + 12(G_t) + 12(G_r) + 20 \times \log_{10}{\frac{3 \times 10^8(c)/76.5 \times 10^9(\lambda)}{(4 \pi)^{3/2} \times 100^2(R)}} + 13.6(\sigma) = -110.5 \text{ dBm} $$
For the noise power, the receiver bandwidth $B$ can be calculated based on the receiver sampling rate and the total data acquision time:
$$ B = 10 \times \log_{10}{\frac{20 \times 10^6 (f_s)}{1024(N_s) \times 512(N_p)}} = 15.814 \text{ dB} $$
Then:
$$ P_{\text{noise}} = 11(F)+15.814(B)+10 \times \log_{10}{1.38 \times 10^{-23}(k)}+10 \times \log_{10}{290(T)}+30 =-147.16 \text{ dBm} $$
Thus, the calculated $SNR$ (in decibels) would be:
$$ SNR = P_r - P_{\text{noise}} = 36.66 \text{ dB} $$
The calculated SNR matches with the simulated result as shown in the plot above.