CARLA ? C-Shenron based Simualtor for Sensor data generation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

11 KiB

🚨 The Isotropic Illumination Problem — Why Shenron Cannot See the Car

Date: 2026-04-14
Engineer: Fox ADAS Pipeline | Antigravity AI
Status: 🔴 CRITICAL — Root Cause Identified, Implementation Deferred
Prerequisite Reading: Shenron_debug.md (Iterations 01–26)


Executive Summary

After 30+ iterations of calibrating RCS physics, fixing coordinate bugs, tuning CFAR thresholds, adjusting gain, and increasing ray density, the AWRL1432 radar still cannot reliably detect a vehicle at 25m in a straight-line braking scenario.

The root cause is not in the signal processing, the CFAR threshold, or the gain. It is a fundamental architectural omission in the Shenron physics engine:

Shenron does not simulate the radar's antenna radiation pattern.
Every scatterer in the scene — whether it's at 0° (directly ahead) or at 80° (a distant wall) — receives and returns energy as if it were perfectly on boresight.

This single missing physics element explains why 30 iterations of downstream tuning have failed to reliably produce the car as a detection, and why the Radarbook (with 8 vRx) sometimes succeeds where the 1432 (6 vRx) consistently fails.


The Evidence

Diagnostic Script Output (track_full_state.py)

The following table shows where the strongest peak in each radar's Range-Doppler map is located:

Frame Radar Range (m) Angle (deg) Magnitude (dB)
6 1432 20.76 76.57° 138.5
6 R-Book 20.39 -84.93° 142.4
8 1432 20.76 76.57° 142.0
8 R-Book 20.39 73.14° 142.0
14 1432 7.65 69.00° 135.5
14 R-Book 20.39 -84.93° 141.7

The car is at 0° azimuth (straight ahead). Yet the strongest detection is consistently at 70–85° — far off to the side. This is because the side-clutter (barriers, walls, trees at those wide angles) is returning the same power as the car, since Shenron treats all angles equally.

Visual Confirmation (Range-Azimuth Heatmap)

The RA heatmap from the dashboard shows complete, uniform energy rings extending from -90° to +90°. In a real radar, you would see a focused 120° sector with significant energy roll-off beyond ±60°.


Why Previous Iterations Could Not Fix This

Looking back at the iteration history, here is what each major tuning attempt was actually fighting against:

Iteration What We Tried Why It Felt Like It Worked Why It Didn't Actually Fix It
10 Metal Roughness tuning Reduced some specular reflections Clutter at 80° was still as loud as car at 0°
14a Vertical Gaussian Damping Killed ceiling/floor clutter by 90% Only addressed elevation. Azimuthal clutter was untouched.
16 Area-Density Integration (+234%) Boosted car signal significantly Also boosted wall/barrier signal by the same 234%
26 Pure 1/R⁴ alignment Correct physics — distance now matters But angle still doesn't matter. A wall at 80° at 20m is just as "loud" as a car at 0° at 20m
This Session Gain 110→115dB, CFAR 20→15, voxel_rho 0.05→0.02 Peak SNR rose from 15→21 dB The peak is at 76°, not 0°. We boosted the wrong target.

[!CAUTION] The fundamental issue: Every iteration that "lifts all boats" (gain, density, normalization) lifts the clutter equally with the target. Without angular selectivity, the car can never be louder than the surrounding environment unless it is physically closer or has a dramatically higher RCS.


The Missing Physics: Antenna Radiation Pattern

What a Real Radar Does

A real FMCW radar's patch antenna array has a directional gain pattern. The transmitted energy is concentrated in a forward-facing beam. A typical 77 GHz ADAS radar has:

  • 3dB Beamwidth (Azimuth): ±60° (120° total)
  • Gain at Boresight (0°): Maximum (0 dB relative)
  • Gain at ±60°: -3 dB (half power)
  • Gain at ±80°: -10 to -15 dB (almost invisible)
  • Gain at ±90°: -20 dB or below (effectively blind)

This means a wall at 80° would return 10–15 dB less power than a car at 0°, even if they were at the same range with the same RCS. The car would dominate the detection.

What Shenron Currently Does

Sceneset.py → get_loss_3():

    # --- Iteration 14a: Vertical Antenna Gain (Gaussian Damping) ---
    phi_deg = np.rad2deg(np.abs(np.pi/2 - elev_angle))
    G_vertical = np.exp(-2.77 * np.power(phi_deg / radar.vertical_beamwidth, 2))
    
    P_incident = (1 / np.power(rho, tx_dist_loss_exponent)) * K_sq * G_vertical
    #                                                                 ^^^^^^^^^^^
    #                                              Only VERTICAL gain is applied.
    #                                              There is NO horizontal/azimuthal gain.

The P_incident calculation includes:

  • Distance decay (1/R²) — Correct
  • Vertical beam pattern (G_vertical) — Added in Iteration 14a
  • Horizontal beam pattern (G_horizontal) — MISSING

Every LiDAR point, regardless of its azimuth angle relative to the radar boresight, receives the same transmit power. The ADC synthesis in heatmap_gen_fast.py then faithfully encodes these equal-power returns into the beamforming vectors, creating the uniform rings we see in the RA heatmap.


The Proposed Fix

Implementation (Single Line Addition)

In Sceneset.py, inside get_loss_3(), after the vertical gain calculation:

