From 95225a5811317eec00a9f4d0bfc262f14c998e12 Mon Sep 17 00:00:00 2001 From: PoliEcho Date: Fri, 7 Aug 2026 15:37:13 +0200 Subject: [PATCH] add usage of text --- Kconfig | 4 + src/core/gfx.cpp | 8 +- src/core/units.hpp | 13 ++- src/main.cpp | 219 +++++++++++++++++++++++++++------------------ 4 files changed, 148 insertions(+), 96 deletions(-) diff --git a/Kconfig b/Kconfig index 973a008..efc6c8c 100644 --- a/Kconfig +++ b/Kconfig @@ -68,6 +68,10 @@ config CHARACTER_SPACING range 1 255 default 1 +config NO_CALLSIGN_IDENTIFICATION + string "Callsign used for aircraft with unknown callsign" + default "UNK" + comment "Receiver configuration" config FALLBACK_LAT diff --git a/src/core/gfx.cpp b/src/core/gfx.cpp index 9ef3629..96ef7ca 100644 --- a/src/core/gfx.cpp +++ b/src/core/gfx.cpp @@ -42,7 +42,7 @@ draw::color_t interpolateColor(double value, return stops.back().color; } -#ifdef CONFIG_METRIC + draw::color_t get_altitude_color(uint32_t value) { static constexpr std::array stops = {{ #ifdef CONFIG_METRIC @@ -57,8 +57,7 @@ draw::color_t get_altitude_color(uint32_t value) { {6000, {40, 175, 215}}, {9000, {50, 110, 240}}, {12000, {140, 50, 220}} -#endif -#ifndef CONFIG_METRIC +#else {0, {220, 90, 20}}, // Brown/Dark Orange {500, {245, 115, 25}}, // Orange {1000, {250, 150, 30}}, // Light Orange @@ -74,7 +73,6 @@ draw::color_t get_altitude_color(uint32_t value) { }}; return interpolateColor(value, stops); } -#endif enum letter_id { LETTER_A, @@ -171,7 +169,7 @@ void putchar(const char c, uint16_t x, uint16_t y, const draw::color_t color) { y++; } } -void puts(const std::string &s, uint16_t x, uint16_t y, draw::color_t color) { +void puts(const std::string &s, const uint16_t x, const uint16_t y, const draw::color_t color) { for (size_t i = 0; i < s.length(); i++) { putchar(s[i], x+((FONT_WIDTH+CONFIG_CHARACTER_SPACING)*i), y, color); } diff --git a/src/core/units.hpp b/src/core/units.hpp index 221a513..9174215 100644 --- a/src/core/units.hpp +++ b/src/core/units.hpp @@ -1,9 +1,16 @@ #pragma once +#include "config.hpp" template static inline T feet_to_meters(T ft) { return static_cast(ft * 0.3048); } template -static inline T knot_to_km(T kn) { - return static_cast(kn * 0.5399568); -} \ No newline at end of file +static inline T knot_to_km(T kt) { + return static_cast(kt * 1.852); +} + +#ifdef CONFIG_METRIC +#define SPEED_UNIT "kmph" +#else +#define SPEED_UNIT "knot" +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b999e0b..6e42a2b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,39 +2,38 @@ #include "core/color.h" #include "core/config.hpp" #include "core/font.hpp" +#include "core/geo.hpp" +#include "core/gfx.hpp" +#include "core/global.hpp" #include "core/units.hpp" #include "hal/draw.hpp" #include "hal/hal.hpp" #include "hal/net.hpp" #include "nlohmann/json_fwd.hpp" +#include #include #include -#include #include #include #include #include -#include "core/global.hpp" -#include "core/geo.hpp" -#include "core/gfx.hpp" #ifndef CONFIG_AUTOSCALE constexpr #endif -uint16_t max_range = CONFIG_MAX_RANGE; - + uint16_t max_range = CONFIG_MAX_RANGE; int main() { if (hal::init() != 0) { return 1; } const auto [screen_w, screen_h] = hal::get_screen_size(); - #ifndef CONFIG_AUTOSCALE +#ifndef CONFIG_AUTOSCALE const - #endif - float pixels_per_km = - static_cast(screen_h > screen_w ? screen_w : screen_h) / - (max_range * 2); +#endif + float pixels_per_km = + static_cast(screen_h > screen_w ? screen_w : screen_h) / + (max_range * 2); bool odd_even = true; const uint16_t middle_x = (screen_w / 2); @@ -85,94 +84,138 @@ int main() { } } - #ifdef CONFIG_AUTOSCALE +#ifdef CONFIG_AUTOSCALE { // fardest aircraft in km uint16_t fardest_aircraft_distance_linear = 0; - #endif +#endif - { // draw planes - nlohmann::json aircraft = net::http_get_json(std::format("{}/aircraft.json", CONFIG_BASE_URL)); - if (aircraft!= nullptr) { - for(nlohmann::json &craft : aircraft["aircraft"]) { - - uint32_t altitude; - try { - if(craft["alt_baro"].is_string()) { + { // draw planes + nlohmann::json aircraft = net::http_get_json( + std::format("{}/aircraft.json", CONFIG_BASE_URL)); + if (aircraft != nullptr) { + for (nlohmann::json &craft : aircraft["aircraft"]) { + + uint32_t altitude; + try { + if (craft["alt_baro"].is_string()) { + altitude = 0; + } else { + altitude = craft["alt_baro"].get(); +#ifdef CONFIG_METRIC + altitude = feet_to_meters(altitude); +#endif + } + } catch (...) { + std::clog << YELLOW "[WARNING]" RESET + " aircraft with no alt data detected!\n"; altitude = 0; - } else { - altitude =craft["alt_baro"].get(); - #ifdef CONFIG_METRIC - altitude = feet_to_meters(altitude); - #endif } - } catch(...) { - std::clog << YELLOW"[WARNING]" RESET " aircraft with no alt data detected!\n"; - altitude = 0; + #ifndef CONFIG_METRIC + // aircraft ground speed in knots + float speed_knot; + #endif + // aircraft ground speed in km/h + float speed; + // aircraft track in degreees + float track; + try { + #ifdef CONFIG_METRIC + speed = knot_to_km(craft["gs"].get()); + #else + speed_knot = craft["gs"].get(); + speed = knot_to_km(speed_knot); + #endif + + track = craft["track"].get(); + } catch (...) { + std::clog << YELLOW + "[WARNING]" RESET + " aircraft with no ground speed or track data detected!\n"; + speed = 0; + } + draw::color_t color = get_altitude_color(altitude); + try { + const auto [x_offset, y_offset] = get_offset_from_station( + craft["lat"].get(), craft["lon"].get()); +#ifdef CONFIG_AUTOSCALE + if (std::abs(x_offset) / 1000 > + fardest_aircraft_distance_linear) { + fardest_aircraft_distance_linear = std::abs(x_offset) / 1000; + } + if (std::abs(y_offset) / 1000 > + fardest_aircraft_distance_linear) { + fardest_aircraft_distance_linear = std::abs(y_offset) / 1000; + } +#endif + const uint16_t x_center = + middle_x + ((x_offset / 1000) * pixels_per_km); + const uint16_t y_center = + middle_y + ((y_offset / 1000) * pixels_per_km); + // draw::pixel(x_center, y_center, color); + + // speed in pixels per hour + const float speed_pph = speed * pixels_per_km; + // lenght of Time-Based Vector + const float vector_lenght = + (speed_pph / 60) * CONFIG_TIME_BASED_VECTOR_LENGHT; + + // track in radians + const float track_rad = + std::fmod((track - 90), 365.0f) * + (static_cast(std::numbers::pi) / 180.0f); + + draw::line(x_center, y_center, + x_center + (vector_lenght * std::cos(track_rad)), + y_center + (vector_lenght * std::sin(track_rad)), + color); + draw::rhombus(x_center, y_center, 8 /*TODO: remove magic*/, + color); + + { + std::string callsign; + try { + callsign = craft["flight"].get(); + } catch (...) { + std::clog << YELLOW "[WARNING]" RESET + " aircraft with no callsign detected!\n"; + callsign = CONFIG_NO_CALLSIGN_IDENTIFICATION; + } + // print some info + font::puts(callsign, x_center + 10 /*TODO: remove magic*/, y_center, color); + font::puts(std::to_string(static_cast( + #ifdef CONFIG_METRIC + speed + #else + speed_knot + #endif + )) + SPEED_UNIT, x_center + 10 /*TODO: remove magic*/, y_center + FONT_HEIGHT +CONFIG_CHARACTER_SPACING, color); + } + } catch (...) { + std::clog << YELLOW "[WARNING]" RESET + " aircraft with no lat/lon data detected!\n"; + } } - - // aircraft gorund speed in km/h - float speed; - // aircraft track in degreees - float track; - try { - speed = knot_to_km(craft["gs"].get()); - track = craft["track"].get(); - } catch(...) { - std::clog << YELLOW"[WARNING]" RESET " aircraft with no ground speed or track data detected!\n"; - speed = 0; + } else { + // TODO draw vizual error + std::cerr << RED "[ERROR]" RESET " failed to get aircraft\n"; + } + } +#ifdef CONFIG_AUTOSCALE + if (fardest_aircraft_distance_linear > 0) { + for (uint16_t i = CONFIG_FIRST_RING_DISTANCE; i < UINT16_MAX; i *= 2) { + if (i + (CONFIG_RANGE_PADDING / 2) >= + fardest_aircraft_distance_linear) { + max_range = i + CONFIG_RANGE_PADDING; + pixels_per_km = + static_cast(screen_h > screen_w ? screen_w : screen_h) / + (max_range * 2); + break; } - draw::color_t color= get_altitude_color(altitude); - try { - const auto [x_offset,y_offset] = get_offset_from_station(craft["lat"].get(), craft["lon"].get()); - #ifdef CONFIG_AUTOSCALE - if(std::abs(x_offset)/1000 > fardest_aircraft_distance_linear) { - fardest_aircraft_distance_linear = std::abs(x_offset)/1000; - } - if(std::abs(y_offset)/1000 > fardest_aircraft_distance_linear) { - fardest_aircraft_distance_linear = std::abs(y_offset)/1000; - } - #endif - const uint16_t x_center = middle_x+((x_offset/1000)*pixels_per_km); - const uint16_t y_center = middle_y+((y_offset/1000)*pixels_per_km); - // draw::pixel(x_center, y_center, color); - - //speed in pixels per hour - const float speed_pph = speed* pixels_per_km; - // lenght of Time-Based Vector - const float vector_lenght = (speed_pph/60) * CONFIG_TIME_BASED_VECTOR_LENGHT; - - // track in radians - const float track_rad = std::fmod((track-90),365.0f) * (static_cast(std::numbers::pi)/180.0f); - - - draw::line(x_center, y_center,x_center + (vector_lenght*std::cos(track_rad)), y_center + (vector_lenght*std::sin(track_rad)), color); - draw::rhombus(x_center, y_center, 8/*TODO: remove magic*/,color); - font::puts("TEST123", x_center+10, y_center, color); - } catch(...) { - std::clog << YELLOW"[WARNING]" RESET " aircraft with no lat/lon data detected!\n"; } - - } - } else { - // TODO draw vizual error - std::cerr << RED"[ERROR]" RESET " failed to get aircraft\n"; } } - #ifdef CONFIG_AUTOSCALE - if (fardest_aircraft_distance_linear > 0) { - for(uint16_t i = CONFIG_FIRST_RING_DISTANCE; i < UINT16_MAX; i*=2) { - if (i+(CONFIG_RANGE_PADDING/2) >= fardest_aircraft_distance_linear) { - max_range = i+CONFIG_RANGE_PADDING; - pixels_per_km = - static_cast(screen_h > screen_w ? screen_w : screen_h) / - (max_range * 2); - break; - } - } - } - } - #endif +#endif hal::end_frame(); }