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 QZSSEphemeris.hpp |
10 |
|
|
/// @brief QZSS Ephemeris information |
11 |
|
|
/// @author P. Peitschat (Hiwi) |
12 |
|
|
/// @author T. Topp (topp@ins.uni-stuttgart.de) |
13 |
|
|
/// @date 2023-10-23 |
14 |
|
|
|
15 |
|
|
#pragma once |
16 |
|
|
|
17 |
|
|
#include <bitset> |
18 |
|
|
|
19 |
|
|
#include "Navigation/GNSS/Satellite/internal/SatNavData.hpp" |
20 |
|
|
|
21 |
|
|
#include "Navigation/Time/InsTime.hpp" |
22 |
|
|
|
23 |
|
|
namespace NAV |
24 |
|
|
{ |
25 |
|
|
|
26 |
|
|
/// @brief Broadcasted ephemeris message data |
27 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, Table 4.1.2-4, p.46 and Table 4.1.2-7, p.49 |
28 |
|
|
class QZSSEphemeris final : public SatNavData |
29 |
|
|
{ |
30 |
|
|
public: |
31 |
|
|
// ####################################################################################################### |
32 |
|
|
// Members |
33 |
|
|
// ####################################################################################################### |
34 |
|
|
|
35 |
|
|
// ------------------------------------------ Time Parameters -------------------------------------------- |
36 |
|
|
|
37 |
|
|
/// @brief Time of Clock |
38 |
|
|
const InsTime toc; |
39 |
|
|
|
40 |
|
|
/// @brief Time of Ephemeris |
41 |
|
|
const InsTime toe; |
42 |
|
|
|
43 |
|
|
/// @brief Issue of Data, Ephemeris |
44 |
|
|
/// |
45 |
|
|
/// Users can detect the update of the ephemeris parameter by IODE |
46 |
|
|
/// |
47 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 4.1.2.4, p.50 |
48 |
|
|
const size_t IODE; |
49 |
|
|
|
50 |
|
|
/// @brief Issue of Data, Clock |
51 |
|
|
/// |
52 |
|
|
/// Users can detect the update of SV clock parameter by IODC |
53 |
|
|
/// 2 MSBs (most significant bit) of IODC indicate fit intervals: |
54 |
|
|
/// -------------------------------------------------- |
55 |
|
|
/// | 2 MSBs of IODC(binary) | Fit intervals(minutes) |
56 |
|
|
/// -------------------------------------------------- |
57 |
|
|
/// | 00 | 15 |
58 |
|
|
/// | 01 | 30 |
59 |
|
|
/// | 10 | 60 |
60 |
|
|
/// | 11 | 120 |
61 |
|
|
/// -------------------------------------------------- |
62 |
|
|
/// |
63 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 4.1.2.3, p.48 |
64 |
|
|
const size_t IODC; |
65 |
|
|
|
66 |
|
|
/// Polynomial coefficients for clock correction |
67 |
|
|
/// - a(0) bias [s] |
68 |
|
|
/// - a(1) drift [s/s] |
69 |
|
|
/// - a(2) drift rate (aging) [s/s^2] |
70 |
|
|
/// |
71 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 5.5.1, p.130 |
72 |
|
|
const std::array<double, 3> a; |
73 |
|
|
|
74 |
|
|
// --------------------------------------- Keplerian Parameters ------------------------------------------ |
75 |
|
|
|
76 |
|
|
const double sqrt_A; ///< Square root of the semi-major axis [m^1/2] |
77 |
|
|
const double e; ///< Eccentricity [-] |
78 |
|
|
const double i_0; ///< Inclination angle at reference time [rad] |
79 |
|
|
const double Omega_0; ///< Longitude of the ascending node at reference time [rad] |
80 |
|
|
const double omega; ///< Argument of perigee [rad] |
81 |
|
|
const double M_0; ///< Mean anomaly at reference time [rad] |
82 |
|
|
|
83 |
|
|
// -------------------------------------- Pertubation Parameters ----------------------------------------- |
84 |
|
|
|
85 |
|
|
const double delta_n; ///< Mean motion difference from computed value [rad/s] |
86 |
|
|
const double Omega_dot; ///< Rate of right ascension [rad/s] |
87 |
|
|
const double i_dot; ///< Rate of inclination angle [rad/s] |
88 |
|
|
const double Cus; ///< Amplitude of the sine harmonic correction term to the argument of latitude [rad] |
89 |
|
|
const double Cuc; ///< Amplitude of the cosine harmonic correction term to the argument of latitude [rad] |
90 |
|
|
const double Cis; ///< Amplitude of the sine harmonic correction term to the angle of inclination [rad] |
91 |
|
|
const double Cic; ///< Amplitude of the cosine harmonic correction term to the angle of inclination [rad] |
92 |
|
|
const double Crs; ///< Amplitude of the sine harmonic correction term to the orbit radius [m] |
93 |
|
|
const double Crc; ///< Amplitude of the cosine harmonic correction term to the orbit radius [m] |
94 |
|
|
|
95 |
|
|
// ----------------------------------------------- Other ------------------------------------------------- |
96 |
|
|
|
97 |
|
|
/// @brief SV accuracy [m] |
98 |
|
|
/// |
99 |
|
|
/// Derived from an URA index of the SV for the standard positioning service user. |
100 |
|
|
/// |
101 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 4.1.2.3, p.47 |
102 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 5.4.3, p.125 ff. |
103 |
|
|
/// @note See \cite IS-GPS-200M GPS ICD, ch. 20.3.3.3.1.3, p.92ff |
104 |
|
|
const double svAccuracy; |
105 |
|
|
|
106 |
|
|
/// @brief SV health |
107 |
|
|
/// |
108 |
|
|
/// This consists of the 1MSB health and the 5LSBs health |
109 |
|
|
/// |
110 |
|
|
/// 1-bit Health |
111 |
|
|
/// -------------------------------------------------- |
112 |
|
|
/// Bit Location | Name | Target Signal |
113 |
|
|
/// -------------------------------------------------- |
114 |
|
|
/// 1st bit (MSB) | L1 Health | L1C/A or L1C/B |
115 |
|
|
/// -------------------------------------------------- |
116 |
|
|
/// |
117 |
|
|
/// 5-bit Health |
118 |
|
|
/// -------------------------------------------------- |
119 |
|
|
/// Bit Location | Name | Target Signal |
120 |
|
|
/// -------------------------------------------------- |
121 |
|
|
/// 1st bit (MSB) | L1C/A Health | L1C/A |
122 |
|
|
/// 2nd bit | L2 Health | L2C |
123 |
|
|
/// 3rd bit | L5 Health | L5 |
124 |
|
|
/// 4th bit | L1C Health | L1C |
125 |
|
|
/// 5th bit (LSB) | L1C/B Health | L1C/B |
126 |
|
|
/// -------------------------------------------------- |
127 |
|
|
/// |
128 |
|
|
/// The 5-bit health parameter is defined differently from GPS. For details, see \cite IS-QZSS-PNT-005 IS QZSS, ch. 4.1.2.7, p.61 |
129 |
|
|
/// |
130 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 4.1.2.3, p.47 |
131 |
|
|
const std::bitset<6> svHealth; |
132 |
|
|
|
133 |
|
|
/// @brief Indicate which code(s) is (are) commanded ON for the in-phase component of the L2 channel. |
134 |
|
|
/// |
135 |
|
|
/// Fixed to '2'. |
136 |
|
|
/// |
137 |
|
|
/// @note See \cite IS-GPS-200M GPS ICD, ch. 20.3.3.3.1.2, p.92 |
138 |
|
|
/// @note See \cite RINEX-3.04, A31 |
139 |
|
|
const uint8_t L2ChannelCodes; |
140 |
|
|
|
141 |
|
|
/// @brief Data Flag for L2 P-Code |
142 |
|
|
/// |
143 |
|
|
/// Fixed to '1' since QZSS does not track L2P. |
144 |
|
|
/// |
145 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 4.1.2.3, p.48 |
146 |
|
|
const bool L2DataFlagPCode; |
147 |
|
|
|
148 |
|
|
/// @brief Group delay between SV clock and L1C/A [s] |
149 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 5.8, p.141 ff. |
150 |
|
|
const double T_GD; |
151 |
|
|
|
152 |
|
|
/// @brief Fit Interval period of the ephemeris |
153 |
|
|
/// |
154 |
|
|
/// "0": 2 hours |
155 |
|
|
/// "1": Greater than 2 hours |
156 |
|
|
/// |
157 |
|
|
/// For QZSS always fixed to "0", since fit interval period of the ephemeris is 2 hours (see Table 4.1.1-2.). |
158 |
|
|
/// |
159 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 4.1.2.4, p.50 |
160 |
|
|
const bool fitIntervalFlag; |
161 |
|
|
|
162 |
|
|
// ####################################################################################################### |
163 |
|
|
// Functions |
164 |
|
|
// ####################################################################################################### |
165 |
|
|
|
166 |
|
|
/// @brief Constructor |
167 |
|
|
/// @param[in] toc Time the Clock information is calculated (Time of Clock) |
168 |
|
|
/// @param[in] toe Time the Orbit information is calculated (Time of Ephemeris) |
169 |
|
|
/// @param[in] IODE Issue of Data, Ephemeris |
170 |
|
|
/// @param[in] IODC Issue of Data, Clock |
171 |
|
|
/// @param[in] a Polynomial coefficients for clock correction (a0 bias [s], a1 drift [s/s], a2 drift rate (aging) [s/s^2]) |
172 |
|
|
/// @param[in] sqrt_A Square root of the semi-major axis [m^1/2] |
173 |
|
|
/// @param[in] e Eccentricity [-] |
174 |
|
|
/// @param[in] i_0 Inclination angle at reference time [rad] |
175 |
|
|
/// @param[in] Omega_0 Longitude of the ascending node at reference time [rad] |
176 |
|
|
/// @param[in] omega Argument of perigee [rad] |
177 |
|
|
/// @param[in] M_0 Mean anomaly at reference time [rad] |
178 |
|
|
/// @param[in] delta_n Mean motion difference from computed value [rad/s] |
179 |
|
|
/// @param[in] Omega_dot Rate of change of right ascension [rad/s] |
180 |
|
|
/// @param[in] i_dot Rate of change of inclination [rad/s] |
181 |
|
|
/// @param[in] Cus Amplitude of the sine harmonic correction term to the argument of latitude [rad] |
182 |
|
|
/// @param[in] Cuc Amplitude of the cosine harmonic correction term to the argument of latitude [rad] |
183 |
|
|
/// @param[in] Cis Amplitude of the sine harmonic correction term to the angle of inclination [rad] |
184 |
|
|
/// @param[in] Cic Amplitude of the cosine harmonic correction term to the angle of inclination [rad] |
185 |
|
|
/// @param[in] Crs Amplitude of the sine harmonic correction term to the orbit radius [m] |
186 |
|
|
/// @param[in] Crc Amplitude of the cosine harmonic correction term to the orbit radius [m] |
187 |
|
|
/// @param[in] svAccuracy SV accuracy [m] |
188 |
|
|
/// @param[in] svHealth SV Health |
189 |
|
|
/// @param[in] L2ChannelCodes Indicate which code(s) is (are) commanded ON for the in-phase component of the L2 channel |
190 |
|
|
/// @param[in] L2DataFlagPCode Data Flag for L2 P-Code (fixed to '1') |
191 |
|
|
/// @param[in] T_GD Group delay between SV clock and L1C/A [s] |
192 |
|
|
/// @param[in] fitIntervalFlag Fit Interval period of the ephemeris |
193 |
|
|
QZSSEphemeris(const InsTime& toc, const InsTime& toe, |
194 |
|
|
const size_t& IODE, const size_t& IODC, |
195 |
|
|
const std::array<double, 3>& a, |
196 |
|
|
const double& sqrt_A, const double& e, const double& i_0, const double& Omega_0, const double& omega, const double& M_0, |
197 |
|
|
const double& delta_n, const double& Omega_dot, const double& i_dot, const double& Cus, const double& Cuc, |
198 |
|
|
const double& Cis, const double& Cic, const double& Crs, const double& Crc, |
199 |
|
|
const double& svAccuracy, uint8_t svHealth, |
200 |
|
|
uint8_t L2ChannelCodes, bool L2DataFlagPCode, |
201 |
|
|
const double& T_GD, bool fitIntervalFlag); |
202 |
|
|
|
203 |
|
|
#ifdef TESTING |
204 |
|
|
/// @brief Constructor for pasting raw data from Nav files |
205 |
|
|
/// @param[in] year Time of Clock year |
206 |
|
|
/// @param[in] month Time of Clock month |
207 |
|
|
/// @param[in] day Time of Clock day |
208 |
|
|
/// @param[in] hour Time of Clock hour |
209 |
|
|
/// @param[in] minute Time of Clock minute |
210 |
|
|
/// @param[in] second Time of Clock second |
211 |
|
|
/// @param[in] svClockBias Clock correction a(0) bias [s] |
212 |
|
|
/// @param[in] svClockDrift Clock correction a(1) drift [s/s] |
213 |
|
|
/// @param[in] svClockDriftRate Clock correction a(2) drift rate (aging) [s/s^2] |
214 |
|
|
/// @param[in] IODE Issue of Data, Ephemeris |
215 |
|
|
/// @param[in] Crs Amplitude of the sine harmonic correction term to the orbit radius [m] |
216 |
|
|
/// @param[in] delta_n Mean motion difference from computed value [rad/s] |
217 |
|
|
/// @param[in] M_0 Mean anomaly at reference time [rad] |
218 |
|
|
/// @param[in] Cuc Amplitude of the cosine harmonic correction term to the argument of latitude [rad] |
219 |
|
|
/// @param[in] e Eccentricity [-] |
220 |
|
|
/// @param[in] Cus Amplitude of the sine harmonic correction term to the argument of latitude [rad] |
221 |
|
|
/// @param[in] sqrt_A Square root of the semi-major axis [m^1/2] |
222 |
|
|
/// @param[in] Toe Time of Ephemeris |
223 |
|
|
/// @param[in] Cic Amplitude of the cosine harmonic correction term to the angle of inclination [rad] |
224 |
|
|
/// @param[in] Omega_0 Longitude of the ascending node at reference time [rad] |
225 |
|
|
/// @param[in] Cis Amplitude of the sine harmonic correction term to the angle of inclination [rad] |
226 |
|
|
/// @param[in] i_0 Inclination angle at reference time [rad] |
227 |
|
|
/// @param[in] Crc Amplitude of the cosine harmonic correction term to the orbit radius [m] |
228 |
|
|
/// @param[in] omega Argument of perigee [rad] |
229 |
|
|
/// @param[in] Omega_dot Rate of change of right ascension [rad/s] |
230 |
|
|
/// @param[in] i_dot Rate of change of inclination [rad/s] |
231 |
|
|
/// @param[in] L2ChannelCodes Indicate which code(s) is (are) commanded ON for the in-phase component of the L2 channel. |
232 |
|
|
/// @param[in] GPSWeek GPS Week to go with Toe |
233 |
|
|
/// @param[in] L2DataFlagPCode Data Flag for L2 P-Code |
234 |
|
|
/// @param[in] svAccuracy SV accuracy [m] |
235 |
|
|
/// @param[in] svHealth SV health |
236 |
|
|
/// @param[in] T_GD Estimated Group Delay Differential. L1 and L2 correction term [s] |
237 |
|
|
/// @param[in] IODC Issue of Data, Clock |
238 |
|
|
/// @param[in] TransmissionTimeOfMessage Transmission time of message |
239 |
|
|
/// @param[in] fitIntervalFlag Fit Interval period of the ephemeris |
240 |
|
|
/// @param[in] spare1 Spare data |
241 |
|
|
/// @param[in] spare2 Spare data |
242 |
|
|
QZSSEphemeris(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t minute, double second, double svClockBias, double svClockDrift, double svClockDriftRate, |
243 |
|
|
double IODE, double Crs, double delta_n, double M_0, |
244 |
|
|
double Cuc, double e, double Cus, double sqrt_A, |
245 |
|
|
double Toe, double Cic, double Omega_0, double Cis, |
246 |
|
|
double i_0, double Crc, double omega, double Omega_dot, |
247 |
|
|
double i_dot, double L2ChannelCodes, double GPSWeek, double L2DataFlagPCode, |
248 |
|
|
double svAccuracy, double svHealth, double T_GD, double IODC, |
249 |
|
|
double TransmissionTimeOfMessage, double fitIntervalFlag, double spare1 = 0.0, double spare2 = 0.0); |
250 |
|
|
#endif |
251 |
|
|
|
252 |
|
|
/// @brief Destructor |
253 |
|
2172 |
~QZSSEphemeris() final = default; |
254 |
|
|
/// @brief Copy Constructor |
255 |
|
|
QZSSEphemeris(const QZSSEphemeris&) = default; |
256 |
|
|
/// @brief Move Constructor |
257 |
|
|
QZSSEphemeris(QZSSEphemeris&&) = default; |
258 |
|
|
/// @brief Copy assignment operator |
259 |
|
|
QZSSEphemeris& operator=(const QZSSEphemeris&) = delete; |
260 |
|
|
/// @brief Move assignment operator |
261 |
|
|
QZSSEphemeris& operator=(QZSSEphemeris&&) = delete; |
262 |
|
|
|
263 |
|
|
/// @brief Calculates the Variance of the satellite position in [m^2] |
264 |
|
|
[[nodiscard]] double calcSatellitePositionVariance() const final; |
265 |
|
|
|
266 |
|
|
/// @brief Calculates clock bias and drift of the satellite |
267 |
|
|
/// @param[in] recvTime Receive time of the signal |
268 |
|
|
/// @param[in] dist Distance between receiver and satellite (normally the pseudorange) [m] |
269 |
|
|
/// @param[in] freq Signal Frequency |
270 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 5.5.2, p.130 |
271 |
|
|
[[nodiscard]] Corrections calcClockCorrections(const InsTime& recvTime, double dist, const Frequency& freq) const final; |
272 |
|
|
|
273 |
|
|
/// @brief Checks whether the signal is healthy |
274 |
|
|
[[nodiscard]] bool isHealthy() const final; |
275 |
|
|
|
276 |
|
|
private: |
277 |
|
|
/// @brief Calculates position, velocity and acceleration of the satellite at transmission time |
278 |
|
|
/// @param[in] transTime Transmit time of the signal |
279 |
|
|
/// @param[in] calc Flags which determine what should be calculated and returned |
280 |
|
|
/// @note See \cite IS-QZSS-PNT-005 IS QZSS, ch. 5.6.1.2, p.133 ff. |
281 |
|
|
/// @note See \cite IS-GPS-200M IS-GPS-200 ch. 20.3.3.4.3.1 Table 20-IV p.106-109 |
282 |
|
|
[[nodiscard]] PosVelAccel calcSatelliteData(const InsTime& transTime, Orbit::Calc calc) const final; |
283 |
|
|
}; |
284 |
|
|
|
285 |
|
|
} // namespace NAV |
286 |
|
|
|