Files
modular-radar/01_classes.md

208 lines
11 KiB
Markdown

This components discusses the c++ classes suggested for this project.
======================================================================
The radar class
This pertains to the radars, including controls, shaders, target data, text description,
and status text.
This class shall consist of both a base class and subordinate classes for each radar.
The functions in this class shall be performed in thread 1 as they will directly
interact with the shaders and the keyboard, which are all in thread 1.
Examples of data and functions for this class and it subordinates:
1. Shaders - functions that can be called by the initialization function that will compile,
link, and load the shaders for each radar. The subordinates for each radar would have
the specific shaders that are used for that radar. If a shader is to be used by more than
one radar, that shader should be compiled, linked, and loaded by the base class before the
shader loading functions for each of the subordinate classes' shader loading functions.
Initially, I will have separate shaders for each radar to facilitate debugging and then
(maybe) later, work on combining them.
2. Left hand panel text. Functions that display the description for each radar on the left hand
panel. In addition, the control names and Keyboard Keys shall be displayed at the bottom
of the left hand panel. Please note that in the future, this left hand panel may be moved
to a second physical monitor.
3. Text status panel to be located below the left-hand text panel (bottom of the left
side of the screen, NOT below the scope). The scope takes the full right-side height
with no panel beneath it. The status panel will display the current control settings
and the range and bearing and description of targets that are on or near the bearing
and range cursor. The text status panel shall manage the hit-test. The hit test shall
determine which (if any) targets are either directly the same range and the same
bearing as the cursor or close to it. The closeness shall be determined by a
configuration variable. Since the cursor information as well as the target information
is already in thread 1, this operation shall be performed by the CPU as the CPU will
have all information on the target, including the name and description.
Please note that any text (such as the vessel name and registration) will not be part
of the SSBO target information. It will need to be formed in text blocks that can
be submitted as textures to be inserted into the status text panel at the bottom of
the left side of the screen.
4. Target data. This will handle the target data that is presented by both the simulator
and the raspberry pi data. All that data will be in the format of the
struct target_data_to_thread_1_structure. The expectation is that the target's local
cartesian offsets in meters relative to the radar. Note that this will be different
for each radar and will dynamically change based on the police boat's radar position.
I am expecting that the target data input functions may be common for all target data
will all be the same for all radars and could be handled by the base class.
Note that there will be a difference in handling the target data that is exclusive
for the police boat will be the police boat's location and heading. This affects the
radar display for the police boat. Perhaps I can suggest that the these three values
should be furnished as uniforms to the shaders for the police boat: 1. int police_boat;
1 is police boat and 0 is not, 2. vec2 police_location; in local coordinate space,
and 3. float police_boat heading.
Please note that this is running in thread 1. The data input to this is being
provided by the traffic_cop, which is running on thread 2. The traffic_cop needs
to assert the mutex-target-data before writing any target data to here.
Please note that the target data that is used by the shaders does not include
the target name nor target registration (text fields). The followoing
data structure is to be used:
ssbo_target_information { // This is what is sent to the shaders as SSBO
float target_x; // Pre-converted local Cartesian offset X (meters relative to radar)
float target_y; // Pre-converted local Cartesian offset Y (meters relative to radar)
float length; // Vessel length bounds (meters)
float beam; // Vessel beam bounds (meters)
float course; // Course over ground vector (radians relative to True North)
float altitude; // Target altitude profile (meters = 0 for boats)
float current_reflectivity; // derivied from vessel_type (see table below)
float height_estimate; // derived from vessel_type (see table below)
float noiseglint; // derived from vessel_type (see table below)
int32_t police_boat; // this indicates that the target is for the roaming
// police boat. 1 = police boat
uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft
int type; // target type (0 for boat 1 for aircraft)
};
5. Graticule. This is the same for both chain home and marine-ascope. It
is also the same for marine_traffic and police boat.
6. North indicator for the police boat. Not used anywhere else. It is a second
graticule that rotates when the police boat changes direction.
7. Range Rings and Distance Calibration. For a-scope, small 'ticks' are inserted
by a crystal oscillator to indicate distances. For a ppi scope, they are rings
generated by the sweep to indicated ranges. I suggest two base class members
that are used by either the chain hoome/marine ascope which use range ticks or the
marine traffic/police boat radar which use range rings.
8. Update. This is run once every 30th of a second. I will call everything on this list
to perform an update with the shaders. The order would be, Target data, graticle,
range rings/range ticks (depending on what radar is being used), police boat north
indicator, left hand panel, and text status penel. Perhaps some of these that
have not changed such as the left panel text may not need to be updated.
===============================================================================
The Keyboard controls class
The keyboard controls class (which runs in thread 1) is activated whenever anyone
presses a key on the keyboard. It's functon is to recognize the keystrokes used
for controls and then set the global CPU variables and the uniforms within the
shaders. It will affect only those variables pertaining to the radar that is currently
being used. Any other keystrokes will be ignored except for key 1, which will return
the system to the radar selection stage
The physical control panel class.
The physical control panel class will be constructed later after hardware selection.
It will run on Thread 6 and needs to assert the mutex-to-pass-controls-to-thread-1
mutex before changing any global variables for controls.
===============================================================================
The Traffic Cop class
This class is for the traffic_cop which accepts data from the simulator or the
raspberry pis. It will change the GPS coordinates to the coordinates for whichever
radar is being used before it sends the radar information to Thread 1. It will need
to assert the mutex-target-data mutext before sending data to thread 1.
The data structure that will be received by the traffic_cop is the following
structure:
struct target_data_structure {
double target_longitude;
double target_latitude;
std::string vessel_name; // will be null for no available name
std::string registration; // will be null for no registration
float length; // in meters
float beam; // in meters
int vessel_type; // AIS type code or aircraft type
uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft
float course; // course over ground, degrees, based on true north
float speed; // speed over ground, knots
float altitude; // meters, but 0 for boats
int type; // type of target; vessel or aircraft; 0 = vessel
int police_boat // 1 is police boat; 0 is not
time_t timestamp;
};
The data structure that is sent by the traffic cop to thread one (the target data in
the radar class):
struct target_data_to_thread_1_structure {
float target_x; // Pre-converted local Cartesian offset X (meters relative to radar)
float target_y; // Pre-converted local Cartesian offset Y (meters relative to radar)
std::string vessel_name; // will be null for no available name
std::string registration; // will be null for no registration
float length; // Vessel length bounds (meters)
float beam; // Vessel beam bounds (meters)
float course; // Course over ground vector (radians relative to True North)
float altitude; // Target altitude profile (meters = 0 for boats)
time_t timestamp; // Data aging tracking identifier
float current_reflectivity; // derived from calculation based on material - is dynamic
float height_estimate; // derived from vessel_type (see table below)
float noiseglint; // derived from vessel_type (see table below)
int32_t police_boat; // this indicates that the target is for the roaming police boat. 1 = police boat
int type; // target type (0 for boat 1 for aircraft)
uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft
};
===============================================================================
CURRENT IMPLEMENTATION STATUS (stub phase)
Files: include/01_classes.h, src/01_classes.cpp
What is built:
RadarBase — abstract base class with three pure virtual methods:
render_left_panel() — renders radar description and keyboard control list
render_scope() — renders scope content (stub: radar name + "stub" label)
render_status_bar() — renders current control uniform values
Four stub subclasses, each overriding all three methods:
ChainHomeRadar (Ventnor, Isle of Wight)
MarineAScopeRadar (Community Boating Center, Bellingham Bay)
MarineTrafficRadar (center of Bellingham Bay)
PoliceboatRadar (Taylor Dock / Boulevard Park, Bellingham Bay)
One global instance of each subclass is declared in 01_classes.h and defined
in 01_classes.cpp: g_chain_home, g_marine_ascope, g_marine_traffic, g_police_boat.
What is NOT yet built (future components):
- Real scope rendering (radar sweep, target blips, graticule, range rings/ticks,
north indicator, P7 persistence layer, land/terrain background)
- Target data ingestion from Traffic Cop
- The Keyboard controls class (keyboard handling currently lives in the
static key_callback() function in src/main.cpp)
- The Traffic Cop class (Thread 2) — not yet started
- The Simulator class (Thread 3) — not yet started
- Per-frame update() method — the 30 Hz render loop in main.cpp calls
render_left_panel(), render_scope(), and render_status_bar() directly
Both target data structures (target_data_structure and
target_data_to_thread_1_structure) are defined in
include/data_structure_and_constants.h and will be used when the
Traffic Cop and Simulator components are built.