884 lines
54 KiB
Markdown
884 lines
54 KiB
Markdown
Introduction:
|
|
|
|
This is a project for a museum to demonstrate a simulation of a 1950's to 1960's
|
|
vintage marine radar and air traffic control radar
|
|
|
|
The project will be implemented on a Geekom A8 Max
|
|
with AMD AI chip R9-8945HS with 32 GB ram
|
|
|
|
# Project: C++ OpenGL Radar Simulation
|
|
**Environment:** Ubuntu Linux (Remote SSH from Windows)
|
|
**Tech Stack:** C++20, OpenGL 3.3 Core, GLFW, GLAD, FreeType
|
|
|
|
|
|
The operating system is Linux (Ubuntu)
|
|
Details:
|
|
|
|
Distributor ID: Ubuntu
|
|
Description: Ubuntu 25.10
|
|
Release: 25.10
|
|
Codename: questing
|
|
|
|
The compiler is cpp (Ubuntu 15.2.0-4ubuntu4) 15.2.0
|
|
|
|
We plan to use the cmake for building.
|
|
|
|
Please add MIT license header to each file
|
|
Please add Author: Mark Allyn to each file
|
|
|
|
Here is the directory structure with files already installed:
|
|
All directories are in the new-radar top level directory. The
|
|
entire directory list is /home/maallyn/new-radar on the Geekom.
|
|
|
|
./shaders
|
|
./shaders/CLAUDE.md
|
|
./glad
|
|
./glad/src
|
|
./glad/src/glad.c
|
|
./include
|
|
./include/glad
|
|
./include/glad/glad.h
|
|
./include/CLAUDE.md
|
|
./include/KHR
|
|
./include/KHR/khrplatform.h
|
|
./new-claude
|
|
./README.md
|
|
./CMakeLists.txt
|
|
./build
|
|
./build/CLAUDE.md
|
|
./CLAUDE.md
|
|
./.new-claude.swp
|
|
./LICENSE
|
|
./src
|
|
./src/CLAUDE.md
|
|
|
|
==================================================================
|
|
|
|
GENERAL STUFF
|
|
|
|
==================================================================
|
|
|
|
Please note that all on-screen text shall be white and fully
|
|
illuminated and is not subject to phosphor persistence or decay.
|
|
|
|
Exceptions:
|
|
|
|
Graticule text: should be incandescent for the bearing marks.
|
|
Graticule text for all a-scope should be incandescent, not white
|
|
and not phosphor as they are dependent on glass graticules with etched
|
|
lines and text.
|
|
|
|
PPI Scope Range Ring Markers Text on the PPI scope range rings shall be blue
|
|
fade to yellow green as on p7 phosphor. Which is the same for ppi targets.
|
|
|
|
Please note that direction as stated here are True directions. 000 is True North
|
|
|
|
Maximum Range is 6 miles for marine type radar
|
|
Maximum Range is 20 miles for air traffic control radar.
|
|
Maximum Range is 100 miles for chain home
|
|
Maximum Range 10 miles for precision approach radar; graticule is
|
|
incandescent showing the azimuth path and elevation path as described
|
|
below in PAR description. Those graticules are etched glass for minimal
|
|
parallax
|
|
|
|
The proposed location of the marine radar antenna is in the middle of Bellingham
|
|
Bay on a 100 foot platform. (This should be mentioned as fictitious in the description)
|
|
Location is 48.74361448950435 latitude, -122.56466911663048 longitude
|
|
|
|
The proposed location of the air traffic control radar is the Bellingham
|
|
airport (BLI) control tower. Latitude: 48° 47' 33.7" N ; Longitude: 122° 32' 15.1" W
|
|
|
|
The proposed location for the chain home would be at the original location on
|
|
the UK coast facing the European Continent
|
|
|
|
The following types of scope will be used; (note that these are not all
|
|
going to show at once. They will be selectable using a push button (a letter on
|
|
the keyboard until I get physical buttons that are connected to a gpio pin.
|
|
The selection key should be s (short for scope)
|
|
|
|
Please note that all keyboard based controls need to be described in each
|
|
scope's left hand text panel. These are different for each scope. Note that
|
|
the s for selecting a scope should be in each scope's description and what
|
|
would the next scope be.
|
|
|
|
Also note 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 description that you can advance without waiting
|
|
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
|
|
description 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 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
|
|
any key or operates any control on the panel. This
|
|
should be articulated in the descriptive text
|
|
|
|
|
|
1. Exhibit introduction - a text block describing the exhibit and the
|
|
basics on how to use it and what you are seeing. This should be text only. Top would
|
|
be in all caps, "WELCOME TO MUSEUM VINTAGE RADAR EXHIBIT"
|
|
|
|
2. Marine A-Scope - (horizontal axis is range; vertical axis is amplitude of
|
|
return pulse; bearing will be set via a bearing control; current implementation
|
|
would be two keys on the keyboard; one key to go clockwise on bearing and another
|
|
key would be to go counterclockwise. The A scope phosphor is P1, which is green.
|
|
The c key for clockwise on a scope and v for counterclockwise.
|
|
The step rate for this control, before the knob is implemented would be one or two
|
|
degrees per key press, but if the key is held down, it would increase slowly due to
|
|
how long the key is depressed
|
|
|
|
The A scope graticule is manually swapped out at each maximum range value
|
|
by the operator during the period. Here we will have to fake it out. And that
|
|
graticule needs to have an incandescent color. That graticule will have three horizontal
|
|
graticule lines for estimating return pulse strength. The range lines (vertical lines)
|
|
must match the interim and final ranges as selected by the max range selection
|
|
To change maximum range, use key u for up and d for down. Possible settings are 2,4,6
|
|
miles; this must be noted clearly on the description text.
|
|
|
|
Max is 2; one interim range at 1
|
|
Max is 4; one interim range at 2
|
|
Max is 6; one interim range at 4
|
|
|
|
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
|
|
'floodlighting' the target area (in World War 2, that would be the English Channel.
|
|
Since we don't care about land reflections with the original chain home setup was
|
|
facing the English Channel, we can tell visitors that this radar is set at the
|
|
English Channel (do this explanation on the explanation side panel for this
|
|
radar mode. And for simulating operator using this radar, there would be two controls,
|
|
one for the 'nulling the signal at the correct direction; simulating the behavior
|
|
of the goniometer and the other for using the goniometer for elevation. For museum
|
|
accuracy, we need to simulate the sharp 'null' when the goniometer is at the direction
|
|
of the signal. This concept needs to be covered in the description text thoroughly
|
|
as this is a bit advanced. I need your advice on how to do this for children and those
|
|
who never heard of chain home.
|
|
|
|
The goniometer vertical and horizontal switch could be key [ for toggling. The goniometer 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.
|
|
|
|
Targets for Chain Home would all have to be simulated as there will be no ais
|
|
nor ads-b. Simulations would show several aircraft approaching the radar in many
|
|
different directions and ranges. The museum visitor for exercise could try to sort
|
|
out the targets by range and bearing and elevation by the nulling procedure noted
|
|
above as well as the distance of the pulse from the origin.
|
|
|
|
The graticule is etched glass (side lit with incandescent lights) with 10 mile
|
|
markers for range (horizontal axis). There are no vertical markers; the signal
|
|
strength value is not important. The only vertical value that is important is the
|
|
nulling of the signal based on bearing and elevation from the manipulation of the
|
|
goniometer.
|
|
|
|
The refresh rates for chain home were slow in order to avoid aliasing with targets
|
|
far away, the pulse repetition frequency (PRF) is about 25 times per second. This
|
|
rate is 1/2 of the standard 50 Hz for British power.
|
|
|
|
The operator did have a switch to switch from the 25 pulses per second PRF to 12.5
|
|
pulses per second PRF so that they could help eliminate the range ambiguity
|
|
problem, where a target far away could appear to be right on site since that echo
|
|
would return at the precise time for the next pulse to go out at 25 PRF. This needs
|
|
to be explained in the explainer window for the chain home. Mention that mountains or planes
|
|
in the continent could have that kind of range. Furthermore, the operator can reduce
|
|
the PRF in order to reduce confusion caused by other radio transmissions such as press-to-talk
|
|
communications transmissions.
|
|
|
|
Let's assign key . for toggling between 25 and 12.5 PRF. There is no range selection.
|
|
Note on description; this is to reduce use of the shift key.
|
|
|
|
Because of the slow repetition rate, the phosphor used was an early implementation
|
|
of the p7 phosphor so that the targets will still glow between the sweeps and not cause
|
|
flickering.
|
|
|
|
Another unique feature would be a response to the drifting problem in early electronics.
|
|
The scope electronics would use a crystal calibrator that puts tiny pips or spikes at
|
|
known intervals (10 miles). The operator would use a knob, or control, to stretch or
|
|
shrink the electronic trace so that the 10 mile pips align perfectly with the 10 mile
|
|
marks on the edge lit glass graticule.
|
|
|
|
Let's assign key n for shrink and m for stretch. (may be ambiguous, but I am running
|
|
out of keys. Note in the descriptor.
|
|
|
|
|
|
4. Marine PPI Scope -
|
|
marine scopes have the following items in common:
|
|
Targets, range rings, and range ring text levels shall be treated the same for
|
|
presentation. 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
|
|
persist and fade out together. They should be faded out by the time the sweep
|
|
to that location.
|
|
|
|
The maximum range settings are 6 miles for the marine radar scope
|
|
Rings should be 2,4, and 6 miles for marine.
|
|
The max range settings for marine ppi will be u for up and d for
|
|
down. If you are in the marine ppi, you change only the max range for the marine
|
|
ppi. The possible max range values for
|
|
the marine radar are 2,4,6
|
|
miles.
|
|
|
|
Marine:
|
|
Max is 2; one interim range at 1, final ring at 2
|
|
Max is 4; one interim range at 2, final ring at 4
|
|
Max is 6; one interim range at 4, final ring at 6
|
|
|
|
Note on range. If cursor range is beyone max, clamp it to the max.
|
|
|
|
Bear in mind that the max range setting is independent for both radars.
|
|
|
|
The bearing graticule (lit incandescent) There should
|
|
be an inner circle with tickmarks for each degree, starting at 0 (north) and going
|
|
clockwise to the last tick, which is 359. Outside the inner ring shall be text
|
|
labels for every 15 degrees. Outside the text labels, there will be
|
|
an outer ring. Both inner and outer rings, along with ticks, and the bearing
|
|
labels are to be incandescent color.
|
|
|
|
The sweep time shall be 4 seconds for the marine scope
|
|
|
|
The sweep direction is clockwise, which means that the antenna
|
|
dish rotates clockwise.
|
|
|
|
The scope has a cursor for range and bearing. The cursor consists of a
|
|
section of a ring ( 10 degrees) and a cross line for bearing.
|
|
The cursor should be yellow (it
|
|
a plastic overlay in the period time. Two controls control the cursor; range and
|
|
bearing. Both were physical crank controls. For now, both we need to use key pairs
|
|
on the keyboard. A white text indication of range and bearing should be put under
|
|
the scope. In the real day, it was a machanical readout. The key sequence would be
|
|
r for bearing to the right and l for bearing for the left; and t for higher range
|
|
and y for smaller range. These controls should have slow movement for single stroke; but
|
|
gradual for for holding key down.
|
|
|
|
5. Air Traffic PPI Scope -
|
|
Targets, range rings, and range ring text levels
|
|
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
|
|
persist and fade out together. They should be faded out by the time the sweep
|
|
to that location.
|
|
|
|
Rings should be 5,10,15,20 for the air traffic control radar.
|
|
The max range settings for air ppi will be u for up and d for
|
|
down. Use of these controls affect only the scope you are in. No other scopes are
|
|
affected.
|
|
The ranges for air traffic control radar are 5,10,15,20
|
|
miles.
|
|
|
|
Air Traffic Control:
|
|
Max is 5; one interim range; two total; rings at 2.5; final ring at 5
|
|
Max is 10; four interim ranges, five total; 2,4,6,8; final ring at 10
|
|
Max is 15; three interim ranges four total; 4,8,12; final ring at 15
|
|
Max is 20, three interim ranges four total; 5,10,15; final ring at 20
|
|
|
|
Note on range. If cursor range is beyone max, clamp it to the max.
|
|
|
|
Bear in mind that the max range setting is independent for both radars.
|
|
|
|
The bearing graticule (lit incandescent) for the scopes are the same. There should
|
|
be an inner circle with tickmarks for each degree, starting at 0 (north) and going
|
|
clockwise to the last tick, which is 359. Outside the inner ring shall be text
|
|
labels for every 15 degrees. Outside the text labels, there will be
|
|
an outer ring. Both inner and outer rings, along with ticks, and the bearing
|
|
labels are to be incandescent color.
|
|
|
|
The sweep time shall be 5 seconds for the
|
|
air traffic scope.
|
|
|
|
The sweep direction on the scope is clockwise, which means that the antenna
|
|
dish rotates clockwise.
|
|
|
|
The scope has cursor for range and bearing. The cursor consists of a
|
|
section of a ring ( 10 degrees) and a cross line for bearing.
|
|
The cursor should be yellow (it
|
|
a plastic overlay in the period time. Two controls control the cursor; range and
|
|
bearing. Both were physical crank controls. For now, both we need to use key pairs
|
|
on the keyboard. A white text indication of range and bearing should be put under
|
|
the scope. In the real day, it was a machanical readout. The key sequence would be
|
|
r for bearing to the right and l for bearing for the left; and t for higher range
|
|
and y for smaller range.
|
|
These controls should have slow movement for single stroke; but
|
|
gradual for for holding key down.
|
|
|
|
6. Precision approach (PAR for short)
|
|
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
|
|
does not have to rely on any equipment on the plane itself to help with landing.
|
|
The display shows the full 10-mile approach path, but the controller's active guidance window
|
|
is roughly the last 5 miles, intensifying from about 2 miles out to touchdown.
|
|
This needs to be carefully explained on the explainer screen.
|
|
Let's locate this at the south end of Runway 16/34 landing at BLI and let's have the
|
|
active runway 34 (northbound landing)
|
|
|
|
Locate at the end of Runway 16/34
|
|
at Bellingham Airport (BLI). Two vertically stacked scopes share the
|
|
right panel. Top scope: azimuth (lateral deviation vs. range from
|
|
touchdown). Bottom scope: elevation (vertical deviation vs. range).
|
|
Have the azimuth scope to about 1/3 larger than the elevation scope
|
|
Both use P7 phosphor; graticules are incandescent etched glass.
|
|
Range: 10 miles maximum, fixed (no range change control).
|
|
Non-linear scale: inner 5 miles occupies 70% of horizontal width.
|
|
All targets are simulated. No cursor or bearing controls; PAR
|
|
has no bearing selection — it always points toward the runway.
|
|
Sweep rate: approximately 30 Hz alternating between azimuth and
|
|
elevation planes so that each will scan 1/15 th of a second.
|
|
|
|
THREADS
|
|
|
|
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 │ │ │ ✓ │ │ │ │
|
|
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
|
│ 1 │ Gain increase │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
|
|
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
|
│ 2 │ Gain decrease │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
|
|
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
|
│ 3 │ Rain clutter filter increase │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
|
|
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
|
│ 4 │ Rain clutter filter decrease │ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │
|
|
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
|
│ 5 │ Wave clutter filter increase │ │ ✓ │ ✓ │ ✓ │ │ │
|
|
├─────┼─────────────────────────────────────┼───────┼──────────┼──────────────┼────────────┼─────────┼─────┤
|
|
│ 6 │ Wave clutter filter decrease │ │ ✓ │ ✓ │ ✓ │ │ │
|
|
└─────┴─────────────────────────────────────┴───────┴──────────┴──────────────┴────────────┴─────────┴─────┘
|
|
|
|
Table for general controls not yet implemented on the keyboard in the table above:
|
|
|
|
1. Intensity
|
|
2. Focus
|
|
3. Astigmatism
|
|
4. Graticule light intensity
|
|
|
|
Note: Gain (keys 1/2), rain clutter (keys 3/4), and wave clutter (keys 5/6) are now
|
|
in the keyboard control table above. They remain physical encoder controls on the
|
|
operator panel when that hardware is installed; the keyboard keys are the temporary
|
|
stand-in. All three have defaults in settings.h.
|
|
|
|
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 polling 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 polls 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
|
|
|
|
Every control listed above — both keyboard controls and the 7 general operator controls —
|
|
shall have a corresponding default constant in settings.h. This allows any startup value
|
|
to be changed at compile time without touching scope or rendering code.
|
|
|
|
The 7 general controls (Intensity, Focus, Astigmatism, Gain, Rain Clutter, Wave Clutter,
|
|
Graticule Intensity) are physical encoder controls not yet purchased. Their placeholder
|
|
default constants are defined in settings.h. KnobPanel (Thread 3) will compile and run
|
|
from the start but will idle without ever acquiring Mutex A until real hardware is wired
|
|
in. SharedRenderState holds the default values unchanged; Thread 1 reads and applies them
|
|
every frame. No feature flags or conditional compilation are needed — the code path is
|
|
complete end-to-end, always at the compile-time default.
|
|
|
|
Three of the 7 general controls — Gain, Rain Clutter, and Wave Clutter — have temporary
|
|
keyboard implementations (keys 1/2, 3/4, and 5/6 respectively) that write to the same
|
|
SharedRenderState fields the hardware encoders will eventually write to. When physical
|
|
encoders are installed, the keyboard keys can be removed or left as redundant overrides.
|
|
|
|
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.
|
|
|
|
Underneath each scope's description will be cursor range and bearing from the radar
|
|
location; and the setting of maximum range; and the bearing offset; for 0 would
|
|
be to have 0 degrees pointing to true north (this is needed if I decide to
|
|
implement a radar on a boat. If implemented, use k for bearing to right; and
|
|
j for bearing to left. Make note in description that this is only used if this
|
|
is a radar on a boat. (perhaps later on, I could add a PPI on a boat scenario)
|
|
|
|
Please note that some keys may be the same from scope to scope. This is okay. Each
|
|
scope's controls are for that scope that you are connected do.They will not effect
|
|
settings on another scope.
|
|
|
|
Please note that the maximum range setting on a scope specific to that scope
|
|
and will be in that scope's definition. and the bearing selection
|
|
is scope specific. The manually operated radar dish for the a scope is not the same
|
|
as the PPI radar dishes. They are from different eras. In addition, all range and
|
|
bearing data for marine is separate than for air traffic control. They are completely
|
|
different radars. Range and bearing for the precision approach radar will be different
|
|
than any other radar as that radar is located at the end of the runway and scan both
|
|
horizontal and vertical.
|
|
|
|
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)
|
|
- Gain: default (0.5), 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
|
|
- Key-hold acceleration for gain, rain clutter, and wave clutter keys
|
|
|
|
==================================================================
|
|
|
|
LEFT PANEL TEXT — ONE ENTRY PER SCOPE
|
|
|
|
==================================================================
|
|
|
|
Note: Each left panel renders its description text followed immediately by its
|
|
control table. Every panel also states the next scope name so the visitor knows
|
|
what pressing s will show. The s / S advance note appears in every panel.
|
|
|
|
------------------------------------------------------------------
|
|
PANEL 1 — EXHIBIT INTRODUCTION
|
|
------------------------------------------------------------------
|
|
|
|
Header (all caps, large):
|
|
WELCOME TO THE MUSEUM VINTAGE RADAR EXHIBIT
|
|
|
|
Body:
|
|
Welcome! This exhibit lets you experience how radar worked from the 1940s
|
|
through the 1960s — technology that changed the course of World War 2 and
|
|
shaped modern aviation and maritime safety.
|
|
|
|
Radar works by sending out short bursts of radio energy and listening for
|
|
the echo that bounces back from ships, aircraft, and terrain. By measuring
|
|
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.
|
|
|
|
This exhibit features six 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
|
|
automatic 120-second advance. Press S (shift+s) to go back.
|
|
Pressing any key or control resets the 120-second timer.
|
|
|
|
Next: Marine A-Scope →
|
|
|
|
┌─────┬───────────────────────┐
|
|
│ KEY │ FUNCTION │
|
|
├─────┼───────────────────────┤
|
|
│ s │ Next display │
|
|
│ S │ Previous display │
|
|
└─────┴───────────────────────┘
|
|
|
|
------------------------------------------------------------------
|
|
PANEL 2 — MARINE A-SCOPE
|
|
------------------------------------------------------------------
|
|
|
|
The A-Scope was one of the earliest radar displays, used aboard ships and
|
|
in coastal stations in the 1950s. Unlike the circular display you may have
|
|
seen in movies, the A-Scope sweeps left to right: distance (range) runs
|
|
along the bottom axis, and the height of each spike shows how strong the
|
|
echo is from that direction.
|
|
|
|
To look in a different direction, the operator physically rotates the
|
|
antenna by hand. Use c and v to rotate the antenna on this display.
|
|
|
|
The green glow is the P1 phosphor coating on the inside of the cathode ray
|
|
tube. In a real radar room this was often the only light in the space.
|
|
|
|
The glass panel in front of the screen is the graticule — an etched,
|
|
back-lit calibration scale for measuring range. When you change the maximum
|
|
range setting, watch the operator swap the graticule panel by hand — just
|
|
as it was done in the period.
|
|
|
|
Location: Bellingham Bay, WA — a fictional 100-foot mid-bay platform.
|
|
|
|
Press s to advance. Press S to go back. Auto-advance in 120 seconds.
|
|
Any key press resets the timer. Next: Chain Home A-Scope →
|
|
|
|
┌──────┬──────────────────────────────┐
|
|
│ KEY │ FUNCTION │
|
|
├──────┼──────────────────────────────┤
|
|
│ s/S │ Next / previous scope │
|
|
│ c/v │ Bearing clockwise / CCW │
|
|
│ u/d │ Max range up / down (2,4,6) │
|
|
│ 1/2 │ Gain increase / decrease │
|
|
│ 3/4 │ Rain filter increase / dec │
|
|
│ 5/6 │ Wave filter increase / dec │
|
|
└──────┴──────────────────────────────┘
|
|
|
|
------------------------------------------------------------------
|
|
PANEL 3 — CHAIN HOME A-SCOPE
|
|
------------------------------------------------------------------
|
|
|
|
Chain Home was Britain's early warning radar network, built in the late
|
|
1930s and critical during the Battle of Britain (1940). Instead of a
|
|
rotating dish, it used a fixed array of tall transmit towers that flooded
|
|
the sky over the English Channel with radio energy — a technique called
|
|
floodlighting. Aircraft crossing the Channel reflected this energy back
|
|
to separate receive antennas, sometimes at ranges up to 100 miles.
|
|
|
|
FINDING DIRECTION — THE GONIOMETER
|
|
Because there was no rotating dish, finding the bearing and altitude of a
|
|
target required a technique called nulling. A device called a goniometer
|
|
electronically combined signals from several receive antennas. The operator
|
|
slowly turned the goniometer dial while watching the screen. In most
|
|
positions the signal was strong. But at one precise setting the signal
|
|
suddenly disappeared — this was the null. When nulled, the goniometer was
|
|
pointing directly at the aircraft. Think of it like tuning a radio: you
|
|
search for the silent spot between two stations. Press [ to switch the
|
|
goniometer between bearing (horizontal) and elevation (vertical) modes.
|
|
Use keys 9 and 0 to tune — turn slowly, the null appears suddenly.
|
|
|
|
CALIBRATOR PIPS
|
|
Early electronics drifted, stretching or compressing the range scale.
|
|
The crystal calibrator injects tiny spikes at exact 10-mile intervals.
|
|
Use n to shrink and m to stretch the trace until the pips line up with
|
|
the 10-mile marks on the glass graticule.
|
|
|
|
This display is set at the Chain Home station at Poling, East Sussex,
|
|
facing the English Channel. All targets are simulated German aircraft.
|
|
|
|
Press s to advance. Press S to go back. Auto-advance in 120 seconds.
|
|
Any key press resets the timer. Next: Marine PPI →
|
|
|
|
┌──────┬─────────────────────────────────┐
|
|
│ KEY │ FUNCTION │
|
|
├──────┼─────────────────────────────────┤
|
|
│ s/S │ Next / previous scope │
|
|
│ [ │ Goniometer mode: bearing / elev │
|
|
│ 9/0 │ Goniometer tune left / right │
|
|
│ . │ Toggle PRF: 25 Hz / 12.5 Hz │
|
|
│ n/m │ Calibrator shrink / stretch │
|
|
│ 1/2 │ Gain increase / decrease │
|
|
│ 3/4 │ Rain filter increase / dec │
|
|
│ 5/6 │ Wave filter increase / dec │
|
|
└──────┴─────────────────────────────────┘
|
|
|
|
------------------------------------------------------------------
|
|
PANEL 4 — MARINE PPI SCOPE
|
|
------------------------------------------------------------------
|
|
|
|
The PPI (Plan Position Indicator) became the standard radar display for
|
|
ships from the late 1950s onward. The antenna rotates clockwise and the
|
|
sweep line rotates with it, painting a map of everything within range.
|
|
Targets glow bright blue the instant the sweep passes over them, then
|
|
fade through green to yellow before the sweep returns — this is the P7
|
|
phosphor persistence that keeps the picture visible between sweeps.
|
|
|
|
The dotted range rings give distance reference. The incandescent bearing
|
|
scale shows True direction (0 = North, clockwise to 359).
|
|
|
|
The yellow overlay is a mechanical cursor — a plastic ring and crosshair
|
|
mounted in front of the screen. Use the cursor keys to position it over a
|
|
target; range and bearing read out below the scope.
|
|
|
|
Location: Bellingham Bay, WA — a fictional 100-foot mid-bay platform.
|
|
Targets: AIS-equipped vessels and simulated traffic.
|
|
|
|
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 (2, 4, 6 mi) │
|
|
│ r/l │ Cursor bearing right / left │
|
|
│ t/y │ Cursor range increase / decrease │
|
|
│ k/j │ Antenna offset right / left │
|
|
│ │ (boat heading correction — zero │
|
|
│ │ means antenna faces True North) │
|
|
│ 1/2 │ Gain increase / decrease │
|
|
│ 3/4 │ Rain filter increase / decrease │
|
|
│ 5/6 │ Wave filter increase / decrease │
|
|
└──────┴────────────────────────────────────┘
|
|
|
|
------------------------------------------------------------------
|
|
PANEL 5 — AIR TRAFFIC CONTROL PPI SCOPE
|
|
------------------------------------------------------------------
|
|
|
|
This is the Airport Surveillance Radar (ASR) display used by air traffic
|
|
controllers at regional airports in the 1960s. It works on the same
|
|
principle as the marine PPI but covers a larger area (up to 20 miles) and
|
|
is optimised for tracking aircraft rather than ships. The S-Band frequency
|
|
(3 GHz) gives a good balance of range, resolution, and resistance to
|
|
weather clutter for airspace surveillance.
|
|
|
|
Controllers used this display to sequence arriving and departing aircraft,
|
|
identify potential conflicts, and provide navigation guidance to pilots
|
|
flying in low visibility conditions.
|
|
|
|
Location: Bellingham International Airport (BLI), dedicated radar tower.
|
|
Targets: ADS-B equipped aircraft and simulated traffic.
|
|
|
|
Press s to advance. Press S to go back. Auto-advance in 120 seconds.
|
|
Any key press resets the timer. Next: Precision Approach Radar →
|
|
|
|
┌──────┬──────────────────────────────────────────┐
|
|
│ KEY │ FUNCTION │
|
|
├──────┼──────────────────────────────────────────┤
|
|
│ s/S │ Next / previous scope │
|
|
│ u/d │ Max range up / down (5, 10, 15, 20 mi) │
|
|
│ r/l │ Cursor bearing right / left │
|
|
│ t/y │ Cursor range increase / decrease │
|
|
│ k/j │ Antenna offset right / left │
|
|
│ 1/2 │ Gain increase / decrease │
|
|
│ 3/4 │ Rain filter increase / decrease │
|
|
└──────┴──────────────────────────────────────────┘
|
|
|
|
------------------------------------------------------------------
|
|
PANEL 6 — PRECISION APPROACH RADAR (PAR)
|
|
------------------------------------------------------------------
|
|
|
|
The Precision Approach Radar was developed during World War 2 and refined
|
|
through the 1950s. It gives a controller a precise picture of exactly where
|
|
an aircraft is on its final approach to the runway — both its left-right
|
|
position and its altitude.
|
|
|
|
Unlike instrument landing systems that require special equipment on the
|
|
aircraft, PAR needed nothing from the pilot's plane. The controller watched
|
|
the display and talked the pilot down over the radio: "You are slightly
|
|
right of centerline, begin correcting left. You are above the glide path,
|
|
begin a slightly steeper descent." This made PAR invaluable when a plane's
|
|
own instruments failed or when visibility dropped to near zero in heavy fog.
|
|
|
|
TOP DISPLAY — AZIMUTH (left-right)
|
|
Shows whether the aircraft is left or right of the runway centerline.
|
|
The centerline runs horizontally through the middle of the display.
|
|
|
|
BOTTOM DISPLAY — ELEVATION (up-down)
|
|
Shows whether the aircraft is above or below the correct glide slope.
|
|
The ideal descent path runs through the center of the display.
|
|
|
|
Both displays expand the inner 5 miles to 70% of the screen width —
|
|
giving maximum precision during the critical final approach phase.
|
|
|
|
Location: South end of Runway 16/34, Bellingham Airport (BLI).
|
|
Active runway: 34 (aircraft landing northbound). All traffic is simulated.
|
|
|
|
Press s to advance. Press S to go back. Auto-advance in 120 seconds.
|
|
Any key press resets the timer. Next: Exhibit Introduction →
|
|
|
|
┌──────┬──────────────────────────────┐
|
|
│ KEY │ FUNCTION │
|
|
├──────┼──────────────────────────────┤
|
|
│ s/S │ Next / previous scope │
|
|
│ 1/2 │ Gain increase / decrease │
|
|
│ 3/4 │ Rain filter increase / dec │
|
|
└──────┴──────────────────────────────┘
|