Incorporated all changes into CLAUDE.md

This commit is contained in:
2026-04-21 20:57:57 -07:00
parent 8f052b6595
commit b6d3415ee7
4 changed files with 502 additions and 358 deletions

560
CLAUDE.md
View File

@@ -277,7 +277,81 @@ should be articulated in the descriptive text
and y for smaller range. These controls should have slow movement for single stroke; but and y for smaller range. These controls should have slow movement for single stroke; but
gradual for for holding key down. gradual for for holding key down.
5. Air Traffic PPI Scope - 5. Police Patrol Boat PPI
This scope shows the radar display aboard a simulated Bellingham Police
Department patrol vessel making its routine waterfront patrol. Unlike all
other scopes in this exhibit the radar origin is not fixed — it moves with
the boat, making this a genuinely different operational experience.
THE PATROL VESSEL AND ITS RADAR
The vessel carries a professional-grade open-array radar: 6 kW peak power,
24-inch open array, ~1.9° horizontal beamwidth, mounted 34 m above the
waterline on a flybridge or radar arch. This is a working law-enforcement
vessel, not a recreational boat; the equipment reflects that. The narrower
beamwidth (vs a recreational radome's 46°) gives better azimuth resolution
and less sea clutter per range cell — important when searching for small
targets such as kayakers and stand-up paddleboards near the ferry lane.
MAX RANGE: 2 miles. Range steps: 0.5 / 1 / 2 miles.
The patrol mission is close-in situational awareness. The tight range steps
let the officer zoom into the marina entrance, Whatcom Waterway, or the
ferry lane without switching to a different scope.
RADAR HORIZON: ~4.3 nm at 3.5 m antenna height. Range is mission-limited
(2 miles) rather than horizon-limited.
PATROL ROUTE (v1 — open water only)
The simulated vessel follows a continuous back-and-forth patrol of the
working waterfront at variable speed. Entry into Squalicum Marina and
Whatcom Waterway is deferred to a future version; v1 stays in open water
where the radar geometry is straightforward.
Speed by zone:
Open waterfront / ferry lane: 10 knots
Near docks and breakwater: 4 knots
Route (loaded from data/patrol_route.json at startup):
Whatcom Waterway entrance → ferry terminal → Boulevard Park →
Taylor Dock → Community Boating Center → reverse and repeat
SMALL TARGET SCENARIO — FERRY LANE
The Bellingham terminal serves Alaska Marine Highway ferries up to 400 ft.
The simulator places a scripted stand-up paddleboarder on a slow drift
across the ferry departure lane, plus random kayakers near the harbor mouth.
These are marginal radar targets: low RCS, no metal, minimal freeboard.
At 10 kt approach in light chop the paddleboarder may show as a faint
intermittent blip or vanish into sea clutter entirely. Visitors can try the
wave clutter filter (keys 5/6) and observe how suppressing clutter can also
suppress the very target they are looking for. This is the central teaching
moment of this scope: radar does not see everything.
DISPLAY ORIENTATION
Default is North-up (000° at top). The k/j keys rotate the display offset.
Matching the offset to the boat's heading puts the bow at the top — Head-up
mode. The left panel labels the current mode and shows the heading marker,
a white dashed line from scope center toward the bow, drawn after all
phosphor content so it never decays.
TERRAIN AND BREAKWATER CLUTTER
The concrete Squalicum Harbor outer breakwater is a strong radar return and
a significant shadow-caster. Everything behind the breakwater from the
patrol boat's point of view is shadowed — no return. The marina interior is
not visible from open water. This is realistic and visible on the scope.
Coastline, piers, and the ferry terminal structure also appear as clutter.
Shadow masks are pre-computed for patrol route waypoints by
terrain_preprocess and selected at runtime by nearest-waypoint lookup.
Left panel status (below description text):
Zone: [plain text, e.g. "Ferry lane — open waterfront"]
Boat pos: XX.XXXX°N XXX.XXXX°W
Boat heading: XXX°T
Boat speed: X.X kt
Display mode: North-up (or Head-up)
Cursor range: X.X nm
Cursor brg: XXX°T
Max range: X.X mi
6. Air Traffic PPI Scope -
Targets, range rings, and range ring text levels Targets, range rings, and range ring text levels
All are P7 phosphor. Immediate strike by the electron beam is blue. All are P7 phosphor. Immediate strike by the electron beam is blue.
persistence is green/yellow. Targets, range rings, and range ring labels shall all persistence is green/yellow. Targets, range rings, and range ring labels shall all
@@ -326,7 +400,7 @@ should be articulated in the descriptive text
These controls should have slow movement for single stroke; but These controls should have slow movement for single stroke; but
gradual for for holding key down. gradual for for holding key down.
6. Precision approach (PAR for short) 7. Precision approach (PAR for short)
PAR was developed in WWII and matured in the 1950s. With a fixed 10 mile range, it was PAR was developed in WWII and matured in the 1950s. With a fixed 10 mile range, it was
controller who talked the pilot down verbally over radio, which means that the pilot controller who talked the pilot down verbally over radio, which means that the pilot
does not have to rely on any equipment on the plane itself to help with landing. does not have to rely on any equipment on the plane itself to help with landing.
@@ -365,57 +439,62 @@ Threads 2,3, need mutex access to shared data that is read by thread 1.
Thread 2 needs mutex access for shared data with thread 4, the simulator Thread 2 needs mutex access for shared data with thread 4, the simulator
SUMMARY OF Controls: SUMMARY OF Controls:
● ┌─────┬─────────────────────────────────────┬───────┬──────────┬──────────────┬────────────┬─────────┬─────┐ ● ┌─────┬─────────────────────────────────────┬───────┬──────────┬──────────────┬────────────┬──────────┬─────────┬─────┐
│ Key │ Function │ Intro │ Marine A │ Chain Home A │ Marine PPI │ ATC PPI │ PAR │ │ Key │ Function │ Intro │ Marine A │ Chain Home A │ Marine PPI │ Boat PPI │ ATC PPI │ PAR │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ s │ Advance to next scope │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ │ s │ Advance to next scope │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ S │ back to previous scope │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ │ S │ back to previous scope │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ c │ Bearing clockwise │ │ ✓ │ │ │ │ │ │ c │ Bearing clockwise │ │ ✓ │ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ v │ Bearing counterclockwise │ │ ✓ │ │ │ │ │ │ v │ Bearing counterclockwise │ │ ✓ │ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ u │ Max range up │ │ ✓ │ │ ✓ │ ✓ │ │ │ u │ Max range up │ │ ✓ │ │ ✓ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ d │ Max range down │ │ ✓ │ │ ✓ │ ✓ │ │ │ d │ Max range down │ │ ✓ │ │ ✓ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ r │ Cursor bearing right │ │ │ │ ✓ │ ✓ │ │ │ r │ Cursor bearing right │ │ │ │ ✓ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ l │ Cursor bearing left │ │ │ │ ✓ │ ✓ │ │ │ l │ Cursor bearing left │ │ │ │ ✓ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ t │ Cursor range increase │ │ │ │ ✓ │ ✓ │ │ │ t │ Cursor range increase │ │ │ │ ✓ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ y │ Cursor range decrease │ │ │ │ ✓ │ ✓ │ │ │ y │ Cursor range decrease │ │ │ │ ✓ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ k │ Antenna bearing offset right (boat) │ │ │ │ ✓ │ ✓ │ │ │ k │ Display offset right (boat heading) │ │ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ j │ Antenna bearing offset left (boat) │ │ │ │ ✓ │ ✓ │ │ │ j │ Display offset left (boat heading) │ │ │ │ ✓ │ ✓ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ [ │ Goniometer H/V switch │ │ │ ✓ │ │ │ │ │ [ │ Goniometer H/V switch │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ 9 │ Goniometer tune left │ │ │ ✓ │ │ │ │ │ 9 │ Goniometer tune left │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ 0 │ Goniometer tune right │ │ │ ✓ │ │ │ │ │ 0 │ Goniometer tune right │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ . │ Toggle PRF (25/12.5 Hz) │ │ │ ✓ │ │ │ │ │ . │ Toggle PRF (25/12.5 Hz) │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ n │ Calibrator shrink │ │ │ ✓ │ │ │ │ │ n │ Calibrator shrink │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ m │ Calibrator stretch │ │ │ ✓ │ │ │ │ │ m │ Calibrator stretch │ │ │ ✓ │ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ 1 │ Gain increase │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ │ 1 │ Gain increase │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ 2 │ Gain decrease │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ │ 2 │ Gain decrease │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ 3 │ Rain clutter filter increase │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ │ 3 │ Rain clutter filter increase │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ 4 │ Rain clutter filter decrease │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ │ 4 │ Rain clutter filter decrease │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ 5 │ Wave clutter filter increase │ │ ✓ │ ✓ │ ✓ │ │ │ │ 5 │ Wave clutter filter increase │ │ ✓ │ ✓ │ ✓ │ ✓ │ │ │
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤ ├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼──────────┼─────────┼─────┤
│ 6 │ Wave clutter filter decrease │ │ ✓ │ ✓ │ ✓ │ │ │ │ 6 │ Wave clutter filter decrease │ │ ✓ │ ✓ │ ✓ │ ✓ │ │ │
└─────┴─────────────────────────────────────┴───────┴──────────┴──────────────┴────────────┴─────────┴─────┘ └─────┴─────────────────────────────────────┴───────┴──────────┴──────────────┴────────────┴──────────┴─────────┴─────┘
Note: k/j (display bearing offset) are for marine PPI scopes only. The fixed ATC tower
at BLI has no heading offset need. On the fixed Marine PPI, k/j demonstrate North-up vs.
Head-up orientation as a teaching aid. On the Boat PPI, k/j are operationally meaningful:
zero offset = North-up (chart-style); offset matching boat heading = Head-up (bow at top).
Table for general controls not yet implemented on the keyboard in the table above: Table for general controls not yet implemented on the keyboard in the table above:
@@ -521,6 +600,7 @@ Class Hierarchy:
│ └── ChainHomeAScope │ └── ChainHomeAScope
├── PPIScope (abstract) ├── PPIScope (abstract)
│ ├── MarinePPIScope │ ├── MarinePPIScope
│ ├── BoatPPIScope
│ └── ATCPPIScope │ └── ATCPPIScope
└── PARScope └── PARScope
@@ -570,6 +650,21 @@ MarinePPIScope : public PPIScope
- Max range: 2, 4, 6 miles with correct ring sets - Max range: 2, 4, 6 miles with correct ring sets
- Keys: u (range up), d (range down) — this scope only - Keys: u (range up), d (range down) — this scope only
BoatPPIScope : public PPIScope
- Direct subclass of PPIScope (not of MarinePPIScope)
- Range steps: 0.5 / 1 / 2 miles; sweep time 4 s; phosphor P7
- Radar parameters: 6 kW, 1.9° open array (distinct from 30 kW / 0.5° coastal)
- Radar origin = boat lat/lon from SharedRenderState, updated every sweep
- Variable patrol speed per route segment (loaded from data/patrol_route.json)
- Heading marker: white dashed line from scope center toward boat heading;
drawn after all phosphor content so it always appears fully bright
- Nearest pre-computed shadow mask selected each sweep via
TerrainMap::selectNearestBoatMask() — no runtime ray-marching
- Display mode indicator: "North-up" / "Head-up" based on offset vs heading
- Left panel status: zone text, lat/lon, boat heading, speed, display mode
- Keys: u/d (range 0.5/1/2), r/l (cursor bearing), t/y (cursor range),
k/j (display offset), 1/2 (gain), 3/4 (rain filter), 5/6 (wave filter)
ATCPPIScope : public PPIScope ATCPPIScope : public PPIScope
- Sweep time: 5 seconds - Sweep time: 5 seconds
- Max range: 5, 10, 15, 20 miles with correct ring sets - Max range: 5, 10, 15, 20 miles with correct ring sets
@@ -606,6 +701,10 @@ File layout:
scope_chain_home.h / scope_chain_home.cpp scope_chain_home.h / scope_chain_home.cpp
scope_ppi.h / scope_ppi.cpp — abstract PPIScope scope_ppi.h / scope_ppi.cpp — abstract PPIScope
scope_marine_ppi.h / scope_marine_ppi.cpp scope_marine_ppi.h / scope_marine_ppi.cpp
scope_boat_ppi.h / scope_boat_ppi.cpp — BoatPPIScope; police patrol boat;
moving radar origin; variable speed;
heading marker; display-mode tracking;
nearest-mask selection from TerrainMap
scope_atc_ppi.h / scope_atc_ppi.cpp scope_atc_ppi.h / scope_atc_ppi.cpp
scope_par.h / scope_par.cpp scope_par.h / scope_par.cpp
phosphor.h / phosphor.cpp phosphor.h / phosphor.cpp
@@ -620,6 +719,11 @@ File layout:
settings.h — all tunable constants; no .cpp needed settings.h — all tunable constants; no .cpp needed
data/
patrol_route.json — boat waypoints with lat/lon and speed per
segment; loaded by Simulator at startup;
not compiled in — edit without rebuild
shaders/ shaders/
phosphor.vert / phosphor.frag — parameterized for P1 and P7 via uniforms phosphor.vert / phosphor.frag — parameterized for P1 and P7 via uniforms
graticule.vert / graticule.frag graticule.vert / graticule.frag
@@ -660,6 +764,30 @@ settings.h — tunable constants:
- ATC terrain clutter suppressed flag (bool, default true) - ATC terrain clutter suppressed flag (bool, default true)
- ATC terrain shadow enabled flag (bool, default true) - ATC terrain shadow enabled flag (bool, default true)
- LiDAR structure height threshold for man-made classification - LiDAR structure height threshold for man-made classification
- BOAT_PATROL_ROUTE_JSON: path to patrol route file (default "data/patrol_route.json")
Waypoints and per-segment speeds live in the JSON, not in settings.h, so
the route can be adjusted without recompiling
- BOAT_WAYPOINT_ARRIVAL_M: radius within which a waypoint is considered
reached, advancing to the next (default 50.0 m)
- BOAT_HEADING_TURN_RATE_DEG_S: maximum turn rate deg/s for heading
interpolation — realistic, not instantaneous (default 3.0)
- BOAT_HEADUP_TOLERANCE_DEG: offset within ±this value of boat heading
triggers "Head-up" label in left panel (default 5.0)
- BOAT_HEADING_MARKER_COLOR: RGB color of heading marker line (default white)
- BOAT_HEADING_MARKER_FRACTION: marker length as fraction of scope radius
(default 0.35)
- BOAT_HEADING_MARKER_DASH_PX: dash length in pixels (default 8)
- BOAT_HEADING_MARKER_GAP_PX: gap length in pixels (default 4)
- BOAT_CLUTTER_MASK_COUNT: number of pre-computed boat shadow masks (default 6)
- BOAT_MASK_SWITCH_THRESHOLD_M: minimum boat displacement from last selected
mask waypoint before a new mask is selected (default 500.0 m)
- METERS_PER_DEGREE: flat-earth scale factor for lat/lon → meters conversion
(111320.0, valid for 2 nm max range)
- Patrol boat radar parameters: BOAT_PEAK_POWER_W (6000), BOAT_FREQ_HZ,
BOAT_HORIZ_BEAMWIDTH_DEG (1.9), BOAT_VERT_BEAMWIDTH_DEG (20.0),
BOAT_ANTENNA_HEIGHT_M (3.5)
- Boat PPI range steps: BOAT_RANGE_STEPS[] = {0.5, 1.0, 2.0} miles,
BOAT_RANGE_STEP_COUNT = 3
================================================================== ==================================================================
@@ -688,7 +816,7 @@ Body:
the time it takes for the echo to return, the radar calculates how far away the time it takes for the echo to return, the radar calculates how far away
the object is. Rotating the antenna builds a map of everything around it. the object is. Rotating the antenna builds a map of everything around it.
This exhibit features six radar displays. Explore each one at your own pace. This exhibit features seven radar displays. Explore each one at your own pace.
Press s at any time to jump to the next display — do not wait for the Press s at any time to jump to the next display — do not wait for the
automatic 120-second advance. Press S (shift+s) to go back. automatic 120-second advance. Press S (shift+s) to go back.
@@ -810,25 +938,81 @@ PANEL 4 — MARINE PPI SCOPE
Targets: AIS-equipped vessels and simulated traffic. Targets: AIS-equipped vessels and simulated traffic.
Press s to advance. Press S to go back. Auto-advance in 120 seconds. Press s to advance. Press S to go back. Auto-advance in 120 seconds.
Any key press resets the timer. Next: ATC PPI Any key press resets the timer. Next: Marine PPI — Boat Scenario
┌──────┬────────────────────────────────────┐ ┌──────┬────────────────────────────────────────────────
│ KEY │ FUNCTION │ │ KEY │ FUNCTION │
├──────┼────────────────────────────────────┤ ├──────┼────────────────────────────────────────────────
│ s/S │ Next / previous scope │ │ s/S │ Next / previous scope │
│ u/d │ Max range up / down (2, 4, 6 mi) │ │ u/d │ Max range up / down (2, 4, 6 mi) │
│ r/l │ Cursor bearing right / left │ │ r/l │ Cursor bearing right / left │
│ t/y │ Cursor range increase / decrease │ │ t/y │ Cursor range increase / decrease │
│ k/j │ Antenna offset right / left │ │ k/j │ Display offset right / left
│ │ (boat heading correction — zero │ │ (zero = North-up; rotate to match heading
│ │ means antenna faces True North) │ │ = Head-up — a teaching aid on fixed radar)
│ 1/2 │ Gain increase / decrease │ │ 1/2 │ Gain increase / decrease │
│ 3/4 │ Rain filter increase / decrease │ │ 3/4 │ Rain filter increase / decrease │
│ 5/6 │ Wave filter increase / decrease │ │ 5/6 │ Wave filter increase / decrease │
└──────┴────────────────────────────────────┘ └──────┴────────────────────────────────────────────────
------------------------------------------------------------------ ------------------------------------------------------------------
PANEL 5 — AIR TRAFFIC CONTROL PPI SCOPE PANEL 5 — POLICE PATROL BOAT PPI
------------------------------------------------------------------
This display is from the radar aboard a Bellingham Police Department
patrol vessel making its routine waterfront patrol. The scope center
is the boat — it moves with the patrol route, not fixed in the bay.
THE RADAR IS DIFFERENT HERE
The patrol boat carries a professional 6-kilowatt open-array radar
with a 1.9-degree beam — narrower than a cheap boat radar, but wider
than the big 30-kilowatt coastal radar you saw two displays back. The
blips look noticeably fatter than on the coastal radar. The maximum
range here is 2 miles: the patrol mission is close-in harbor work,
not long-range scanning.
THE FERRY LANE PROBLEM
The Bellingham terminal serves Alaska state ferries up to 400 feet
long. When a ferry departs, anyone in the departure lane — a kayaker,
a paddleboarder — must get clear. Watch the scope carefully: there
is a stand-up paddleboarder drifting slowly near the ferry lane.
Can you spot it?
Stand-up paddleboards are very hard to see on radar. No metal, almost
no freeboard, small size — the radar echo is barely above the noise.
Try adjusting the wave clutter filter (keys 5 and 6). Turning it up
reduces the sea clutter that is hiding the target — but it may also
suppress the target itself. This trade-off is real. Radar does not
see everything.
NORTH-UP AND HEAD-UP
By default the scope shows North-up: True North at the top, like a
chart. Press k or j to rotate the display. When the heading marker
(white dashed line) points straight up, you are in Head-up mode —
the bow is at the top. This is how most early marine radars worked.
Location: Bellingham waterfront patrol, Bellingham Bay, WA.
Targets: AIS vessels, paddleboarder, random kayakers.
Press s to advance. Press S to go back. Auto-advance in 120 seconds.
Any key press resets the timer. Next: ATC PPI →
┌──────┬────────────────────────────────────────────────┐
│ KEY │ FUNCTION │
├──────┼────────────────────────────────────────────────┤
│ s/S │ Next / previous scope │
│ u/d │ Max range up / down (0.5, 1, 2 mi) │
│ r/l │ Cursor bearing right / left │
│ t/y │ Cursor range increase / decrease │
│ k/j │ Display offset right / left │
│ │ (0° = North-up; match heading = Head-up) │
│ 1/2 │ Gain increase / decrease │
│ 3/4 │ Rain filter increase / decrease │
│ 5/6 │ Wave filter increase / decrease │
└──────┴────────────────────────────────────────────────┘
------------------------------------------------------------------
PANEL 6 — AIR TRAFFIC CONTROL PPI SCOPE
------------------------------------------------------------------ ------------------------------------------------------------------
This is the Airport Surveillance Radar (ASR) display used by air traffic This is the Airport Surveillance Radar (ASR) display used by air traffic
@@ -855,13 +1039,12 @@ PANEL 5 — AIR TRAFFIC CONTROL PPI SCOPE
│ u/d │ Max range up / down (5, 10, 15, 20 mi) │ │ u/d │ Max range up / down (5, 10, 15, 20 mi) │
│ r/l │ Cursor bearing right / left │ │ r/l │ Cursor bearing right / left │
│ t/y │ Cursor range increase / decrease │ │ t/y │ Cursor range increase / decrease │
│ k/j │ Antenna offset right / left │
│ 1/2 │ Gain increase / decrease │ │ 1/2 │ Gain increase / decrease │
│ 3/4 │ Rain filter increase / decrease │ │ 3/4 │ Rain filter increase / decrease │
└──────┴──────────────────────────────────────────┘ └──────┴──────────────────────────────────────────┘
------------------------------------------------------------------ ------------------------------------------------------------------
PANEL 6 — PRECISION APPROACH RADAR (PAR) PANEL 7 — PRECISION APPROACH RADAR (PAR)
------------------------------------------------------------------ ------------------------------------------------------------------
The Precision Approach Radar was developed during World War 2 and refined The Precision Approach Radar was developed during World War 2 and refined
@@ -1069,6 +1252,27 @@ RADAR PARAMETERS — PAR (X Band):
Pulse width: short (high range resolution) Pulse width: short (high range resolution)
PRF: high (~30 Hz alternating az/el) PRF: high (~30 Hz alternating az/el)
RADAR PARAMETERS — PATROL BOAT (X Band):
Frequency: 93009500 MHz (X-band; treat same as marine for exhibit)
Peak power: 6 kW
Antenna type: Open array, 24-inch (610 mm)
Horizontal beamwidth: 1.9 degrees
Vertical beamwidth: 20 degrees
Antenna height: 3.5 m above waterline (flybridge or radar arch)
Radar horizon: ~4.3 nm to sea-level target
Operational max range: 2 miles (mission-limited, not horizon-limited)
NOTE — beamwidth comparison:
Fixed coastal marine: 0.5° — sharp blips, high azimuth resolution
Police patrol boat: 1.9° — noticeably fatter blips; good exhibit contrast
Consumer radome: 46° — poorest resolution (not used in this exhibit)
NOTE — small target detection in sea clutter:
The narrower 1.9° beam illuminates ~1/3 the sea surface area per range
cell compared to a 5° radome, improving signal-to-clutter ratio by ~5 dB.
Even so, a stand-up paddleboard (RCS ~0.10.5 m²) is marginal in any chop.
Detection is realistic only in near-calm conditions at ≤1 mile.
All radar parameters shall have corresponding constexpr constants All radar parameters shall have corresponding constexpr constants
in settings.h so they can be tuned without touching equation code. in settings.h so they can be tuned without touching equation code.
@@ -1175,10 +1379,31 @@ SHADOW / LINE-OF-SIGHT MASKING
the offset as a rotation uniform and samples the polar texture at the offset as a rotation uniform and samples the polar texture at
the offset angle. Zero CPU overhead; no shadow recomputation. the offset angle. Zero CPU overhead; no shadow recomputation.
Future boat scenario (not in v1): Boat PPI scope scenario:
If the radar antenna physically moves to a new lat/lon, the shadow When BoatPPIScope is active, SharedRenderState.boatModeActive is set
mask would be recomputed on a background thread while the display TRUE. LandClutter uses boatLatDeg / boatLonDeg as the polar grid origin
continues with the previous mask. instead of the fixed marine platform position.
Shadow mask selection: terrain_preprocess pre-computes BOAT_CLUTTER_MASK_COUNT
shadow masks for waypoints evenly spaced around the simulated route.
These are written as:
map/lidar_processed/shadow_boat_NNN.u8 — one file per boat mask waypoint
NNN = zero-padded index
At runtime, TerrainMap::selectNearestBoatMask() scans the BOAT_CLUTTER_MASK_COUNT
waypoints and returns the index whose position is nearest to the current boat
lat/lon (straight-line distance). The selected mask changes at most once per
4-second sweep when the boat has moved more than BOAT_MASK_SWITCH_THRESHOLD_M
(default 500 m) from the last selected waypoint position.
Since Bellingham Bay is open water, the major terrain shadowing features
(Chuckanut Mountain, Eliza Island, Lummi Island) are visible from most bay
positions. The nearest-mask approximation introduces negligible error within
the 500 m switching threshold.
The terrain clutter shader receives the boat position offset as a translation
uniform (u_radarOffsetM, a vec2) in addition to the bearing offset rotation.
The shader adds this offset when sampling the polar texture so coastline
features appear at their correct positions relative to the moving radar.
PER-SCOPE TERRAIN BEHAVIOR PER-SCOPE TERRAIN BEHAVIOR
@@ -1219,11 +1444,14 @@ TERRAIN CLUTTER SHADER
texture, and outputs P7-compatible phosphor color and alpha so texture, and outputs P7-compatible phosphor color and alpha so
terrain returns decay on the same timescale as target echoes. terrain returns decay on the same timescale as target echoes.
Uniforms: Uniforms:
u_bearingOffsetDeg — boat heading correction (default 0.0) u_bearingOffsetDeg — display heading correction (default 0.0)
u_radarOffsetM — vec2 (dx_m, dy_m) from fixed marine platform origin
to current radar position; (0,0) for fixed scopes,
non-zero for Boat PPI as boat moves around the bay
u_clutterSuppressed — bool; 1 = suppress (ATC mode) u_clutterSuppressed — bool; 1 = suppress (ATC mode)
u_maxRangeM — current scope max range in meters u_maxRangeM — current scope max range in meters
u_clutterBrightness — TERRAIN_MARINE_CLUTTER_BRIGHTNESS scale u_clutterBrightness — TERRAIN_MARINE_CLUTTER_BRIGHTNESS scale
Used by MarinePPIScope and ATCPPIScope. Used by MarinePPIScope, BoatPPIScope, and ATCPPIScope.
================================================================== ==================================================================
@@ -1257,15 +1485,23 @@ PIPELINE (runs in order)
7. Material classification: 7. Material classification:
Load S-57 ENC (US5WA45M.000) via GDAL/OGR. Load S-57 ENC (US5WA45M.000) via GDAL/OGR.
Apply classification rules described in TERRAIN section above. Apply classification rules described in TERRAIN section above.
8. Compute shadow mask for marine platform and ATC tower using radial 8. Compute shadow masks using radial elevation-angle march along each
elevation-angle march along each azimuth bearing. azimuth bearing for each of the following radar positions:
- Fixed marine platform (lat 48.7436, lon -122.5647)
- ATC tower at BLI
- BOAT_CLUTTER_MASK_COUNT boat waypoints from BOAT_SIM_WAYPOINTS[]
All shadow masks use the same algorithm; only the origin differs.
9. Write to map/lidar_processed/: 9. Write to map/lidar_processed/:
elevation.f32 float32 row-major grid, meters, WGS84 elevation.f32 float32 row-major grid, meters, WGS84
material.u8 uint8 per cell (0=water 1=soil 2=rock 3=concrete) material.u8 uint8 per cell (0=water 1=soil 2=rock 3=concrete)
shadow_marine.u8 uint8 visibility mask for marine radar shadow_marine.u8 uint8 visibility mask for marine radar
shadow_atc.u8 uint8 visibility mask for ATC radar shadow_atc.u8 uint8 visibility mask for ATC radar
shadow_boat_000.u8 …
shadow_boat_NNN.u8 uint8 visibility masks for boat waypoints;
NNN = zero-padded waypoint index
terrain_meta.json grid dimensions, lat/lon origin, cell size, terrain_meta.json grid dimensions, lat/lon origin, cell size,
source file checksums, processing date source file checksums, processing date,
boat mask waypoint lat/lon list
RUNTIME VALIDATION RUNTIME VALIDATION
TerrainMap reads terrain_meta.json at startup and compares the stored TerrainMap reads terrain_meta.json at startup and compares the stored
@@ -1280,14 +1516,184 @@ OUTPUT FILES (map/lidar_processed/)
material.u8 — uint8 material classification grid material.u8 — uint8 material classification grid
shadow_marine.u8 — uint8 line-of-sight mask, marine radar shadow_marine.u8 — uint8 line-of-sight mask, marine radar
shadow_atc.u8 — uint8 line-of-sight mask, ATC radar shadow_atc.u8 — uint8 line-of-sight mask, ATC radar
terrain_meta.json — metadata and provenance record shadow_boat_000.u8 … — uint8 line-of-sight masks for boat waypoints
shadow_boat_NNN.u8 (BOAT_CLUTTER_MASK_COUNT files total)
terrain_meta.json — metadata, provenance record, and boat mask
waypoint lat/lon list used for nearest-mask lookup
These five files are the only terrain inputs at runtime. These files are the only terrain inputs at runtime.
The raw zip archives in map/lidar_raw/ are never opened by The raw zip archives in map/lidar_raw/ are never opened by
the exhibit binary. the exhibit binary.
================================================================== ==================================================================
BOAT SCENARIO
==================================================================
The boat scenario (scope 5 — Police Patrol Boat PPI) simulates a Bellingham
Police Department patrol vessel making its waterfront patrol. The radar is a
6 kW professional open-array unit (1.9° beamwidth), not the same hardware as
the fixed coastal marine radar. The radar origin moves with the boat every sweep.
PATROL ROUTE FILE — data/patrol_route.json
Loaded by the Simulator at startup. Not compiled in — the route can be
refined without a rebuild. Format (approximate):
{
"waypoints": [
{ "lat": 48.7530, "lon": -122.5150, "speed_kt": 10.0,
"zone": "Ferry lane — open waterfront" },
{ "lat": 48.7480, "lon": -122.5050, "speed_kt": 4.0,
"zone": "Near Squalicum breakwater" },
{ "lat": 48.7460, "lon": -122.5120, "speed_kt": 10.0,
"zone": "Open waterfront west" },
{ "lat": 48.7380, "lon": -122.5200, "speed_kt": 10.0,
"zone": "Boulevard Park approach" },
{ "lat": 48.7340, "lon": -122.5150, "speed_kt": 4.0,
"zone": "Taylor Dock area" },
{ "lat": 48.7320, "lon": -122.5050, "speed_kt": 4.0,
"zone": "Community Boating Center" }
],
"loop": "reverse"
}
"loop": "reverse" means the boat reaches the last waypoint then reverses
direction back through the list — a back-and-forth patrol, not a closed loop.
All coordinates are open water; marina and Whatcom Waterway entry deferred.
Adjust lat/lon values to keep the vessel in navigable water once the ENC
coastline is loaded. Values above are starting approximations.
BOAT NAVIGATION SIMULATION (Simulator, Thread 4)
The Simulator maintains a BoatNavigator sub-object that loads the JSON route
at startup and advances the vessel each time TrafficCop polls. Data returned
to TrafficCop alongside the regular target list:
boat_lat_deg — current latitude (degrees WGS84)
boat_lon_deg — current longitude (degrees WGS84)
boat_heading_deg — current true heading (degrees, 0 = north)
boat_speed_kts — current speed from active waypoint segment
boat_zone_str — zone label string for left panel display
TrafficCop writes these to SharedRenderState under Mutex A.
Thread 1 reads them every frame when BoatPPIScope is active.
Navigation algorithm (runs in Simulator::poll(), Thread 4):
1. Compute great-circle bearing from current position to next waypoint.
2. Rotate boatHeadingDeg toward that bearing at up to
BOAT_HEADING_TURN_RATE_DEG_S per elapsed second (clamped).
3. Advance position along current heading at the current segment speed_kt.
4. If distance to next waypoint < BOAT_WAYPOINT_ARRIVAL_M, advance index.
On reverse-loop: flip traversal direction at each end.
5. Store updated state in BoatNavigator; return to TrafficCop on poll.
SIMULATED SMALL TARGETS
The Simulator generates two categories of small targets for the patrol scope:
Scripted paddleboarder:
A single stand-up paddleboarder drifts slowly across the ferry departure
lane on a fixed looping path (~0.5 kt, random drift added). RCS set to
BOAT_SUP_RCS_M2 (default 0.2 m²). This target also appears on the fixed
Marine PPI scope (same Bellingham Bay coverage area, same target pipeline).
Random kayakers:
BOAT_RANDOM_KAYAK_COUNT (default 2) kayaks wander within a defined zone
near the ferry terminal and harbor mouth. RCS set to BOAT_KAYAK_RCS_M2
(default 0.4 m² — slightly larger than SUP due to hull and occupant).
Random targets also appear on the fixed Marine PPI.
These use the same radar equation path as all other targets; the low RCS
values naturally produce faint, intermittent blips in any sea state, which
is the exhibit's intended behavior. No special-casing required.
Settings.h additions for small targets:
BOAT_SUP_RCS_M2 0.2 — stand-up paddleboard + paddler RCS (m²)
BOAT_KAYAK_RCS_M2 0.4 — kayak + occupant RCS (m²)
BOAT_RANDOM_KAYAK_COUNT 2 — number of random kayak targets
BOAT_KAYAK_ZONE_LAT/LON — bounding box for random kayak positions
SHARED STATE ADDITIONS
SharedRenderState new fields (all under Mutex A):
float boatLatDeg = 0.0f (set from JSON WP0 at startup)
float boatLonDeg = 0.0f
float boatHeadingDeg = 0.0f
float boatSpeedKts = 0.0f
char boatZone[64] = "" — zone label, copied from JSON waypoint
bool boatModeActive = false — set TRUE by ScopeManager when BoatPPIScope
active, FALSE for all other scopes
TARGET PROJECTION FOR MOVING RADAR ORIGIN
For fixed scopes, target positions are projected from a known constant origin.
For the Boat PPI, TrafficCop recalculates each target's polar coordinates
relative to the boat's current position after every poll.
Flat-earth projection (adequate for 2 nm max range):
dx_m = (target_lon boat_lon) × cos(boat_lat × π/180) × METERS_PER_DEGREE
dy_m = (target_lat boat_lat) × METERS_PER_DEGREE
range_m = sqrt(dx_m² + dy_m²)
bearing_deg = atan2(dx_m, dy_m) × 180/π (adjusted to 0360, CW from north)
METERS_PER_DEGREE = 111320.0 (constexpr in settings.h).
Result (range_m, bearing_deg, brightness) stored in TargetBuffer under Mutex B.
HEADING MARKER RENDERING
BoatPPIScope::renderHeadingMarker() runs inside render() after all phosphor
content, using the graticule shader so the line never decays.
Geometry: dashed line from scope center to
center + BOAT_HEADING_MARKER_FRACTION × scope_radius
in the direction (boatHeadingDeg + bearingOffsetDeg).
Color: BOAT_HEADING_MARKER_COLOR (default white).
Dash/gap: BOAT_HEADING_MARKER_DASH_PX / BOAT_HEADING_MARKER_GAP_PX.
DISPLAY MODE LOGIC
Every frame, BoatPPIScope computes:
float diff = fabs(fmod(bearingOffsetDeg boatHeadingDeg + 540.0f, 360.0f) 180.0f)
mode = (diff <= BOAT_HEADUP_TOLERANCE_DEG) ? "Head-up" : "North-up"
Rendered as white text in the left-panel status area.
TERRAIN CLUTTER AND BREAKWATER SHADOWS
See SHADOW / LINE-OF-SIGHT MASKING → Boat PPI scope scenario for the
mask-selection algorithm and shadow_boat_NNN.u8 file set.
The Squalicum Harbor outer breakwater is a significant shadow-caster.
From any open-water patrol position the interior of the marina basin is
shadowed — nothing behind the breakwater is visible. This is realistic
and is visible on the scope as a sharp shadow arc on the far side of the
breakwater return.
At the start of each 4-second sweep, BoatPPIScope::updateLandClutter() calls:
1. TerrainMap::selectNearestBoatMask(boatLatDeg, boatLonDeg)
2. LandClutter::generateForBoat(boatLatDeg, boatLonDeg, maskIndex)
3. Upload new polar clutter texture to GPU.
If the mask index is unchanged from the previous sweep, steps 23 are skipped.
Terrain clutter shader receives:
u_radarOffsetM = vec2(
(boatLon MARINE_PLATFORM_LON) × cos(boatLat × π/180) × METERS_PER_DEGREE,
(boatLat MARINE_PLATFORM_LAT) × METERS_PER_DEGREE)
V1 GEOMETRY SCOPE (open water only — marina deferred)
Vector features needed from NOAA ENC 18424 for the v1 patrol route:
- Outer shoreline of Bellingham Bay
- Squalicum Harbor outer breakwater (solid, strong return, shadow-caster)
- Ferry terminal structure (Bellingham Cruise Terminal area)
- Taylor Dock pier outline (weak return — wood, but pilings visible)
- Boulevard Park shoreline
Internal marina dock fingers, Whatcom Waterway channel walls, and Georgia
Pacific / Waterfront District structures are deferred until the patrol
route is extended into those areas in a future version.
==================================================================
FILE LAYOUT (COMPLETE — including additions) FILE LAYOUT (COMPLETE — including additions)
================================================================== ==================================================================
@@ -1302,6 +1708,7 @@ src/
scope_chain_home.h / scope_chain_home.cpp scope_chain_home.h / scope_chain_home.cpp
scope_ppi.h / scope_ppi.cpp scope_ppi.h / scope_ppi.cpp
scope_marine_ppi.h / scope_marine_ppi.cpp scope_marine_ppi.h / scope_marine_ppi.cpp
scope_boat_ppi.h / scope_boat_ppi.cpp
scope_atc_ppi.h / scope_atc_ppi.cpp scope_atc_ppi.h / scope_atc_ppi.cpp
scope_par.h / scope_par.cpp scope_par.h / scope_par.cpp
phosphor.h / phosphor.cpp phosphor.h / phosphor.cpp
@@ -1338,4 +1745,5 @@ shaders/
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 terrain_clutter.vert / terrain_clutter.frag — polar clutter texture overlay
on PPI; P7-compatible decay; on PPI; P7-compatible decay;
bearing offset rotation uniform bearing offset rotation uniform;
u_radarOffsetM vec2 for boat origin

228
additions
View File

@@ -1,228 +0,0 @@
==================================================================
ADDITION: BOAT RADAR — BELLINGHAM POLICE PATROL BOAT
==================================================================
I want to add a radar scope showing the view from a marine radar
mounted on a Bellingham Police Department patrol boat. The boat
is on a continuous back-and-forth patrol of the working waterfront.
PATROL ROUTE:
Police boats do patrol inside Squalicum Marina (theft, vandalism,
welfare checks) and inside Whatcom Waterway (commercial port
security). They do not rely on seeing over the breakwater --
the concrete breakwater shadows the inner basin.
Speed varies by zone:
Open waterfront: 10 knots
Whatcom Waterway: 3-5 knots (narrow, industrial)
Inside marina: 3-4 knots (displacement speed, no wake)
Proposed full route (continuous, reversing at each end):
Whatcom Waterway entrance
-> slow to 4 knots, transit Whatcom Waterway
-> exit to bay, accelerate to 10 knots
-> Squalicum Marina outer breakwater entrance
-> slow to 3-4 knots, tour inner marina basin
-> exit marina, accelerate to 10 knots
-> west along waterfront
-> Boulevard Park
-> Taylor Dock
-> Community Boating Center
-> reverse and repeat
INSIDE MARINA -- RADAR CLUTTER NOTE:
At 2-3 m antenna height inside a marina full of sailboat masts,
the radar picture will be heavily cluttered with mast returns,
appearing as a dense ring around the boat. This is realistic and
is a good exhibit teaching moment -- visitors can use the sea/wave
clutter filter (already designed) to try to suppress it. The boat
radar's wide beamwidth (4-6 deg) makes the clutter worse than the
big coastal radar would show.
PATROL SPEED:
Approximately 10 knots.
10 knots is reasonable -- typical working-waterfront patrol speed
is 8-12 knots, fast enough to respond quickly but slow enough to
observe traffic and avoid wake damage near the docks.
WHAT THIS MEANS FOR THE DISPLAY:
Unlike all the other radars in this exhibit, the radar origin is
not fixed. It moves with the boat along the patrol route. The
radar antenna is on the boat, so the PPI scope center tracks the
boat's position.
The boat also changes heading as it follows the shoreline, which
means the bearing offset (already implemented as the k/j keys on
the marine PPI) will be continuously updated by the simulator as
the boat turns -- the operator does not manually drive the boat.
The boat's heading at any point along the route determines the
antenna offset so that True North stays at the top of the scope.
SIMULATOR ARCHITECTURE:
The patrol boat position is the radar PLATFORM, not a target.
It should be managed by the existing Simulator (Thread 4) as a
special PatrolPlatform object alongside the target list -- NOT a
separate simulator thread, and NOT built into the scope/rendering
code (Thread 1).
The TrafficCop (Thread 2) already polls the Simulator each sweep.
It will also retrieve the current platform lat/lon and heading at
the same poll and write them to SharedRenderState under Mutex A.
Thread 1 reads platform position and heading to set the PPI scope
center point and bearing offset before rendering each frame.
The patrol route is a sequence of lat/lon waypoints with speed
per segment. The Simulator interpolates position between waypoints
using elapsed time and the segment speed.
DECISIONS:
1. SCOPE CLASS: New BoatPPIScope, a subclass of PPIScope directly
(not a subclass of MarinePPIScope). Same controls as MarinePPIScope.
Moving origin is specific to this class.
2. WAYPOINTS: JSON data file, e.g. data/patrol_route.json.
Loaded at startup by the Simulator. Each entry has lat/lon and
speed for that segment. settings.h stays as tunable constants only.
3. LEFT PANEL: Both -- a plain text zone description (e.g.
"Currently: Open waterfront, heading west") AND a numeric
lat/lon readout below it. Visitor-friendly text plus precise data.
4. SIMULATED SMALL TARGETS: Both scripted and random.
- Scripted: a paddleboarder drifts slowly across the ferry lane
on a fixed loop (dramatic, repeatable, good for exhibit)
- Random: additional kayakers/small boats wander within a defined
zone near the ferry terminal and harbor mouth
- These small targets also appear on the fixed MARINE PPI scope
(same Bellingham Bay coverage area, same target pipeline)
5. SCOPE ORDER: Boat PPI goes immediately after Marine PPI.
New sequence: Intro -> Marine A -> Chain Home A -> Marine PPI
-> Boat PPI -> ATC PPI -> PAR -> (back to Intro)
6. MARINA AND WHATCOM WATERWAY: Deferred. The patrol route for v1
stays in open water only. The boat does NOT enter Squalicum Marina
or Whatcom Waterway in the first implementation. Those can be
added in a later version once the shoreline geometry problem
is solved (see LIDAR/CHART NOTE below).
LIDAR AND SHORELINE GEOMETRY NOTE:
The marina, breakwater, Whatcom Waterway, and Georgia Pacific site
all require accurate geometry to simulate correctly -- both as radar
return sources and as shadow-casters.
TWO DATA SOURCES:
1. NOAA Electronic Navigational Chart 18424 (Bellingham Bay)
Free vector download from charts.noaa.gov (ENC format).
Already clean vector polygons: breakwater, piers, channel edges,
ferry terminal, dock outlines. Best starting point -- no point
cloud processing required.
2. Washington State LIDAR Portal (lidarportal.dnr.wa.gov)
Free LIDAR point cloud downloads for Whatcom County.
0.5-1 meter horizontal resolution. Captures individual pilings,
building edges, breakwater detail, Georgia Pacific site remnants.
Use this when finer detail is needed (inside marina, Whatcom
Waterway structures). Requires offline processing to extract
obstruction polygons before use in the simulation.
GEORGIA PACIFIC SITE:
Most of the old GP pulp mill has been demolished. The area is
now the Bellingham Waterfront District (partially built). LIDAR
or ENC data will show whatever was on-site at survey time. For
the exhibit this is acceptable -- it is a patrol scenario,
not a live chart.
HOW GEOMETRY FEEDS INTO THE SIMULATION:
Shoreline and obstruction data is processed ONCE offline into
a set of vector polygons representing hard radar-reflective
features. These are loaded at Thread 1 startup as a static VBO.
Read-only after load -- no mutex required (already noted in
the design). The radar sweep computes returns from these
polygons the same way it handles vessel targets.
RADAR SHADOW ZONES:
The breakwater does not just produce a return -- it shadows
everything behind it. To simulate this correctly, the sweep
must raycast from the current radar position, find the first
intersection with each obstruction polygon, and mark everything
beyond that intersection as shadowed (no return). This is a
per-sweep raycast operation, implementable CPU-side each sweep
or in a compute shader. Shadow simulation is required even for
the v1 open-water-only route, because the breakwater shadow
is clearly visible from outside.
V1 GEOMETRY SCOPE (open water only -- marina deferred):
Only these features are needed for the first version:
- Outer shoreline of Bellingham Bay (simple polygon)
- Squalicum Harbor breakwater (solid obstruction, shadow-caster)
- Ferry terminal structure
- Taylor Dock pier outline (weak return -- wood, but pilings show)
- Boulevard Park shoreline
NOAA ENC 18424 provides all of these in vector form.
Internal marina dock fingers and Whatcom Waterway structures
are deferred until the boat patrol route enters those areas.
4. The radar hardware spec for the boat radar is DIFFERENT from
the fixed coastal marine radar. Typical police/patrol boat radar:
Frequency: 9.3 - 9.5 GHz (X-band, same band, slightly
different frequency -- treat as same for exhibit)
Peak power: 2 kW to 4 kW (NOT the 30 kW of the fixed
coastal radar -- this is a small-vessel unit)
Antenna type: Radome (enclosed dome, ~60 cm diameter) --
more rugged and lower wind resistance than
an open array, typical for patrol boats
Horizontal beamwidth: 4 to 6 degrees (vs 0.5 deg for the big
coastal radar -- targets will appear as
noticeably fatter blips; good exhibit contrast)
Antenna height: 2 to 3 meters above waterline (radar arch
or short mast on a 25-35 foot patrol vessel)
RADAR HORIZON at 2.5 m antenna height:
horizon = 2.23 x sqrt(2.5) = approx 3.5 nautical miles
(~4 statute miles) to a sea-level target.
Compare: fixed coastal radar at 15 m sees ~8.6 nautical miles.
MAX RANGE DECISION: 2 miles maximum.
The patrol boat's job is close-in situational awareness, not
long-range surveillance (the fixed coastal radar handles that).
2 miles puts the entire inner harbor on screen at once.
RANGE STEPS: 0.5 / 1 / 2 miles.
Tighter steps than the fixed marine scopes (2/4/6) because the
officer needs a close-in zoom for marina and waterway work:
0.5 mi -- tight quarters, marina basin, Whatcom Waterway
1.0 mi -- inner harbor, near-shore patrol
2.0 mi -- full harbor picture, ferry lane monitoring
SMALL TARGET DETECTION NOTE (important for exhibit realism):
A paddleboard or kayak is a marginal radar target at any range.
Very small RCS, almost no freeboard. At 2-4 kW with 4-6 degree
beamwidth, a paddleboarder may show as a faint intermittent blip
or may wash into the noise floor entirely -- especially in chop.
A kayak carrying a small aluminum radar reflector shows much
better. This is realistic and worth simulating: the exhibit
shows visitors that radar does not see everything, and that
small non-metallic targets are genuinely hard to detect.
FERRY LANE SCENARIO:
The Bellingham terminal serves the Alaska Marine Highway System
(state ferries up to 400 feet). A paddleboarder or kayaker
drifting into the departure lane is a real hazard the patrol
officer watches for. Simulated small targets (paddleboards,
kayaks) near the ferry lane would make a compelling exhibit
moment -- visitor tries to spot them on the radar before the
ferry moves.
5. Should the left panel description explain that this is a moving
platform, and show the current boat position (lat/lon or a
simple text description of where on the route the boat is)?
6. I do not care about the size or material of the police boat
itself since it is the platform the radar is mounted on, not
a target.

View File

View File

@@ -1,36 +0,0 @@
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