Adding land features including lidar
This commit is contained in:
249
CLAUDE.md
249
CLAUDE.md
@@ -8,7 +8,7 @@ with AMD AI chip R9-8945HS with 32 GB ram
|
|||||||
|
|
||||||
# Project: C++ OpenGL Radar Simulation
|
# Project: C++ OpenGL Radar Simulation
|
||||||
**Environment:** Ubuntu Linux (Remote SSH from Windows)
|
**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)
|
The operating system is Linux (Ubuntu)
|
||||||
@@ -51,6 +51,15 @@ entire directory list is /home/maallyn/new-radar on the Geekom.
|
|||||||
./LICENSE
|
./LICENSE
|
||||||
./src
|
./src
|
||||||
./src/CLAUDE.md
|
./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
|
- 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
|
- 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
|
- 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)
|
FILE LAYOUT (COMPLETE — including additions)
|
||||||
|
|
||||||
==================================================================
|
==================================================================
|
||||||
@@ -1082,6 +1315,13 @@ src/
|
|||||||
rpi_receiver.h / rpi_receiver.cpp
|
rpi_receiver.h / rpi_receiver.cpp
|
||||||
db_panel.h / db_panel.cpp — Dear ImGui DB management panel
|
db_panel.h / db_panel.cpp — Dear ImGui DB management panel
|
||||||
(--database mode only)
|
(--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
|
settings.h — all constexpr constants; no .cpp
|
||||||
|
|
||||||
imgui/ — Dear ImGui source, compiled in
|
imgui/ — Dear ImGui source, compiled in
|
||||||
@@ -1091,8 +1331,11 @@ src/
|
|||||||
imgui_draw.cpp / imgui_tables.cpp / imgui_widgets.cpp
|
imgui_draw.cpp / imgui_tables.cpp / imgui_widgets.cpp
|
||||||
|
|
||||||
shaders/
|
shaders/
|
||||||
phosphor.vert / phosphor.frag — P1 and P7 via uniforms
|
phosphor.vert / phosphor.frag — P1 and P7 via uniforms
|
||||||
graticule.vert / graticule.frag
|
graticule.vert / graticule.frag
|
||||||
text.vert / text.frag
|
text.vert / text.frag
|
||||||
sweep.vert / sweep.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
|
||||||
|
|||||||
202
DESIGN.md
202
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
|
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/
|
for Chain Home targets only, before the result is passed to the bloom/
|
||||||
brightness pipeline.
|
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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
116
src/settings.h
116
src/settings.h
@@ -361,6 +361,122 @@
|
|||||||
* range is approximately 2–5)
|
* 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
|
* PAR GEOMETRY
|
||||||
|
|||||||
Reference in New Issue
Block a user