make shure that all changes were reflected in the .md file
This commit is contained in:
@@ -167,3 +167,41 @@ struct target_data_to_thread_1_structure {
|
|||||||
uint32_t mmsi; // AIS unique identifier; ICAO hex address 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.
|
||||||
|
|
||||||
|
|||||||
@@ -69,3 +69,57 @@ field:
|
|||||||
instructs the user to use the 1 and 2 keyboard keys to select the radar. The 1 key
|
instructs the user to use the 1 and 2 keyboard keys to select the radar. The 1 key
|
||||||
steps forward in a circle and the 2 key steps backward and the enter key makes the
|
steps forward in a circle and the 2 key steps backward and the enter key makes the
|
||||||
selection
|
selection
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
CURRENT IMPLEMENTATION STATUS
|
||||||
|
|
||||||
|
This spec covers two related but distinct pieces of the 02_text_description component:
|
||||||
|
|
||||||
|
A. Text renderer engine
|
||||||
|
Files: include/02_text_description.h, src/02_text_description.cpp
|
||||||
|
Status: COMPLETE
|
||||||
|
|
||||||
|
Implements the TextRenderer class using FreeType. Loads printable ASCII glyphs
|
||||||
|
(codes 32-126) from a TTF font into individual GL_RED textures and renders them
|
||||||
|
as textured quads into whichever viewport is currently active.
|
||||||
|
|
||||||
|
Public methods:
|
||||||
|
initialize_shaders() — compiles/links shaders/02_text_description_{vert,frag}.glsl
|
||||||
|
initialize_font(path, size) — loads a TTF font at a given pixel height
|
||||||
|
render_text() — renders a string at a viewport-local pixel coordinate
|
||||||
|
render_text_wrapped() — renders with automatic word-wrapping at a max pixel width
|
||||||
|
get_text_width() — returns the pixel width of a string at a given scale
|
||||||
|
set_projection(w, h) — sets the orthographic projection for a viewport
|
||||||
|
cleanup() — releases all GL resources and glyph textures
|
||||||
|
|
||||||
|
Two global instances are defined in src/02_text_description.cpp and declared
|
||||||
|
extern in the header:
|
||||||
|
g_text_renderer — loaded at FONT_SIZE_NORMAL (body text, controls, status bar)
|
||||||
|
g_text_renderer_large — loaded at FONT_SIZE_TITLE (panel titles, scope headings)
|
||||||
|
|
||||||
|
Font path and sizes are defined in include/settings.h:
|
||||||
|
FONT_PATH "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
|
||||||
|
FONT_SIZE_NORMAL 18 px
|
||||||
|
FONT_SIZE_TITLE 26 px
|
||||||
|
|
||||||
|
B. Left-panel text content for each radar
|
||||||
|
File: src/01_classes.cpp (render_left_panel() methods in each radar subclass)
|
||||||
|
Status: STUB — text content implemented; actual scope rendering is not yet done.
|
||||||
|
|
||||||
|
Each radar subclass in 01_classes renders:
|
||||||
|
- Radar title (large renderer, white)
|
||||||
|
- Location sub-header (small scale, white)
|
||||||
|
- 3-4 lines of description text (white)
|
||||||
|
- "--- CONTROLS ---" header (red) followed by per-control entries
|
||||||
|
(label in red, keystroke(s) in pink, on the same line)
|
||||||
|
- "1 - Return to Radar Selection" (yellow)
|
||||||
|
|
||||||
|
The intro scene (item 5 above) is rendered by render_intro_left_panel() in
|
||||||
|
src/main.cpp, which shows a welcome paragraph on the left panel and the
|
||||||
|
radar selection list centred in the scope viewport.
|
||||||
|
|
||||||
|
Status bar content for each radar is rendered by render_status_bar() in
|
||||||
|
src/01_classes.cpp, displaying current uniform values (intensity, sensitivity,
|
||||||
|
STC sensitivity/range, and radar-specific values such as max range, cursor
|
||||||
|
positions, radiogoniometer, or antenna bearing) in yellow.
|
||||||
|
|||||||
@@ -33,3 +33,65 @@ The following is suggested.
|
|||||||
5. Run in a loop where every 30th of a second, update the selected radar.
|
5. Run in a loop where every 30th of a second, update the selected radar.
|
||||||
|
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
|
CURRENT IMPLEMENTATION STATUS
|
||||||
|
|
||||||
|
File: src/main.cpp
|
||||||
|
Status: COMPLETE (stub phase)
|
||||||
|
|
||||||
|
The five-step flow described above is fully implemented in main():
|
||||||
|
|
||||||
|
Step 1 — parse_args()
|
||||||
|
Parses argv[] for radar names (chain_home, marine_ascope, marine_traffic,
|
||||||
|
police_boat). Sets radar_management[].available for each named radar.
|
||||||
|
With no arguments, all radars are made available.
|
||||||
|
|
||||||
|
STUB NOTE: The current build unconditionally sets operatable=1 for all four
|
||||||
|
radars before checking availability. When real radar components are built,
|
||||||
|
only the ones that are fully implemented should have operatable set to 1.
|
||||||
|
The check "available only if operatable" already works correctly in the code;
|
||||||
|
only the stub's operatable override needs to be updated.
|
||||||
|
|
||||||
|
Step 2 — GLFW / GLAD / OpenGL initialization
|
||||||
|
Creates a 1920x1080 window (WINDOW_WIDTH x WINDOW_HEIGHT from settings.h),
|
||||||
|
initialises GLAD, enables GL_DEBUG_OUTPUT (controlled by ENABLE_GL_DEBUG_OUTPUT
|
||||||
|
in settings.h), and sets global GL state (blending, no depth test).
|
||||||
|
|
||||||
|
Step 3 — Intro / selection screen
|
||||||
|
Renders the welcome text on the left panel (render_intro_left_panel()) and
|
||||||
|
the radar selection list centred in the scope viewport (render_radar_list()).
|
||||||
|
The status bar shows keyboard instructions (render_selection_status_bar()).
|
||||||
|
|
||||||
|
Step 4 — Selection loop
|
||||||
|
The GLFW key callback (key_callback) handles:
|
||||||
|
- Key 1: step selection forward
|
||||||
|
- Key 2: step selection backward
|
||||||
|
- ENTER: activate the highlighted radar; call reset_radar_controls()
|
||||||
|
- ESC: close the window
|
||||||
|
If exactly one radar is available, the application auto-activates it after
|
||||||
|
5 seconds (shows the selection screen during the countdown; breaks early
|
||||||
|
if ENTER is pressed).
|
||||||
|
|
||||||
|
Step 5 — Main render loop (~30 Hz)
|
||||||
|
Uses std::chrono::steady_clock to target a 1/30 s frame period.
|
||||||
|
Each frame:
|
||||||
|
- Polls GLFW events
|
||||||
|
- If SELECTION state: calls render_selection_screen()
|
||||||
|
- If OPERATING state: calls render_operating_screen(), which delegates
|
||||||
|
to g_active_radar->render_left_panel(), render_status_bar(),
|
||||||
|
render_scope() through the RadarBase virtual interface.
|
||||||
|
|
||||||
|
Additional features implemented:
|
||||||
|
- GL debug callback (gl_debug_callback) enabled via ENABLE_GL_DEBUG_OUTPUT
|
||||||
|
- Debug border-box renderer (draw_border_box) enabled via DEBUG_DRAW_WINDOW_BORDERS
|
||||||
|
in settings.h — draws white outlines around each panel for layout verification
|
||||||
|
- reset_radar_controls(): resets uniform_max_range, uniform_range_cursor,
|
||||||
|
uniform_bearing_cursor to defaults for the selected radar when it is activated
|
||||||
|
- Keyboard controls for all scope uniforms (intensity, sensitivity, STC, noise
|
||||||
|
filter, radiogoniometer, max range, range cursor, bearing cursor, antenna
|
||||||
|
rotation) are implemented in key_callback(); the controls are appropriately
|
||||||
|
restricted by radar type (e.g. noise filter only for PPI scopes)
|
||||||
|
|
||||||
|
Application state is tracked by AppState enum (SELECTION, OPERATING) in main.cpp.
|
||||||
|
The active radar object is pointed to by g_active_radar (a RadarBase*).
|
||||||
|
current_radar (global in global_data.cpp) holds the RADAR_* index of the active radar.
|
||||||
|
|||||||
101
README.md
101
README.md
@@ -1,3 +1,100 @@
|
|||||||
# radar-simulation
|
# radar-simulator
|
||||||
|
|
||||||
Source code for possible radar exhibit
|
Museum exhibit software simulating 1940s–1960s vintage radar systems.
|
||||||
|
|
||||||
|
## Project overview
|
||||||
|
|
||||||
|
This application runs as a full-screen interactive exhibit on a Geekom A8 Max
|
||||||
|
(AMD Ryzen 9 8945HS, Radeon 780M GPU, Ubuntu 25.10). Visitors can explore four
|
||||||
|
historical radar types by cycling through a selection screen and interacting with
|
||||||
|
keyboard controls.
|
||||||
|
|
||||||
|
**Four radar displays:**
|
||||||
|
|
||||||
|
| # | Name | Type | Location |
|
||||||
|
|---|------|------|----------|
|
||||||
|
| 1 | Chain Home | A-scope (WWII, 1940s) | RAF Ventnor, Isle of Wight |
|
||||||
|
| 2 | Marine A-Scope | A-scope (pre-PPI, manually steered dish) | Community Boating Center, Bellingham Bay WA |
|
||||||
|
| 3 | Marine Traffic Control | PPI scope | Center of Bellingham Bay WA |
|
||||||
|
| 4 | Police Boat | PPI scope (moving platform) | Taylor Dock / Boulevard Park, Bellingham Bay WA |
|
||||||
|
|
||||||
|
## Tech stack
|
||||||
|
|
||||||
|
- **Language:** C++20
|
||||||
|
- **Graphics:** OpenGL 4.3 Core, GLFW, GLAD
|
||||||
|
- **Text:** FreeType 2
|
||||||
|
- **Maps/LIDAR:** GDAL (libgdal-dev)
|
||||||
|
- **Database:** PostgreSQL (database: radar, user: radar)
|
||||||
|
- **Build:** CMake
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p build && cd build
|
||||||
|
cmake ..
|
||||||
|
make -j$(nproc)
|
||||||
|
```
|
||||||
|
|
||||||
|
The executable is `build/radar_simulator`.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# All four radars available
|
||||||
|
./radar_simulator
|
||||||
|
|
||||||
|
# Specific radars only
|
||||||
|
./radar_simulator chain_home marine_ascope
|
||||||
|
./radar_simulator marine_traffic police_boat
|
||||||
|
```
|
||||||
|
|
||||||
|
If only one radar is specified, it auto-activates after 5 seconds.
|
||||||
|
|
||||||
|
## Screen layout
|
||||||
|
|
||||||
|
The window is 1920×1080 and is divided into three areas:
|
||||||
|
|
||||||
|
- **Left text panel** (upper-left, 500 px wide): radar description and keyboard controls
|
||||||
|
- **Status bar** (lower-left, 500×250 px): current control values in yellow
|
||||||
|
- **Scope** (right side, square, full height): radar display
|
||||||
|
|
||||||
|
## Keyboard controls
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| **1** | Step forward in radar selection (or return to selection when operating) |
|
||||||
|
| **2** | Step backward in radar selection |
|
||||||
|
| **ENTER** | Activate selected radar |
|
||||||
|
| **ESC** | Exit |
|
||||||
|
| **3 / 4** | Intensity lower / higher |
|
||||||
|
| **5 / 6** | Receiver sensitivity lower / higher |
|
||||||
|
| **Q / W** | STC sensitivity lower / higher |
|
||||||
|
| **E / R** | STC range lower / higher |
|
||||||
|
| **T / Y** | Rain noise filter lower / higher (PPI scopes only) |
|
||||||
|
| **U / I** | Radiogoniometer left / right (Chain Home only) |
|
||||||
|
| **O / P** | Max range step down / up (all except Chain Home) |
|
||||||
|
| **A / S** | Range cursor lower / higher (PPI scopes only) |
|
||||||
|
| **D / F** | Bearing cursor CCW / CW (PPI scopes only) |
|
||||||
|
| **G / H** | Antenna rotation CCW / CW (Marine A-Scope only) |
|
||||||
|
|
||||||
|
## Component .md files
|
||||||
|
|
||||||
|
Each component has a specification and status file:
|
||||||
|
|
||||||
|
- `01_classes.md` — class hierarchy (RadarBase + 4 subclasses; stubs built)
|
||||||
|
- `02_text_description.md` — text renderer and left-panel text content (complete)
|
||||||
|
- `03_setup_and_radar_selection.md` — startup, selection loop, main render loop (complete)
|
||||||
|
|
||||||
|
## Current build state
|
||||||
|
|
||||||
|
The initialization and radar-management infrastructure is complete:
|
||||||
|
|
||||||
|
- Four stub radar subclasses render description text, keyboard control lists,
|
||||||
|
and current control values in the status bar.
|
||||||
|
- The scope area shows the radar name with a `[stub]` label — no actual radar
|
||||||
|
simulation is drawn yet.
|
||||||
|
- All keyboard controls update CPU globals; uniforms will be pushed to shaders
|
||||||
|
as each scope component is built.
|
||||||
|
|
||||||
|
Real radar scope rendering (sweep, targets, graticule, range rings/ticks,
|
||||||
|
terrain, P7 phosphor persistence) will be added one radar at a time.
|
||||||
|
|||||||
Reference in New Issue
Block a user