0.3.0
Loading...
Searching...
No Matches
SNRMask.cpp
Go to the documentation of this file.
1// This file is part of INSTINCT, the INS Toolkit for Integrated
2// Navigation Concepts and Training by the Institute of Navigation of
3// the University of Stuttgart, Germany.
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9/// @file SNRMask.cpp
10/// @brief Signal to Noise Ratio Mask
11/// @author T. Topp (topp@ins.uni-stuttgart.de)
12/// @date 2023-12-17
13
14#include "SNRMask.hpp"
15
16#include <imgui.h>
17#include <fmt/format.h>
18
21
22namespace NAV
23{
24
26{
27 const auto frequencies = Frequency::GetAll();
28 for (size_t i = 0; i < frequencies.size(); i++)
29 {
30 mask.at(i).first = frequencies.at(i);
31 mask.at(i).second.second = true;
32 }
33}
34
35bool SNRMask::ShowGuiWidgets(const char* label)
36{
37 bool changed = false;
38 if (!label) { label = "SNR Mask"; }
39
40 if (isInactive()) { ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]); }
41 if (ImGui::Button(fmt::format("{}", label).c_str()))
42 {
43 ImGui::OpenPopup(fmt::format("SNR Mask##Popup - {}", label).c_str());
44 }
45 if (isInactive())
46 {
47 ImGui::PopStyleColor();
48 if (ImGui::IsItemHovered())
49 {
50 ImGui::SetTooltip("Inactive due to all values being 0");
51 }
52 }
53
54 constexpr float INPUT_WIDTH = 40.0F;
55
56 if (ImGui::BeginPopup(fmt::format("SNR Mask##Popup - {}", label).c_str()))
57 {
58 if (ImGui::BeginTable(fmt::format("").c_str(), elevations.size() + 2, ImGuiTableFlags_Borders))
59 {
60 ImGui::TableSetupColumn("Elevation:");
61 for (const auto& elevation : elevations)
62 {
63 ImGui::TableSetupColumn(fmt::format("< {:.0f}", rad2deg(elevation)).c_str());
64 }
65 ImGui::TableSetupColumn("");
66 ImGui::TableHeadersRow();
67
68 ImGui::TableNextColumn();
69 ImGui::TextUnformatted("All");
70 ImGui::SameLine();
71 gui::widgets::HelpMarker("- The values for each frequency are used for the calculation,\n"
72 " this row is only used to change all frequencies at the same time.\n"
73 "- Grayed out when not all frequencies below have the same value.");
74 for (size_t i = 0; i < allOverride.first.size(); ++i)
75 {
76 ImGui::TableNextColumn();
77 ImGui::SetNextItemWidth(INPUT_WIDTH);
78 if (allOverride.second && i != 0) { ImGui::BeginDisabled(); }
79 bool anyValueDiffers = std::ranges::any_of(mask, [&](const auto& freqMask) {
80 return allOverride.first.at(i) != freqMask.second.first.at(i);
81 });
82 if (anyValueDiffers) { ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]); }
83 if (ImGui::DragDouble(fmt::format("##all {} {}", label, i).c_str(), &allOverride.first.at(i), 1.0, 0.0, 100.0, "%.1f"))
84 {
85 changed = true;
86 if (!allOverride.second)
87 {
88 for (auto& freqSNRs : mask)
89 {
90 freqSNRs.second.first.at(i) = allOverride.first.at(i);
91 }
92 }
93 else
94 {
95 for (size_t i = 0; i < allOverride.first.size(); ++i)
96 {
97 allOverride.first.at(i) = allOverride.first[0];
98 for (auto& freqSNRs : mask)
99 {
100 freqSNRs.second.first.at(i) = allOverride.first.at(i);
101 }
102 }
103 }
104 }
105 if (anyValueDiffers) { ImGui::PopStyleColor(); }
106 if (allOverride.second && i != 0) { ImGui::EndDisabled(); }
107 }
108 ImGui::TableNextColumn();
109 if (ImGui::Checkbox(fmt::format("##lock together - all {}", label).c_str(), &allOverride.second))
110 {
111 changed = true;
112 if (allOverride.second)
113 {
114 for (size_t i = 0; i < allOverride.first.size(); ++i)
115 {
116 allOverride.first.at(i) = allOverride.first[0];
117 for (auto& freqSNRs : mask)
118 {
119 freqSNRs.second.first.at(i) = allOverride.first.at(i);
120 }
121 }
122 }
123 }
124 if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Lock all values together"); }
125
126 for (auto& [freq, SNRs] : mask)
127 {
128 ImGui::TableNextColumn();
129 ImGui::TextUnformatted(fmt::format("{}", freq).c_str());
130 for (size_t i = 0; i < SNRs.first.size(); ++i)
131 {
132 ImGui::TableNextColumn();
133 ImGui::SetNextItemWidth(INPUT_WIDTH);
134 if (SNRs.second && i != 0) { ImGui::BeginDisabled(); }
135 if (ImGui::DragDouble(fmt::format("##{} {} {}", freq, label, i).c_str(), &SNRs.first.at(i), 1.0, 0.0, 100.0, "%.1f"))
136 {
137 changed = true;
138 if (SNRs.second)
139 {
140 for (size_t j = 1; j < SNRs.first.size(); ++j)
141 {
142 SNRs.first.at(j) = SNRs.first.at(i);
143 }
144 }
145 }
146 if (SNRs.second && i != 0) { ImGui::EndDisabled(); }
147 }
148 ImGui::TableNextColumn();
149 if (ImGui::Checkbox(fmt::format("##lock together - all {} {}", freq, label).c_str(), &SNRs.second))
150 {
151 changed = true;
152 if (SNRs.second)
153 {
154 for (size_t i = 1; i < SNRs.first.size(); ++i)
155 {
156 SNRs.first.at(i) = SNRs.first[0];
157 }
158 }
159 }
160 if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Lock all values together"); }
161 }
162
163 ImGui::EndTable();
164 }
165
166 ImGui::EndPopup();
167 }
168
169 return changed;
170}
171
173{
174 return std::ranges::all_of(mask, [](const auto& freqMask) {
175 return std::ranges::all_of(freqMask.second.first, [](const auto& SNR) {
176 return SNR < 1e-7;
177 });
178 });
179}
180
181bool SNRMask::checkSNRMask(Frequency freq, double elevation, double SNR) const
182{
183 for (const auto& [maskFreq, SNRs] : mask)
184 {
185 if (maskFreq == freq)
186 {
187 for (size_t i = 0; i < elevations.size(); i++)
188 {
189 if (elevation <= elevations.at(i))
190 {
191 return SNR > SNRs.first.at(i);
192 }
193 }
194 }
195 }
196
197 return false;
198}
199
200void to_json(json& j, const SNRMask& obj)
201{
202 j = json{
203 { "allOverride", obj.allOverride },
204 { "mask", obj.mask },
205 };
206}
207
208void from_json(const json& j, SNRMask& obj)
209{
210 if (j.contains("allOverride")) { j.at("allOverride").get_to(obj.allOverride); }
211 if (j.contains("mask")) { j.at("mask").get_to(obj.mask); }
212}
213
214} // namespace NAV
nlohmann::json json
json namespace
Text Help Marker (?) with Tooltip.
Signal to Noise Ratio Mask.
Frequency definition for different satellite systems.
Definition Frequency.hpp:59
static constexpr std::array< Frequency, 27 > GetAll()
Returns a list with all possible frequencies.
bool checkSNRMask(Frequency freq, double elevation, double SNR) const
Checks wether the SNR values passes the SNR mask.
Definition SNRMask.cpp:181
bool ShowGuiWidgets(const char *label=nullptr)
Shows a button to select the SNR Mask.
Definition SNRMask.cpp:35
std::pair< std::array< double, elevations.size()>, bool > allOverride
Values when changed override all others.
Definition SNRMask.hpp:73
SNRMask()
Default Constructor.
Definition SNRMask.cpp:25
static constexpr std::array< double, 10 > elevations
Elevations [rad]. Checks to smaller or equal than the value.
Definition SNRMask.hpp:59
std::array< std::pair< Frequency, std::pair< std::array< double, elevations.size()>, bool > >, Frequency::GetAll().size()> mask
Masks for all frequencies and SNR [dbHz] values + lock together boolean.
Definition SNRMask.hpp:76
bool isInactive() const
Checks wether all SNR values are 0.
Definition SNRMask.cpp:172
ImGui extensions.
bool DragDouble(const char *label, double *v, float v_speed, double v_min, double v_max, const char *format, ImGuiSliderFlags flags)
Shows a Drag GUI element for 'double'.
Definition imgui_ex.cpp:19
void HelpMarker(const char *desc, const char *symbol="(?)")
Text Help Marker, e.g. '(?)', with Tooltip.
void to_json(json &j, const Node &node)
Converts the provided node into a json object.
Definition Node.cpp:990
void from_json(const json &j, Node &node)
Converts the provided json object into a node object.
Definition Node.cpp:1007
constexpr auto rad2deg(const T &rad)
Convert Radians to Degree.
Definition Units.hpp:39