add additions to claude.md

This commit is contained in:
2026-04-21 09:06:10 -07:00
parent 5d1b626281
commit 864417a257
3 changed files with 339 additions and 0 deletions

215
CLAUDE.md
View File

@@ -881,3 +881,218 @@ PANEL 6 — PRECISION APPROACH RADAR (PAR)
│ 1/2 │ Gain increase / decrease │ │ 1/2 │ Gain increase / decrease │
│ 3/4 │ Rain filter increase / dec │ │ 3/4 │ Rain filter increase / dec │
└──────┴──────────────────────────────┘ └──────┴──────────────────────────────┘
==================================================================
UNITS
==================================================================
All dimensions are stored and computed in METERS throughout the
entire system — in shared state, in the database, in shaders, and
in all target data structures.
Any incoming value that arrives in feet (e.g. ADS-B altitude,
antenna heights from configuration) MUST be converted to meters
at the data boundary — in RPiReceiver::parseFrame() or
Simulator::poll() — before the value enters any shared data
structure. No feet values may appear anywhere inside the system
after the conversion point.
Conversion constant in settings.h:
FEET_TO_METERS = 0.3048 (exact)
==================================================================
DEFAULT TARGET DIMENSIONS
==================================================================
When a target is first seen with no database record, the system
inserts a row using the defaults below. All values in meters.
need_update is set TRUE so the operator knows to fill in real data.
┌──────────────────┬───────────┬──────────────────┬────────────┐
│ Category │ Length (m)│ Width/Beam (m) │ Material │
├──────────────────┼───────────┼──────────────────┼────────────┤
│ GA aircraft │ 4.0 │ 1.0 (fuselage) │ aluminum │
│ Commercial a/c │ 30.0 │ 5.0 (fuselage) │ aluminum │
│ AIS vessel │ 20.0 │ 5.0 (beam) │ steel │
│ Simulator boat │ 6.0 │ 2.0 (beam) │ fiberglass │
└──────────────────┴───────────┴──────────────────┴────────────┘
Notes:
- AIS vessels are legally required commercial traffic, so steel is
the correct default material.
- Simulator boats are small pleasure craft, so fiberglass is correct.
- The system defaults all new aircraft to GA. The operator must
update commercial entries via the --database panel.
- Height above water/ground defaults to 0 for vessels and 0 for
aircraft (updated by live data).
==================================================================
POSTGRESQL DATABASE
==================================================================
PostgreSQL is installed. Database: radar. User: radar. Password: radar.
User has full privileges on database radar.
Schema (all dimensions in METERS):
1. target_type ENUM('AIS', 'ADSB', 'LOCAL')
2. target_id BIGINT — MMSI for marine; ICAO 24-bit address for
aircraft; simulator may reuse same space
3. length_m REAL — length in meters
4. width_m REAL — beam (vessels) or fuselage width (aircraft)
in meters
5. height_m REAL — height above water/ground in meters
6. material ENUM('fiberglass', 'wood', 'aluminum', 'steel')
7. need_update BOOLEAN DEFAULT TRUE
8. last_seen TIMESTAMPTZ — ISO 8601, updated each time target
is received from any source
9. last_updated TIMESTAMPTZ — ISO 8601, updated when operator saves
changes via DB panel
10. track history — deferred to a future version; not in v1 schema
The fields length_m, width_m, height_m, and material are used by the
CPU to compute RCS before passing to the shader. They are static
per-target data uploaded to GPU via SSBO or uniform array each frame.
Per-frame dynamic fields (location, heading, altitude) are NOT stored
in the database. They live in TargetBuffer (Threads 2/4) and are
updated from live Raspberry Pi or simulator data each sweep.
==================================================================
DATABASE MANAGEMENT PANEL
==================================================================
Activated by command-line flag: --database
In this mode NO radar display is shown. main.cpp skips all scope
and shader initialization and starts the Dear ImGui loop instead.
Toolkit: Dear ImGui, integrated with GLFW/OpenGL 3.3.
Source lives in src/imgui/ and is compiled directly into the project
(no separate install step required).
The panel provides:
- Scrollable table of all targets with need_update highlighted
- Inline edit fields for length, width, height, material
- Dropdown for target_type
- Save button that writes to PostgreSQL via libpq
- Quit button to exit the DB panel (then start main exhibit separately)
==================================================================
RADAR EQUATION AND BLOOM
==================================================================
The radar equation is evaluated CPU-side to compute received power
(P_r) for each target. The result drives target brightness and bloom.
Computation happens in TrafficCop after each poll, outside any mutex
lock (read-only access to target physical data at that point).
The computed brightness value is uploaded per-target to the GPU via
SSBO or uniform array. The phosphor shader reads it to set amplitude.
BLOOM POST-PROCESSING (bloom.vert / bloom.frag):
Separate shader pair. Pipeline:
1. Render targets to offscreen FBO at full computed brightness
2. Apply two-pass Gaussian blur to pixels above luminance threshold
3. Additively blend blurred result back onto main framebuffer
Constants in settings.h: BLOOM_LUMINANCE_THRESHOLD,
BLOOM_BLUR_RADIUS_PX, BLOOM_BLEND_STRENGTH
RADAR PARAMETERS — MARINE (X Band):
Frequency: 9225 MHz
Peak power: 30 kW
Horizontal beamwidth: 0.5 degrees
Vertical beamwidth: 20 degrees
Antenna length: 15 feet (4.572 m)
Antenna height: 50 feet (15.24 m) above surface
RADAR PARAMETERS — ATC (S Band):
Frequency: 3000 MHz (3 GHz)
Peak power: 25 kW (exhibit value; real ASR is higher)
Horizontal beamwidth: 1.4 degrees
Vertical beamwidth: 5 degrees
Antenna width: 20 feet (6.096 m)
Antenna height: 50 feet (15.24 m) above runway
RADAR PARAMETERS — CHAIN HOME (AMES Type 1):
Frequency: 30 MHz
Peak power: 500 kW
Pulse width: 20 microseconds
PRF: 25 Hz or 12.5 Hz (operator selectable)
Transmit gain (Gt): ~7.5 linear (~8.7 dBi) — floodlight, not a beam
formula: G = 30000 / (az_bw_deg × el_bw_deg)
with az ~100 deg, el ~40 deg
Receive gain (Gr): 4 to 10 linear (610 dBi)
System loss: ~8 dB (transmission line)
Bistatic: yes — separate transmit and receive antennas
RCS resonance: at 30 MHz (lambda ~10 m) aircraft are in the
Mie/resonant scattering region; RCS is multiplied
by CHAIN_HOME_RCS_RESONANCE_FACTOR (default 3.0)
before radar equation computation. Applied to
Chain Home targets only.
RADAR PARAMETERS — PAR (X Band):
Peak power: 100 kW
Frequency: ~10 GHz (lambda ~3 cm)
Antenna size: ~5 meters
Beamwidth: ~0.34 degrees (lambda/D)
Horizontal scan: 20 degrees total
Vertical scan: 10 degrees total
Pulse width: short (high range resolution)
PRF: high (~30 Hz alternating az/el)
All radar parameters shall have corresponding constexpr constants
in settings.h so they can be tuned without touching equation code.
==================================================================
FILE LAYOUT (COMPLETE — including additions)
==================================================================
src/
main.cpp
scope_manager.h / scope_manager.cpp
scope.h / scope.cpp
scope_intro.h / scope_intro.cpp
scope_ascope.h / scope_ascope.cpp
scope_marine_a.h / scope_marine_a.cpp
scope_chain_home.h / scope_chain_home.cpp
scope_ppi.h / scope_ppi.cpp
scope_marine_ppi.h / scope_marine_ppi.cpp
scope_atc_ppi.h / scope_atc_ppi.cpp
scope_par.h / scope_par.cpp
phosphor.h / phosphor.cpp
graticule.h / graticule.cpp
left_panel.h / left_panel.cpp
shared_render_state.h / shared_render_state.cpp
target_buffer.h / target_buffer.cpp
traffic_cop.h / traffic_cop.cpp
simulator.h / simulator.cpp
knob_panel.h / knob_panel.cpp
rpi_receiver.h / rpi_receiver.cpp
db_panel.h / db_panel.cpp — Dear ImGui DB management panel
(--database mode only)
settings.h — all constexpr constants; no .cpp
imgui/ — Dear ImGui source, compiled in
imgui.h / imgui.cpp
imgui_impl_glfw.h / imgui_impl_glfw.cpp
imgui_impl_opengl3.h / imgui_impl_opengl3.cpp
imgui_draw.cpp / imgui_tables.cpp / imgui_widgets.cpp
shaders/
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

