0.4.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
Klobuchar.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#include "Klobuchar.hpp"
10
11#include <algorithm>
15#include "util/Assert.h"
16#include "util/Logger.hpp"
17
18namespace NAV
19{
20
21double calcIonosphericTimeDelay_Klobuchar(double tow, Frequency freq, int8_t freqNum,
22 double latitude, double longitude,
23 double elevation, double azimuth,
24 const std::array<double, 4>& alpha, const std::array<double, 4>& beta)
25{
26 double phi_u = rad2semicircles(latitude); // User geodetic latitude [semi-circles] WGS 84
27 double lambda_u = rad2semicircles(longitude); // User geodetic longitude [semi-circles] WGS 84
28 double E = rad2semicircles(elevation); // Angle between the user and satellite [semi-circles]
29
30 // Earth's central angle between the user position and the earth projection of ionospheric intersection point [semi-circles]
31 double psi = 0.0137 / (E + 0.11) - 0.022;
32 LOG_DATA("psi {} [semi-circles] (Earth's central angle between the user position and the earth projection of ionospheric intersection point)", psi);
33
34 // Sub-ionospheric latitude (geodetic latitude of the earth projection of the ionospheric intersection point) [semi-circles]
35 // Also known as Ionospheric Pierce Point IPP
36 double phi_I = std::clamp(phi_u + psi * std::cos(azimuth), -0.416, 0.416);
37 LOG_DATA("phi_I {} [semi-circles] (Sub-ionospheric latitude)", phi_I);
38
39 // Sub-ionospheric longitude (geodetic longitude of the earth projection of the ionospheric intersection point) [semi-circles]
40 // Also known as Ionospheric Pierce Point IPP
41 double lambda_I = lambda_u + (psi * std::sin(azimuth)) / std::cos(semicircles2rad(phi_I));
42 LOG_DATA("lambda_I {} [semi-circles] (Sub-ionospheric longitude)", lambda_I);
43
44 // Geomagnetic latitude of the earth projection of the ionospheric intersection point (mean ionospheric height assumed 350 km) [semi-circles]
45 double phi_m = phi_I + 0.064 * std::cos(semicircles2rad(lambda_I - 1.617));
46 LOG_DATA("phi_m {} [semi-circles] (Geomagnetic latitude)", phi_m);
47
48 // Local time [s]
49 double t = std::fmod(4.32e4 * lambda_I + tow, InsTimeUtil::SECONDS_PER_DAY);
50 if (t < 0)
51 {
53 }
54 LOG_DATA("t {} [s] (Local time)", t);
55
56 // Slant factor / obliquity factor [-]
57 double F = 1.0 + 16.0 * std::pow(0.53 - E, 3);
58 LOG_DATA("F {} [-] (Slant factor / obliquity factor)", F);
59
60 // Period of the model in [s]
61 double PER = 0.0;
62 for (size_t n = 0; n < beta.size(); ++n)
63 {
64 PER += beta.at(n) * std::pow(phi_m, n);
65 }
66 PER = std::max(PER, 72000.0);
67 LOG_DATA("PER {} [s] (Period of the model)", PER);
68
69 // Amplitude of the vertical delay in [s]
70 double AMP = 0.0;
71 for (size_t n = 0; n < beta.size(); ++n)
72 {
73 AMP += alpha.at(n) * std::pow(phi_m, n);
74 }
75 AMP = std::max(AMP, 0.0);
76 LOG_DATA("AMP {} [s] (Amplitude of the vertical delay)", AMP);
77
78 // Phase [rad]
79 double x = (2 * M_PI * (t - 50400.0)) / PER;
80 LOG_DATA("x {} [rad] (Phase)", x);
81
82 // Ionospheric delay [s]
83 double T_iono = std::abs(x) < 1.57 ? F * (5e-9 + AMP * (1.0 - std::pow(x, 2) / 2.0 + std::pow(x, 4) / 24.0))
84 : F * 5e-9;
85 LOG_DATA("T_iono_L1 {} [s] (Ionospheric delay)", T_iono);
86
87 // T_iono is referred to the L1 frequency; if the user is operating on the L2 frequency, the correction term must be multiplied by γ
88 T_iono *= ratioFreqSquared(G01, freq, 0, freqNum);
89 LOG_DATA("T_iono {} [s] (Ionospheric delay for requested frequency)", T_iono);
90
91 return T_iono;
92}
93
94} // namespace NAV
Assertion helpers.
GNSS helper functions.
The class is responsible for all time-related tasks.
Klobuchar Ionospheric correction model.
Utility class for logging to console and file.
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
Definition Logger.hpp:29
Frequency definition for different satellite systems.
Definition Frequency.hpp:59
constexpr int32_t SECONDS_PER_DAY
Seconds / Day.
Definition InsTime.hpp:60
double ratioFreqSquared(Frequency f1, Frequency f2, int8_t num1, int8_t num2)
Calculates the ration of the frequencies squared γ
Definition Functions.cpp:24
@ G01
GPS L1 (1575.42 MHz).
Definition Frequency.hpp:28
constexpr auto semicircles2rad(const T &semicircles)
Convert Semicircles to Radians.
Definition Units.hpp:57
constexpr auto rad2semicircles(const T &rad)
Convert Radians to Semicircles.
Definition Units.hpp:66
double calcIonosphericTimeDelay_Klobuchar(double tow, Frequency freq, int8_t freqNum, double latitude, double longitude, double elevation, double azimuth, const std::array< double, 4 > &alpha, const std::array< double, 4 > &beta)
Calculates the ionospheric time delay with the Klobuchar model.
Definition Klobuchar.cpp:21