340 lines
13 KiB
Markdown
340 lines
13 KiB
Markdown
Introduction:
|
|
|
|
This is a project for a museum to demonstrate a simulation of a 1950's to 1960's
|
|
vintage marine radar.
|
|
|
|
There will be two scopes. An early A Scope and a PPI scope.
|
|
|
|
The PPI scope will take up the entire right hand side of the display
|
|
(1 inch margins on top,bottom, and right hand side) and the A Scope will
|
|
be smaller, located in the center of the left hand
|
|
side of the display near the left margin.
|
|
|
|
Please impliment 1 inch margins around both scopes. I am getting them cut off
|
|
|
|
Display should be whole screen. An escape, possibly with the escape key
|
|
needs to be provided to exit the program and go back to shell.
|
|
|
|
We have to simulate everything as we are not allowed to have an actual radar at
|
|
our location because we are not on the water.
|
|
|
|
The proposed location of the radar antenna is at the dock of the Community
|
|
boating center in Bellingham, Washington.
|
|
Location is 48.72° N Latitude and -122.51° W Longitude
|
|
|
|
Zero degrees on Radar Scope is True North.
|
|
|
|
The proposed maximum range is 15 miles.
|
|
Selectable ranges should be 2, 5, 10, and 15 miles
|
|
|
|
The project will be implemented on a Geekom A8 Max
|
|
with AMD AI chip R9-8945HS with 32 GB ram
|
|
|
|
The communications for the SDR radios will be handled by
|
|
Raspberry Pi 5
|
|
|
|
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.
|
|
|
|
Here is the directory structure with files already installed:
|
|
|
|
./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
|
|
|
|
The following classes would be needed:
|
|
|
|
1. Operation of display; set up of display and any operation
|
|
that feeds data to the display. This should be in the main
|
|
context. It cannot wait for data or anything. It would
|
|
require a mutex for each user sending data.
|
|
|
|
2. Operator controls. These feed to control data input to the
|
|
display class using appropriate mutexes. This would also
|
|
include updating graticules for changing range on the PPI
|
|
scope and changing range and bearing for the A scope
|
|
|
|
3. Radar targets from receivers AIS, ADS-B, and UAT
|
|
|
|
4. Simulated (fake) radar targets
|
|
|
|
5. Any code needed to process topographical data for the shoreline
|
|
|
|
Each of these can run as its own thread, but they all have to use
|
|
mutexes in order to send anything to the display. Perhaps they could
|
|
be polled by a dispatcher that will tell each one its turn to send
|
|
data to the display.
|
|
The simulator will use ads-b and ais and uat received on airspy
|
|
SDR radios communicating with Raspberry Pi 5 single board computers
|
|
running linux.
|
|
|
|
I plan to have a variety of phony targets simulated in addition to
|
|
those received on uat, ads-b, and ais.
|
|
|
|
Note that directions shall be true, not magnetic
|
|
|
|
Note that shoreline data is from NOAA maps
|
|
(NOAA provides free ENC (Electronic Nautical Chart) data in S-57 format covering
|
|
Bellingham Bay and surrounding waters.)
|
|
|
|
I prefer to have separate shader sets for each major function to facilitate
|
|
troubleshooting
|
|
Major functions:
|
|
1. A scope radar
|
|
2. A scope graticule operation
|
|
3. PPI scope active targets
|
|
4. PPI scope graticule Bearing marks
|
|
5. PPI scope graticule range rings
|
|
6. PPI scope handling of the shoreline using some sort of topographical map
|
|
7. PPI scope persistence phosphor
|
|
8. Rain scatter
|
|
9. Wave scatter
|
|
|
|
Display colors:
|
|
1. A Scope is P1 (same as oscilloscope)
|
|
2. A Scope graticule is incandescent color
|
|
3. PPI scope active targets including scatters, graticule range rings, shoreline,
|
|
all p7 phosphor (active blue)
|
|
4. All persistence (also p7 greenish yellow persistence) for PPI scope active targets including
|
|
scatters, graticule range rings, shoreline
|
|
5. PPI scope bearing ring and ticks is incandescent color.
|
|
|
|
Coordinates:
|
|
|
|
Please note that all target information furnished to the
|
|
display be in local coordinates.
|
|
Local coordinates have center (0,0) at location of radar
|
|
base at the community boating center. Maximum coordinate size
|
|
is 15 miles from the center.
|
|
|
|
Signal strength:
|
|
|
|
Need to have following fixed signal strength:
|
|
Size is part of data for some targets (based on AIS and ADS-B
|
|
data. Use size of boat (usually in feet) expressed in length
|
|
and width. Use those values in relation of the heading if known.
|
|
Unknown heading shall assume size is between length and width.
|
|
1. large ship (over 100 feet) would be bright and blooming slightly
|
|
2. yachts ( 50 to 100 feet) feet would be bright but not blooming
|
|
3. sailboats ( 10 to 50 feet) would be medium bright and not blooming
|
|
4. kayaks and rowboats would be dim
|
|
5. May consider fading small boats like kayaks
|
|
and sailboats above 10 miles
|
|
|
|
Details of each feature:
|
|
|
|
A scope:
|
|
1. Displays range, does not rotate. You must use control to set bearing.
|
|
Range is horizontal axis and strength of signal is vertical axis.
|
|
The full range setting is shared with the full range setting
|
|
of the PPI scope
|
|
|
|
2. Graticule is tricky. In the day, the operator would have a stack of
|
|
graticules for each range setting. To fake this out, We could have the
|
|
graticule appear to move up and out and the replacement graticule move
|
|
in and down in place. The operator takes them out from a slot above the
|
|
scope and inserts the replacement through the same slot. All these graticules
|
|
are lighted with incandescent colors. Graticule should have vertical lines
|
|
for each range and a horizontal line at the bottom. Left of the screen you
|
|
have the words "SIGNAL STRENGTH" and bottom of the screen you
|
|
have the words "RANGE"
|
|
Movement of graticles would be a bit slow and erratic (maybe about 10 seconds)
|
|
|
|
Note on screen update vs pulse repetition frequency. We need to be careful
|
|
since we have no control of the display update frequency and need
|
|
to do whatever is needed to reduce aliasing or flickering
|
|
|
|
PPI Scope active targets
|
|
1. Active boats/planes; brightness determined by size as noted above
|
|
2. Blue
|
|
|
|
PPI Scope range rings
|
|
1. blue (dim)
|
|
2. These change if operator changes max range
|
|
|
|
PPI Scope cursor (In the day, this was a moveable plastic
|
|
overlay on scope, back lit by incandescent lamp. We need to
|
|
simulate this. Movement of this is via the Range and Bearing controls
|
|
cursor consists of flat line for range and box for bearing.
|
|
|
|
PPI Scope Bearing ticks and ring
|
|
|
|
1. Tick mark every degree
|
|
2. 0 degrees is top of display
|
|
3. Degrees count clockwise.
|
|
4. Use text for every 10 degrees, but text on outside of ring.
|
|
5. Have ring around tick marks
|
|
6. 2nd ring around the text marks
|
|
|
|
Controls:
|
|
|
|
Here are the controls that I am proposing
|
|
|
|
1. Intensity
|
|
2. Focus
|
|
3. Astigmatism
|
|
4. Range selection (for both a scope and ppi scope) for maximum range.
|
|
Changes range rings on ppi and changes graticule selection on A scope
|
|
5. Sensitivity
|
|
6. Sensitivity time control STC / sea clutter
|
|
7. Bearing A scope: which in the old days uses a servo motor to
|
|
rotate the antenna. Feedback was with mechanical numbers. I am proposing
|
|
to use a small USB digital display; Size should be no larger
|
|
than 1 by 3 inches. PPI Scope: This control can also be for the ppi cursor.
|
|
8. Magnetron tune
|
|
9. FTC / Rain Clutter
|
|
10. Off-centering (two controls; one for each axis)
|
|
11. Graticule brilliance
|
|
12. Reset (in case kids really mess things up)
|
|
13. Pulse length selection (short pulse for better range resolution,
|
|
long pulse for better sensitivity at distance; operator selectable)
|
|
14. Pulse repetition frequency
|
|
|
|
|
|
(Please suggest other controls I may have missed.)
|
|
|
|
Now, for controls, the tentative approach is to use encoders (that do not
|
|
have end stops so they cannot be broken by visitors at the museum) I will
|
|
need help on how to implement them. I am guessing a few Raspberry Pis to
|
|
handle the encoders. I am thinking of encoders that have one common terminal and
|
|
a clockwise pulse terminal and a counter clockwise pulse terminal.
|
|
|
|
Let's do this like this. The control handling will be a different class and run
|
|
as a separate thread from the display. Each control function will have a parameter
|
|
for how many pulses received and in what direction. That would be permanent.
|
|
|
|
Temporary code necessary for changing control selection and value via the
|
|
keyboard until I get the necessary hardware for the controls.
|
|
|
|
Also please note that this will need to be flexible as encoders can
|
|
be expensive, especially robust ones that kids cannot break.
|
|
|
|
Text Rendering:
|
|
|
|
Use freetype fonts libfreetype6:amd64
|
|
|
|
Communication:
|
|
|
|
All I know now is that I plan to use a combination of Raspberry Pi 5 and an Airspy
|
|
SDR for each of ais, ads-b, and uat. UAT (978 MHz) and ADS-B (1090 MHz) are different
|
|
frequencies and require separate SDRs, but a single Raspberry Pi 5 is powerful enough
|
|
to run both dump1090 (ADS-B) and dump978 (UAT) simultaneously with two SDRs on its USB
|
|
ports. AIS requires a separate Raspberry Pi with its own SDR tuned to VHF 161/162 MHz.
|
|
|
|
Each Raspberry Pi will act as a server fielding requests from this program.
|
|
|
|
Each Raspberry Pi is a separate instantiation of a class called RemoteTargetSource.
|
|
Those classes will use a common target data structure:
|
|
|
|
1. double longitude
|
|
2. double latitude
|
|
3. std::string vessel_name
|
|
4. std::string registration
|
|
5. float length_meters
|
|
6. float beam_meters
|
|
7. int vessel_type (AIS type code; aircraft type for ADS-B/UAT)
|
|
8. uint32_t mmsi (AIS unique identifier; ICAO hex address for aircraft)
|
|
9. float course (course over ground, degrees based on true north)
|
|
10. float speed (speed over ground, knots)
|
|
11. time_t timestamp (time of last fix; used to age out stale targets)
|
|
12. float altitude (meters; 0 for surface vessels)
|
|
13. TargetType type (enum: vessel, aircraft, etc.)
|
|
|
|
The RPi communication thread blocks on a socket read until data arrives, then
|
|
writes to a shared target queue protected by a mutex and signals a condition
|
|
variable. The main application consumes from that queue.
|
|
Prefer TCP.
|
|
|
|
The Raspberry Pi code will live in a separate git repository with its own CLAUDE.md
|
|
and its own CMakeLists.txt, since it targets a different architecture (ARM) and has
|
|
a different toolchain and dependencies. Do not mix it into this repository hierarchy
|
|
|
|
|
|
NEW suggestions =======
|
|
|
|
1. The a scope bearing must not follow the rotating sweep on the ppi scope. The A scope
|
|
during the time they were popular before the ppi scope used a manual control to set the
|
|
bearing. The bearing setting uses a servo motor to rotate the dish antenna to the bearing
|
|
desired by the operator. We need to simulate that by not a scope not to follow the bearing
|
|
shown on the ppi scope. This bearing must be controled by control 7.
|
|
|
|
2. Add two more controls; Range for ppi scope cursor and Bearing for the PPI scope cursor
|
|
|
|
3. Pleae add a small window under the A scope to show the setting of the A scope bearnig.
|
|
|
|
4. Temporary: Have the bearing for a scope set to the location of one of the current targets.
|
|
|
|
5. Have the cursor on the ppi scope follow one of the targets and not move around.
|
|
|
|
New update 1
|
|
|
|
1. I notice that the height of the pulse on the A scope seems to be going up and down in sync
|
|
with the ppi scope rotating.
|
|
2. Add a range figure in the small box under the A scope
|
|
3. Have the a scope graticules change a little faster
|
|
4. it appears that the cursor range ring sometimes appears outside the boundary of the scope
|
|
|
|
New update 2
|
|
1. Add small text window above that a scope that says "Operator Manually Changing Range Graticule"
|
|
This appears only when the graticule is changing
|
|
|
|
|
|
NOTE on my plan for coding
|
|
|
|
1. I want to test and debug the code feature by feature.
|
|
2. I do not want any code created on features until I am ready.
|
|
|
|
Order of testing features.
|
|
|
|
1. General initialization and set up basic boundaries of the two scopes
|
|
on the screen. No features on each scope yet.
|
|
2. Edge graticule on ppi scope (Bearing ticks and numbers)
|
|
3. Replaceable graticule on A Scope. Have it update for each different range
|
|
and hold for 5 seconds for each range
|
|
4. PPI scope range rings; both active display and persistence display - test
|
|
for each range settings; hold for 5 seconds each
|
|
5. PPI scope active target operation, as well as persistance. Create
|
|
four fake targets: one small, one large and two very large with
|
|
1. target 5 miles north of radar, 100 feet long heding 1 knot south
|
|
head on, width of target is 20 feet.
|
|
2. target 5 miles south of radar, 20 feet long, 5 feet wide
|
|
headng away at 20 knots
|
|
3. 6 mile east 30 feet long, heading north about 30 knots, full side view to radar
|
|
4. 6 mile west 100 feet long, heading south 5 knots, full side view
|
|
6. PPI scope cursor - test by slowly changing range and bearing
|
|
7. PPI scope weather noise - test by changing noise level slowly
|
|
8. PPI scope waves noise - test by changing noise level slowly
|
|
9. PPI scope handling of shoreline - test by running for a few seconds
|
|
|
|
========================================================
|
|
|
|
Generate code for testiong feature 1,2,3,4,5,6 nly;
|
|
|