first commit
This commit is contained in:
188
CLAUDE.md
Normal file
188
CLAUDE.md
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
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/4.5 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.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
==================================================================
|
||||||
|
Please note that all on-screen text shall be white and fully
|
||||||
|
illuminated and is not subject to phosphor persistance or decay.
|
||||||
|
The exception would be graticule text, which should be incandescent
|
||||||
|
for the bearing marks. Text on the PPI scope range rings shall be blue
|
||||||
|
but fade to yellow green as on p7 phosphor.
|
||||||
|
|
||||||
|
Please note that direction as stated here are True directions.
|
||||||
|
|
||||||
|
Maximum Range is 6 miles for marine type radar
|
||||||
|
Maximum Range is 20 miles for air traffic control radar.
|
||||||
|
|
||||||
|
The proposed location of the marine radar antenna is in the middle of Bellingham
|
||||||
|
Bay on a 100 foot platform.
|
||||||
|
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 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
|
||||||
|
the keyboard until I get physical buttons that are connected to a gpio pin.
|
||||||
|
The selection key should be s (short for scope)
|
||||||
|
|
||||||
|
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 implimented, use k for bearing to right; and
|
||||||
|
j for bearing to left.
|
||||||
|
|
||||||
|
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 completly
|
||||||
|
different radars. Range and bearing for the precision aproach 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 note that the precision approach radar is a future
|
||||||
|
radar that will be described in a later section of the CLAUDE.md file.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
1. A-Scope - (horizontal axis is range; vertical axis is amplitude of
|
||||||
|
return pulse; bearing will be set via a bearing control; current implimentation
|
||||||
|
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 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)
|
||||||
|
shal be: 2,4,6 miles.
|
||||||
|
To change maximum range, use key u for up and d for down. Possible settings are 2,4,6
|
||||||
|
miles
|
||||||
|
|
||||||
|
Max is 2; one interim range at 1
|
||||||
|
Max is 4; one interim range at 2
|
||||||
|
Max is 6; one interim range at 4
|
||||||
|
|
||||||
|
A scope is used only for marine. Other a scope use was for chain home radar, but
|
||||||
|
I don't know if I will include that one. It would be a whole new section and you
|
||||||
|
cannot change the range. It is fixed off the coast of England, facing the Europe
|
||||||
|
continent.
|
||||||
|
|
||||||
|
|
||||||
|
2. PPI Scope - There are two PPI Scopes; one for marine and one for air traffic control.
|
||||||
|
Both 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. Immediatel strike by the electron beam is blue.
|
||||||
|
persistance is green/yellow. Targets, range rings, and range ring labels shall all
|
||||||
|
persiste 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 and 20 miles
|
||||||
|
for the air traffic radar scope. Rings should be 2,4, and 6 miles for marine.
|
||||||
|
Rings should be 5,10,15,20 for the air traffic control radar.
|
||||||
|
The max range settings for both marine and air 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. Likewise for the air traffic control ppi. The possible max range values for
|
||||||
|
the marine radar are 2,4,6 and for the air traffic conrtrol radar are 5,10,15,20
|
||||||
|
miles.
|
||||||
|
|
||||||
|
Marine:
|
||||||
|
Max is 2; one interim range at 1
|
||||||
|
Max is 4; one interim range at 2
|
||||||
|
Max is 6; one interim range at 4
|
||||||
|
|
||||||
|
Air Traffic Control:
|
||||||
|
Max is 5; one interim rainge at 2.5
|
||||||
|
Max is 10; four interim ranges, 2,4,6,
|
||||||
|
Max is 15; three interim ranges 4,8,12
|
||||||
|
Max is 20, three interim ranges 5.10.15
|
||||||
|
|
||||||
|
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 graticle (lit incandescent) for both scopes are the same. There shold
|
||||||
|
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 innter 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 and 5 seconds for the
|
||||||
|
air traffic scope.
|
||||||
|
|
||||||
|
The sweep direction on both scopes is clockwise, which means that the entenna
|
||||||
|
dish rotates clockwise.
|
||||||
|
|
||||||
|
Both scopes each have 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 sewuence 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.
|
||||||
|
|
||||||
|
3. Precision approach (to be defined later)
|
||||||
|
4. Other scope types may be added later.
|
||||||
|
|
||||||
|
[other scopes to be defined later]
|
||||||
|
|
||||||
|
Please analyze and comment. Please do not generate any code file nor shader files.
|
||||||
18
LICENSE
Normal file
18
LICENSE
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 maallyn
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
|
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
||||||
|
following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||||
|
portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||||
|
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||||
|
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# radar-simulation
|
||||||
|
|
||||||
|
Source code for possible radar exhibit
|
||||||
1833
glad/src/glad.c
Executable file
1833
glad/src/glad.c
Executable file
File diff suppressed because it is too large
Load Diff
311
include/KHR/khrplatform.h
Executable file
311
include/KHR/khrplatform.h
Executable file
@@ -0,0 +1,311 @@
|
|||||||
|
#ifndef __khrplatform_h_
|
||||||
|
#define __khrplatform_h_
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
** copy of this software and/or associated documentation files (the
|
||||||
|
** "Materials"), to deal in the Materials without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
** permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included
|
||||||
|
** in all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Khronos platform-specific types and definitions.
|
||||||
|
*
|
||||||
|
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||||
|
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||||
|
* The last semantic modification to khrplatform.h was at commit ID:
|
||||||
|
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||||
|
*
|
||||||
|
* Adopters may modify this file to suit their platform. Adopters are
|
||||||
|
* encouraged to submit platform specific modifications to the Khronos
|
||||||
|
* group so that they can be included in future versions of this file.
|
||||||
|
* Please submit changes by filing pull requests or issues on
|
||||||
|
* the EGL Registry repository linked above.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* See the Implementer's Guidelines for information about where this file
|
||||||
|
* should be located on your system and for more details of its use:
|
||||||
|
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||||
|
*
|
||||||
|
* This file should be included as
|
||||||
|
* #include <KHR/khrplatform.h>
|
||||||
|
* by Khronos client API header files that use its types and defines.
|
||||||
|
*
|
||||||
|
* The types in khrplatform.h should only be used to define API-specific types.
|
||||||
|
*
|
||||||
|
* Types defined in khrplatform.h:
|
||||||
|
* khronos_int8_t signed 8 bit
|
||||||
|
* khronos_uint8_t unsigned 8 bit
|
||||||
|
* khronos_int16_t signed 16 bit
|
||||||
|
* khronos_uint16_t unsigned 16 bit
|
||||||
|
* khronos_int32_t signed 32 bit
|
||||||
|
* khronos_uint32_t unsigned 32 bit
|
||||||
|
* khronos_int64_t signed 64 bit
|
||||||
|
* khronos_uint64_t unsigned 64 bit
|
||||||
|
* khronos_intptr_t signed same number of bits as a pointer
|
||||||
|
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||||
|
* khronos_ssize_t signed size
|
||||||
|
* khronos_usize_t unsigned size
|
||||||
|
* khronos_float_t signed 32 bit floating point
|
||||||
|
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||||
|
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||||
|
* nanoseconds
|
||||||
|
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||||
|
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||||
|
* only be used as a base type when a client API's boolean type is
|
||||||
|
* an enum. Client APIs which use an integer or other type for
|
||||||
|
* booleans cannot use this as the base type for their boolean.
|
||||||
|
*
|
||||||
|
* Tokens defined in khrplatform.h:
|
||||||
|
*
|
||||||
|
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||||
|
*
|
||||||
|
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||||
|
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||||
|
*
|
||||||
|
* Calling convention macros defined in this file:
|
||||||
|
* KHRONOS_APICALL
|
||||||
|
* KHRONOS_APIENTRY
|
||||||
|
* KHRONOS_APIATTRIBUTES
|
||||||
|
*
|
||||||
|
* These may be used in function prototypes as:
|
||||||
|
*
|
||||||
|
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||||
|
* int arg1,
|
||||||
|
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||||
|
# define KHRONOS_STATIC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APICALL
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This precedes the return type of the function in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(KHRONOS_STATIC)
|
||||||
|
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||||
|
* header compatible with static linking. */
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
# define KHRONOS_APICALL __declspec(dllimport)
|
||||||
|
#elif defined (__SYMBIAN32__)
|
||||||
|
# define KHRONOS_APICALL IMPORT_C
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIENTRY
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the return type of the function and precedes the function
|
||||||
|
* name in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||||
|
/* Win32 but not WinCE */
|
||||||
|
# define KHRONOS_APIENTRY __stdcall
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIATTRIBUTES
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the closing parenthesis of the function prototype arguments.
|
||||||
|
*/
|
||||||
|
#if defined (__ARMCC_2__)
|
||||||
|
#define KHRONOS_APIATTRIBUTES __softfp
|
||||||
|
#else
|
||||||
|
#define KHRONOS_APIATTRIBUTES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* basic type definitions
|
||||||
|
*-----------------------------------------------------------------------*/
|
||||||
|
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <stdint.h>
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
/*
|
||||||
|
* To support platform where unsigned long cannot be used interchangeably with
|
||||||
|
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||||
|
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||||
|
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||||
|
* unsigned long long or similar (this results in different C++ name mangling).
|
||||||
|
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||||
|
* platforms where the size of a pointer is larger than the size of long.
|
||||||
|
*/
|
||||||
|
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||||
|
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||||
|
#define KHRONOS_USE_INTPTR_T
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__VMS ) || defined(__sgi)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <inttypes.h>
|
||||||
|
*/
|
||||||
|
#include <inttypes.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Win32
|
||||||
|
*/
|
||||||
|
typedef __int32 khronos_int32_t;
|
||||||
|
typedef unsigned __int32 khronos_uint32_t;
|
||||||
|
typedef __int64 khronos_int64_t;
|
||||||
|
typedef unsigned __int64 khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(__sun__) || defined(__digital__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sun or Digital
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#if defined(__arch64__) || defined(_LP64)
|
||||||
|
typedef long int khronos_int64_t;
|
||||||
|
typedef unsigned long int khronos_uint64_t;
|
||||||
|
#else
|
||||||
|
typedef long long int khronos_int64_t;
|
||||||
|
typedef unsigned long long int khronos_uint64_t;
|
||||||
|
#endif /* __arch64__ */
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hypothetical platform with no float or int64 support
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 0
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 0
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic fallback
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that are (so far) the same on all platforms
|
||||||
|
*/
|
||||||
|
typedef signed char khronos_int8_t;
|
||||||
|
typedef unsigned char khronos_uint8_t;
|
||||||
|
typedef signed short int khronos_int16_t;
|
||||||
|
typedef unsigned short int khronos_uint16_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||||
|
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||||
|
* to be the only LLP64 architecture in current use.
|
||||||
|
*/
|
||||||
|
#ifdef KHRONOS_USE_INTPTR_T
|
||||||
|
typedef intptr_t khronos_intptr_t;
|
||||||
|
typedef uintptr_t khronos_uintptr_t;
|
||||||
|
#elif defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_intptr_t;
|
||||||
|
typedef unsigned long long int khronos_uintptr_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_intptr_t;
|
||||||
|
typedef unsigned long int khronos_uintptr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_ssize_t;
|
||||||
|
typedef unsigned long long int khronos_usize_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_ssize_t;
|
||||||
|
typedef unsigned long int khronos_usize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_FLOAT
|
||||||
|
/*
|
||||||
|
* Float type
|
||||||
|
*/
|
||||||
|
typedef float khronos_float_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_INT64
|
||||||
|
/* Time types
|
||||||
|
*
|
||||||
|
* These types can be used to represent a time interval in nanoseconds or
|
||||||
|
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||||
|
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||||
|
* time the system booted). The Unadjusted System Time is an unsigned
|
||||||
|
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||||
|
* may be either signed or unsigned.
|
||||||
|
*/
|
||||||
|
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||||
|
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dummy value used to pad enum types to 32 bits.
|
||||||
|
*/
|
||||||
|
#ifndef KHRONOS_MAX_ENUM
|
||||||
|
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumerated boolean type
|
||||||
|
*
|
||||||
|
* Values other than zero should be considered to be true. Therefore
|
||||||
|
* comparisons should not be made against KHRONOS_TRUE.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
KHRONOS_FALSE = 0,
|
||||||
|
KHRONOS_TRUE = 1,
|
||||||
|
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||||
|
} khronos_boolean_enum_t;
|
||||||
|
|
||||||
|
#endif /* __khrplatform_h_ */
|
||||||
3694
include/glad/glad.h
Executable file
3694
include/glad/glad.h
Executable file
File diff suppressed because it is too large
Load Diff
279
new-claude
Normal file
279
new-claude
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
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/2 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.
|
||||||
|
|
||||||
|
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
|
||||||
|
out location because 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
|
||||||
|
|
||||||
|
The proposed maximum range is 15 miles.
|
||||||
|
Selectable ranges sould be 2, 5, 10, and 15 miles
|
||||||
|
|
||||||
|
The project will be implimented on on a Geekom A8 Max
|
||||||
|
with AMD AI chip R9-8945HS with 32 GB ram
|
||||||
|
|
||||||
|
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 followng 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 sor 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 shorline
|
||||||
|
|
||||||
|
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 wiht Raspberry pi 4 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.
|
||||||
|
|
||||||
|
I prefer to have separate shader sets for each major function to facilitate
|
||||||
|
troubleshootng
|
||||||
|
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 shorline using some sort of topographical map
|
||||||
|
7. PPI scope persistance 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 white blue)
|
||||||
|
4. All persistance 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. Transition to local candidate
|
||||||
|
from AIS/ADS-B/UAT need to be converted to 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 singnal strength:
|
||||||
|
1. large ship would be bright and blooming
|
||||||
|
2. yachts would be bright but not blooming
|
||||||
|
3. sailboats would be medium bright and not blooming
|
||||||
|
4. kayaks and roaboats would be small and dim
|
||||||
|
|
||||||
|
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 verical axis.
|
||||||
|
Needs
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
PPI Scope active targets
|
||||||
|
1. Active boats/planes; brightness determined by size as noted above
|
||||||
|
2. Blue white color
|
||||||
|
|
||||||
|
PPI Scope range rings
|
||||||
|
1. blue white (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 viy the Range and Bearing controls
|
||||||
|
cursor consistes 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
|
||||||
|
|
||||||
|
Controls:
|
||||||
|
|
||||||
|
Here are the controls that I am proposing
|
||||||
|
|
||||||
|
1. Intensity
|
||||||
|
2. Focus
|
||||||
|
3. Astignatism
|
||||||
|
4. Range selection (for both a scope and ppi scope)
|
||||||
|
5. Sensitivity
|
||||||
|
6. Clutter elimination (I believe only ppi scope; please research)
|
||||||
|
7. There is some sort of control having to do with the mangatron
|
||||||
|
but I don't know what its called and what it does.
|
||||||
|
8. Bearing (only for a scope) which in the old days uses a servo motor to
|
||||||
|
rotate the antenna. I don't know what form of feedback (text on the
|
||||||
|
screen or mechanical numbers on a dial)
|
||||||
|
9. Magnetron tune
|
||||||
|
10. Anti clutter rain (ftc)
|
||||||
|
11. Will not need heading (this will be a fixed radar location for
|
||||||
|
the harbor master or lifeguard
|
||||||
|
12. Off-centering
|
||||||
|
13. Graticule brilliance
|
||||||
|
14. Reset (in case kids really mess things up)
|
||||||
|
15. Pulse length selection (short pulse for better range resolution,
|
||||||
|
long pulse for better sensitivity at distance; operator selectable)
|
||||||
|
|
||||||
|
|
||||||
|
(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 impliment them. I am guessing a few raspberry pies to
|
||||||
|
handle the encoders. I am thinking of encoders have one common terminal and
|
||||||
|
a clockwise pulse terminal and a counter clockwise pulse terminal.
|
||||||
|
|
||||||
|
Let 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 stb_truetype (single-header library, stb_truetype.h from github.com/nothings/stb).
|
||||||
|
Drop stb_truetype.h into the src directory. No additional build dependencies required.
|
||||||
|
Used for graticule degree labels on the PPI bearing ring, range labels, and any
|
||||||
|
vessel name labels from AIS data. Build a font atlas texture at startup from a
|
||||||
|
TTF font file; render characters as textured quads in the shader.
|
||||||
|
|
||||||
|
Communication:
|
||||||
|
|
||||||
|
Communication:
|
||||||
|
|
||||||
|
All I know now is that I plan to use a combination of raspberry pi 4 and a 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 4 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)
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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. Generational initialization and set up basic boundaries of the two scopes
|
||||||
|
on the screen. Now 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 persistance display - test
|
||||||
|
for each range settings; hold for 5 seconds each
|
||||||
|
5. PPI scope cursor - test by slowing changing range and bearing
|
||||||
|
6. PPI scope weather noise - test by changing noise level slowly
|
||||||
|
7. PPI scope waves noise - test by changing noise level slowly
|
||||||
|
8. PPI scope handling of shorline - test by running for a few seconds
|
||||||
|
|
||||||
|
========================================================
|
||||||
|
|
||||||
|
Now, just comment on this, noting any errors or anything you think is smissing.
|
||||||
|
DO NOT GENERATE CODE
|
||||||
317
old_claude
Normal file
317
old_claude
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
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
|
||||||
|
and use a 1/2 inch margin.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# Project: C++ OpenGL Radar Simulation
|
||||||
|
**Environment:** Ubuntu Linux (Remote SSH from Windows)
|
||||||
|
**Tech Stack:** C++20, OpenGL 3.3/4.5 Core, GLFW, GLAD, FreeType
|
||||||
|
|
||||||
|
## Current Architectural State
|
||||||
|
- [cite_start]Main loop handles both simulation logic and rendering[cite: 799, 818].
|
||||||
|
- [cite_start]Drawing functions (drawCircle, drawLine, drawRect) use immediate-mode-style buffer updates (glBufferData) every frame[cite: 866, 871, 875].
|
||||||
|
- [cite_start]Text rendering performs a separate draw call and texture bind for every character[cite: 852, 857].
|
||||||
|
|
||||||
|
## High Priority Refactor Goals
|
||||||
|
1. **Batch Rendering:** Move away from per-shape buffer updates. Implement a persistent Vertex Buffer for static UI elements (scales, graticules) and a separate Dynamic Buffer for moving radar sweeps.
|
||||||
|
2. [cite_start]**Text Optimization:** Create a Texture Atlas for FreeType characters to reduce draw calls from $N$ characters to 1 draw call per string[cite: 812, 816].
|
||||||
|
3. [cite_start]**Radar Sweep Logic:** Implement a "Phosphor Persistence" effect using a Fragment Shader rather than CPU-calculated lines to simulate the P7 radar glow[cite: 787, 788].
|
||||||
|
4. [cite_start]**Coordinate Normalization:** Move the orthographic projection matrix calculation out of the draw functions and into a Global Uniform to save CPU cycles[cite: 851, 862].
|
||||||
|
|
||||||
|
## Operational Constraints
|
||||||
|
- **Environment:** Headless Linux via SSH. No X11 forwarding or Wayland display available.
|
||||||
|
- **No Execution:** Do not attempt to run, execute, or "test" the code in this environment.
|
||||||
|
- **Focus:** Provide code implementation, mathematical logic, and architectural refactoring only.
|
||||||
|
- **Compilation Only:** Assume the user will handle compilation and manual execution on the local machine.
|
||||||
|
- **X11/Display:** Never suggest commands like `glxgears` or running the binary directly, as there is no attached monitor.
|
||||||
|
|
||||||
|
## Rules for AI Assistant
|
||||||
|
- Respect the MIT License of this codebase.
|
||||||
|
- Do not suggest deprecated OpenGL (no glBegin/glEnd).
|
||||||
|
- Maintain high-performance C++20 standards (prefer std::span or std::vector over raw pointers).
|
||||||
|
|
||||||
|
The communications for the SDR radios will be handled by
|
||||||
|
Raspberry Pi 5
|
||||||
|
|
||||||
|
Do not use whole screen.
|
||||||
|
|
||||||
|
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 white 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:
|
||||||
|
1. large ship would be bright and blooming
|
||||||
|
2. yachts would be bright but not blooming
|
||||||
|
3. sailboats would be medium bright and not blooming
|
||||||
|
4. kayaks and rowboats would be small and dim
|
||||||
|
5. May consider fading small boats like kayaks
|
||||||
|
and sailboats above 3 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.
|
||||||
|
|
||||||
|
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 white color
|
||||||
|
|
||||||
|
PPI Scope range rings
|
||||||
|
1. blue white (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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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 cursor - test by slowly changing range and bearing
|
||||||
|
6. PPI scope weather noise - test by changing noise level slowly
|
||||||
|
7. PPI scope waves noise - test by changing noise level slowly
|
||||||
|
8. PPI scope handling of shoreline - test by running for a few seconds
|
||||||
|
|
||||||
|
========================================================
|
||||||
|
|
||||||
|
Generate code for testiong feature 1 and 2 only;
|
||||||
|
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)
|
||||||
|
Do not generate any other code
|
||||||
|
Generate code the run this and hold for 10 seconds and exit
|
||||||
52
sec-stuff
Normal file
52
sec-stuff
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
LOcked key method on backup linode
|
||||||
|
|
||||||
|
from="PROD_IP_HERE",command="/usr/local/bin/run-backup.sh",no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3... (rest of your key)
|
||||||
|
|
||||||
|
Create a simple script at /usr/local/bin/run-backup.sh on the backup machine:
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
# 1. Sync the Gitea Database (assuming it was dumped to a file)
|
||||||
|
# 2. Re-run the Git Clone/Pull for your radar & website projects
|
||||||
|
cd /path/to/backup/folder
|
||||||
|
git pull origin main || git clone http://your-gitea-url/repo.git .
|
||||||
|
|
||||||
|
# Optional: Log the backup time
|
||||||
|
echo "Backup successful: $(date)" >> /var/log/backup_history.log
|
||||||
|
|
||||||
|
|
||||||
|
from="PROD_IP",command="/usr/share/doc/rsync/scripts/rrsync -ro /mnt/backups/ilovearthur/",restrict ssh-rsa AAAAB3...
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
# Sync critical system and user data
|
||||||
|
rsync -az --delete /etc /var /home root@backup.ilovearthur.org:/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Wrapper script on backup server
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
case "$SSH_ORIGINAL_COMMAND" in
|
||||||
|
rsync*)
|
||||||
|
# Allows rsync to only touch the designated backup folder
|
||||||
|
$SSH_ORIGINAL_COMMAND
|
||||||
|
;;
|
||||||
|
"git-sync")
|
||||||
|
# Custom command to refresh your Gitea mirrors
|
||||||
|
cd /home/backups/radar-repo
|
||||||
|
git pull || git clone http://your-gitea-url/repo.git .
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Access Denied: Command not permitted."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
Authorized keys file:
|
||||||
|
|
||||||
|
from="PROD_IP",command="/usr/local/bin/backup-handler.sh",no-agent-forwarding,no-port-forwarding,no-pty ssh-rsa AAAAB3...
|
||||||
|
|
||||||
|
|
||||||
|
from="192.0.2.1,2001:db8::1",command="/usr/local/bin/backup-handler.sh",no-pty ... [your-ssh-key]
|
||||||
|
|
||||||
Reference in New Issue
Block a user