| 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 | /// @file RinexNavFile.hpp | ||
| 10 | /// @brief File reader for RINEX Navigation messages | ||
| 11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
| 12 | /// @date 2022-04-21 | ||
| 13 | |||
| 14 | #pragma once | ||
| 15 | |||
| 16 | #include <set> | ||
| 17 | |||
| 18 | #include "internal/Node/Node.hpp" | ||
| 19 | #include "Nodes/DataProvider/Protocol/FileReader.hpp" | ||
| 20 | |||
| 21 | #include "NodeData/GNSS/GnssNavInfo.hpp" | ||
| 22 | |||
| 23 | namespace NAV | ||
| 24 | { | ||
| 25 | /// File reader Node for RINEX Navigation messages | ||
| 26 | class RinexNavFile : public Node, public FileReader | ||
| 27 | { | ||
| 28 | public: | ||
| 29 | /// @brief Default constructor | ||
| 30 | RinexNavFile(); | ||
| 31 | /// @brief Destructor | ||
| 32 | ~RinexNavFile() override; | ||
| 33 | /// @brief Copy constructor | ||
| 34 | RinexNavFile(const RinexNavFile&) = delete; | ||
| 35 | /// @brief Move constructor | ||
| 36 | RinexNavFile(RinexNavFile&&) = delete; | ||
| 37 | /// @brief Copy assignment operator | ||
| 38 | RinexNavFile& operator=(const RinexNavFile&) = delete; | ||
| 39 | /// @brief Move assignment operator | ||
| 40 | RinexNavFile& operator=(RinexNavFile&&) = delete; | ||
| 41 | |||
| 42 | /// @brief String representation of the Class Type | ||
| 43 | [[nodiscard]] static std::string typeStatic(); | ||
| 44 | |||
| 45 | /// @brief String representation of the Class Type | ||
| 46 | [[nodiscard]] std::string type() const override; | ||
| 47 | |||
| 48 | /// @brief String representation of the Class Category | ||
| 49 | [[nodiscard]] static std::string category(); | ||
| 50 | |||
| 51 | /// @brief ImGui config window which is shown on double click | ||
| 52 | /// @attention Don't forget to set _hasConfig to true in the constructor of the node | ||
| 53 | void guiConfig() override; | ||
| 54 | |||
| 55 | /// @brief Saves the node into a json object | ||
| 56 | [[nodiscard]] json save() const override; | ||
| 57 | |||
| 58 | /// @brief Restores the node from a json object | ||
| 59 | /// @param[in] j Json object with the node state | ||
| 60 | void restore(const json& j) override; | ||
| 61 | |||
| 62 | /// @brief Resets the node. Moves the read cursor to the start | ||
| 63 | bool resetNode() override; | ||
| 64 | |||
| 65 | private: | ||
| 66 | constexpr static size_t OUTPUT_PORT_INDEX_GNSS_NAV_INFO = 0; ///< @brief Object (GnssNavInfo) | ||
| 67 | |||
| 68 | /// @brief Initialize the node | ||
| 69 | bool initialize() override; | ||
| 70 | |||
| 71 | /// @brief Deinitialize the node | ||
| 72 | void deinitialize() override; | ||
| 73 | |||
| 74 | /// @brief Determines the type of the file | ||
| 75 | /// @return The File Type | ||
| 76 | [[nodiscard]] FileType determineFileType() override; | ||
| 77 | |||
| 78 | /// @brief Read the header of the file with correct version | ||
| 79 | /// @param[in] version RINEX version | ||
| 80 | void executeHeaderParser(double version); | ||
| 81 | |||
| 82 | /// @brief Aborts RINEX file reading and deinitializes node | ||
| 83 | 6 | void abortReading() | |
| 84 | { | ||
| 85 |
2/4✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
|
6 | LOG_ERROR("{}: The file '{}' is corrupt in line {}.", nameId(), _path, getCurrentLineNumber()); |
| 86 | 6 | _gnssNavInfo.reset(); | |
| 87 | 6 | doDeinitialize(); | |
| 88 | 6 | }; | |
| 89 | |||
| 90 | /// @brief Read the messages of the file with correct version | ||
| 91 | /// @param[in] version RINEX version | ||
| 92 | void executeOrbitParser(double version); | ||
| 93 | |||
| 94 | /// @brief Parses RINEX version 2.* headers | ||
| 95 | void parseHeader2(); | ||
| 96 | |||
| 97 | /// @brief Parses RINEX version 3.* headers | ||
| 98 | void parseHeader3(); | ||
| 99 | |||
| 100 | /// @brief Parses RINEX version 4.00 headers | ||
| 101 | void parseHeader4(); | ||
| 102 | |||
| 103 | /// @brief Parses RINEX version 2.* messages | ||
| 104 | void parseOrbit2(); | ||
| 105 | |||
| 106 | /// @brief Parses RINEX version 3.* messages | ||
| 107 | void parseOrbit3(); | ||
| 108 | |||
| 109 | /// @brief Parses RINEX version 4.00 messages | ||
| 110 | void parseOrbit4(); | ||
| 111 | |||
| 112 | /// @brief Parses ephemeris message since version 3 | ||
| 113 | /// @param[in] line string | ||
| 114 | /// @param[in] satSys Satellite System | ||
| 115 | /// @param[in] satNum uint8_t Satellite Number | ||
| 116 | /// @return False if message should be skipped | ||
| 117 | bool parseEphemeris(std::string& line, SatelliteSystem satSys, uint8_t satNum); | ||
| 118 | |||
| 119 | /// @brief Read the Header of the file | ||
| 120 | void readHeader() override; | ||
| 121 | |||
| 122 | /// @brief Read the orbit information | ||
| 123 | void readOrbits(); | ||
| 124 | |||
| 125 | /// @brief Supported RINEX versions | ||
| 126 | static inline const std::set<double> _supportedVersions = { 4.00, 3.05, 3.04, 3.03, 3.02, 2.11, 2.10, 2.01 }; | ||
| 127 | |||
| 128 | /// @brief RINEX navigation message types enumeration with continuous range | ||
| 129 | enum class NavMsgType : uint8_t | ||
| 130 | { | ||
| 131 | EPH, ///< Ephemeris | ||
| 132 | STO, ///< System Time Offset | ||
| 133 | EOP, ///< Earth Orientation Parameter | ||
| 134 | ION, ///< Ionosphere | ||
| 135 | UNKNOWN ///< Unknown message type | ||
| 136 | }; | ||
| 137 | |||
| 138 | /// @brief Converts RINEX navigation message string to enum type | ||
| 139 | /// @param[in] type string | ||
| 140 | /// @return navMsgType enum | ||
| 141 | 64 | static NavMsgType getNavMsgType(const std::string& type) | |
| 142 | { | ||
| 143 | 64 | NavMsgType navMsgType = NavMsgType::UNKNOWN; | |
| 144 |
2/2✓ Branch 1 taken 41 times.
✓ Branch 2 taken 23 times.
|
64 | if (type == "EPH") |
| 145 | { | ||
| 146 | 41 | navMsgType = NavMsgType::EPH; | |
| 147 | } | ||
| 148 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 5 times.
|
23 | else if (type == "STO") |
| 149 | { | ||
| 150 | 18 | navMsgType = NavMsgType::STO; | |
| 151 | } | ||
| 152 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
|
5 | else if (type == "EOP") |
| 153 | { | ||
| 154 | ✗ | navMsgType = NavMsgType::EOP; | |
| 155 | } | ||
| 156 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | else if (type == "ION") |
| 157 | { | ||
| 158 | 5 | navMsgType = NavMsgType::ION; | |
| 159 | } | ||
| 160 | 64 | return navMsgType; | |
| 161 | } | ||
| 162 | |||
| 163 | /// @brief Data object to share over the output pin | ||
| 164 | GnssNavInfo _gnssNavInfo; | ||
| 165 | |||
| 166 | /// @brief Version of the RINEX file | ||
| 167 | double _version = 0.0; | ||
| 168 | |||
| 169 | /// Only warn once | ||
| 170 | bool _sbasNotSupportedWarned = false; | ||
| 171 | }; | ||
| 172 | |||
| 173 | } // namespace NAV | ||
| 174 |