8.7 KiB
Shenron Physics Debug Log
Date: 2026-04-03
Engineer: Fox ADAS Pipeline | Antigravity AI
Objective: Resolve physics-based discrepancies in the C-Shenron synthetic radar pipeline, align with AWRL1432BOOST hardware performance, and establish a stable, high-fidelity simulation baseline.
📐 Architecture Overview
The C-Shenron pipeline is a physics-based FMCW radar simulator isolated in scripts/ISOLATE/. It takes CARLA Semantic LiDAR as input and produces a synthetic radar point cloud as output.
CARLA (Semantic LiDAR)
→ lidar.py (Ingestion + Material Mapping)
→ Sceneset.py (Fresnel RCS Physics)
→ heatmap_gen_fast.py (GPU FMCW ADC Synthesis)
→ radar_processor.py (Range/Doppler FFT + CFAR)
→ [x, y, z, velocity, magnitude] PointCloud
Key Coordinate Convention (LOCKED):
- CARLA Frame:
X = Forward,Y = Right (LHS),Z = Up - Shenron Internal Frame:
Index 1 = Forward,Index 0 = Side - The swap
points[:, 0] = CARLA_Y, points[:, 1] = CARLA_Xinlidar.pyis intentional and must not be removed. - MCAP/Foxglove Output: Negate Y to convert from CARLA LHS → ROS RHS.
🐛 Bugs Fixed
Bug #1: The "Cos(Cos)" Reflection Error
File: scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/shenron/Sceneset.py
Root Cause: The specularpoints() method received pre-computed cosine values from CARLA's Semantic LiDAR (cos_inc_angle), but then ran np.cos() on them again inside get_loss_3(). This caused a "double-cosine" effect.
Effect: A perfect perpendicular bounce (true cos = 1.0) was calculated as cos(1.0) = 0.54, implying a 57-degree glancing angle. This caused a massive ~46% RCS energy drop on every flat surface (car hoods, road, walls).
Fix: Removed the erroneous np.cos() call. The engine now directly uses the pre-computed cosine values as intended. Also corrected the specular reflection mask threshold for 2-degree incident angles.
Bug #2: Zeroed-Out Thermal Noise Floor
File: scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/ConfigureRadar.py
Root Cause: The noise generator was multiplied by zero: signal_Noisy = 0 * (...).
Effect: With a zero noise floor, the CFAR detector became violently unstable. It detected infinite false peaks in empty bins because the background noise variance was literally zero, producing random "sparkle" detections with no correlation to actual targets.
Fix: Restored the AWGN noise generator with a proper complex noise implementation using noise_amp * (np.random.randn(...) + 1j * np.random.randn(...)).
Bug #3: LiDAR Metadata Bit-View Error
File: src/recorder.py
Root Cause: CARLA Semantic LiDAR stores object_idx and semantic_tag as uint32 values packed into float32 bit fields. The recorder was reading them as plain floats, producing garbage values (e.g., Object ID of 0.0 for every actor).
Effect: The velocity projection calculation v_radial = dot(actor_vel - ego_vel, direction) always failed the actor lookup, resulting in zero radial velocity stored for every point.
Fix: Applied np.view(np.uint32) to correctly unpack the integer IDs from the float32 bitstream. The same fix was propagated to the MCAP packaging scripts (test_shenron.py, data_to_mcap.py).
Bug #4: Stale RadarProcessor Axes (Range Scaling Mismatch)
File: scripts/ISOLATE/model_wrapper.py
Root Cause: The RadarProcessor only computed its range axis once at startup, using the default config.yaml values (24GHz, 250MHz). When processing the awrl1432 profile (77GHz, 400MHz), the processor still used the old stale axes to convert FFT bins to meters.
Effect: A ~2x range "stretching" — objects at 50m appeared at ~100m. The bandwidth mismatch caused incorrect scaling.
Fix: Added self.processor.__init__() call inside _sync_configs() to force the processor to rebuild its internal range and velocity axes every time the hardware profile changes.
📡 Hardware Profile: AWRL1432 (Iteration 07 — Current Best)
The awrl1432 profile in ConfigureRadar.py has been tuned to match the real-world TI AWRL1432BOOST professional ADAS configuration:
| Parameter | Previous (Iter 05) | Current (Iter 07) | Notes |
|---|---|---|---|
| Frequency | 77 GHz | 77 GHz | Same |
| Bandwidth (B) | 137.2 MHz | 400 MHz | 3x wider |
| Range Resolution | ~109 cm | 37.5 cm | 3x sharper |
| Max Range | ~279 m | ~96 m | Calibrated to ADAS zone |
| Chirps (Np) | 128 | 64 | 2x faster, maintained SNR |
| Samples (N) | 256 | 256 | Unchanged |
| Antennas (nRx) | 6 | 6 | Unchanged |
Signal Processor Config (sim_radar_utils/config.yaml):
fStrt: 77.0e9,fStop: 77.4e9(matching 400MHz bandwidth)Np: 64(matching hardware chirp count)NFFT: 256(matching N_sample)
📦 Data Pipeline Fixes
Sensor Mount Calibration (MCAP Visualization)
Both scripts/test_shenron.py and scripts/data_to_mcap.py now include correct physical mount offsets so sensors align properly in Foxglove:
- LiDAR:
Z = +2.5m(Roof mount) - Radar (Native + Shenron):
X = +2.0m, Z = +1.0m(Front bumper/grille)
LiDAR Point Cloud — Full 7-Column Support
Both MCAP scripts now publish all 7 Semantic LiDAR fields:
[x, y, z, velocity, cos_inc_angle, object_id, semantic_tag]
object_id and semantic_tag are correctly decoded via .view(np.uint32) before packaging.
🏃 Performance Optimization
Testbench Speed (for 9 seconds of data):
| State | Time | Cause |
|---|---|---|
| Before Today | ~20 min | 128 chirps × 3 models |
| Iteration 06 | ~5 min | 32 chirps × 3 models |
| Iteration 07 (Current) | ~5-7 min | 64 chirps × 1 model (awrl1432 only) |
To re-enable all three radar models, update test_shenron.py line 84:
radar_types = ['awrl1432', 'radarbook', 'ti_cascade']
🧭 Coordinate System (Final Reference — DO NOT CHANGE)
This is the authoritative mapping that must be maintained across all files:
CARLA LiDAR Output:
col[0] = X (Forward)
col[1] = Y (Right, LHS)
col[2] = Z (Up)
Shenron Internal Input (after lidar.py swap):
col[0] = CARLA Y (Side) <-- Index 0 is Side
col[1] = CARLA X (Forward) <-- Index 1 is Forward
col[2] = CARLA Z (Up)
Shenron Cropping Filter (Cropped_forRadar):
skew_pc[:, 1] > 0.5 <-- Forward filter (Y=Index 1)
skew_pc[:, 0] in [-30, +30] <-- Side filter (X=Index 0)
skew_pc[:, 1] < 120 <-- Max forward range
MCAP Output (ROS/Foxglove RHS):
Negate Y column before packaging
Apply sensor mount pose offsets
▶️ Running Future Iterations
# Activate Environment
conda activate carla312
# Run the testbench (replace XXXX with your iteration name)
python scripts/test_shenron.py --iter "07_high_def_sync"
# Output: Shenron_debug/iterations/07_high_def_sync/07_high_def_sync.mcap
Known Pending Issues (Next Steps)
- Turn Lag: Shenron points appear to trail ~0.5-1 frame behind the CARLA native radar during sharp turns. Suspected cause: LiDAR data captured at
T-1but rendered with ego pose atT. Requires timestamp sync investigation inrecorder.py. - Angular FOV Validation: Compare Shenron angular output vs. AWRL1432BOOST hardware spec (
+/- 60°) to ensure angular clipping is not removing valid detections. - CFAR Threshold Tuning: The
threshold: 20inconfig.yamlmay need adjustment after the noise floor restoration. Consider running a "Clear Road" baseline to calibrate the false alarm rate.
📁 Key Files Reference
| File | Role |
|---|---|
scripts/ISOLATE/model_wrapper.py |
Public API — single entry point for Shenron |
scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/lidar.py |
LiDAR ingestion, semantic mapping, axis swap |
scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/ConfigureRadar.py |
Hardware profiles (awrl1432, radarbook, ti_cascade) |
scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/shenron/Sceneset.py |
Fresnel reflection + RCS physics |
scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/shenron/heatmap_gen_fast.py |
GPU FMCW ADC synthesis |
scripts/ISOLATE/sim_radar_utils/radar_processor.py |
Range/Doppler FFT + CFAR detection |
scripts/ISOLATE/sim_radar_utils/config.yaml |
DSP processor configuration |
scripts/test_shenron.py |
Testbench — generates and packages iterations |
scripts/data_to_mcap.py |
Main MCAP converter (Dashboard path) |
src/recorder.py |
Data capture — includes velocity + semantic metadata |
intel/shenron_architecture_deepdive.html |
Visual HTML architecture guide |
Generated by Antigravity AI | Fox CARLA ADAS Pipeline | 2026-04-03