diff --git a/.gitignore b/.gitignore index 96b66fa..eb1ea9b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ build* .cache .vscode src/core/config.hpp -readsb +readsb* compile_commands.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 485da17..9c230d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,11 @@ set(BUILD_DOCUMENTATION OFF CACHE BOOL "" FORCE) set(BUILD_BOTH_LIBRARIES OFF CACHE BOOL "" FORCE) set(PACKAGE_DEBIAN OFF CACHE BOOL "" FORCE) +# Automatically collect core sources and platform-specific HAL files +file(GLOB CORE_SOURCES CONFIGURE_DEPENDS "src/core/*.cpp" "src/core/*.c") +file(GLOB HAL_PICO_SOURCES CONFIGURE_DEPENDS "src/hal/*_pico.cpp") +file(GLOB HAL_LINUX_SOURCES CONFIGURE_DEPENDS "src/hal/*_linux.cpp") + if(BUILD_FOR_PICO) set(PICO_BOARD pico_w CACHE STRING "Board type") include(pico_sdk_import.cmake) @@ -25,8 +30,8 @@ if(BUILD_FOR_PICO) add_executable(p-rad src/main.cpp - src/core/logic.cpp - src/hal/hal_pico.cpp + ${CORE_SOURCES} + ${HAL_PICO_SOURCES} ) target_compile_definitions(p-rad PRIVATE PICO_BUILD) @@ -47,8 +52,8 @@ else() add_executable(p-rad src/main.cpp - src/core/logic.cpp - src/hal/hal_linux.cpp + ${CORE_SOURCES} + ${HAL_LINUX_SOURCES} ) target_include_directories(p-rad PRIVATE src) diff --git a/src/core/const.hpp b/src/core/const.hpp index 1d6334b..33c5654 100644 --- a/src/core/const.hpp +++ b/src/core/const.hpp @@ -4,3 +4,4 @@ constexpr char* user_agent = "p-rad/0.1"; +#define ARRAY_LENGHT(arr) sizeof(arr) / sizeof(arr[0]) \ No newline at end of file diff --git a/src/core/geo.cpp b/src/core/geo.cpp new file mode 100644 index 0000000..07b4a6d --- /dev/null +++ b/src/core/geo.cpp @@ -0,0 +1,16 @@ +#include +#include +#include +#include "global.hpp" +std::tuple get_offset_from_station(double lat, double lon) { + const GeographicLib::Geodesic &geod = GeographicLib::Geodesic::WGS84(); + + double distance, azi1, azi2; + geod.Inverse(receiver_lat, receiver_lon, lat, lon, distance, azi1, + azi2); + + double azi_rad = azi1 * M_PI / 180.0; + + + return {static_cast(distance * std::sin(azi_rad)),static_cast(-distance * std::cos(azi_rad))}; +} \ No newline at end of file diff --git a/src/core/geo.hpp b/src/core/geo.hpp new file mode 100644 index 0000000..8b6a60d --- /dev/null +++ b/src/core/geo.hpp @@ -0,0 +1,3 @@ +#pragma once +#include +std::tuple get_offset_from_station(double lat, double lon); \ No newline at end of file diff --git a/src/core/global.cpp b/src/core/global.cpp new file mode 100644 index 0000000..d5633ba --- /dev/null +++ b/src/core/global.cpp @@ -0,0 +1,2 @@ + float receiver_lat; + float receiver_lon; \ No newline at end of file diff --git a/src/core/global.hpp b/src/core/global.hpp new file mode 100644 index 0000000..69270b9 --- /dev/null +++ b/src/core/global.hpp @@ -0,0 +1,3 @@ +#pragma once +extern float receiver_lat; +extern float receiver_lon; \ No newline at end of file diff --git a/src/hal/draw.hpp b/src/hal/draw.hpp index 6cd230a..d80132a 100644 --- a/src/hal/draw.hpp +++ b/src/hal/draw.hpp @@ -18,4 +18,5 @@ struct rect_t { void pixel(const uint16_t x, const uint16_t y, const color_t color); void filled_rect(const rect_t* rect, const color_t color); void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radius, const color_t color); + void rhombus(const uint16_t x_center, const uint16_t y_center,const uint16_t radius, const color_t color); } \ No newline at end of file diff --git a/src/hal/hal_linux.cpp b/src/hal/hal_linux.cpp index 9d3c3df..9dab85a 100644 --- a/src/hal/hal_linux.cpp +++ b/src/hal/hal_linux.cpp @@ -142,6 +142,13 @@ void circle(const uint16_t x_center, const uint16_t y_center,const uint16_t radi } } } + +void rhombus(const uint16_t x_center, const uint16_t y_center,const uint16_t radius, const color_t color) { + SDL_SetRenderDrawColor(main_sdl_session.renderer, color.r, color.g, color.b, + 0xff); + const SDL_FPoint points[] = {{static_cast(x_center+radius),static_cast(y_center)},{static_cast(x_center),static_cast(y_center+radius)},{static_cast(x_center-radius),static_cast(y_center)},{static_cast(x_center),static_cast(y_center-radius)},{static_cast(x_center+radius),static_cast(y_center)}}; + SDL_RenderLines(main_sdl_session.renderer, points, ARRAY_LENGHT(points)); +} } // namespace draw namespace net { diff --git a/src/main.cpp b/src/main.cpp index fa901b4..3403de0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,8 @@ #include #include #include +#include "core/global.hpp" +#include "core/geo.hpp" int main() { if (hal::init() != 0) { @@ -24,8 +26,6 @@ int main() { const uint16_t middle_x = (screen_w / 2); const uint16_t middle_y = (screen_h / 2); - float receiver_lat; - float receiver_lon; { nlohmann::json receiver = net::http_get_json(std::format("{}/receiver.json", base_url)); @@ -72,6 +72,27 @@ int main() { } } + { // draw planes + nlohmann::json aircraft = net::http_get_json(std::format("{}/aircraft.json", base_url)); + if (aircraft!= nullptr) { + for(nlohmann::json &craft : aircraft["aircraft"]) { + try { + const auto [x_offset,y_offset] = get_offset_from_station(craft["lat"].get(), craft["lon"].get()); + 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, {0xff,0x68,0x00}); + draw::rhombus(x_center, y_center, 8/*TODO: remove magic*/,{0xff,0x68,0x00}); + } 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"; + } + } + hal::end_frame(); } } \ No newline at end of file