5.2 KiB
Shenron Physics Pipeline Deep-Dive
To understand why the simulated data isn't matching your AWRL1432BOOST real-world recordings, we need to look under the hood of Shenron's physics engine. The pipeline translates native CARLA Semantic LiDAR into raw radio frequency (RF) samples before they are ever clustered into points.
Here is the step-by-step technical data flow and where the physics mappings occur:
1. Scene Geometry & Material Ingestion (lidar.py)
CARLA native radar is sparsely ray-cast. To achieve high-fidelity FMCW simulation, Shenron uses Semantic LiDAR as a dense scene representation.
- It ingests the point cloud shape:
[x, y, z, radial_velocity, cos_inc_angle, object_idx, semantic_tag]. - Using
new_map_material(), it re-maps CARLA'ssemantic_taginto electromagnetic properties. For example, Vehicles become "Metal" ($R_{perm} = 100000$), Buildings become "Concrete" ($R_{perm} = 5.24$), and Pedestrians remain low-reflectivity models.
2. Electromagnetics & RCS Modeling (Sceneset.py)
This is where the standard geometric points are converted into Radar Cross Sections (RCS) or "Reflection Powers".
- The engine converts Cartesian coordinates
(x, y, z)into Spherical coordinates(rho, theta, elevation). - It calls
get_loss_3()to calculate Signal Attenuation based on the Radar Equation $\frac{P_r}{P_t} = \frac{G^2 \sigma \lambda^2}{(4\pi)^3 R^4}$. - The total loss is split into two physical properties:
- **Specular Reflection ($P_{spec}$):** Direct mirror-like bounces. Extremely high power but requires the surface normal to be almost perfectly aimed at the sensor ($\theta < 2^\circ$).
- **Diffuse Scattering ($P_{scat}$):** Lambertian scattering (rough surfaces like roads and grass that scatter waves in all directions).
- It mathematically uses Fresnel Coefficients (permittivity) and surface roughness equations to calculate the final target amplitude.
3. ADC Raw Signal Generation (heatmap_gen_fast.py / CUDA)
Once Shenron knows exactly where the points are and how loud they should reflect, it builds the actual Analog-to-Digital Converter (ADC) data cube ([Chirps, Antennas, Samples]).
- Time of Flight ($\tau$): Uses $\tau = \frac{2R}{c} + \frac{2v \cdot T_{rep}}{c}$ to model range scaling and the Doppler frequency shift across successive chirps based on the
radial_velocity. - Antenna Phase ($\Delta$): Calculates the slight delays between different Rx antennas based on the
theta(Azimuth) spacing. - Dechirping: Multiplies the transmitted FMCW sweep by the returning simulated waves to generate the intermediate frequency (IF)
signal. - Thermal Noise: Generates the raw ADC noise floor via
np.random.normal()and adds it to the clean signal.
4. Signal Processing (RadarProcessor)
Finally, model_wrapper.py passes the synthetic adc_data to a traditional DSP pipeline:
- Range FFT: Resolves the objects into specific distance bins.
- Doppler FFT: Resolves object velocities.
- CFAR Detection: Identifies peaks above the surrounding noise floor.
- Angle of Arrival: Resolves Azimuth.
🚨 Critical Bugs Identified
While doing this trace, I discovered three major structural flaws in the Shenron code that explain exactly why your point clouds look erratic, static, or entirely uncorrelated to your physical AWRL1432:
Bug 1: The "Cos(Cos)" Reflection Bug
In lidar.py (Line 150 & 168), the system extracts the cos_inc_angle from CARLA (sem_lidar_frame[:, 4]) and assigns it to the index angles_carla.
However, inside get_loss_3() (Line 420), it takes this value and runs np.cos(angles).
- The Error: By executing
cos(cos_value), the math breaks completely. A perfect perpendicular bounce (which has a true cosine of 1.0) is calculated as $cos(1.0) = 0.5403$ (which implies a massive 57-degree glancing deflection!). - The Result: The radar physics engine fundamentally miscalculates the physical reflection, causing giant RCS drops on flat surfaces like car chassis, wiping out the specular points you expect to see.
Bug 2: Zeroed-Out Thermal Noise Floor
In ConfigureRadar.py (Line 133) for both radarbook and awrl1432, the noise generator code looks like this:
signal_Noisy = np.random.normal(0,1,size=(self.nRx,self.N_sample))
signal_Noisy = 0*(signal_Noisy + 1j*signal_Noisy)
- The Error: The entire noise floor is forcefully zeroed out (
0 * ...). - The Result: Without a thermal noise floor, the Constant False Alarm Rate (CFAR) algorithm in
RadarProcessorbecomes violently unstable. It starts detecting infinite peaks in random empty bins because the background noise variance is literally zero, causing "random values rather than actual vehicle movements."
Bug 3: Hardcoded Backwards Override
In generate_shenron.py (Line 38), the orchestrator explicitly ignores our shiny new config file: Let's look at the initialization:
model = ShenronRadarModel(radar_type='radarbook')
- The Error: The batch processing script is strictly hardcoded to the old
radarbookprofile. - The Result: Even though we set
awrl1432as the default insimulator_configs.yaml, the offline generation script completely ignores it, so you're still processing data at 24GHz with 1MHz sampling!