| Line | Branch | Exec | Source |
|---|---|---|---|
| 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 | #include "SinglePointPositioning.hpp" | ||
| 10 | #include <imgui.h> | ||
| 11 | |||
| 12 | #include "Navigation/GNSS/Positioning/SPP/Algorithm.hpp" | ||
| 13 | #include "NodeData/State/PosVel.hpp" | ||
| 14 | #include "internal/NodeManager.hpp" | ||
| 15 | #include <fmt/core.h> | ||
| 16 | namespace nm = NAV::NodeManager; | ||
| 17 | #include "internal/FlowManager.hpp" | ||
| 18 | #include "internal/gui/NodeEditorApplication.hpp" | ||
| 19 | #include "internal/gui/widgets/imgui_ex.hpp" | ||
| 20 | |||
| 21 | #include "Navigation/Constants.hpp" | ||
| 22 | |||
| 23 | #include "NodeData/GNSS/GnssObs.hpp" | ||
| 24 | #include "NodeData/GNSS/GnssNavInfo.hpp" | ||
| 25 | #include "NodeData/GNSS/SppSolution.hpp" | ||
| 26 | |||
| 27 | #include "util/Logger.hpp" | ||
| 28 | #include "util/Container/Vector.hpp" | ||
| 29 | |||
| 30 | 122 | NAV::SinglePointPositioning::SinglePointPositioning() | |
| 31 |
4/8✓ Branch 1 taken 122 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 122 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 122 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 122 times.
✗ Branch 14 not taken.
|
122 | : Node(typeStatic()) |
| 32 | { | ||
| 33 | LOG_TRACE("{}: called", name); | ||
| 34 | |||
| 35 | 122 | _hasConfig = true; | |
| 36 | 122 | _guiConfigDefaultWindowSize = { 538, 536 }; | |
| 37 | |||
| 38 |
5/10✓ Branch 1 taken 122 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 122 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 122 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 122 times.
✓ Branch 14 taken 122 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
366 | nm::CreateInputPin(this, NAV::GnssObs::type().c_str(), Pin::Type::Flow, { NAV::GnssObs::type() }, &SinglePointPositioning::recvGnssObs); |
| 39 |
1/2✓ Branch 1 taken 122 times.
✗ Branch 2 not taken.
|
122 | _dynamicInputPins.addPin(this); // GnssNavInfo |
| 40 | |||
| 41 |
5/10✓ Branch 2 taken 122 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 122 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 122 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 122 times.
✓ Branch 15 taken 122 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
488 | nm::CreateOutputPin(this, NAV::SppSolution::type().c_str(), Pin::Type::Flow, { NAV::SppSolution::type() }); |
| 42 | 366 | } | |
| 43 | |||
| 44 | 260 | NAV::SinglePointPositioning::~SinglePointPositioning() | |
| 45 | { | ||
| 46 | LOG_TRACE("{}: called", nameId()); | ||
| 47 | 260 | } | |
| 48 | |||
| 49 | 236 | std::string NAV::SinglePointPositioning::typeStatic() | |
| 50 | { | ||
| 51 |
1/2✓ Branch 1 taken 236 times.
✗ Branch 2 not taken.
|
472 | return "SinglePointPositioning - SPP"; |
| 52 | } | ||
| 53 | |||
| 54 | ✗ | std::string NAV::SinglePointPositioning::type() const | |
| 55 | { | ||
| 56 | ✗ | return typeStatic(); | |
| 57 | } | ||
| 58 | |||
| 59 | 114 | std::string NAV::SinglePointPositioning::category() | |
| 60 | { | ||
| 61 |
1/2✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
|
228 | return "Data Processor"; |
| 62 | } | ||
| 63 | |||
| 64 | ✗ | void NAV::SinglePointPositioning::guiConfig() | |
| 65 | { | ||
| 66 | ✗ | auto nSatColumnContent = [&](size_t pinIndex) -> bool { | |
| 67 | ✗ | if (auto gnssNavInfo = getInputValue<GnssNavInfo>(pinIndex)) | |
| 68 | { | ||
| 69 | ✗ | size_t usedSatNum = 0; | |
| 70 | ✗ | std::string usedSats; | |
| 71 | ✗ | std::string allSats; | |
| 72 | |||
| 73 | ✗ | std::string filler = ", "; | |
| 74 | ✗ | for (const auto& satellite : gnssNavInfo->v->satellites()) | |
| 75 | { | ||
| 76 | ✗ | if (_algorithm._obsFilter.isSatelliteAllowed(satellite.first)) | |
| 77 | { | ||
| 78 | ✗ | usedSatNum++; | |
| 79 | ✗ | usedSats += (allSats.empty() ? "" : filler) + fmt::format("{}", satellite.first); | |
| 80 | } | ||
| 81 | ✗ | allSats += (allSats.empty() ? "" : filler) + fmt::format("{}", satellite.first); | |
| 82 | } | ||
| 83 | ✗ | ImGui::TextUnformatted(fmt::format("{} / {}", usedSatNum, gnssNavInfo->v->nSatellites()).c_str()); | |
| 84 | ✗ | if (ImGui::IsItemHovered()) | |
| 85 | { | ||
| 86 | ✗ | ImGui::SetTooltip("Used satellites: %s\n" | |
| 87 | "Avail satellites: %s", | ||
| 88 | usedSats.c_str(), allSats.c_str()); | ||
| 89 | } | ||
| 90 | ✗ | } | |
| 91 | ✗ | return false; | |
| 92 | ✗ | }; | |
| 93 | |||
| 94 | ✗ | if (_dynamicInputPins.ShowGuiWidgets(size_t(id), inputPins, this, { { .header = "# Sat", .content = nSatColumnContent } })) | |
| 95 | { | ||
| 96 | ✗ | flow::ApplyChanges(); | |
| 97 | } | ||
| 98 | |||
| 99 | ✗ | ImGui::Separator(); | |
| 100 | |||
| 101 | // ########################################################################################################### | ||
| 102 | |||
| 103 | ✗ | const float itemWidth = 280.0F * gui::NodeEditorApplication::windowFontRatio(); | |
| 104 | ✗ | const float unitWidth = 100.0F * gui::NodeEditorApplication::windowFontRatio(); | |
| 105 | |||
| 106 | ✗ | if (_algorithm.ShowGuiWidgets(nameId().c_str(), itemWidth, unitWidth)) | |
| 107 | { | ||
| 108 | ✗ | flow::ApplyChanges(); | |
| 109 | } | ||
| 110 | ✗ | } | |
| 111 | |||
| 112 | ✗ | [[nodiscard]] json NAV::SinglePointPositioning::save() const | |
| 113 | { | ||
| 114 | LOG_TRACE("{}: called", nameId()); | ||
| 115 | |||
| 116 | return { | ||
| 117 | ✗ | { "dynamicInputPins", _dynamicInputPins }, | |
| 118 | ✗ | { "algorithm", _algorithm }, | |
| 119 | ✗ | }; | |
| 120 | ✗ | } | |
| 121 | |||
| 122 | 8 | void NAV::SinglePointPositioning::restore(json const& j) | |
| 123 | { | ||
| 124 | LOG_TRACE("{}: called", nameId()); | ||
| 125 | |||
| 126 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | if (j.contains("dynamicInputPins")) { NAV::gui::widgets::from_json(j.at("dynamicInputPins"), _dynamicInputPins, this); } |
| 127 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | if (j.contains("algorithm")) { j.at("algorithm").get_to(_algorithm); } |
| 128 | 8 | } | |
| 129 | |||
| 130 | 24 | bool NAV::SinglePointPositioning::initialize() | |
| 131 | { | ||
| 132 | LOG_TRACE("{}: called", nameId()); | ||
| 133 | |||
| 134 |
2/4✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 24 times.
|
48 | if (std::all_of(inputPins.begin() + INPUT_PORT_INDEX_GNSS_NAV_INFO, inputPins.end(), [](const InputPin& inputPin) { return !inputPin.isPinLinked(); })) |
| 135 | { | ||
| 136 | ✗ | LOG_ERROR("{}: You need to connect a GNSS NavigationInfo provider", nameId()); | |
| 137 | ✗ | return false; | |
| 138 | } | ||
| 139 | |||
| 140 | 24 | _algorithm.reset(); | |
| 141 | |||
| 142 |
2/4✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
|
24 | LOG_DEBUG("{}: initialized", nameId()); |
| 143 | |||
| 144 | 24 | return true; | |
| 145 | } | ||
| 146 | |||
| 147 | 8 | void NAV::SinglePointPositioning::deinitialize() | |
| 148 | { | ||
| 149 | LOG_TRACE("{}: called", nameId()); | ||
| 150 | 8 | } | |
| 151 | |||
| 152 | 125 | void NAV::SinglePointPositioning::pinAddCallback(Node* node) | |
| 153 | { | ||
| 154 |
5/10✓ Branch 2 taken 125 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 125 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 125 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 125 times.
✓ Branch 15 taken 125 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
500 | nm::CreateInputPin(node, NAV::GnssNavInfo::type().c_str(), Pin::Type::Object, { NAV::GnssNavInfo::type() }); |
| 155 | 250 | } | |
| 156 | |||
| 157 | ✗ | void NAV::SinglePointPositioning::pinDeleteCallback(Node* node, size_t pinIdx) | |
| 158 | { | ||
| 159 | ✗ | nm::DeleteInputPin(node->inputPins.at(pinIdx)); | |
| 160 | ✗ | } | |
| 161 | |||
| 162 | 944 | void NAV::SinglePointPositioning::recvGnssObs(NAV::InputPin::NodeDataQueue& queue, size_t /* pinIdx */) | |
| 163 | { | ||
| 164 | // Collection of all connected navigation data providers | ||
| 165 | 944 | std::vector<InputPin::IncomingLink::ValueWrapper<GnssNavInfo>> gnssNavInfoWrappers; | |
| 166 | 944 | std::vector<const GnssNavInfo*> gnssNavInfos; | |
| 167 |
3/4✓ Branch 1 taken 2587 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1643 times.
✓ Branch 4 taken 944 times.
|
2587 | for (size_t i = 0; i < _dynamicInputPins.getNumberOfDynamicPins(); i++) |
| 168 | { | ||
| 169 |
2/4✓ Branch 1 taken 1643 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1643 times.
✗ Branch 5 not taken.
|
1643 | if (auto gnssNavInfo = getInputValue<GnssNavInfo>(INPUT_PORT_INDEX_GNSS_NAV_INFO + i)) |
| 170 | { | ||
| 171 |
1/2✓ Branch 2 taken 1643 times.
✗ Branch 3 not taken.
|
1643 | gnssNavInfoWrappers.push_back(*gnssNavInfo); |
| 172 |
1/2✓ Branch 2 taken 1643 times.
✗ Branch 3 not taken.
|
1643 | gnssNavInfos.push_back(gnssNavInfo->v); |
| 173 | 1643 | } | |
| 174 | } | ||
| 175 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 944 times.
|
944 | if (gnssNavInfos.empty()) { return; } |
| 176 | |||
| 177 |
1/2✓ Branch 1 taken 944 times.
✗ Branch 2 not taken.
|
944 | auto gnssObs = std::static_pointer_cast<const GnssObs>(queue.extract_front()); |
| 178 | LOG_DATA("{}: [{}] Calculating SPP", nameId(), gnssObs->insTime.toYMDHMS(GPST)); | ||
| 179 | |||
| 180 |
3/6✓ Branch 1 taken 944 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 944 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 944 times.
✗ Branch 9 not taken.
|
944 | if (auto sppSol = _algorithm.calcSppSolution(gnssObs, gnssNavInfos, nameId())) |
| 181 | { | ||
| 182 |
1/2✓ Branch 2 taken 944 times.
✗ Branch 3 not taken.
|
944 | invokeCallbacks(OUTPUT_PORT_INDEX_SPPSOL, sppSol); |
| 183 | 944 | } | |
| 184 | 944 | } | |
| 185 |