View File

@@ -187,13 +187,25 @@ src/
simulator.h / simulator.cpp simulator.h / simulator.cpp
knob_panel.h / knob_panel.cpp knob_panel.h / knob_panel.cpp
rpi_receiver.h / rpi_receiver.cpp rpi_receiver.h / rpi_receiver.cpp
db_panel.h / db_panel.cpp — Dear ImGui database management panel
(active only when --database flag passed;
no radar rendering in this mode)
settings.h — all tunable constants (no .cpp needed) settings.h — all tunable constants (no .cpp needed)
imgui/ — Dear ImGui source, compiled into project
imgui.h / imgui.cpp
imgui_impl_glfw.h / imgui_impl_glfw.cpp
imgui_impl_opengl3.h / imgui_impl_opengl3.cpp
imgui_draw.cpp / imgui_tables.cpp / imgui_widgets.cpp
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
text.vert / text.frag text.vert / text.frag
sweep.vert / sweep.frag sweep.vert / sweep.frag
bloom.vert / bloom.frag — two-pass bloom: render to FBO, Gaussian
blur bright spots, blend back; used for
target blooming from radar equation output
``` ```
--- ---
@@ -342,3 +354,51 @@ No raw `new` or `delete` anywhere in the codebase. No `malloc`/`free`.
are blocked during the animation. The new range value is latched when the are blocked during the animation. The new range value is latched when the
key is pressed but not applied to the scope state until SLIDING_IN completes. key is pressed but not applied to the scope state until SLIDING_IN completes.
Animation duration is approximately 0.5 seconds per slide (out and in). Animation duration is approximately 0.5 seconds per slide (out and in).
12. **All dimensions are stored and computed in meters** throughout the system.
Any incoming data from Raspberry Pi receivers or the simulator that arrives in
feet (e.g., altitude from ADS-B in feet, antenna heights) is converted to
meters at the boundary in `RPiReceiver::parseFrame()` or `Simulator::poll()`
before the value enters any shared data structure. No feet values appear
anywhere inside the system after the conversion point.
Conversion: 1 foot = 0.3048 meters exactly.
13. **Default target dimensions** used when a target is first seen with no
database record. All values in meters. `need_update` is set TRUE for all
defaults so the operator knows to fill in real data.
| Category | Length (m) | Fuselage/Beam width (m) | Material |
|---|---|---|---|
| GA aircraft | 4.0 | 1.0 | aluminum |
| Commercial a/c| 30.0 | 5.0 | aluminum |
| AIS vessel | 20.0 | 5.0 | steel |
| Simulator boat| 6.0 | 2.0 | fiberglass |
AIS-sourced vessels default to steel (legally required commercial traffic).
Simulator-sourced boats default to fiberglass (small pleasure craft).
Aircraft source type does not disambiguate GA vs. commercial — the system
defaults to GA and lets the operator correct it.
14. **Bloom post-processing** uses a dedicated `bloom.vert` / `bloom.frag` shader
pair. The pipeline is: render targets to an offscreen FBO at full computed
brightness (from radar equation output), apply a two-pass Gaussian blur to
pixels above a luminance threshold, then additively blend the blurred result
back onto the main framebuffer. Bloom threshold and blur radius are
`constexpr` constants in `settings.h`.
15. **Dear ImGui** is used for the database management panel, activated by the
`--database` command-line flag. In that mode no radar rendering occurs —
main.cpp skips the scope/shader initialization path entirely and starts the
ImGui loop instead. ImGui source files live under `src/imgui/` and are
compiled directly into the project (no separate install step). The panel
provides: a scrollable target table with `need_update` highlighted, inline
edit fields for length/width/height/material, a dropdown for target type,
and a Save button that writes to PostgreSQL via libpq.
16. **Chain Home RCS resonance** is modelled with a multiplier constant
`CHAIN_HOME_RCS_RESONANCE_FACTOR` in `settings.h`. At 30 MHz (λ ≈ 10 m),
aircraft with wingspans of 1030 m are in the Mie/resonant scattering
region; RCS can be 25× the geometric cross section. The default value is
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.

