import radarsimpy
print("`RadarSimPy` used in this example is version: " + str(radarsimpy.__version__))
`RadarSimPy` used in this example is version: 15.2.0
Radar Cross Section (RCS) of a Car¶
Radar Cross Section (σ) quantifies how detectable an object is by radar — it represents the effective scattering area that intercepts and reflects energy back toward the receiver, in m² (or dBsm).
RCS depends on:
- Geometry and size: Shape and orientation of reflecting surfaces
- Frequency: Rayleigh (target ≪ λ), resonance (target ≈ λ), optical (target ≫ λ)
- Aspect angle: Large variations as different surfaces face the radar
- Polarization: Incident/scattered wave orientation
- Material: Conductivity and permittivity affect reflection coefficients
For complex objects like vehicles, RCS is best estimated through simulation using ray tracing + physical optics (PO), which accurately captures multi-bounce reflections and edge diffraction.
This Example¶
- Target: Lamborghini Aventador 3D model (STL)
- Frequency: 76 GHz (automotive radar W-band, λ ≈ 3.95 mm)
- Sweep: 0°–180° azimuth at 90° elevation, 1° steps
- Polarization: Vertical [0, 0, 1]
3D Model Loading¶
Import Required Modules¶
import pymeshlab
import numpy as np
import plotly.graph_objs as go
from IPython.display import Image, display
# Set to True for interactive plots; False renders a static JPEG (e.g. for HTML export)
INTERACTIVE = False
def show(fig):
if INTERACTIVE:
fig.show()
else:
display(Image(fig.to_image(format="jpg", scale=2)))
# Define target configuration
target = {
"model": "../models/vehicles/lamborgini_aventador.stl",
"unit": "m",
"location": (0, 0, 0),
}
Visualize 3D Model¶
Load and display the car mesh to verify geometry and identify major reflecting surfaces before simulation.
ms = pymeshlab.MeshSet()
ms.load_new_mesh(target["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],
color="lightsteelblue",
flatshading=False,
lighting=dict(
ambient=0.4,
diffuse=0.9,
specular=0.3,
roughness=0.5,
fresnel=0.2,
),
lightposition=dict(x=1000, y=500, z=1000),
)
)
fig.update_layout(
scene=dict(
aspectmode="data",
camera=dict(eye=dict(x=1.5, y=-1.5, z=0.75)),
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
zaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
),
margin=dict(l=5, r=0, b=20, t=30),
height=400,
)
show(fig)
RCS Simulation vs Observation Angle¶
sim_rcs computes RCS via ray tracing + physical optics. Ray density controls the accuracy–speed trade-off: each ray launched toward the target contributes to the scattered field estimate.
| Parameter | Value | Notes |
|---|---|---|
| Frequency | 76 GHz | Automotive radar W-band |
| Azimuth φ | 0°–180°, 1° step | Horizontal sweep |
| Elevation θ | 90° (fixed) | Horizontal plane |
| Polarization | [0, 0, 1] | Vertical |
| Ray density | 0.1 rays/λ² | Fast computation |
# Import time module for performance measurement
import time
# Import RCS simulation function
from radarsimpy.simulator import sim_rcs
# Define observation angles
phi = np.arange(0, 180, 1) # Azimuth angles: 0° to 180° in 1° steps
theta = np.zeros_like(phi) + 90 # Elevation angle: fixed at 90° (horizontal plane)
# Radar configuration
freq = 76e9 # Operating frequency: 76 GHz (automotive radar)
pol = [0, 0, 1] # Polarization vector: vertical polarization
density = 0.1 # Ray density: 0.1 rays per wavelength²
# Start timing
tic = time.time()
# Simulate RCS for all observation angles
# Returns RCS in linear scale (m²), convert to dBsm
rcs = 10 * np.log10(sim_rcs([target], freq, phi, theta, pol, density=density))
# End timing
toc = time.time()
# Display execution time
print("Exec time: " + str(toc - tic) + " s")
Exec time: 2.203721046447754 s
Visualize RCS Pattern¶
Expect peak RCS near broadside angles (0°, 90°, 180°) where large flat surfaces are perpendicular to the radar. Typical automotive targets show 30–40 dB RCS variation with aspect angle.
fig = go.Figure()
fig.add_trace(go.Scatter(x=phi, y=rcs, mode="lines", name="RCS"))
fig.update_layout(
title="RCS vs Observation Angle (76 GHz, Vertical Polarization)",
yaxis=dict(title="RCS (dBsm)"),
xaxis=dict(title="Azimuth Angle (Degrees)", dtick=20),
height=500,
)
show(fig)
Summary¶
- RCS of a complex 3D target is simulated using ray tracing + physical optics via
sim_rcs. - Vehicle RCS shows strong aspect-angle dependence (30–40 dB variation); peaks occur at broadside incidence where large flat panels face the radar.
- Ray density controls the accuracy–speed trade-off: higher density improves accuracy at the cost of longer computation.
Things to Try¶
| Experiment | Parameter to change | Observable effect |
|---|---|---|
| Higher accuracy | Increase density to 0.5 or 1.0 |
Smoother, more accurate RCS pattern |
| Different band | Change freq to 24 GHz or 79 GHz |
Pattern shifts with wavelength scaling |
| Horizontal pol | pol = [0, 1, 0] |
Different RCS magnitude and nulls |
| Elevation sweep | Vary theta |
RCS changes with look-up angle |
| Full 3D pattern | Vary both φ and θ | 2D heatmap of RCS |