# --- Iteration 14a: Vertical Antenna Gain (Gaussian Damping) ---
phi_deg = np.rad2deg(np.abs(np.pi/2 - elev_angle))
G_vertical = np.exp(-2.77 * np.power(phi_deg / radar.vertical_beamwidth, 2))

# --- NEW: Horizontal Antenna Gain (Azimuthal Beam Pattern) ---
# theta is computed in specularpoints() as:
#   theta = pi/2 - arctan(x / y)      where y=forward, x=side
# This means theta=pi/2 (90°) is boresight (straight ahead).
# The azimuth offset from boresight is: az_offset = |pi/2 - theta|
az_offset_deg = np.rad2deg(np.abs(np.pi/2 - theta_for_gain))  # degrees off boresight
G_horizontal = np.exp(-2.77 * np.power(az_offset_deg / radar.horizontal_beamwidth, 2))

P_incident = (1 / np.power(rho, tx_dist_loss_exponent)) * K_sq * G_vertical * G_horizontal

ConfigureRadar.py Addition

Add self.horizontal_beamwidth to each radar profile:

Radar horizontal_beamwidth Physical Basis
awrl1432 60.0 (±60° = 120° total) 6 vRx, narrow-beam ADAS profile
radarbook 90.0 (±90° = 180° total) 8 vRx, wider research-grade beam
ti_cascade 60.0 MIMO cascade, comparable to 1432

Coordinate Note

[!WARNING] The theta variable passed to heatmap_gen is the angular position of each scatterer in radar coordinates (pi/2 - arctan(x/y)). This is the correct variable to use for the azimuthal gain. However, it is computed in specularpoints() and returned alongside rho, loss, and speed. It is not currently passed to get_loss_3(). The fix requires either:

  1. Passing theta into get_loss_3() as a new argument, or
  2. Re-computing the azimuth angle inside get_loss_3() from the point coordinates.

Impact Assessment: What Happens to Previous Iterations?

[!IMPORTANT] This is a "tide change" fix, not an additive tweak. Once implemented, the energy landscape of the entire simulation changes fundamentally. Here is what to expect:

Parameters That Will Likely Need Re-Tuning

Parameter Current Value Expected Direction Reason
Gain (dB) 115 ↓ Decrease back toward 105–110 With clutter suppressed, the car will be the dominant target again. The current 115dB was compensating for clutter competition.
CFAR Threshold 15 ↑ Increase back toward 18–20 Lower threshold was needed to "dig out" the car from equal-power clutter. With clutter gone, sensitivity can be reduced to avoid ground noise.
voxel_rho 0.02 ↑ Increase back toward~0.05 Higher ray density was needed to "outpower" the clutter. With beam shaping, fewer rays on the car will still dominate.
Metal Roughness (Iter 10) 0.00005 Likely unchanged Material physics is orthogonal to beam pattern.
Z-Filter (Iter 13) -2.2m Likely unchanged Ground clutter filtering is still needed regardless of azimuth.
Vertical Beamwidth (Iter 14a) 20.0° Likely unchanged Elevation damping is still correct and complementary.

Parameters That Should Remain Stable

  • Bandwidth (137.2 MHz): Hardware-derived, not a compensation knob.
  • Chirps (128): Hardware-derived.
  • Coordinate System: Locked since Iteration 05.
  • Semantic Tag Mapping: Bug fix, not tuning.
  • 1/R⁴ Power Law (Iter 26): Correct physics, complementary to beam pattern.

The Core Prediction

Once the horizontal beam pattern is implemented:

  1. The car at 0° will be the dominant detection in Range-Doppler. The peak tracker should lock onto Range Bin 19 consistently.
  2. Side-clutter at 80° will be attenuated by ~15-20 dB, effectively removing it from CFAR contention.
  3. The RA heatmap will transform from "full rings" to a focused 120° sector — matching what you see on real hardware.
  4. Many of the compensatory tuning parameters (gain, CFAR, voxel density) can likely be relaxed back to more physically accurate values, because they were fighting the wrong battle.

Why the Radarbook Sometimes Worked

The Radarbook succeeded in some frames not because it has a beam pattern (it doesn't either), but because:

  1. 8 vRx vs 6 vRx: More antennas = narrower main lobe in the Angle-FFT output. The DSP-level beamforming partially compensates for the missing physics-level beam shaping.
  2. Higher Doppler Resolution: With 128 chirps at a much longer chirp_rep (0.75ms vs 36.4µs), the Radarbook has ~3.5x better velocity resolution. This allows it to separate the (slightly) moving car from the static side-clutter in the Doppler domain, even if both are equally loud in the Range domain.

The 1432, with fewer antennas and coarser Doppler bins, has no such "escape hatch."


  1. Implement G_horizontal in get_loss_3() — The single most impactful change.
  2. Run Braking scenario with current settings (115dB gain, CFAR 15, voxel 0.02) — This will likely produce a very dense, accurate point cloud because the car now has a 15-20dB advantage.
  3. Gradually relax compensatory parameters — Bring gain back toward 110, CFAR toward 18, and voxel toward 0.05, verifying detection stability at each step.
  4. Final Calibration — Once stable, this becomes the new "Iteration 31" baseline.

Key Files for Implementation

File Change Required
scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/shenron/Sceneset.py Add G_horizontal to get_loss_3()
scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/ConfigureRadar.py Add horizontal_beamwidth to all profiles
scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/shenron/Sceneset.py Pass theta (or recompute azimuth) into get_loss_3()

Generated by Antigravity AI | Fox CARLA ADAS Pipeline | 2026-04-14