close to finishing claude.md file
This commit is contained in:
254
CLAUDE.md
254
CLAUDE.md
@@ -105,9 +105,10 @@ Also not that when the radar exhibit starts, the very first option will
|
||||
be on the screen. Then the screen will advance through the scopes by two means;
|
||||
the pressing of the s key by the user, or automatically at every 120 seconds. You will
|
||||
need to emphasize in the first desciption that you can advance without waiting
|
||||
for the automatic advancing by pressing the s key. This should be articulated for the
|
||||
for the automatic advancing by pressing the s key. You can reverse by hitting the S key
|
||||
(upper case s) This should be articulated for the
|
||||
discrition window for each scope. When the main exhibit descriptor screen comes up, it's
|
||||
important to highlight the feature that the user can press the s key any time to 'hurry up'
|
||||
important to highlight the feature that the user can press the s key or the S key any time to 'hurry up'
|
||||
the scope advancement.
|
||||
|
||||
Also ensure that the timeout clock will reset when the user changes to a new scope, or presses
|
||||
@@ -143,6 +144,20 @@ should be articulated in the descriptive text
|
||||
In addition to the blips for targets, there would be a floor of noise (signal received by
|
||||
rain and waves. This needs to be shown.
|
||||
|
||||
Graticule swap simulation: In the period, changing maximum range required the operator
|
||||
to physically slide the glass graticule panel upward and out from in front of the CRT,
|
||||
then slide the replacement graticule (calibrated for the new range) downward into position.
|
||||
This must be simulated when the operator presses u or d to change range.
|
||||
|
||||
The graticule swap animation uses four states:
|
||||
NORMAL - graticule in place, scope operating normally
|
||||
SLIDING_OUT - old graticule translates upward off screen (~0.5 seconds)
|
||||
BARE_CRT - no graticule visible; CRT trace and noise floor still running
|
||||
SLIDING_IN - new graticule (correct lines for new range) slides down into position (~0.5 seconds)
|
||||
After SLIDING_IN completes, state returns to NORMAL with the new range active.
|
||||
The u and d keys are ignored during the swap animation (operator's hands are busy).
|
||||
The graticule remains incandescent color throughout — it is edge-lit glass.
|
||||
|
||||
3. Chain Home A Scope There is a second use of the a-scope.
|
||||
That is for the early world war 2 chain home
|
||||
radar. This operated very differently. You have a large array of high power transmitters
|
||||
@@ -158,7 +173,7 @@ should be articulated in the descriptive text
|
||||
as this is a bit advanced. I need your advise to how to do this for children and those
|
||||
who never heard of chain home.
|
||||
|
||||
The goniometer vert and h switch could be keys [ and ] and the gonometer tuning
|
||||
The goniometer vertical and horizontal switch could be key [ for toggling. The gonometer tuning
|
||||
would be 9 and 0 to avoid using the shift key. The tuning keys should have one unit
|
||||
for single press, but a slow build of of speed if key is held down. This has to stay
|
||||
slow due to the sudden appearance of the null.
|
||||
@@ -325,8 +340,96 @@ should be articulated in the descriptive text
|
||||
Sweep rate: approximately 30 Hz alternating between azimuth and
|
||||
elevation planes so that each will scan 1/15 th of a second.
|
||||
|
||||
THREADS
|
||||
|
||||
[remove modularity and threads; will work this out later before implementation]
|
||||
These are the threads of processes:
|
||||
|
||||
1. Display initiation and operation (anything that 'touches' the display and the shaders) Thread 1
|
||||
2. Software that receives data for targets. Thread 2 (this is the traffic cop that polls the
|
||||
raspberry pis. and the Simulator. This needs mutex access to shared data with thread 1. It will
|
||||
also need mutex access to shared data with thread 4 (the simulator)
|
||||
3. Knob panel - thread 3 - uses a mutex to write shared state variables that thread 1 reads
|
||||
to send to the shaders.
|
||||
4. Simulator, thread 4. It is polled by the traffic cop
|
||||
|
||||
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
|
||||
|
||||
SUMMARY OF Controls:
|
||||
● ┌─────┬─────────────────────────────────────┬───────┬──────────┬──────────────┬────────────┬─────────┬─────┐
|
||||
│ Key │ Function │ Intro │ Marine A │ Chain Home A │ Marine PPI │ ATC PPI │ PAR │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ s │ Advance to next scope │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ S │ back to previous scope │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ c │ Bearing clockwise │ │ ✓ │ │ │ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ v │ Bearing counterclockwise │ │ ✓ │ │ │ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ u │ Max range up │ │ ✓ │ │ ✓ │ ✓ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ d │ Max range down │ │ ✓ │ │ ✓ │ ✓ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ r │ Cursor bearing right │ │ │ │ ✓ │ ✓ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ l │ Cursor bearing left │ │ │ │ ✓ │ ✓ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ t │ Cursor range increase │ │ │ │ ✓ │ ✓ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ y │ Cursor range decrease │ │ │ │ ✓ │ ✓ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ k │ Antenna bearing offset right (boat) │ │ │ │ ✓ │ ✓ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ j │ Antenna bearing offset left (boat) │ │ │ │ ✓ │ ✓ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ [ │ Goniometer H/V switch │ │ │ ✓ │ │ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ 9 │ Goniometer tune left │ │ │ ✓ │ │ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ 0 │ Goniometer tune right │ │ │ ✓ │ │ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ . │ Toggle PRF (25/12.5 Hz) │ │ │ ✓ │ │ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ n │ Calibrator shrink │ │ │ ✓ │ │ │ │
|
||||
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
||||
│ m │ Calibrator stretch │ │ │ ✓ │ │ │ │
|
||||
└─────┴─────────────────────────────────────┴───────┴──────────┴──────────────┴────────────┴─────────┴─────┘
|
||||
|
||||
SUMMARY of target handling:
|
||||
|
||||
The traffic cop handles anything that is coming from the simulator as well as the raspberry pi's
|
||||
It will use pollnig to find if anything is available from the raspberry pis and the simulator. It will
|
||||
poll each source once per beam update
|
||||
|
||||
The raspberry pi receiver pulls the data from each raspberry pi. If nothing, it does nothing else
|
||||
for this sweep. If there is data, it will provide data to the traffic cop upon poll.
|
||||
|
||||
Each raspberry pi, after boot-up, will respond to poles from the raspberry pi receiver (thread 2)
|
||||
|
||||
The Simulator will run all fake targets. It will provide data to the traffic cop upon traffic cop poll.
|
||||
It can run as a separate thread. It will not write data to anywhere except when polled by the traffic cop.
|
||||
|
||||
|
||||
CONTROLS
|
||||
|
||||
Things to note about the keyboard type controls.
|
||||
The letter on the keyboard are temporary. When I get around to making
|
||||
the operators panel, this all will go away.
|
||||
|
||||
Implementation of controls:
|
||||
|
||||
1. For keyboard controls. Those are run as thread one where The keyboard callback
|
||||
belongs to GLFW (glfwSetKeyCallback)
|
||||
They will manipulate the shaders only.
|
||||
|
||||
2. The control desk controls will have to mutex to access the state variables that
|
||||
thread 1 sends to the shaders.
|
||||
|
||||
3. If the control does not yet exist, we still want stubs for receiving control
|
||||
data for that control. It's just that nothing will call it.
|
||||
|
||||
Scope and left window arrangement.
|
||||
|
||||
For each scope, put the scope itself on the right hand of the window.
|
||||
On the left hand of the window will be a text description of that scope.
|
||||
@@ -351,6 +454,145 @@ different radars. Range and bearing for the precision aproach radar will be diff
|
||||
than any other radar as that radar is located at the end of the runway and scan both
|
||||
horizontal and vertical.
|
||||
|
||||
[other scopes to be defined later]
|
||||
|
||||
Please analyze and comment. Please do not generate any code file nor shader files.
|
||||
|
||||
==================================================================
|
||||
|
||||
CLASS DESIGN AND FILE LAYOUT
|
||||
|
||||
==================================================================
|
||||
|
||||
Class Hierarchy:
|
||||
|
||||
Scope (abstract base)
|
||||
├── ExhibitIntro
|
||||
├── AScope (abstract)
|
||||
│ ├── MarineAScope
|
||||
│ └── ChainHomeAScope
|
||||
├── PPIScope (abstract)
|
||||
│ ├── MarinePPIScope
|
||||
│ └── ATCPPIScope
|
||||
└── PARScope
|
||||
|
||||
Scope (abstract base) — everything all scopes share:
|
||||
- Left panel text rendering
|
||||
- s / S key handling (scope advance / reverse)
|
||||
- Auto-advance timer reset on any key or control input
|
||||
- Pure virtual: render(), handleKey(), getDescription()
|
||||
|
||||
ExhibitIntro : public Scope
|
||||
- Text-only rendering, no radar display
|
||||
- Header: "WELCOME TO MUSEUM VINTAGE RADAR EXHIBIT" (all caps)
|
||||
|
||||
AScope : public Scope (abstract) — shared A-scope behavior:
|
||||
- Horizontal range axis, vertical amplitude axis
|
||||
- Noise floor rendering (rain/wave clutter)
|
||||
- Incandescent graticule (three horizontal amplitude lines + vertical range lines)
|
||||
- Bearing control with key-hold acceleration
|
||||
- Phosphor type as parameter (P1 or P7)
|
||||
|
||||
MarineAScope : public AScope
|
||||
- P1 phosphor (green)
|
||||
- Range settings: 2, 4, 6 miles
|
||||
- Graticule swap animation state machine (NORMAL/SLIDING_OUT/BARE_CRT/SLIDING_IN)
|
||||
when operator changes max range — see Marine A-Scope section above for full detail
|
||||
- Keys: c (bearing CW), v (bearing CCW), u (range up), d (range down)
|
||||
u and d ignored during graticule swap animation
|
||||
|
||||
ChainHomeAScope : public AScope
|
||||
- P7 phosphor (early implementation)
|
||||
- Goniometer state: H/V mode toggle, azimuth angle, elevation angle
|
||||
- PRF toggle: 25 Hz / 12.5 Hz
|
||||
- Calibrator stretch/shrink scale factor
|
||||
- Fixed 100-mile range
|
||||
- Keys: [ (goniometer H/V toggle), 9/0 (tune), . (PRF), n/m (calibrator)
|
||||
|
||||
PPIScope : public Scope (abstract) — shared PPI behavior:
|
||||
- Clockwise sweep with P7 phosphor persistence (blue strike, green/yellow decay)
|
||||
- Incandescent bearing graticule (1-degree ticks, 15-degree labels, inner/outer rings)
|
||||
- Yellow cursor: 10-degree arc + bearing crossline
|
||||
- Cursor range/bearing readout under scope (white text)
|
||||
- Bearing offset for boat mode (k/j)
|
||||
- Cursor range clamped to max range
|
||||
|
||||
MarinePPIScope : public PPIScope
|
||||
- Sweep time: 4 seconds
|
||||
- Max range: 2, 4, 6 miles with correct ring sets
|
||||
- Keys: u (range up), d (range down) — this scope only
|
||||
|
||||
ATCPPIScope : public PPIScope
|
||||
- Sweep time: 5 seconds
|
||||
- Max range: 5, 10, 15, 20 miles with correct ring sets
|
||||
- Keys: u (range up), d (range down) — this scope only
|
||||
|
||||
PARScope : public Scope
|
||||
- Two stacked sub-scopes: azimuth (top, ~1/3 larger) and elevation (bottom)
|
||||
- 30 Hz alternating scan between planes (~15 Hz each)
|
||||
- Fixed 10-mile range, non-linear scale (inner 5 miles = 70% width)
|
||||
- P7 phosphor; incandescent etched glass graticules
|
||||
- All targets simulated; no cursor or bearing controls
|
||||
|
||||
Supporting classes:
|
||||
ScopeManager Thread 1 — owns scope list, s/S switching, 120s auto-advance timer
|
||||
PhosphorRenderer Thread 1 — P1 and P7 decay/persistence; shared dependency
|
||||
Graticule Thread 1 — incandescent graticule lines/text; parameterized per scope
|
||||
LeftPanel Thread 1 — scope description text panel (left side of window)
|
||||
SharedRenderState Threads 1,2,3 — Mutex A; state vars Thread 1 reads each frame for shader uniforms
|
||||
TargetBuffer Threads 2,4 — Mutex B; target data handoff between TrafficCop and Simulator
|
||||
TrafficCop Thread 2 — polls Simulator and RPi receivers; writes to SharedRenderState
|
||||
Simulator Thread 4 — runs fake targets; returns data to TrafficCop when polled
|
||||
KnobPanel Thread 3 — future hardware stub; writes to SharedRenderState under Mutex A
|
||||
RPiReceiver Thread 2 — stub; one per Raspberry Pi; called by TrafficCop
|
||||
|
||||
File layout:
|
||||
|
||||
src/
|
||||
main.cpp
|
||||
scope_manager.h / scope_manager.cpp
|
||||
scope.h / scope.cpp — abstract Scope base
|
||||
scope_intro.h / scope_intro.cpp
|
||||
scope_ascope.h / scope_ascope.cpp — abstract AScope
|
||||
scope_marine_a.h / scope_marine_a.cpp
|
||||
scope_chain_home.h / scope_chain_home.cpp
|
||||
scope_ppi.h / scope_ppi.cpp — abstract PPIScope
|
||||
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
|
||||
|
||||
settings.h — all tunable constants; no .cpp needed
|
||||
|
||||
shaders/
|
||||
phosphor.vert / phosphor.frag — parameterized for P1 and P7 via uniforms
|
||||
graticule.vert / graticule.frag
|
||||
text.vert / text.frag
|
||||
sweep.vert / sweep.frag
|
||||
|
||||
settings.h — tunable constants:
|
||||
All magic numbers live here. Every source file that needs a tunable value
|
||||
includes settings.h. No values are hardcoded elsewhere.
|
||||
Categories planned:
|
||||
- Phosphor P1 color
|
||||
- Phosphor P7 strike color, persistence color, decay times (PPI and Chain Home)
|
||||
- Sweep line width, brightness, fade trail, periods per scope
|
||||
- PAR scan rate; Chain Home PRF high and low
|
||||
- Graticule incandescent color, line widths
|
||||
- PPI bearing ring tick lengths, label interval, font size
|
||||
- PPI range ring line width, label size, label color
|
||||
- Cursor color, line width, arc span
|
||||
- Noise floor amplitude and variation (Marine A-Scope)
|
||||
- Graticule swap animation durations (slide out, bare CRT, slide in)
|
||||
- Key-hold acceleration (initial step, rate, max) — separate for goniometer
|
||||
- Auto-advance timer interval (120 seconds)
|
||||
- Window size and panel layout fractions
|
||||
- PAR azimuth/elevation height fractions
|
||||
- UI text color and size; cursor readout text size
|
||||
- Graticule label color (incandescent)
|
||||
|
||||
Reference in New Issue
Block a user