From db321b4a8fc00307ecd10a5877452d136ca837bc Mon Sep 17 00:00:00 2001 From: Aang23 Date: Wed, 8 Nov 2023 15:09:07 +0100 Subject: [PATCH] Allow auto-starting autotracking & the SDR in CLI --- src-interface/recorder/recorder.cpp | 97 +++++++++---------- src-interface/recorder/recorder.h | 2 + src-interface/recorder/recorder_proc.cpp | 66 +++++++++++-- .../recorder/tracking/tracking_widget.cpp | 25 +++++ src-ui/main.cpp | 33 ++++--- 5 files changed, 150 insertions(+), 73 deletions(-) diff --git a/src-interface/recorder/recorder.cpp b/src-interface/recorder/recorder.cpp index 930044f57..73bb08256 100644 --- a/src-interface/recorder/recorder.cpp +++ b/src-interface/recorder/recorder.cpp @@ -98,6 +98,47 @@ namespace satdump fft_plot->set_size(fft_size); waterfall_plot->set_size(fft_size); waterfall_plot->set_rate(fft_rate, waterfall_rate); + + // Attempt to apply provided CLI settings + auto &cli_settings = satdump::config::main_cfg["cli"]; + + if (cli_settings.contains("source")) + { + std::string source = cli_settings["source"]; + for (int i = 0; i < (int)sources.size(); i++) + { + if (sources[i].source_type == source) + { + if (cli_settings.contains("source_id") && cli_settings["source_id"].get() != sources[i].unique_id) + continue; + + try + { + source_ptr = dsp::getSourceFromDescriptor(sources[i]); + source_ptr->open(); + sdr_select_id = i; + break; + } + catch (std::runtime_error &e) + { + logger->error(e.what()); + } + } + } + } + + if (source_ptr) + { + if (cli_settings.contains("samplerate")) + source_ptr->set_samplerate(cli_settings["samplerate"].get()); + source_ptr->set_settings(cli_settings); + } + + if (cli_settings.contains("start_recorder_device") && cli_settings["start_recorder_device"].get()) + start(); + + if (cli_settings.contains("engage_autotrack") && cli_settings["engage_autotrack"].get()) + try_init_tracking_widget(); } RecorderApplication::~RecorderApplication() @@ -135,7 +176,7 @@ namespace satdump ImGui::BeginGroup(); float wf_size = recorder_size.y - ((is_processing && !processing_modules_floating_windows) ? 250 * ui_scale : 0); // + 13 * ui_scale; - ImGui::BeginChild("RecorderChildPanel", { left_width, wf_size }, false, ImGuiWindowFlags_NoBringToFrontOnFocus); + ImGui::BeginChild("RecorderChildPanel", {left_width, wf_size}, false, ImGuiWindowFlags_NoBringToFrontOnFocus); { if (ImGui::CollapsingHeader("Device", ImGuiTreeNodeFlags_DefaultOpen)) { @@ -315,8 +356,7 @@ namespace satdump Pipeline selected_pipeline = pipelines[pipeline_selector.pipeline_id]; if (selected_pipeline.preset.frequencies.size() > 0) { - if (ImGui::BeginCombo("Freq###presetscombo", selected_pipeline.preset.frequencies[pipeline_preset_id].second == frequency_mhz * 1e6 ? - selected_pipeline.preset.frequencies[pipeline_preset_id].first.c_str() : "")) + if (ImGui::BeginCombo("Freq###presetscombo", selected_pipeline.preset.frequencies[pipeline_preset_id].second == frequency_mhz * 1e6 ? selected_pipeline.preset.frequencies[pipeline_preset_id].first.c_str() : "")) { for (int n = 0; n < (int)selected_pipeline.preset.frequencies.size(); n++) { @@ -423,54 +463,7 @@ namespace satdump if (ImGui::CollapsingHeader("Tracking")) { - if (tracking_widget == nullptr) - { - tracking_widget = new TrackingWidget(); - - tracking_widget->aos_callback = [this](tracking::SatellitePass, tracking::TrackedObject obj) - { - if(obj.live) - stop_processing(); - if (obj.record) - stop_recording(); - - if (obj.live || obj.record) - { - frequency_mhz = obj.frequency; - if (is_started) - set_frequency(frequency_mhz); - else - start(); - - //Catch situations where source could not start - if (!is_started) - { - logger->error("Could not start recorder/processor since the source could not be started!"); - return; - } - } - - if (obj.live) - { - pipeline_selector.select_pipeline(pipelines[obj.pipeline_selector->pipeline_id].name); - pipeline_selector.setParameters(obj.pipeline_selector->getParameters()); - start_processing(); - } - - if (obj.record) - { - start_recording(); - } - }; - - tracking_widget->los_callback = [this](tracking::SatellitePass, tracking::TrackedObject obj) - { - if(obj.record) - stop_recording(); - if (obj.live) - stop_processing(); - }; - } + try_init_tracking_widget(); tracking_widget->render(); } @@ -488,7 +481,7 @@ namespace satdump ImGui::TableNextColumn(); ImGui::BeginGroup(); - ImGui::BeginChild("RecorderFFT", { right_width, wf_size }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); + ImGui::BeginChild("RecorderFFT", {right_width, wf_size}, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); { float fft_height = wf_size * (show_waterfall ? waterfall_ratio : 1.0); float wf_height = wf_size * (1 - waterfall_ratio) + 15 * ui_scale; diff --git a/src-interface/recorder/recorder.h b/src-interface/recorder/recorder.h index 17e903667..53ff9bad4 100644 --- a/src-interface/recorder/recorder.h +++ b/src-interface/recorder/recorder.h @@ -105,6 +105,8 @@ namespace satdump void start_recording(); void stop_recording(); + void try_init_tracking_widget(); + uint64_t get_samplerate() { if (current_decimation > 0) diff --git a/src-interface/recorder/recorder_proc.cpp b/src-interface/recorder/recorder_proc.cpp index 513aa0379..544698cde 100644 --- a/src-interface/recorder/recorder_proc.cpp +++ b/src-interface/recorder/recorder_proc.cpp @@ -125,7 +125,7 @@ namespace satdump { source_ptr->set_samplerate(cfg["samplerate"]); } - catch (std::exception&) + catch (std::exception &) { } } @@ -154,13 +154,13 @@ namespace satdump 2, 3, #ifdef BUILD_ZIQ - 4, - 5, - 6, + 4, + 5, + 6, #endif #ifdef BUILD_ZIQ2 - 7, - 8, + 7, + 8, #endif }; @@ -307,7 +307,7 @@ namespace satdump std::ostringstream ss; double ms_val = fmod(timeValue_precise, 1.0) * 1e3; - ss << "-" << std::fixed << std::setprecision(0) << std::setw(3) << std::setfill('0') << ms_val; + ss << "-" << std::fixed << std::setprecision(0) << std::setw(3) << std::setfill('0') << ms_val; timestamp += ss.str(); } @@ -332,4 +332,56 @@ namespace satdump is_recording = false; } } + + void RecorderApplication::try_init_tracking_widget() + { + if (tracking_widget == nullptr) + { + tracking_widget = new TrackingWidget(); + + tracking_widget->aos_callback = [this](tracking::SatellitePass, tracking::TrackedObject obj) + { + if (obj.live) + stop_processing(); + if (obj.record) + stop_recording(); + + if (obj.live || obj.record) + { + frequency_mhz = obj.frequency; + if (is_started) + set_frequency(frequency_mhz); + else + start(); + + // Catch situations where source could not start + if (!is_started) + { + logger->error("Could not start recorder/processor since the source could not be started!"); + return; + } + } + + if (obj.live) + { + pipeline_selector.select_pipeline(pipelines[obj.pipeline_selector->pipeline_id].name); + pipeline_selector.setParameters(obj.pipeline_selector->getParameters()); + start_processing(); + } + + if (obj.record) + { + start_recording(); + } + }; + + tracking_widget->los_callback = [this](tracking::SatellitePass, tracking::TrackedObject obj) + { + if (obj.record) + stop_recording(); + if (obj.live) + stop_processing(); + }; + } + } } \ No newline at end of file diff --git a/src-interface/recorder/tracking/tracking_widget.cpp b/src-interface/recorder/tracking/tracking_widget.cpp index b8d38524a..cc4e3565b 100644 --- a/src-interface/recorder/tracking/tracking_widget.cpp +++ b/src-interface/recorder/tracking/tracking_widget.cpp @@ -55,6 +55,31 @@ namespace satdump // Start threads backend_thread = std::thread(&TrackingWidget::backend_run, this); rotatorth_thread = std::thread(&TrackingWidget::rotatorth_run, this); + + // Attempt to apply provided CLI settings + auto &cli_settings = satdump::config::main_cfg["cli"]; + + if (cli_settings.contains("engage_autotrack") && cli_settings["engage_autotrack"].get()) + { + upcoming_satellite_passes_mtx.lock(); + autotrack_engaged = true; + updateAutotrackPasses(); + + if (upcoming_satellite_passes_sel.size() > 0) + { + for (int i = 0; i < (int)general_tle_registry.size(); i++) + if (general_tle_registry[i].norad == upcoming_satellite_passes_sel[0].norad) + current_satellite = i; + horizons_mode = false; + backend_needs_update = true; + autotrack_pass_has_started = false; + } + else + { + autotrack_engaged = false; + } + upcoming_satellite_passes_mtx.unlock(); + } } TrackingWidget::~TrackingWidget() diff --git a/src-ui/main.cpp b/src-ui/main.cpp index e54fa1c42..d596e7735 100644 --- a/src-ui/main.cpp +++ b/src-ui/main.cpp @@ -25,7 +25,7 @@ static void glfw_error_callback(int error, const char *description) logger->error("Glfw Error " + std::to_string(error) + ": " + description); } -void window_content_scale_callback(GLFWwindow*, float xscale, float) +void window_content_scale_callback(GLFWwindow *, float xscale, float) { satdump::updateUI(xscale / style::macos_framebuffer_scale()); style::setFonts(); @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) #endif // Decide GL+GLSL versions - const char* OPENGL_VERSIONS_GLSL[] = { "#version 100", "#version 130", "#version 150" }; + const char *OPENGL_VERSIONS_GLSL[] = {"#version 100", "#version 130", "#version 150"}; int selected_glsl; #if defined(IMGUI_IMPL_OPENGL_ES2) // GL ES 2.0 + GLSL 100 @@ -97,18 +97,18 @@ int main(int argc, char *argv[]) selected_glsl = 2; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac #else // GL 3.0 + GLSL 130 selected_glsl = 1; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); - //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only - //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only + // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only + // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only #endif - GLFWwindow* window = glfwCreateWindow(1000, 600, std::string("SatDump v" + (std::string)SATDUMP_VERSION).c_str(), nullptr, nullptr); + GLFWwindow *window = glfwCreateWindow(1000, 600, std::string("SatDump v" + (std::string)SATDUMP_VERSION).c_str(), nullptr, nullptr); if (window == nullptr) { logger->warn("Could not init GLFW Window; falling back to OpenGL 2.1..."); @@ -177,7 +177,7 @@ int main(int argc, char *argv[]) glfwSetWindowIcon(window, 1, &img); #endif - //Handle DPI changes + // Handle DPI changes float display_scale; #if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3) glfwSetWindowContentScaleCallback(window, window_content_scale_callback); @@ -187,7 +187,7 @@ int main(int argc, char *argv[]) display_scale = 1.0f; #endif - //Set font + // Set font style::setFonts(display_scale); // Init Loading Screen @@ -198,15 +198,19 @@ int main(int argc, char *argv[]) satdump::tle_do_update_on_init = false; satdump::initSatdump(); + // See if we need to add arguments + if (argc > 1) + satdump::config::main_cfg["cli"] = parse_common_flags(argc - 1, &argv[1]); + // Init UI satdump::initMainUI(display_scale); - //Shut down loading screen + // Shut down loading screen logger->del_sink(loading_screen_sink); loading_screen_sink.reset(); glfwSwapInterval(1); // Enable vsync for the rest of the program - //Set font again to adjust for DPI + // Set font again to adjust for DPI style::setFonts(); #ifndef IMGUI_IMPL_OPENGL_ES2 if (fallback_gl) @@ -228,7 +232,8 @@ int main(int argc, char *argv[]) } // TLE - satdump::ui_thread_pool.push([&](int){ satdump::autoUpdateTLE(satdump::user_path + "/satdump_tles.txt"); }); + satdump::ui_thread_pool.push([&](int) + { satdump::autoUpdateTLE(satdump::user_path + "/satdump_tles.txt"); }); // Attach signal signal(SIGINT, sig_handler_ui); @@ -268,7 +273,7 @@ int main(int argc, char *argv[]) glClear(GL_COLOR_BUFFER_BIT); #ifndef IMGUI_IMPL_OPENGL_ES2 - if(fallback_gl) + if (fallback_gl) ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); else #endif @@ -282,7 +287,7 @@ int main(int argc, char *argv[]) // Cleanup #ifndef IMGUI_IMPL_OPENGL_ES2 - if(fallback_gl) + if (fallback_gl) ImGui_ImplOpenGL2_Shutdown(); else #endif