View File

@@ -297,6 +297,70 @@
* larger frames are discarded as malformed * larger frames are discarded as malformed
*/ */
/*
* ================================================================
* UNITS AND CONVERSION
* ================================================================
* All dimensions inside the system are stored and computed in meters.
* Any incoming value in feet (ADS-B altitude, antenna heights, etc.)
* must be converted at the data boundary before entering shared state.
*
* FEET_TO_METERS Exact conversion factor: 0.3048
*/
/*
* ================================================================
* DEFAULT TARGET DIMENSIONS (meters, need_update = TRUE)
* ================================================================
* Used when a target is first seen with no database record.
* All values in meters. Operator must update with real dimensions.
*
* GA aircraft (general aviation):
* DEFAULT_GA_LENGTH_M 4.0 (approx Cessna-class)
* DEFAULT_GA_WIDTH_M 1.0 (fuselage width)
*
* Commercial aircraft:
* DEFAULT_COMM_LENGTH_M 30.0 (narrow-body airliner)
* DEFAULT_COMM_WIDTH_M 5.0 (fuselage width)
*
* AIS vessel (commercially registered, defaults to steel):
* DEFAULT_AIS_VESSEL_LENGTH_M 20.0
* DEFAULT_AIS_VESSEL_BEAM_M 5.0
*
* Simulator boat (small pleasure craft, defaults to fiberglass):
* DEFAULT_SIM_BOAT_LENGTH_M 6.0
* DEFAULT_SIM_BOAT_BEAM_M 2.0
*
* Note: system defaults all new aircraft to GA; operator corrects
* commercial entries via the --database panel.
*/
/*
* ================================================================
* BLOOM POST-PROCESSING
* ================================================================
* Two-pass Gaussian blur applied to pixels above a luminance
* threshold, then additively blended onto the main framebuffer.
* Driven by radar equation output brightness.
*
* BLOOM_LUMINANCE_THRESHOLD Minimum brightness to bloom (0.01.0)
* BLOOM_BLUR_RADIUS_PX Gaussian kernel half-width in pixels
* BLOOM_BLEND_STRENGTH Additive blend weight (0.01.0)
*/
/*
* ================================================================
* CHAIN HOME — RCS RESONANCE
* ================================================================
* At 30 MHz (lambda ~10 m) aircraft wingspans fall in the Mie/
* resonant scattering region. RCS is multiplied by this factor
* before the radar equation computes received power. Applied to
* Chain Home targets only.
*
* CHAIN_HOME_RCS_RESONANCE_FACTOR 3.0 (mid-range Mie estimate;
* range is approximately 25)
*/
/* /*
* ================================================================ * ================================================================
* PAR GEOMETRY * PAR GEOMETRY