From 8f052b65953f63be2c0c41b6cc9bd4474210a8a6 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Tue, 21 Apr 2026 20:00:11 -0700 Subject: [PATCH] Adding land features including lidar --- CLAUDE.md | 249 +++++++++++++++++++++++++++++++++++++++++++++++- DESIGN.md | 202 +++++++++++++++++++++++++++++++++++++++ additions.lidar | 36 +++++++ src/settings.h | 116 ++++++++++++++++++++++ 4 files changed, 600 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 1c2c89c..8a78ba4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ with AMD AI chip R9-8945HS with 32 GB ram # Project: C++ OpenGL Radar Simulation **Environment:** Ubuntu Linux (Remote SSH from Windows) -**Tech Stack:** C++20, OpenGL 3.3 Core, GLFW, GLAD, FreeType +**Tech Stack:** C++20, OpenGL 3.3 Core, GLFW, GLAD, FreeType, GDAL (libgdal-dev) The operating system is Linux (Ubuntu) @@ -51,6 +51,15 @@ entire directory list is /home/maallyn/new-radar on the Geekom. ./LICENSE ./src ./src/CLAUDE.md +./map +./map/lidar_processed +./map/charts_enc +./map/charts_enc/US5WA45M.000 +./map/charts_enc/n48_w123_1arc_v3.tif +./map/lidar_raw +./map/lidar_raw/wa2022_nooksack_dem_J1364940.zip +./map/lidar_raw/wa2016_west_dem_J1364939.zip + ================================================================== @@ -641,6 +650,16 @@ settings.h — tunable constants: - Rain clutter filter: default (0.0 = off), minimum (0.0), maximum (1.0), keyboard step size - Wave clutter filter: default (0.0 = off), minimum (0.0), maximum (1.0), keyboard step size - Key-hold acceleration for gain, rain clutter, and wave clutter keys + - Terrain bounding box (lat/lon min/max) and processed cell size + - Terrain material σ° values (soil, rock, concrete, water calm/rough) + - Terrain material speckle/grain amplitudes (soil, rock, concrete) + - Terrain classification thresholds (rock elevation, rock slope) + - Terrain polar grid dimensions (range bins, bearing bins) + - Terrain clutter brightness scale for marine PPI + - Terrain boat recompute threshold (degrees bearing offset change) + - ATC terrain clutter suppressed flag (bool, default true) + - ATC terrain shadow enabled flag (bool, default true) + - LiDAR structure height threshold for man-made classification ================================================================== @@ -1055,6 +1074,220 @@ in settings.h so they can be tuned without touching equation code. ================================================================== +TERRAIN AND LAND CLUTTER + +================================================================== + +DATA SOURCES + map/charts_enc/US5WA45M.000 + S-57 Electronic Navigational Chart; coastline polygon, + pier/breakwater geometry, named landmarks. Parsed with GDAL/OGR. + + map/charts_enc/n48_w123_1arc_v3.tif + USGS 1 arc-second (~30 m) DEM GeoTIFF. Terrain elevation for the + Bellingham area — Cascades, Chuckanut Mountain, coastal lowlands. + + map/lidar_raw/wa2016_west_dem_J1364939.zip + 2016 western WA LiDAR DEM. Resolves waterfront structures, + breakwaters, piers, Boulevard Park boardwalk, and other man-made + features at ~1 m resolution. + + map/lidar_raw/wa2022_nooksack_dem_J1364940.zip + 2022 Nooksack basin LiDAR DEM. Covers the delta and lowlands + northeast of Bellingham Bay; used for terrain shadowing from the + northeast quadrant. + + All three sources are processed offline by terrain_preprocess into + binary grids in map/lidar_processed/. The raw files are never opened + at exhibit runtime. See TERRAIN PREPROCESSING section below. + + GDAL (libgdal-dev) is a required build dependency for + terrain_preprocess. It is NOT linked into the main radar binary. + +CLASSES + + TerrainMap (Thread 1, read-only after init) + Loaded once at startup from map/lidar_processed/. Reads the four + binary grids and the metadata JSON. Provides: + - Elevation query by lat/lon + - Material query by lat/lon + - Pre-computed polar clutter grid (range × bearing bins) per + fixed radar location + - Line-of-sight shadow mask per radar location + Thread 1 only after init; no mutex required. + + LandClutter (Thread 1) + Queries TerrainMap to generate clutter returns for each scope. + Called once per full sweep rotation, not once per frame. + - Marine A-Scope: produces amplitude samples along the current + antenna bearing for injection into the range trace. + - Marine PPI / ATC PPI: produces a polar texture (range × bearing) + uploaded to the GPU once per sweep period. + +TERRAIN MATERIALS AND RCS + + Each terrain cell is classified as one of four materials. Normalized + backscatter coefficient σ° (linear, m²/m²) is defined in settings.h: + + TERRAIN_SIGMA0_SOIL ~0.010 (−20 dB) — moist vegetated soil + TERRAIN_SIGMA0_ROCK ~0.032 (−15 dB) — exposed rock, rough face + TERRAIN_SIGMA0_CONCRETE ~0.100 (−10 dB) — smooth hard surface; + structures produce + corner-reflector effect + TERRAIN_SIGMA0_WATER_CALM ~0.0003 (−35 dB) — open water, calm; + mostly specular, low + backscatter + TERRAIN_SIGMA0_WATER_ROUGH ~0.010 (−20 dB) — choppy sea, sea clutter + + Classification rules applied by terrain_preprocess at build time: + - Below sea level or inside S-57 coastline polygon → water + - Inside S-57 pier/breakwater/wharf feature → concrete + - Elevation > TERRAIN_ROCK_THRESHOLD_M AND slope + > TERRAIN_ROCK_SLOPE_THRESHOLD_DEG → rock + - All remaining land cells → soil + +RADAR EQUATION FOR TERRAIN (area-extensive / clutter form) + + P_r = (P_t × G² × λ² × σ° × A_cell) / ((4π)³ × R⁴) + + A_cell is the terrain cell area projected along the beam. + Evaluated CPU-side in LandClutter for each illuminated cell. + Result drives per-cell brightness in the clutter texture. + Same radar parameters (P_t, G, λ) used for point targets. + +SHADOW / LINE-OF-SIGHT MASKING + + Computed by terrain_preprocess for each fixed radar location and + stored in the processed data as uint8 shadow masks. Algorithm: march + outward from the radar along each azimuth radial, tracking the maximum + elevation angle seen. Any cell whose surface angle falls below that + maximum is shadowed — clutter amplitude = 0 and target returns through + that cell are attenuated proportionally. + + Shadow masks stored per radar location: + map/lidar_processed/shadow_marine.u8 — marine bay platform + map/lidar_processed/shadow_atc.u8 — BLI ATC tower + + Bearing offset (k/j keys on PPI scopes): + The k/j keys change display heading only — which direction appears + at the top of the scope. They do NOT move the radar geographically. + The shadow mask is unchanged. The terrain clutter shader receives + the offset as a rotation uniform and samples the polar texture at + the offset angle. Zero CPU overhead; no shadow recomputation. + + Future boat scenario (not in v1): + If the radar antenna physically moves to a new lat/lon, the shadow + mask would be recomputed on a background thread while the display + continues with the previous mask. + +PER-SCOPE TERRAIN BEHAVIOR + + Marine A-Scope: + Land returns appear as stable blips at fixed ranges on the current + antenna bearing. Concrete structures give strong returns; soil/hills + give moderate returns; shadowed areas return nothing. Period + operators were trained to discard stable blips when searching for + moving targets. + + Marine PPI (fixed platform and boat heading offset): + Land clutter is fully visible. Coastline, hills, piers, and + breakwaters paint exactly as on a real period marine radar. The + clutter texture updates once per 4-second sweep rotation. + + ATC PPI: + Moving Target Indicator (MTI) cancellation suppresses land clutter. + Controlled by ATC_TERRAIN_CLUTTER_SUPPRESSED (default true) in + settings.h. Terrain shadowing of aircraft IS applied — controlled + by ATC_TERRAIN_SHADOW_ENABLED (default true). Aircraft approaching + behind a ridge appear at reduced amplitude or disappear until they + clear the ridge, as on period ASR equipment. + + Chain Home A-Scope: + No terrain data applied. The exhibit scenario faces the English + Channel; the transmitter floodlights the sea. Land returns are + not simulated for this scope. + + PAR: + No terrain clutter. PAR points at a single fixed approach path; + the narrow beam and short range make land returns negligible. + +TERRAIN CLUTTER SHADER + + terrain_clutter.vert / terrain_clutter.frag + Renders the polar clutter texture as a quad overlay on the PPI + scope. Converts screen coordinates to polar, samples the clutter + texture, and outputs P7-compatible phosphor color and alpha so + terrain returns decay on the same timescale as target echoes. + Uniforms: + u_bearingOffsetDeg — boat heading correction (default 0.0) + u_clutterSuppressed — bool; 1 = suppress (ATC mode) + u_maxRangeM — current scope max range in meters + u_clutterBrightness — TERRAIN_MARINE_CLUTTER_BRIGHTNESS scale + Used by MarinePPIScope and ATCPPIScope. + +================================================================== + +TERRAIN PREPROCESSING + +================================================================== + +The raw LiDAR zip files cannot be used at exhibit runtime. The offline +tool terrain_preprocess processes them once and writes ready-to-use +binary grids to map/lidar_processed/. Must be run before first launch +and re-run whenever TERRAIN_BBOX_* or TERRAIN_PROCESSED_CELL_DEG +constants in settings.h change. + +TOOL + Build target: terrain_preprocess (separate CMake executable) + Source: src/terrain_preprocess.cpp + Links: GDAL only; NOT linked into the main radar binary + Run: ./terrain_preprocess (from build directory) + +PIPELINE (runs in order) + 1. Unzip both LiDAR archives to a temp directory. + 2. Inventory tiles — enumerate .tif / .img files, check CRS and + native resolution of each. + 3. Merge tiles within each survey into a GDAL VRT mosaic. + 4. Warp both surveys to WGS84 (EPSG:4326) at + TERRAIN_PROCESSED_CELL_DEG resolution. + 5. Crop to bounding box: TERRAIN_BBOX_LAT_MIN/MAX, + TERRAIN_BBOX_LON_MIN/MAX. + 6. Merge the two surveys — where they overlap, the 2022 Nooksack + data wins over the 2016 western data (higher vintage / resolution). + 7. Material classification: + Load S-57 ENC (US5WA45M.000) via GDAL/OGR. + Apply classification rules described in TERRAIN section above. + 8. Compute shadow mask for marine platform and ATC tower using radial + elevation-angle march along each azimuth bearing. + 9. Write to map/lidar_processed/: + elevation.f32 float32 row-major grid, meters, WGS84 + material.u8 uint8 per cell (0=water 1=soil 2=rock 3=concrete) + shadow_marine.u8 uint8 visibility mask for marine radar + shadow_atc.u8 uint8 visibility mask for ATC radar + terrain_meta.json grid dimensions, lat/lon origin, cell size, + source file checksums, processing date + +RUNTIME VALIDATION + TerrainMap reads terrain_meta.json at startup and compares the stored + bounding box and cell-size values against current settings.h constants. + If they differ it prints a warning and continues with stale data: + WARNING: terrain data was built with different bounding box or + cell size — re-run terrain_preprocess before exhibit launch. + The exhibit does not crash; it runs with the old grid. + +OUTPUT FILES (map/lidar_processed/) + elevation.f32 — float32 elevation grid + material.u8 — uint8 material classification grid + shadow_marine.u8 — uint8 line-of-sight mask, marine radar + shadow_atc.u8 — uint8 line-of-sight mask, ATC radar + terrain_meta.json — metadata and provenance record + + These five files are the only terrain inputs at runtime. + The raw zip archives in map/lidar_raw/ are never opened by + the exhibit binary. + +================================================================== + FILE LAYOUT (COMPLETE — including additions) ================================================================== @@ -1082,6 +1315,13 @@ src/ rpi_receiver.h / rpi_receiver.cpp db_panel.h / db_panel.cpp — Dear ImGui DB management panel (--database mode only) + terrain_map.h / terrain_map.cpp — DEM load, shadow mask, polar clutter + grid; read-only after init, Thread 1 + land_clutter.h / land_clutter.cpp — per-sweep clutter arrays for A-scope + range trace and PPI clutter texture + terrain_preprocess.cpp — standalone offline preprocessing tool; + separate CMake target; links GDAL only; + NOT part of main radar binary settings.h — all constexpr constants; no .cpp imgui/ — Dear ImGui source, compiled in @@ -1091,8 +1331,11 @@ src/ imgui_draw.cpp / imgui_tables.cpp / imgui_widgets.cpp shaders/ - phosphor.vert / phosphor.frag — P1 and P7 via uniforms + phosphor.vert / phosphor.frag — P1 and P7 via uniforms graticule.vert / graticule.frag text.vert / text.frag sweep.vert / sweep.frag - bloom.vert / bloom.frag — FBO bloom post-processing + bloom.vert / bloom.frag — FBO bloom post-processing + terrain_clutter.vert / terrain_clutter.frag — polar clutter texture overlay + on PPI; P7-compatible decay; + bearing offset rotation uniform diff --git a/DESIGN.md b/DESIGN.md index 961a5b3..9a72f74 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -402,3 +402,205 @@ No raw `new` or `delete` anywhere in the codebase. No `malloc`/`free`. 3.0 (a mid-range estimate). This is applied in the radar equation computation for Chain Home targets only, before the result is passed to the bloom/ brightness pipeline. + +17. **Terrain and land clutter** are rendered from pre-processed binary grids + in `map/lidar_processed/`. The offline tool `terrain_preprocess` fuses the + SRTM DEM, both LiDAR surveys, and the S-57 ENC into elevation, material, + and shadow-mask grids. At runtime `TerrainMap` loads these grids once; + `LandClutter` generates a polar clutter texture once per sweep period. + See the TERRAIN CLUTTER VISUAL DESIGN REFERENCE section below for + per-material appearance and speckle tuning guidance. + +--- + +## Terrain Clutter Visual Design Reference + +All tunable values described here have corresponding constants in +`src/settings.h`. Edit `settings.h` to change values; this section +explains the perceptual intent behind each constant. + +### Purpose + +The goal is historical authenticity. Period marine radar operators in the +1950s saw the Bellingham shoreline as a bright, stable ring of returns that +formed a recognizable coastline silhouette. Skilled operators mentally +subtracted this from the display and watched only for moving or changing +returns. That experience should be reproducible on this exhibit. + +--- + +### Material Visual Character + +**SOIL** (vegetated land, fields, low hills) + +Period appearance: moderate-brightness, moderately grainy returns. The +grain (speckle) is high because vegetation is irregular — individual trees, +bushes, and undulations produce slightly different returns each sweep. +The overall brightness holds steady between sweeps but the texture shimmers. + +- σ° constant: `TERRAIN_SIGMA0_SOIL` (~0.010, −20 dB) +- Speckle: `TERRAIN_SPECKLE_SOIL` (suggested starting value: **0.35**) +- Appearance: mid-grey; clearly visible but not dominating. Rolling + hillsides read as a diffuse bright edge along the coastline + and inland ridges. + +--- + +**ROCK** (exposed cliff faces, upper Chuckanut ridgeline, rock outcrops) + +Period appearance: brighter than soil, less speckle. Rock faces are +geometrically consistent so returns are stable sweep to sweep. Steep faces +pointing toward the radar return a disproportionately strong echo. + +- σ° constant: `TERRAIN_SIGMA0_ROCK` (~0.032, −15 dB) +- Speckle: `TERRAIN_SPECKLE_ROCK` (suggested starting value: **0.20**) +- Appearance: noticeably brighter than soil; Chuckanut Mountain's western + face reads as a bright arc, stable between sweeps. Little + shimmer — the texture is coarser and more consistent. + +--- + +**CONCRETE** (breakwaters, piers, dock structures, Boulevard Park boardwalk, +harbor facilities) + +Period appearance: the strongest land returns on the scope after large steel +vessels. Structures built over water (piers on pilings, breakwater walls) +produce corner-reflector effects — the right-angle junction between the +vertical face and the water surface acts as a retroreflector. Operators used +these as navigation aids; the Bellingham harbor entrance is identifiable by +its distinctive bright return pattern. + +- σ° constant: `TERRAIN_SIGMA0_CONCRETE` (~0.100, −10 dB) +- Speckle: `TERRAIN_SPECKLE_CONCRETE` (suggested starting value: **0.12**) +- Appearance: bright, stable, low shimmer. Breakwaters and piers appear as + sharp bright lines or arcs. The Boulevard Park boardwalk over + the water appears as a bright thin arc. These features should + be the most prominent land returns on the scope after large + steel ships. + +--- + +**WATER — CALM** (open bay, light wind) + +Period appearance: very weak, near-invisible. Calm water reflects most radar +energy away from the antenna (specular reflection). Operators saw a nearly +blank area over open water even at high gain. + +- σ° constant: `TERRAIN_SIGMA0_WATER_CALM` (~0.0003, −35 dB) +- Appearance: at normal gain, essentially black. Only visible at extreme + gain settings as a faint salt-and-pepper noise floor. + +--- + +**WATER — ROUGH** (choppy bay, wind >10 knots) + +Period appearance: a low-level fuzzy return rising from the noise floor, +affecting the inner ranges most strongly. Sea clutter was a major nuisance +on small-vessel marine radar. The wave clutter filter (keys 5/6) suppresses +this. + +- σ° constant: `TERRAIN_SIGMA0_WATER_ROUGH` (~0.010, −20 dB) +- Appearance: at normal gain, a hazy shimmer at short ranges that fades + outward. Heavy speckle — random wave facets scatter + incoherently. The wave clutter filter reduces this. + +--- + +### Speckle / Grain Tuning Guide + +Speckle simulates pulse-to-pulse amplitude variation caused by incoherent +scattering from irregular surfaces. Implemented as a per-cell random +fraction multiplied by the computed P_r each sweep: + +``` +Speckle = P_r × (1.0 + TERRAIN_SPECKLE_xxx × random(−1, +1)) +``` + +Values close to 0.0 give stable, solid returns (correct for concrete and +large flat surfaces). Values closer to 0.5 give vigorous shimmer (correct +for vegetation and choppy water). Values above 0.5 are unrealistically noisy +for terrain — avoid unless simulating a very rough or complex surface. + +Suggested starting values: + +| Constant | Value | Character | +|-----------------------------|-------|-----------------------------------------| +| `TERRAIN_SPECKLE_SOIL` | 0.35 | visible shimmer, naturalistic | +| `TERRAIN_SPECKLE_ROCK` | 0.20 | moderate, stable with some texture | +| `TERRAIN_SPECKLE_CONCRETE` | 0.12 | mostly stable; slight flicker from edge | + +**Tuning procedure:** +1. Set max range to 6 miles on the Marine PPI. +2. Rotate to a bearing showing the Bellingham breakwater and open bay. +3. Adjust `TERRAIN_MARINE_CLUTTER_BRIGHTNESS` until the breakwater return + is clearly bright but does not wash out nearby ship targets. +4. Adjust `TERRAIN_SIGMA0_CONCRETE` if breakwater brightness relative to + soil hills looks wrong. +5. Adjust speckle values until soil hillsides shimmer naturally and concrete + structures hold steady between sweeps. +6. Verify at all three marine range settings (2, 4, 6 miles) that clutter + does not overwhelm vessel targets at any range. + +--- + +### Overall Brightness Balance + +The most important perceptual tuning parameter is +`TERRAIN_MARINE_CLUTTER_BRIGHTNESS`. It is a linear scale factor applied to +all terrain return brightness before the clutter texture is uploaded to the +GPU. It does not change the relative balance between materials — it scales +all terrain uniformly. + +**Target appearance goal:** +- A steel AIS vessel at 3 miles range should be 2–3× brighter than the + strongest adjacent land clutter return (a concrete breakwater). +- The coastline silhouette should be clearly readable as geography — a + visitor who knows Bellingham Bay should recognize the shape. +- Open water should be visually clean at default gain settings. + +Suggested starting value: `TERRAIN_MARINE_CLUTTER_BRIGHTNESS = 0.55` + +**ATC PPI:** `ATC_TERRAIN_CLUTTER_SUPPRESSED = true` means land clutter is +hidden by MTI cancellation — no brightness tuning needed for ATC. If +suppression is disabled for debugging, use `TERRAIN_MARINE_CLUTTER_BRIGHTNESS` +as a guide. + +--- + +### Shadow Zones + +Shadow zones are the most dramatic visual effect on the Marine PPI. They +appear as dark wedge-shaped gaps in the land clutter pattern, pointing +outward from the radar, behind ridgelines and hills. + +Key shadow features visible from the marine bay platform: +- **Chuckanut Mountain** (southwest) casts a prominent shadow into the + southern bay and beyond. +- **Lummi Island** (northwest) shadows a sector of the northern bay. +- **Bellingham waterfront bluff** shadows part of the inner harbor. + +These shadows are inherently dark against surrounding clutter — no tuning +required. Shadow = zero amplitude, computed geometrically by the preprocessor. + +For the ATC scope with `ATC_TERRAIN_SHADOW_ENABLED = true`, shadows affect +aircraft returns only (not the display background, which is suppressed). An +aircraft descending behind Chuckanut Mountain will fade out and reappear as +it clears the ridge on final approach — authentic behavior of period ASR radar. + +--- + +### Polar Clutter Texture Resolution + +`TERRAIN_POLAR_BEARING_BINS` and `TERRAIN_POLAR_RANGE_BINS` control the +resolution of the GPU texture carrying terrain clutter to the shader. +Recommended values: + +| Scope | Bearing bins | Range bins | Notes | +|---------------------|-------------|------------|------------------------------| +| Marine PPI (6 mi) | 720 | 512 | 0.5° matches marine beamwidth| +| ATC PPI (20 mi) | 720 | 1024 | wider range needs more bins | + +The texture is regenerated once per sweep period (every 4–5 seconds), not +every frame. Upload cost is not time-critical. Reducing to 360 bearing bins +is acceptable and halves the texture upload cost at the expense of slightly +blocky angular transitions near prominent features. diff --git a/additions.lidar b/additions.lidar index e69de29..fba0765 100644 --- a/additions.lidar +++ b/additions.lidar @@ -0,0 +1,36 @@ +I just added the following directories (alrady mentioned in the existing CLAUDE.md file +./map +./map/lidar_processed +./map/charts_enc +./map/charts_enc/US5WA45M.000 +./map/charts_enc/n48_w123_1arc_v3.tif +./map/lidar_raw +./map/lidar_raw/wa2022_nooksack_dem_J1364940.zip +./map/lidar_raw/wa2016_west_dem_J1364939.zip + +We need code for the marine a scope and marine ppi scope and the +on-boat ppi radar to show reflectivity from the ./map/charts_enc/US5WA45M.000 +and ./map/charts_enc/n48_w123_1arc_v3.tif (include whatever addional shader +files that may be needed. Consider with the topographical map the effect of higher hils +closer to lower hills will shadow the lower hills from the radar where ever the radar is, +which will change if there is a radar on a boat. + +The ./map/lidar_raw/wa2016_west_dem_J1364939.zip contains information for the lidar +mapping of any man made structures, including features on the waterfront; breakwaters, +piers, and structures built over the water such as the boulevard park boardwalk + +We will need to include the information in the ./map/lidar_raw/wa2016_west_dem_J1364939.zip +file to contribute to the reflection on the shore and land features. + +The marine a-scope and the maring PPI scope and the on boat ppi scope needs to show these +features. + +The Air traffic control radar in the day would blank out the shore features, but would show +the effects of shadowing of aircraft by the taller hils. + +The land featuresl should be subject +to the effects of the radar equation. Consider the materials be soil, rock, and concrete. + +In order to provide visual balance, the grain for returns of the shoreline, the mountains and +hills and the man made structures should be included in the settings.h file and DESIGN.md file + diff --git a/src/settings.h b/src/settings.h index 7c5b533..c2e798b 100644 --- a/src/settings.h +++ b/src/settings.h @@ -361,6 +361,122 @@ * range is approximately 2–5) */ +/* + * ================================================================ + * TERRAIN — BOUNDING BOX AND GRID + * ================================================================ + * The preprocessor crops both LiDAR surveys to this box and builds + * the binary grids at TERRAIN_PROCESSED_CELL_DEG resolution. + * If any of these values change, re-run terrain_preprocess. + * TerrainMap validates these against terrain_meta.json at startup + * and warns if a mismatch is found. + * + * TERRAIN_BBOX_LAT_MIN Southern edge of processed grid (degrees) + * TERRAIN_BBOX_LAT_MAX Northern edge of processed grid (degrees) + * TERRAIN_BBOX_LON_MIN Western edge of processed grid (degrees) + * TERRAIN_BBOX_LON_MAX Eastern edge of processed grid (degrees) + * Default box covers all three fixed radar locations plus the full + * 20-mile ATC radius: 48.5 N to 49.05 N, 122.0 W to 123.2 W + * + * TERRAIN_PROCESSED_CELL_DEG Cell size in degrees; ~0.0003° ≈ 30 m + * at this latitude. Matches SRTM resolution; + * LiDAR detail is resampled to this grid. + */ + +/* + * ================================================================ + * TERRAIN — MATERIAL CLASSIFICATION THRESHOLDS + * ================================================================ + * Applied by terrain_preprocess during material classification pass. + * Cells above both thresholds are classified as rock; all other + * non-water, non-structure land cells are classified as soil. + * + * TERRAIN_ROCK_THRESHOLD_M Minimum elevation for rock class (meters) + * TERRAIN_ROCK_SLOPE_THRESHOLD_DEG Minimum local slope for rock class (degrees) + * TERRAIN_STRUCTURE_HEIGHT_THRESHOLD_M + * Minimum height above surrounding terrain + * to classify a LiDAR feature as man-made + * concrete (meters; default 2.0) + */ + +/* + * ================================================================ + * TERRAIN — MATERIAL BACKSCATTER COEFFICIENTS (σ°) + * ================================================================ + * Normalized radar backscatter coefficient per material, linear + * (m²/m²). Used in the clutter radar equation inside LandClutter. + * Multiply by cell area and radar equation factors to get P_r. + * + * TERRAIN_SIGMA0_SOIL ~0.010 (−20 dB) moist vegetated land + * TERRAIN_SIGMA0_ROCK ~0.032 (−15 dB) exposed rock, rough face + * TERRAIN_SIGMA0_CONCRETE ~0.100 (−10 dB) hard smooth surface; + * corner reflectors from + * structure edges + * TERRAIN_SIGMA0_WATER_CALM ~0.0003 (−35 dB) flat water, specular + * TERRAIN_SIGMA0_WATER_ROUGH ~0.010 (−20 dB) choppy sea, sea clutter + */ + +/* + * ================================================================ + * TERRAIN — SPECKLE / GRAIN AMPLITUDES + * ================================================================ + * Random amplitude variation applied per cell per sweep to simulate + * the characteristic grainy texture of real radar land clutter. + * Values are fractional (0.0–1.0) multiplied by the computed P_r + * for each cell. See DESIGN.md for perceptual tuning guidance. + * + * TERRAIN_SPECKLE_SOIL Speckle fraction for soil returns + * TERRAIN_SPECKLE_ROCK Speckle fraction for rock returns + * TERRAIN_SPECKLE_CONCRETE Speckle fraction for concrete returns + * (lower than soil — structures are + * geometrically stable, less random) + */ + +/* + * ================================================================ + * TERRAIN — POLAR CLUTTER GRID DIMENSIONS + * ================================================================ + * The polar texture uploaded to the GPU for PPI rendering. Larger + * values give finer angular and range resolution but cost more VRAM + * and upload time. Texture is regenerated once per sweep period. + * + * TERRAIN_POLAR_BEARING_BINS Number of angular bins (360 minimum; + * 720 for 0.5° resolution) + * TERRAIN_POLAR_RANGE_BINS Number of range bins across max range + * (512 is sufficient for 6-mile marine; + * 1024 for 20-mile ATC) + */ + +/* + * ================================================================ + * TERRAIN — RENDERING AND DISPLAY FLAGS + * ================================================================ + * + * TERRAIN_MARINE_CLUTTER_BRIGHTNESS + * Overall brightness scale factor for + * land clutter on marine PPI (0.0–1.0). + * Tuned for visual balance against live + * target returns. See DESIGN.md. + * + * TERRAIN_BOAT_RECOMPUTE_THRESHOLD_DEG + * Reserved for future boat scenario. + * Minimum bearing offset change (degrees) + * before a background shadow recompute + * is triggered when the boat moves. + * Not used in v1 (fixed platforms only). + * + * ATC_TERRAIN_CLUTTER_SUPPRESSED + * true = suppress land clutter on ATC PPI + * (MTI cancellation; default true). + * Set false to show raw land clutter for + * debugging or demonstration purposes. + * + * ATC_TERRAIN_SHADOW_ENABLED true = apply terrain shadow attenuation + * to aircraft returns on ATC PPI. + * Aircraft behind hills appear at reduced + * amplitude or absent (default true). + */ + /* * ================================================================ * PAR GEOMETRY