24#include <unordered_map>
25#include <unordered_set>
37#include <Eigen/src/Core/Matrix.h>
89 if (!_antennas.empty()) {
return; }
91 LOG_DEBUG(
"Reading ANTEX files started...");
93 auto path = flow::GetProgramRootPath() /
"resources" /
"gnss" /
"antex";
94 if (!std::filesystem::exists(path))
96 LOG_WARN(
"Not reading ANTEX files because path does not exist: {}", path);
99 for (
const auto& entry : std::filesystem::directory_iterator(path))
101 if (entry.path().extension() !=
".atx") {
continue; }
102 LOG_DEBUG(
"Reading {}...", entry.path().string());
104 std::ifstream fs(entry.path());
107 LOG_ERROR(
"Could not read ANTEX file: {}", entry.path().string());
111 auto extHeaderLabel = [](
const std::string& line) {
112 return str::trim_copy(std::string_view(line).substr(60, 20));
117 bool antenna =
false;
118 std::string antennaType;
123 while (std::getline(fs, line) && !fs.eof())
125 auto label = extHeaderLabel(line);
126 if (label ==
"START OF ANTENNA") { antenna =
true; }
127 else if (label ==
"END OF ANTENNA")
137 if (label ==
"TYPE / SERIAL NO")
139 antennaType = str::trim_copy(line.substr(0, 20));
146 else if (label ==
"METH / BY / # / DATE")
149 auto strDate = line.substr(50, 10);
150 auto day = std::stoi(strDate.substr(0, 2));
151 auto strMon = strDate.substr(3, 3);
153 if (strMon ==
"JAN") { mon = 1; }
154 if (strMon ==
"FEB") { mon = 2; }
155 if (strMon ==
"MAR") { mon = 3; }
156 if (strMon ==
"APR") { mon = 4; }
157 if (strMon ==
"MAY") { mon = 5; }
158 if (strMon ==
"JUN") { mon = 6; }
159 if (strMon ==
"JUL") { mon = 7; }
160 if (strMon ==
"AUG") { mon = 8; }
161 if (strMon ==
"SEP") { mon = 9; }
162 if (strMon ==
"OCT") { mon = 10; }
163 if (strMon ==
"NOV") { mon = 11; }
164 if (strMon ==
"DEZ") { mon = 12; }
165 auto year = 2000 + std::stoi(strDate.substr(7, 2));
168 else if (label ==
"VALID FROM")
170 validFrom =
InsTime(std::stoi(line.substr(0, 6)),
171 std::stoi(line.substr(6, 6)),
172 std::stoi(line.substr(12, 6)),
173 std::stoi(line.substr(18, 6)),
174 std::stoi(line.substr(24, 6)),
175 std::stod(line.substr(30, 13)),
178 else if (label ==
"VALID UNTIL")
180 validUntil =
InsTime(std::stoi(line.substr(0, 6)),
181 std::stoi(line.substr(6, 6)),
182 std::stoi(line.substr(12, 6)),
183 std::stoi(line.substr(18, 6)),
184 std::stoi(line.substr(24, 6)),
185 std::stod(line.substr(30, 13)),
188 else if (label ==
"START OF FREQUENCY")
190 frequency = getFreqFromString(line.substr(3, 3));
192 else if (label ==
"END OF FREQUENCY") { frequency =
Freq_None; }
195 if (label ==
"NORTH / EAST / UP")
197 auto& antenna = _antennas[antennaType];
198 _antennaNames.insert(antennaType);
199 auto antInfo = std::find_if(antenna.antennaInfo.begin(), antenna.antennaInfo.end(), [&](
const Antenna::AntennaInfo& antInfo) {
200 return antInfo.from == validFrom && antInfo.until == validUntil;
202 if (antInfo == antenna.antennaInfo.end())
204 antenna.antennaInfo.emplace_back(date, validFrom, validUntil);
205 antInfo = antenna.antennaInfo.end() - 1;
215 antInfo->
freqInformation[frequency].phaseCenterOffsetToARP = Eigen::Vector3d(str::stod(line.substr(0, 10), 0.0),
216 str::stod(line.substr(10, 10), 0.0),
217 str::stod(line.substr(20, 10), 0.0))
219 LOG_DATA(
" Adding antenna '{}' [{}]{} phaseCenterOffsetToARP: {}", antennaType,
Frequency(frequency),
221 antInfo->
freqInformation.at(frequency).phaseCenterOffsetToARP.transpose());
228 LOG_DEBUG(
"Reading ANTEX file finished.");
234 _notFoundAnt.clear();
235 _notFoundFreq.clear();
244 template<
typename ReceiverType>
246 [[maybe_unused]] ReceiverType receiver, [[maybe_unused]]
const std::string& nameId)
248 if (_antennas.contains(antennaType))
250 const auto& antenna = _antennas.at(antennaType);
252 auto antInfo = antenna.antennaInfo.cend();
253 if (antenna.antennaInfo.size() == 1)
255 antInfo = antenna.antennaInfo.begin();
259 antInfo = std::find_if(antenna.antennaInfo.begin(), antenna.antennaInfo.end(), [&](
const Antenna::AntennaInfo& antInfo) {
260 return (antInfo.from.empty() && antInfo.until.empty())
261 || (antInfo.from.empty() && insTime <= antInfo.until)
262 || (antInfo.until.empty() && antInfo.from <= insTime)
263 || (antInfo.from <= insTime && insTime <= antInfo.until);
266 if (antInfo == antenna.antennaInfo.end())
268 antInfo = antenna.antennaInfo.cend() - 1;
271 if (antInfo->freqInformation.contains(freq))
273 return antInfo->freqInformation.at(freq).phaseCenterOffsetToARP;
275 if (!_notFoundFreq.contains(std::make_pair(antennaType, freq)))
277 LOG_WARN(
"{}: Cannot determine phase center offset, because antenna type '{}' is does not have frequency [{}] in the ANTEX file."
278 " Please provide a new ANTEX file under 'resources/gnss/antex' or consider not using the frequency, as this can introduce height errors of several centimeter.",
280 _notFoundFreq.insert(std::make_pair(antennaType, freq));
283 else if (!_notFoundAnt.contains(antennaType))
285 LOG_WARN(
"{}: Cannot determine phase center offset, because antenna type '{}' for receiver '{}' is not found in the ANTEX files.",
286 nameId, antennaType, receiver);
287 _notFoundAnt.insert(antennaType);
294 const std::set<std::string>&
antennas()
const {
return _antennaNames; };
301 std::unordered_map<std::string, Antenna> _antennas;
304 std::set<std::string> _antennaNames;
307 std::unordered_set<std::string> _notFoundAnt;
310 std::unordered_set<std::pair<std::string, Frequency_>> _notFoundFreq;
314 static Frequency_ getFreqFromString(
const std::string& str)
316 if (str ==
"G01") {
return G01; }
317 if (str ==
"G02") {
return G02; }
318 if (str ==
"G05") {
return G05; }
319 if (str ==
"R01") {
return R01; }
320 if (str ==
"R02") {
return R02; }
321 if (str ==
"E01") {
return E01; }
322 if (str ==
"E05") {
return E05; }
323 if (str ==
"E07") {
return E07; }
324 if (str ==
"E08") {
return E08; }
325 if (str ==
"E06") {
return E06; }
326 if (str ==
"C01") {
return B01; }
327 if (str ==
"C02") {
return B02; }
328 if (str ==
"C07") {
return B07; }
329 if (str ==
"C06") {
return B06; }
330 if (str ==
"J01") {
return J01; }
331 if (str ==
"J02") {
return J02; }
332 if (str ==
"J05") {
return J05; }
333 if (str ==
"J06") {
return J06; }
334 if (str ==
"S01") {
return S01; }
335 if (str ==
"S05") {
return S05; }
Frequency definition for different satellite systems.
Frequency_
Enumerate for GNSS frequencies.
Definition Frequency.hpp:26
@ E07
Galileo E5b (1207.14 MHz).
Definition Frequency.hpp:34
@ J01
QZSS L1 (1575.42 MHz).
Definition Frequency.hpp:47
@ B02
Beidou B1-2 (1561.098 MHz).
Definition Frequency.hpp:42
@ S01
SBAS L1 (1575.42 MHz).
Definition Frequency.hpp:53
@ E06
Galileo E6 (1278.75 MHz).
Definition Frequency.hpp:33
@ Freq_None
None.
Definition Frequency.hpp:27
@ R02
GLONASS, "G2" (1246 MHz).
Definition Frequency.hpp:37
@ E01
Galileo, "E1" (1575.42 MHz).
Definition Frequency.hpp:31
@ B06
Beidou B3 (1268.52 MHz).
Definition Frequency.hpp:44
@ E05
Galileo E5a (1176.45 MHz).
Definition Frequency.hpp:32
@ S05
SBAS L5 (1176.45 MHz).
Definition Frequency.hpp:54
@ R01
GLONASS, "G1" (1602 MHZ).
Definition Frequency.hpp:36
@ G01
GPS L1 (1575.42 MHz).
Definition Frequency.hpp:28
@ B01
Beidou B1 (1575.42 MHz).
Definition Frequency.hpp:41
@ J05
QZSS L5 (1176.45 MHz).
Definition Frequency.hpp:49
@ J02
QZSS L2 (1227.6 MHz).
Definition Frequency.hpp:48
@ B07
Beidou B2b (1207.14 MHz).
Definition Frequency.hpp:45
@ E08
Galileo E5 (E5a + E5b) (1191.795MHz).
Definition Frequency.hpp:35
@ J06
QZSS L6 / LEX (1278.75 MHz).
Definition Frequency.hpp:50
@ G05
GPS L5 (1176.45 MHz).
Definition Frequency.hpp:30
The class is responsible for all time-related tasks.
Utility class for logging to console and file.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
Definition Logger.hpp:67
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
Definition Logger.hpp:29
#define LOG_ERROR
Error occurred, which stops part of the program to work, but not everything.
Definition Logger.hpp:73
#define LOG_WARN
Error occurred, but a fallback option exists and program continues to work normally.
Definition Logger.hpp:71
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
Definition Logger.hpp:65
Utility functions for std::pair.
Utility functions for working with std::strings.
@ GPST
GPS Time.
Definition TimeSystem.hpp:29
ANTEX file reader.
Definition AntexReader.hpp:45
std::optional< Eigen::Vector3d > getAntennaPhaseCenterOffsetToARP(const std::string &antennaType, Frequency_ freq, const InsTime &insTime, ReceiverType receiver, const std::string &nameId)
Get the Antenna Phase Center Offset To ARP if it is found in the ANTEX file.
Definition AntexReader.hpp:245
const std::set< std::string > & antennas() const
Antennas read from the ANTEX files.
Definition AntexReader.hpp:294
static AntexReader & Get()
Get the static Instance of the reader.
Definition AntexReader.hpp:80
void initialize()
Initialize from ANTEX file.
Definition AntexReader.hpp:87
void reset()
Reset the temporary variables.
Definition AntexReader.hpp:232
Frequency definition for different satellite systems.
Definition Frequency.hpp:59
The class is responsible for all time-related tasks.
Definition InsTime.hpp:667
constexpr InsTime_YMDHMS toYMDHMS(TimeSystem timesys=UTC, int digits=-1) const
Converts this time object into a different format.
Definition InsTime.hpp:828
constexpr bool empty() const
Checks if the Time object has a value.
Definition InsTime.hpp:1045
void reset()
Resets the InsTime object.
Definition InsTime.hpp:1051
Antenna frequency dependant information.
Definition AntexReader.hpp:49
Eigen::Vector3d phaseCenterOffsetToARP
Eccentricities of the mean antenna phase center relative to the antenna reference point (ARP)....
Definition AntexReader.hpp:51
Antenna info.
Definition AntexReader.hpp:59
AntennaInfo(const InsTime &date, const InsTime &from, const InsTime &until)
Constructor.
Definition AntexReader.hpp:64
InsTime date
Date of measurement.
Definition AntexReader.hpp:67
InsTime until
Valid until.
Definition AntexReader.hpp:69
InsTime from
Valid from.
Definition AntexReader.hpp:68
std::unordered_map< Frequency_, AntennaFreqInfo > freqInformation
Frequency dependant information.
Definition AntexReader.hpp:72
Antenna information.
Definition AntexReader.hpp:56
std::vector< AntennaInfo > antennaInfo
Antenna Information.
Definition AntexReader.hpp:76