mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
295 lines
13 KiB
C++
295 lines
13 KiB
C++
#include "tracking_widget.h"
|
|
#include "common/utils.h"
|
|
#include "logger.h"
|
|
#include "imgui/imgui.h"
|
|
#include "imgui/imgui_stdlib.h"
|
|
#include "main_ui.h"
|
|
#include "core/module.h"
|
|
#include "core/style.h"
|
|
|
|
namespace satdump
|
|
{
|
|
void TrackingWidget::renderPolarPlot()
|
|
{
|
|
int d_pplot_size = ImGui::GetWindowContentRegionMax().x;
|
|
ImDrawList *draw_list = ImGui::GetWindowDrawList();
|
|
draw_list->AddRectFilled(ImGui::GetCursorScreenPos(),
|
|
ImVec2(ImGui::GetCursorScreenPos().x + d_pplot_size, ImGui::GetCursorScreenPos().y + d_pplot_size),
|
|
light_theme ? ImColor(255, 255, 255, 255) : ImColor::HSV(0, 0, 0));
|
|
|
|
float radius = 0.45;
|
|
float radius1 = d_pplot_size * radius * (3.0 / 9.0);
|
|
float radius2 = d_pplot_size * radius * (6.0 / 9.0);
|
|
float radius3 = d_pplot_size * radius * (9.0 / 9.0);
|
|
|
|
draw_list->AddCircle({ImGui::GetCursorScreenPos().x + (d_pplot_size / 2),
|
|
ImGui::GetCursorScreenPos().y + (d_pplot_size / 2)},
|
|
radius1, ImColor(0, 255, 0, 255), 0, 2);
|
|
draw_list->AddCircle({ImGui::GetCursorScreenPos().x + (d_pplot_size / 2),
|
|
ImGui::GetCursorScreenPos().y + (d_pplot_size / 2)},
|
|
radius2, ImColor(0, 255, 0, 255), 0, 2);
|
|
draw_list->AddCircle({ImGui::GetCursorScreenPos().x + (d_pplot_size / 2),
|
|
ImGui::GetCursorScreenPos().y + (d_pplot_size / 2)},
|
|
radius3, ImColor(0, 255, 0, 255), 0, 2);
|
|
|
|
draw_list->AddLine({ImGui::GetCursorScreenPos().x + (d_pplot_size / 2),
|
|
ImGui::GetCursorScreenPos().y},
|
|
{ImGui::GetCursorScreenPos().x + (d_pplot_size / 2),
|
|
ImGui::GetCursorScreenPos().y + d_pplot_size},
|
|
ImColor(0, 255, 0, 255), 2);
|
|
draw_list->AddLine({ImGui::GetCursorScreenPos().x,
|
|
ImGui::GetCursorScreenPos().y + (d_pplot_size / 2)},
|
|
{ImGui::GetCursorScreenPos().x + d_pplot_size,
|
|
ImGui::GetCursorScreenPos().y + (d_pplot_size / 2)},
|
|
ImColor(0, 255, 0, 255), 2);
|
|
|
|
if (upcoming_pass_points.size() > 1)
|
|
{
|
|
upcoming_passes_mtx.lock();
|
|
for (int i = 0; i < (int)upcoming_pass_points.size() - 1; i++)
|
|
{
|
|
auto &p1 = upcoming_pass_points[i];
|
|
auto &p2 = upcoming_pass_points[i + 1];
|
|
|
|
float point_x1, point_x2, point_y1, point_y2;
|
|
point_x1 = point_x2 = ImGui::GetCursorScreenPos().x + (d_pplot_size / 2);
|
|
point_y1 = point_y2 = ImGui::GetCursorScreenPos().y + (d_pplot_size / 2);
|
|
|
|
point_x1 += sin(p1.first * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - p1.second) / 90.0);
|
|
point_y1 -= cos(p1.first * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - p1.second) / 90.0);
|
|
|
|
point_x2 += sin(p2.first * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - p2.second) / 90.0);
|
|
point_y2 -= cos(p2.first * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - p2.second) / 90.0);
|
|
|
|
draw_list->AddLine({point_x1, point_y1},
|
|
{point_x2, point_y2},
|
|
ImColor(255, 165, 0, 255), 2.0);
|
|
}
|
|
upcoming_passes_mtx.unlock();
|
|
}
|
|
|
|
if (current_el > 0)
|
|
{
|
|
float point_x = ImGui::GetCursorScreenPos().x + (d_pplot_size / 2);
|
|
float point_y = ImGui::GetCursorScreenPos().y + (d_pplot_size / 2);
|
|
|
|
point_x += sin(current_az * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - current_el) / 90.0);
|
|
point_y -= cos(current_az * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - current_el) / 90.0);
|
|
|
|
draw_list->AddCircleFilled({point_x, point_y}, 5 * ui_scale, ImColor(255, 0, 0, 255));
|
|
}
|
|
|
|
if (rotator_handler->is_connected())
|
|
{
|
|
{
|
|
float point_x = ImGui::GetCursorScreenPos().x + (d_pplot_size / 2);
|
|
float point_y = ImGui::GetCursorScreenPos().y + (d_pplot_size / 2);
|
|
|
|
point_x += sin(current_rotator_az * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - current_rotator_el) / 90.0);
|
|
point_y -= cos(current_rotator_az * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - current_rotator_el) / 90.0);
|
|
|
|
draw_list->AddCircle({point_x, point_y}, 9 * ui_scale, ImColor(0, 237, 255, 255), 0, 2.0);
|
|
}
|
|
|
|
if (rotator_engaged)
|
|
{
|
|
float point_x = ImGui::GetCursorScreenPos().x + (d_pplot_size / 2);
|
|
float point_y = ImGui::GetCursorScreenPos().y + (d_pplot_size / 2);
|
|
|
|
point_x += sin(current_req_rotator_az * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - current_req_rotator_el) / 90.0);
|
|
point_y -= cos(current_req_rotator_az * DEG_TO_RAD) * d_pplot_size * radius * ((90.0 - current_req_rotator_el) / 90.0);
|
|
|
|
draw_list->AddLine({point_x - 5 * ui_scale, point_y}, {point_x - 12 * ui_scale, point_y}, ImColor(0, 237, 255, 255), 2.0);
|
|
draw_list->AddLine({point_x + 5 * ui_scale, point_y}, {point_x + 12 * ui_scale, point_y}, ImColor(0, 237, 255, 255), 2.0);
|
|
draw_list->AddLine({point_x, point_y - 5 * ui_scale}, {point_x, point_y - 12 * ui_scale}, ImColor(0, 237, 255, 255), 2.0);
|
|
draw_list->AddLine({point_x, point_y + 5 * ui_scale}, {point_x, point_y + 12 * ui_scale}, ImColor(0, 237, 255, 255), 2.0);
|
|
}
|
|
}
|
|
#if 1
|
|
if (next_aos_time != 0 && next_los_time != 0)
|
|
{
|
|
double timeOffset = 0, ctime = getTime();
|
|
if (next_aos_time > ctime)
|
|
timeOffset = next_aos_time - ctime;
|
|
else
|
|
timeOffset = next_los_time - ctime;
|
|
|
|
int hours = timeOffset / 3600;
|
|
int minutes = fmod(timeOffset / 60, 60);
|
|
int seconds = fmod(timeOffset, 60);
|
|
|
|
std::string time_dis = (hours < 10 ? "0" : "") + std::to_string(hours) + ":" +
|
|
(minutes < 10 ? "0" : "") + std::to_string(minutes) + ":" +
|
|
(seconds < 10 ? "0" : "") + std::to_string(seconds);
|
|
|
|
ImVec2 cur = ImGui::GetCursorPos();
|
|
ImVec2 curs = ImGui::GetCursorScreenPos();
|
|
ImVec2 size = ImGui::CalcTextSize((horizons_mode ? horizonsoptions[current_horizons].second.c_str() : satoptions[current_satellite]).c_str());
|
|
draw_list->AddRectFilled(curs, ImVec2(curs.x + size.x + 2 * ImGui::GetStyle().FramePadding.x, curs.y + size.y), ImColor(0, 0, 0, 180));
|
|
ImGui::TextColored(ImColor(0, 255, 0, 255), "%s", horizons_mode ? horizonsoptions[current_horizons].second.c_str() : satoptions[current_satellite].c_str());
|
|
curs = ImGui::GetCursorScreenPos();
|
|
char buff[9];
|
|
snprintf(buff, sizeof(buff), "Az: %.1f", current_az);
|
|
size = ImGui::CalcTextSize(buff);
|
|
draw_list->AddRectFilled(curs, ImVec2(curs.x + size.x + 2 * ImGui::GetStyle().FramePadding.x, curs.y + size.y), ImColor(0, 0, 0, 180));
|
|
ImGui::TextColored(ImColor(0, 255, 0, 255), "Az: %.1f", current_az);
|
|
curs = ImGui::GetCursorScreenPos();
|
|
snprintf(buff, sizeof(buff), "El: %.1f", current_el);
|
|
size = ImGui::CalcTextSize(buff);
|
|
draw_list->AddRectFilled(curs, ImVec2(curs.x + size.x + 2 * ImGui::GetStyle().FramePadding.x, curs.y + size.y), ImColor(0, 0, 0, 180));
|
|
ImGui::TextColored(ImColor(0, 255, 0, 255), "El: %.1f", current_el);
|
|
|
|
if (next_aos_time > ctime)
|
|
size = ImGui::CalcTextSize(("AOS in" + time_dis).c_str());
|
|
else
|
|
size = ImGui::CalcTextSize(("LOS in" + time_dis).c_str());
|
|
|
|
ImGui::SetCursorPosY(cur.y + d_pplot_size - 20 * ui_scale);
|
|
curs = ImGui::GetCursorScreenPos();
|
|
draw_list->AddRectFilled(curs, ImVec2(curs.x + size.x + 2 * ImGui::GetStyle().FramePadding.x, curs.y + size.y), ImColor(0, 0, 0, 180));
|
|
ImGui::TextColored(ImColor(0, 255, 0, 255), "%s in %s", next_aos_time > ctime ? "AOS" : "LOS", time_dis.c_str());
|
|
|
|
ImGui::SetCursorPos(cur);
|
|
}
|
|
#endif
|
|
ImGui::Dummy(ImVec2(d_pplot_size + 3 * ui_scale, d_pplot_size + 3 * ui_scale));
|
|
}
|
|
|
|
void TrackingWidget::renderSelectionMenu()
|
|
{
|
|
bool update_global = false;
|
|
|
|
if (backend_needs_update)
|
|
style::beginDisabled();
|
|
|
|
if (ImGui::BeginTable("##trackingradiotable", 2, ImGuiTableFlags_None))
|
|
{
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
if (ImGui::RadioButton("Satellites", !horizons_mode))
|
|
{
|
|
horizons_mode = false;
|
|
update_global = true;
|
|
}
|
|
ImGui::TableSetColumnIndex(1);
|
|
if (ImGui::RadioButton("Horizons", horizons_mode))
|
|
{
|
|
if (horizonsoptions.size() == 1)
|
|
horizonsoptions = pullHorizonsList();
|
|
horizons_mode = true;
|
|
update_global = true;
|
|
}
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::SetNextItemWidth(ImGui::GetWindowContentRegionMax().x);
|
|
if (horizons_mode)
|
|
{
|
|
if (ImGui::BeginCombo("###horizonsselectcombo", horizonsoptions[current_horizons].second.c_str()))
|
|
{
|
|
ImGui::InputTextWithHint("##horizonssatellitetracking", u8"\uf422 Search", &horizonssearchstr);
|
|
for (int i = 0; i < (int)horizonsoptions.size(); i++)
|
|
{
|
|
bool show = true;
|
|
if (horizonssearchstr.size() != 0)
|
|
show = isStringPresent(horizonsoptions[i].second, horizonssearchstr);
|
|
if (show)
|
|
{
|
|
if (ImGui::Selectable(horizonsoptions[i].second.c_str(), i == current_horizons))
|
|
{
|
|
current_horizons = i;
|
|
update_global = true;
|
|
}
|
|
}
|
|
}
|
|
ImGui::EndCombo();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ImGui::BeginCombo("###satelliteselectcombo", satoptions[current_satellite].c_str()))
|
|
{
|
|
ImGui::InputTextWithHint("##searchsatellitetracking", u8"\uf422 Search", &satsearchstr);
|
|
for (int i = 0; i < (int)satoptions.size(); i++)
|
|
{
|
|
bool show = true;
|
|
if (satsearchstr.size() != 0)
|
|
show = isStringPresent(satoptions[i], satsearchstr);
|
|
if (show)
|
|
{
|
|
if (ImGui::Selectable(satoptions[i].c_str(), i == current_satellite))
|
|
{
|
|
current_satellite = i;
|
|
update_global = true;
|
|
}
|
|
}
|
|
}
|
|
ImGui::EndCombo();
|
|
}
|
|
}
|
|
|
|
if (backend_needs_update)
|
|
style::endDisabled();
|
|
|
|
if (update_global)
|
|
backend_needs_update = true;
|
|
}
|
|
|
|
void TrackingWidget::renderObjectStatus()
|
|
{
|
|
if (ImGui::BeginTable("##trackingwidgettable", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
|
|
{
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::Text("Azimuth");
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::Text("%.3f", current_az);
|
|
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::Text("Elevation");
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::Text("%.3f", current_el);
|
|
|
|
if (next_aos_time != 0 && next_los_time != 0)
|
|
{
|
|
double timeOffset = 0, ctime = getTime();
|
|
if (next_aos_time > ctime)
|
|
timeOffset = next_aos_time - ctime;
|
|
else
|
|
timeOffset = next_los_time - ctime;
|
|
|
|
int hours = timeOffset / 3600;
|
|
int minutes = fmod(timeOffset / 60, 60);
|
|
int seconds = fmod(timeOffset, 60);
|
|
|
|
std::string time_dis = (hours < 10 ? "0" : "") + std::to_string(hours) + ":" +
|
|
(minutes < 10 ? "0" : "") + std::to_string(minutes) + ":" +
|
|
(seconds < 10 ? "0" : "") + std::to_string(seconds);
|
|
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::Text("Next Event");
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::Text("%s", time_dis.c_str());
|
|
}
|
|
|
|
if (!horizons_mode && satellite_object != nullptr)
|
|
{
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::Text("Azimuth Rate");
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::Text("%.2f", observation_pos.azimuth_rate * RAD_TO_DEG);
|
|
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
ImGui::Text("Elevation Rate");
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::Text("%.2f", observation_pos.elevation_rate * RAD_TO_DEG);
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
}
|
|
}
|