Browse Source
feat(radar): Major Update - Shenron Modularity and Physics Refinement (Iteration 18)
feat(radar): Major Update - Shenron Modularity and Physics Refinement (Iteration 18)
Transitioned the Shenron radar engine from a rigid architecture to a modular,
tunable "Knobs and Dials" framework. This update establishes a physics-first
baseline derived from real-world electromagnetic behavior.
Core Changes:
- Modular Radar Profiles: Pre-configured profiles for TI Cascade, Radarbook,
and AWRL1432 with hardware-specific Bandwidth, Chirp, and nRx parameters.
- Physics Core (Sceneset.py):
- Full implementation of Fresnel and Beckmann-Spizzichino scattering.
- Pure 1/R^4 power law (1/R^2 transmit, 1/R^2 receive) via legacy scaling removal.
- Fixed cos(cos(theta)) bug in CARLA semantic lidar mapping.
- Antenna Gain Integration:
- Implemented separable Azimuth/Elevation gain patterns.
- Added Symmetric Azimuth LUT interpolation and Vertical FOV Hard Cutoff.
- Signal Processing:
- Optimized GPU-accelerated signal synthesis using PyTorch.
- Standardized 110 dB System Calibration Constant for hardware SNR matching.
Additional Documentation:
- intel/radar/SHENRON_MODULAR_ARCHITECTURE.md: Architecture and "Knobs/Dials" overview.
- intel/radar/SHENRON_ANTENNA_GAIN_CALIBRATION.md: Physics of Antenna Gain and 1/R^4 logic.
Note: Remaining magic numbers in get_loss_3 (K_sq, scat_normalization, lobe_frac)
are noted for future migration into ConfigureRadar.py.
main
7 changed files with 466 additions and 15 deletions
-
227intel/radar/Azimuth_Elevation_Gain_Implementation.md
-
28intel/radar/SHENRON_ANTENNA_GAIN_CALIBRATION.md
-
30intel/radar/SHENRON_MODULAR_ARCHITECTURE.md
-
74intel/radar/radar_architecture_answers.md
-
62scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/ConfigureRadar.py
-
1scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/lidar.py
-
53scripts/ISOLATE/e2e_agent_sem_lidar2shenron_package/shenron/Sceneset.py
@ -0,0 +1,227 @@ |
|||
Below is a **precise, implementation‑ready plan** tailored to your current Shenron architecture. This plan assumes **both Azimuth and Elevation LUTs already exist** and focuses on *minimal, safe, radar‑local integration*. |
|||
|
|||
*** |
|||
|
|||
# Implementation Plan: Azimuth & Elevation Radiation Gain Integration |
|||
|
|||
## Goal |
|||
|
|||
Introduce **radar‑specific azimuth and elevation antenna gains** into Shenron such that: |
|||
|
|||
* Each radar applies its own antenna pattern |
|||
* No shared energy values are contaminated |
|||
* Existing energy models and ADC pipelines remain intact |
|||
* Integration aligns with current physics and code structure |
|||
|
|||
*** |
|||
|
|||
## 1. Data Model Extensions (ConfigureRadar.py) |
|||
|
|||
### 1.1 Add Antenna LUT Fields to Radar Configuration |
|||
|
|||
Extend the radar configuration object to carry antenna patterns. |
|||
|
|||
**New Radar Attributes** |
|||
|
|||
* `radar.azimuth_lut` |
|||
* `radar.elevation_lut` |
|||
* `radar.azimuth_lut_angles` (degrees or radians) |
|||
* `radar.elevation_lut_angles` |
|||
* `radar.antenna_gain_mode` (e.g., `"separable"`) |
|||
|
|||
These must be **radar‑instance local**, not global. |
|||
|
|||
*** |
|||
|
|||
### 1.2 LUT Normalization Convention (Decide Once) |
|||
|
|||
Choose and enforce one convention: |
|||
|
|||
* **Linear gain** (recommended, to match existing loss math) |
|||
* LUT values ∈ ℝ⁺ |
|||
* OR |
|||
* **dB gain**, converted to linear on load |
|||
|
|||
✅ Best practice: |
|||
Convert LUTs to **linear gain at load time** and store only linear values. |
|||
|
|||
*** |
|||
|
|||
## 2. Angle Availability Contract |
|||
|
|||
### 2.1 Confirm Angle Variables |
|||
|
|||
From your architecture: |
|||
|
|||
* Azimuth (`theta`) |
|||
* Elevation (`elev_angle`) |
|||
are already computed in `specularpoints()`. |
|||
|
|||
**Action** |
|||
|
|||
* Ensure both angles are: |
|||
* In a known unit (prefer radians internally) |
|||
* Passed directly to `get_loss_3()` with no recomputation |
|||
|
|||
No structural changes needed here. |
|||
|
|||
*** |
|||
|
|||
## 3. Loss Chain Integration Point (Sceneset.py) |
|||
|
|||
### 3.1 Insert Antenna Gain in get\_loss\_3() |
|||
|
|||
Modify `get_loss_3()` to include antenna LUT gain. |
|||
|
|||
**Exact placement** |
|||
|
|||
* After range loss |
|||
* Before material / roughness losses |
|||
* Adjacent to existing vertical antenna gain logic |
|||
|
|||
This preserves physical correctness: |
|||
|
|||
> Antenna attenuates the incident and received wave, not the material physics. |
|||
|
|||
*** |
|||
|
|||
### 3.2 Compute Antenna Gain Per Point |
|||
|
|||
For each point $$i$$: |
|||
|
|||
1. Clamp / wrap angles to LUT domain |
|||
* Azimuth: e.g. $$[-90°, +90°]$$ |
|||
* Elevation: e.g. $$[-45°, +45°]$$ |
|||
|
|||
2. Lookup gains: |
|||
* `G_az[i] = interp(radar.az_lut, theta[i])` |
|||
* `G_el[i] = interp(radar.el_lut, elev_angle[i])` |
|||
|
|||
3. Combine gains (separable model): |
|||
|
|||
$$ |
|||
G_{ant}[i] = G_{az}[i] \times G_{el}[i] |
|||
$$ |
|||
|
|||
4. Apply: |
|||
|
|||
$$ |
|||
loss[i] \leftarrow loss[i] \times G_{ant}[i] |
|||
$$ |
|||
|
|||
✅ Fully vectorized NumPy operation. |
|||
|
|||
*** |
|||
|
|||
## 4. Multi‑Radar Safety Guarantees |
|||
|
|||
No special handling required **if the following rules are followed**: |
|||
|
|||
* Never modify shared `semantic_lidar_data` |
|||
* Antenna gain applied only to: |
|||
* Local loss arrays inside `get_loss_3()` |
|||
* No mutation of radar‑agnostic structures |
|||
|
|||
Your architecture already satisfies these conditions. |
|||
|
|||
*** |
|||
|
|||
## 5. Configuration Loading & Switching |
|||
|
|||
### 5.1 Attach LUTs per Radar Profile |
|||
|
|||
In `ConfigureRadar.py`: |
|||
|
|||
* Load LUTs as part of radar initialization |
|||
* Support per‑profile antenna selection: |
|||
* `"awrl1432_front"` |
|||
* `"awrl1432_corner"` |
|||
* `"generic_patch"` |
|||
|
|||
### 5.2 Runtime Safety |
|||
|
|||
Since each `ShenronRadarModel` owns its radar instance: |
|||
|
|||
* Switching patterns between radars is safe |
|||
* No cross‑profile contamination possible |
|||
|
|||
*** |
|||
|
|||
## 6. ADC Pipeline Interaction (No Changes Required) |
|||
|
|||
Because: |
|||
|
|||
* Antenna gain is applied **before ADC synthesis** |
|||
* Noise is added later in `heatmap_gen_fast.py` |
|||
|
|||
You automatically get: |
|||
|
|||
* Angle‑dependent SNR |
|||
* Realistic CFAR behavior |
|||
* Hardware‑like edge‑of‑FOV noise dominance |
|||
|
|||
✅ Do **not** touch ADC or noise code. |
|||
|
|||
*** |
|||
|
|||
## 7. Validation Hooks (Strongly Recommended) |
|||
|
|||
### 7.1 Internal Diagnostics |
|||
|
|||
Add (optional but useful): |
|||
|
|||
* Store `G_az`, `G_el`, `G_ant` in `last_metrology` |
|||
* Log min / max / mean gain per frame |
|||
|
|||
### 7.2 Visual Validation |
|||
|
|||
Confirm: |
|||
|
|||
* Point density decreases smoothly at FOV edges |
|||
* Peak intensity aligns at boresight |
|||
* Multiple radars show different angular falloff in the same scene |
|||
|
|||
*** |
|||
|
|||
## 8. Performance Impact |
|||
|
|||
* Operations: O(N) per radar, vectorized |
|||
* N ≈ 5k–15k points |
|||
* LUT interpolation cost negligible |
|||
|
|||
✅ Safe for real‑time simulation with multiple radars. |
|||
|
|||
*** |
|||
|
|||
## 9. Extension‑Ready Design |
|||
|
|||
This structure naturally supports later: |
|||
|
|||
* 2D az‑el LUTs |
|||
* Per‑virtual‑antenna offsets |
|||
* Beamforming‑aware gain shaping |
|||
|
|||
No redesign required. |
|||
|
|||
*** |
|||
|
|||
## ✅ Final Summary |
|||
|
|||
| Aspect | Status | |
|||
| ----------------------- | ------ | |
|||
| Radar‑specific | ✅ Yes | |
|||
| Multi‑radar safe | ✅ Yes | |
|||
| Minimal code changes | ✅ Yes | |
|||
| Physically correct | ✅ Yes | |
|||
| ADC‑correct integration | ✅ Yes | |
|||
|
|||
**This plan integrates azimuth & elevation radiation patterns into Shenron cleanly, deterministically, and without architectural risk.** |
|||
|
|||
If you want, next I can: |
|||
|
|||
* Write **exact pseudocode for get\_loss\_3()** |
|||
* Define **LUT file formats** |
|||
* Suggest **default az/el cutoffs for AWRL1432** |
|||
* Design a **radar antenna profile schema** |
|||
|
|||
Just say what’s next. |
|||
@ -0,0 +1,28 @@ |
|||
# Shenron Antenna Gain & Compensation Logic |
|||
|
|||
## 📡 Azimuth & Elevation Gain Integration |
|||
The latest iteration implements a **separable antenna pattern model**. This ensures that targets detected at the edges of the radar's Field of View (FOV) are correctly attenuated, matching real-world hardware behavior. |
|||
|
|||
### 1. Implementation Details (`Sceneset.py`) |
|||
In `get_loss_3()`, the antenna gain $G_{ant}$ is calculated as the product of horizontal and vertical patterns: |
|||
$$G_{ant}(\theta, \phi) = G_{az}(\theta) \times G_{el}(\phi)$$ |
|||
|
|||
- **Azimuth ($\theta$):** Uses a Look-Up Table (LUT) for symmetric gain interpolation. Points outside the precise LUT range are clamped to the nearest edge value. |
|||
- **Elevation ($\phi$):** Implements a **Hard FOV Cutoff**. Points beyond the mechanical vertical beamwidth receive zero gain, accurately simulating physical sensor limitations. |
|||
- **Physics Order:** Gain is applied to the incident power *after* the path loss but *before* the material interaction, ensuring that the antenna pattern does not affect target reflectivity. |
|||
|
|||
### 2. High-Level System Gain (`gain = 110 dB`) |
|||
In `ConfigureRadar.py`, the parameter `self.gain` is set to values like `10 ** (110 / 10)`. |
|||
|
|||
**Why 110 dB?** |
|||
This is a **System-Level Calibration Constant** that encapsulates several physical and simulation factors: |
|||
1. **Transmit Power ($P_t$):** The actual chirping power emitted (typically ~10-15 dBm). |
|||
2. **Peak Antenna Gain ($G_t, G_r$):** The boresight gain of the TX and RX patches. |
|||
3. **Signal Chain Amplification:** Hardware-specific gains in the LNA and Mixer. |
|||
4. **Simulation Scaling:** In physics-based simulations, units computed for unit scatterers ($1/R^2$) result in extremely small floating-point values. The 110 dB factor "lifts" these signals into a dynamic range that maps correctly to real 16-bit or 32-bit ADC data formats. |
|||
|
|||
By tuning this single "dial," the simulation can be calibrated to match the peak Signal-to-Noise Ratio (SNR) seen in real-world hardware datasets. |
|||
|
|||
## ⚙️ Calibration Flow |
|||
- **Standard Baseline:** 110 dB (Calibrated for Iteration 16/18 physics). |
|||
- **Match Hardware:** Adjust this dial ±5 dB if targets at 10m in simulation appear significantly stronger/weaker than in real sensor captures. |
|||
@ -0,0 +1,30 @@ |
|||
# Shenron Modular Radar Architecture |
|||
|
|||
## Overview |
|||
Shenron is a high-fidelity, physics-based radar simulation engine designed for multi-modal ADAS research. The latest iteration (Iteration 18) introduces a modular "Knobs and Dials" approach, allowing the engine to be tuned to match specific hardware characteristics via a centralized configuration system. |
|||
|
|||
## 🏗️ Core Components |
|||
|
|||
### 1. Radar Configuration (`ConfigureRadar.py`) |
|||
This is the "Control Panel" of the simulation. It provides: |
|||
- **Modular Profiles:** Pre-configured settings for `ti_cascade`, `radarbook`, and `awrl1432`. |
|||
- **Tunable Parameters:** |
|||
- `B` (Bandwidth): Impacts range resolution. |
|||
- `chirps`: Impact Doppler resolution and processing gain. |
|||
- `nRx`: Number of receiving antennas (virtual antennas). |
|||
- `gain`: System-level calibration constant ($P_t G_t G_r$ and scaling). |
|||
- `noise_amp`: High-level noise floor control. |
|||
|
|||
### 2. Physics Modeling (`Sceneset.py`) |
|||
The engine simulates electromagnetic interactions using deterministic physical laws: |
|||
- **Material Interactions:** Uses Fresnel equations for reflection and Beckmann-Spizzichino for scattering, indexed by material type (Metal, Concrete, Wood, etc.). |
|||
- **1/R⁴ Power Law:** Implements a pure physical $1/R^2$ transmit and $1/R^2$ receive path loss, ensuring signal strength decays naturally with range. |
|||
- **Occlusion & Hidden Points:** Uses Open3D's hidden point removal and KD-Trees to simulate line-of-sight and density. |
|||
|
|||
### 3. Signal Generation (`heatmap_gen_fast.py`) |
|||
- **GPU Acceleration:** High-performance signal synthesis using PyTorch. |
|||
- **MIMO Processing:** Simulates multi-chirp frames and doppler shifts. |
|||
- **ADC Synthesis:** Multiplies the physics-based voltage signal by the hardware calibration constant to produce raw I/Q-like data. |
|||
|
|||
## 🎛️ The "Knobs and Dials" Philosophy |
|||
The engine is built to be "physics-first, tuning-second." By maintaining a rigid physical baseline (1/R⁴, Fresnel), we can trust that the simulator's spatial and temporal behavior is correct. The "dials" (Bandwidth, Gain, Noise) are used solely to align the simulation with real-world sensor specifications. |
|||
@ -0,0 +1,74 @@ |
|||
# Shenron Radar Architecture Breakdown |
|||
|
|||
This document provides a precise architectural analysis of the Shenron radar simulation pipeline, focusing on ownership, energy flow, and multi-radar extensibility. |
|||
|
|||
### 🏗️ Radar Abstraction & Ownership |
|||
|
|||
1. **Radar Instance Representation**: Represented as a `radar` class in `ConfigureRadar.py`. It is a configuration-heavy object containing both hardware specs (frequency, bandwidth) and physics parameters (beamwidth, gain). |
|||
2. **Signal Generation Ownership**: Each `ShenronRadarModel` (in `model_wrapper.py`) own its own `radar_obj`. The pipeline is private to the instance; radars share the input **Semantic LiDAR** but do not share intermediate artifacts like ADC cubes or calculated losses. |
|||
3. **Metadata Storage**: All sensor-specific metadata (mount pose, FOV, waveform, noise floor) is stored as attributes of the `radar` class. It is accessed by name (e.g., `radar_type='awrl1432'`) during model initialization. |
|||
4. **Sequential vs Parallel**: Processing is currently **sequential**. Within a single frame, the orchestrator iterates through defined radar profiles, generating one set of ADC samples and one point cloud at a time. |
|||
|
|||
### ⚡ Energy Flow & Reuse |
|||
|
|||
5. **Reflected Energy Stage**: First computed in `Sceneset.py` within the `get_loss_3` function. |
|||
6. **Energy Form**: Linear power (normalized unitless factor representing RCS + Path Loss). |
|||
7. **Storage Granularity**: Stored **per-point** in a 1D array of length $N_{pts}$. |
|||
8. **Reuse vs Recompute**: It is currently **recomputed** for every radar profile. Even if the points are identical, `get_loss_3` is called fresh for each radar instance to account for radar-specific gains. |
|||
9. **Radar-Agnostic Stages**: Only the raw `semantic_lidar_data` ingestion and the basic axis-swap in `lidar.py` are truly radar-agnostic. Once the data enters `Cropped_forRadar`, it becomes radar-dependent. |
|||
|
|||
### 🌐 Coordinate Frames & Angular Knowledge |
|||
|
|||
10. **Transformation Point**: Points are transformed into radar-local coordinates in `lidar.py` inside `Cropped_forRadar` via the `rotate_points` function and mount-offset subtraction (e.g., `CARLA_X - 2.0`). |
|||
11. **Derived Quantities**: Azimuth (`theta`) and Elevation (`elev_angle`) are computed derivationally in `specularpoints()` (Lines 221-222) before being passed to the loss function. They are not currently stored in the point structure. |
|||
12. **Re-casting Rays**: Points are represented in Cartesian XYZ; azimuth and elevation can be (and are) computed analytically without re-casting rays. |
|||
13. **Occlusion & Incidence**: Occlusion is strictly **radar-dependent** (calculated from the `radar.center` viewpoint). Incidence angle is calculated relative to surface normals and is partially shared as it is scene-dependent, but its power-contribution is radar-dependent. |
|||
|
|||
### 📉 Loss / Gain Modeling |
|||
|
|||
14. **Modular Support**: Modular support is limited. Code uses fixed functions (`get_loss_3`); there is no plug-in architecture for gain blocks yet. |
|||
15. **Application Relative Order**: Applied in the following order: Range Loss ($1/R^2$ transmit) → Material Permittivity Loss → Surface Roughness Loss → Vertical Antenna Gain. Horizontal gain is currently missing. |
|||
16. **Mathematical Domain**: Applied **multiplicatively in linear space**. |
|||
17. **Scaling Mechanism**: Scaling is currently injected via the `radar.gain` and `radar.vertical_beamwidth` properties passed into the physics functions. |
|||
|
|||
### 🛡️ Multi‑Radar Safety |
|||
|
|||
18. **Shared Tick Structures**: The incoming `semantic_lidar_data` numpy array is the primary shared structure. |
|||
19. **Contamination Risk**: Low. `lidar.py` and `Sceneset` operate on slices or copies (e.g., `skew_pc`, `new_pc`). Internal modifications to `pc[:, 4]` exist but usually target local copies. |
|||
20. **Immutability**: Not strictly enforced by Python, but the workflow treats the input LiDAR as a read-only source. |
|||
21. **Attribute Cloning**: Introducing per-radar antenna loss would **not** require cloning the whole attribute list; it simply requires a new temporary array produced by the radar-specific loss function. |
|||
|
|||
### 📡 ADC & Noise Injection |
|||
|
|||
22. **Thermal Noise Stage**: Added during the ADC synthesis in `heatmap_gen_fast.py` (Line 146). It is added to the clean signal after beamforming. |
|||
23. **ADC Sharing**: Strictly **per-radar**. ADC cubes are not shared across profiles. |
|||
24. **SNR Variation**: Easily introduced via the `radar.noise_amp` property in the profile. |
|||
25. **Power Preservation**: Signal power and noise power are calculated separately and summed; they are not tracked as separate streams after summation. |
|||
|
|||
### ⚙️ Configuration & Extensibility |
|||
|
|||
26. **Profile Loading**: Hardcoded Python classes/dictionaries in `ConfigureRadar.py`. |
|||
27. **Sensor LUTs**: Existing precedent in `lidar.py` for semantic-to-material mapping tables. |
|||
28. **Radiation Patterns**: Can be attached as scalar beamwidths (current) or arrays/LUTs (feasible). |
|||
29. **Runtime Switching**: Fully supported via the `ShenronRadarModel` wrapper. |
|||
|
|||
### 🚀 Performance & Scaling |
|||
|
|||
30. **Point Budget**: 5,000 – 15,000 points per radar per frame (post-cropping). |
|||
31. **LUT Performance**: Highly acceptable; NumPy vectorized lookups for material/angle coefficients are not a bottleneck. |
|||
32. **Memory Pressure**: Low for point data. High for ADC cubes and large Range-Doppler FFT matrices if many radars run concurrently. |
|||
|
|||
### 🐞 Validation & Debugging |
|||
|
|||
33. **Logging Hooks**: The `last_metrology` dictionary in `model_wrapper.py` serves as the primary hook for internal diagnostics. |
|||
34. **Energy Annotation**: The internal `loss` array is calculated but usually discarded; it is not currently appended to the return point cloud. |
|||
35. **Comparison Hook**: Radars can be compared frame-by-frame by running two model instances on the same `semantic_lidar_data` buffer. |
|||
|
|||
### 🔮 Future‑Proofing |
|||
|
|||
36. **MIMO/Virtual Antennas**: Logic lives in `heatmap_gen_fast.py` inside the torch-accelerated phase-delay loop. |
|||
37. **Physics Separation**: A partial separation exists. `Sceneset.py` is "Scene Physics" (Reflection/Scattering), while `ConfigureRadar.py` is "Sensor Physics." |
|||
38. **Antenna Pattern Logic**: Logically belongs to the **Sensor Model** (`ConfigureRadar`) but must be applied during the **Scene Physics** stage to attenuate incident rays before they become ADC signals. |
|||
|
|||
*** |
|||
*Generated by Antigravity AI | Fox Radar ADAS Pipeline Architecture Review* |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue