0.3.0
Loading...
Searching...
No Matches
TightlyCoupledKF.hpp
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
13
14#pragma once
15
16/*
17
18#include "Navigation/GNSS/Core/SatelliteSystem.hpp"
19#include "internal/Node/Node.hpp"
20#include "Navigation/GNSS/Core/Frequency.hpp"
21#include "Navigation/GNSS/Core/Code.hpp"
22#include "Navigation/Time/InsTime.hpp"
23#include "NodeData/State/PosVelAtt.hpp"
24#include "NodeData/GNSS/GnssObs.hpp"
25#include "Navigation/INS/InertialIntegrator.hpp"
26#include "Navigation/GNSS/Positioning/ReceiverClock.hpp"
27#include "Navigation/Atmosphere/Ionosphere/Ionosphere.hpp"
28#include "Navigation/Atmosphere/Troposphere/Troposphere.hpp"
29#include "Navigation/GNSS/Positioning/SPP/Algorithm.hpp"
30#include "NodeData/State/InsGnssTCKFSolution.hpp"
31#include "NodeData/IMU/ImuObs.hpp"
32
33#include "Navigation/Math/KalmanFilter.hpp"
34#include "Navigation/Transformations/Units.hpp"
35
36namespace NAV
37{
39class TightlyCoupledKF : public Node
40{
41 public:
43 TightlyCoupledKF();
45 ~TightlyCoupledKF() override;
47 TightlyCoupledKF(const TightlyCoupledKF&) = delete;
49 TightlyCoupledKF(TightlyCoupledKF&&) = delete;
51 TightlyCoupledKF& operator=(const TightlyCoupledKF&) = delete;
53 TightlyCoupledKF& operator=(TightlyCoupledKF&&) = delete;
55 [[nodiscard]] static std::string typeStatic();
57 [[nodiscard]] std::string type() const override;
59 [[nodiscard]] static std::string category();
60
63 void guiConfig() override;
64
66 [[nodiscard]] json save() const override;
67
70 void restore(const json& j) override;
71
72 private:
73 constexpr static size_t INPUT_PORT_INDEX_IMU = 0; ///< @brief Flow (ImuObs)
74 constexpr static size_t INPUT_PORT_INDEX_GNSS_OBS = 1; ///< @brief Flow (GnssObs)
75 constexpr static size_t INPUT_PORT_INDEX_POS_VEL_ATT_INIT = 2; ///< @brief Flow (PosVelAtt)
76 constexpr static size_t INPUT_PORT_INDEX_GNSS_NAV_INFO = 2; ///< @brief GnssNavInfo
77 constexpr static size_t OUTPUT_PORT_INDEX_SOLUTION = 0; ///< @brief Flow (InsGnssTCKFSolution)
78 constexpr static size_t OUTPUT_PORT_INDEX_x = 1; ///< @brief x̂ State vector
79 constexpr static size_t OUTPUT_PORT_INDEX_P = 2; ///< @brief 𝐏 Error covariance matrix
80 constexpr static size_t OUTPUT_PORT_INDEX_Phi = 3; ///< @brief 𝚽 State transition matrix
81 constexpr static size_t OUTPUT_PORT_INDEX_Q = 4; ///< @brief 𝐐 System/Process noise covariance matrix
82 constexpr static size_t OUTPUT_PORT_INDEX_z = 5; ///< @brief 𝐳 Measurement vector
83 constexpr static size_t OUTPUT_PORT_INDEX_H = 6; ///< @brief 𝐇 Measurement sensitivity Matrix
84 constexpr static size_t OUTPUT_PORT_INDEX_R = 7; ///< @brief 𝐑 = 𝐸{𝐰ₘ𝐰ₘᵀ} Measurement noise covariance matrix
85 constexpr static size_t OUTPUT_PORT_INDEX_K = 8; ///< @brief 𝐊 Kalman gain matrix
86
88 bool initialize() override;
89
91 void deinitialize() override;
92
95 void invokeCallbackWithPosVelAtt(const PosVelAtt& posVelAtt);
96
100 void recvImuObservation(InputPin::NodeDataQueue& queue, size_t pinIdx);
101
105 void recvGnssObs(InputPin::NodeDataQueue& queue, size_t pinIdx);
106
110 void recvPosVelAttInit(InputPin::NodeDataQueue& queue, size_t pinIdx);
111
116 void tightlyCoupledPrediction(const std::shared_ptr<const PosVelAtt>& inertialNavSol, double tau_i, const ImuPos& imuPos);
117
120 void tightlyCoupledUpdate(const std::shared_ptr<const GnssObs>& gnssObservation);
121
123 void addKalmanMatricesPins();
124
126 void removeKalmanMatricesPins();
127
129 void updateExternalPvaInitPin();
130
132 int _dragAndDropPinIndex = -1;
134 size_t _nNavInfoPins = 1;
136 void updateNumberOfInputPins();
137
139 InertialIntegrator _inertialIntegrator;
141 bool _preferAccelerationOverDeltaMeasurements = false;
142
144 std::shared_ptr<const ImuObs> _lastImuObs = nullptr;
145
147 std::array<double, 3> _initalRollPitchYaw{};
149 bool _initializeStateOverExternalPin{};
151 InsTime _externalInitTime;
152
154 ReceiverClock _recvClk{ std::vector<SatelliteSystem>{ GPS } };
155
157 Frequency _filterFreq = G01;
159 Code _filterCode = Code_Default;
161 std::vector<SatId> _excludedSatellites;
163 double _elevationMask = static_cast<double>(15.0_deg);
164
166 IonosphereModel _ionosphereModel = IonosphereModel::Klobuchar;
167
169 TroposphereModelSelection _troposphereModels;
170
172 std::vector<SPP::States::StateKeyType> _interSysErrs;
175 std::vector<SPP::States::StateKeyType> _interSysDrifts;
176
178 InsTime _lastEpochTime; // TODO: Remove?
179
181 KalmanFilter _kalmanFilter{ 17, 8 };
182
183 // ###########################################################################################################
184 // GUI Settings
185 // ###########################################################################################################
186
188 bool _showKalmanFilterOutputPins = false;
189
191 bool _checkKalmanMatricesRanks = true;
192
193 // ###########################################################################################################
194 // Parameters
195 // ###########################################################################################################
196
198 Eigen::Vector3d _b_leverArm_InsGnss{ 0.0, 0.0, 0.0 };
199
200 // ###########################################################################################################
201
203 enum class StdevAccelNoiseUnits : uint8_t
204 {
205 mg_sqrtHz, ///< [mg / √(Hz)]
206 m_s2_sqrtHz, ///< [m / s^2 / √(Hz)]
207 };
209 StdevAccelNoiseUnits _stdevAccelNoiseUnits = StdevAccelNoiseUnits::mg_sqrtHz;
210
213 Eigen::Vector3d _stdev_ra = 0.04 * Eigen::Vector3d::Ones(); // [mg/√(Hz)]
214
215 // ###########################################################################################################
216
218 enum class StdevGyroNoiseUnits : uint8_t
219 {
220 deg_hr_sqrtHz, ///< [deg / hr /√(Hz)]
221 rad_s_sqrtHz, ///< [rad / s /√(Hz)]
222 };
224 StdevGyroNoiseUnits _stdevGyroNoiseUnits = StdevGyroNoiseUnits::deg_hr_sqrtHz;
225
228 Eigen::Vector3d _stdev_rg = 5 * Eigen::Vector3d::Ones(); // [deg/hr/√(Hz)]^2
229
230 // ###########################################################################################################
231
233 enum class StdevAccelBiasUnits : uint8_t
234 {
235 microg, ///< [µg]
236 m_s2, ///< [m / s^2]
237 };
239 StdevAccelBiasUnits _stdevAccelBiasUnits = StdevAccelBiasUnits::microg;
240
243 Eigen::Vector3d _stdev_bad = 10 * Eigen::Vector3d::Ones(); // [µg]
244
246 Eigen::Vector3d _tau_bad = 0.1 * Eigen::Vector3d::Ones();
247
248 // ###########################################################################################################
249
251 enum class StdevGyroBiasUnits : uint8_t
252 {
253 deg_h, ///< [°/h]
254 rad_s, ///< [1/s]
255 };
257 StdevGyroBiasUnits _stdevGyroBiasUnits = StdevGyroBiasUnits::deg_h;
258
261 Eigen::Vector3d _stdev_bgd = 1 * Eigen::Vector3d::Ones(); // [°/h]
262
264 Eigen::Vector3d _tau_bgd = 0.1 * Eigen::Vector3d::Ones();
265
266 // ###########################################################################################################
267
269 enum class StdevClockPhaseUnits : uint8_t
270 {
271 m_sqrtHz, ///< [m / √(Hz)]
272 };
274 StdevClockPhaseUnits _stdevClockPhaseUnits = StdevClockPhaseUnits::m_sqrtHz;
275
278 double _stdev_cp = 0; // [m / √(Hz)]
279
280 // ###########################################################################################################
281
283 enum class StdevClockFreqUnits : uint8_t
284 {
285 m_s_sqrtHz, ///< [m / s / √(Hz)]
286 };
288 StdevClockFreqUnits _stdevClockFreqUnits = StdevClockFreqUnits::m_s_sqrtHz;
289
292 double _stdev_cf = 5; // [m / s / √(Hz)]
293
294 // ###########################################################################################################
295
296 // TODO: Replace with GNSS Measurement Error Model (see SPP node)
297 // /// Possible Units for the Standard deviation of the pseudorange measurement
298 // enum class GnssMeasurementUncertaintyPseudorangeUnit : uint8_t
299 // {
300 // meter2, ///< Variance [m²]
301 // meter, ///< Standard deviation [m]
302 // };
303 // /// Gui selection for the Unit of the input gnssMeasurementUncertaintyPseudorangeUnit parameter
304 // GnssMeasurementUncertaintyPseudorangeUnit _gnssMeasurementUncertaintyPseudorangeUnit = GnssMeasurementUncertaintyPseudorangeUnit::meter;
305
306 // /// @brief GUI selection of the GNSS pseudorange measurement uncertainty (standard deviation σ or Variance σ²).
307 // double _gnssMeasurementUncertaintyPseudorange = 5; // [m]
308
309 // // ###########################################################################################################
310
311 // /// Possible Units for the Standard deviation of the pseudorange-rate measurement
312 // enum class GnssMeasurementUncertaintyPseudorangeRateUnit : uint8_t
313 // {
314 // m2_s2, ///< Variance [m²/s²]
315 // m_s, ///< Standard deviation [m/s]
316 // };
317 // /// Gui selection for the Unit of the input gnssMeasurementUncertaintyPseudorangeRateUnit parameter
318 // GnssMeasurementUncertaintyPseudorangeRateUnit _gnssMeasurementUncertaintyPseudorangeRateUnit = GnssMeasurementUncertaintyPseudorangeRateUnit::m_s;
319
320 // /// @brief GUI selection of the GNSS pseudorange-rate measurement uncertainty (standard deviation σ or Variance σ²).
321 // double _gnssMeasurementUncertaintyPseudorangeRate = 5; // [m/s]
322
323 // ###########################################################################################################
324
326 enum class RandomProcess : uint8_t
327 {
328 // WhiteNoise, ///< White noise
329 // RandomConstant, ///< Random constant
330
331 RandomWalk, ///< Random Walk
332 GaussMarkov1, ///< Gauss-Markov 1st Order
333
334 // GaussMarkov2, ///< Gauss-Markov 2nd Order
335 // GaussMarkov3, ///< Gauss-Markov 3rd Order
336 };
337
339 RandomProcess _randomProcessAccel = RandomProcess::RandomWalk;
341 RandomProcess _randomProcessGyro = RandomProcess::RandomWalk;
342
343 // ###########################################################################################################
344
346 enum class InitCovarianceClockPhaseUnit : uint8_t
347 {
348 m2, ///< Variance [m²]
349 s2, ///< Variance [s²]
350 m, ///< Standard deviation [m]
351 s ///< Standard deviation [s]
352 };
354 InitCovarianceClockPhaseUnit _initCovariancePhaseUnit = InitCovarianceClockPhaseUnit::m;
355
357 double _initCovariancePhase{ 5 };
358
359 // ###########################################################################################################
360
362 enum class InitCovarianceClockFreqUnit : uint8_t
363 {
364 m2_s2, ///< Variance [m²/s²]
365 m_s, ///< Standard deviation [m/s]
366 };
368 InitCovarianceClockFreqUnit _initCovarianceFreqUnit = InitCovarianceClockFreqUnit::m_s;
369
371 double _initCovarianceFreq{ 5 };
372
373 // ###########################################################################################################
374
376 enum class InitCovariancePositionUnit : uint8_t
377 {
378 rad2_rad2_m2, ///< Variance LatLonAlt^2 [rad^2, rad^2, m^2]
379 rad_rad_m, ///< Standard deviation LatLonAlt [rad, rad, m]
380 meter2, ///< Variance NED [m^2, m^2, m^2]
381 meter, ///< Standard deviation NED [m, m, m]
382 };
384 InitCovariancePositionUnit _initCovariancePositionUnit = InitCovariancePositionUnit::meter;
385
387 Eigen::Vector3d _initCovariancePosition{ 100, 100, 100 };
388
389 // ###########################################################################################################
390
392 enum class InitCovarianceVelocityUnit : uint8_t
393 {
394 m2_s2, ///< Variance [m^2/s^2]
395 m_s, ///< Standard deviation [m/s]
396 };
398 InitCovarianceVelocityUnit _initCovarianceVelocityUnit = InitCovarianceVelocityUnit::m_s;
399
401 Eigen::Vector3d _initCovarianceVelocity{ 10, 10, 10 };
402
403 // ###########################################################################################################
404
406 enum class InitCovarianceAttitudeAnglesUnit : uint8_t
407 {
408 rad2, ///< Variance [rad^2]
409 deg2, ///< Variance [deg^2]
410 rad, ///< Standard deviation [rad]
411 deg, ///< Standard deviation [deg]
412 };
414 InitCovarianceAttitudeAnglesUnit _initCovarianceAttitudeAnglesUnit = InitCovarianceAttitudeAnglesUnit::deg;
415
417 Eigen::Vector3d _initCovarianceAttitudeAngles{ 10, 10, 10 };
418
419 // ###########################################################################################################
420
422 enum class InitCovarianceBiasAccelUnit : uint8_t
423 {
424 m2_s4, ///< Variance [m^2/s^4]
425 m_s2, ///< Standard deviation [m/s^2]
426 };
428 InitCovarianceBiasAccelUnit _initCovarianceBiasAccelUnit = InitCovarianceBiasAccelUnit::m_s2;
429
431 Eigen::Vector3d _initCovarianceBiasAccel{ 1, 1, 1 };
432
433 // ###########################################################################################################
434
436 enum class InitCovarianceBiasGyroUnit : uint8_t
437 {
438 rad2_s2, ///< Variance [rad²/s²]
439 deg2_s2, ///< Variance [deg²/s²]
440 rad_s, ///< Standard deviation [rad/s]
441 deg_s, ///< Standard deviation [deg/s]
442 };
444 InitCovarianceBiasGyroUnit _initCovarianceBiasGyroUnit = InitCovarianceBiasGyroUnit::deg_s;
445
447 Eigen::Vector3d _initCovarianceBiasGyro{ 0.5, 0.5, 0.5 };
448
449 // ###########################################################################################################
450
452 enum class PhiCalculationAlgorithm : uint8_t
453 {
454 Exponential, ///< Van-Loan
455 Taylor, ///< Taylor
456 };
458 PhiCalculationAlgorithm _phiCalculationAlgorithm = PhiCalculationAlgorithm::Taylor;
459
461 int _phiCalculationTaylorOrder = 2;
462
464 enum class QCalculationAlgorithm : uint8_t
465 {
466 VanLoan, ///< Van-Loan
467 Taylor1, ///< Taylor
468 };
470 QCalculationAlgorithm _qCalculationAlgorithm = QCalculationAlgorithm::Taylor1;
471
472 // ###########################################################################################################
473
475 enum class InitBiasAccelUnit : uint8_t
476 {
477 m_s2, ///< acceleration [m/s^2]
478 };
480 InitBiasAccelUnit _initBiasAccelUnit = InitBiasAccelUnit::m_s2;
481
483 Eigen::Vector3d _initBiasAccel{ 0.0, 0.0, 0.0 };
484
485 // ###########################################################################################################
486
488 enum class InitBiasGyroUnit : uint8_t
489 {
490 rad_s, ///< angular rate [rad/s]
491 deg_s, ///< angular rate [deg/s]
492 };
494 InitBiasGyroUnit _initBiasGyroUnit = InitBiasGyroUnit::deg_s;
495
497 Eigen::Vector3d _initBiasGyro{ 0.0, 0.0, 0.0 };
498
499 // ###########################################################################################################
500 // Prediction
501 // ###########################################################################################################
502
503 // ------------------------------------------- System matrix 𝐅 ----------------------------------------------
504
518 [[nodiscard]] Eigen::Matrix<double, 17, 17> n_systemMatrix_F(const Eigen::Quaterniond& n_Quat_b,
519 const Eigen::Vector3d& b_specForce_ib,
520 const Eigen::Vector3d& n_omega_in,
521 const Eigen::Vector3d& n_velocity,
522 const Eigen::Vector3d& lla_position,
523 double R_N,
524 double R_E,
525 double g_0,
526 double r_eS_e,
527 const Eigen::Vector3d& tau_bad,
528 const Eigen::Vector3d& tau_bgd) const;
529
540 [[nodiscard]] Eigen::Matrix<double, 17, 17> e_systemMatrix_F(const Eigen::Quaterniond& e_Quat_b,
541 const Eigen::Vector3d& b_specForce_ib,
542 const Eigen::Vector3d& e_position,
543 const Eigen::Vector3d& e_gravitation,
544 double r_eS_e,
545 const Eigen::Vector3d& e_omega_ie,
546 const Eigen::Vector3d& tau_bad,
547 const Eigen::Vector3d& tau_bgd) const;
548
549 // ----------------------------- Noise input matrix 𝐆 & Noise scale matrix 𝐖 -------------------------------
550 // ----------------------------------- System noise covariance matrix 𝐐 -------------------------------------
551
555 [[nodiscard]] static Eigen::Matrix<double, 17, 14> noiseInputMatrix_G(const Eigen::Quaterniond& ien_Quat_b);
556
567 [[nodiscard]] Eigen::Matrix<double, 14, 14> noiseScaleMatrix_W(const Eigen::Vector3d& sigma2_ra, const Eigen::Vector3d& sigma2_rg,
568 const Eigen::Vector3d& sigma2_bad, const Eigen::Vector3d& sigma2_bgd,
569 const Eigen::Vector3d& tau_bad, const Eigen::Vector3d& tau_bgd,
570 const double& sigma2_cPhi, const double& sigma2_cf);
571
586 [[nodiscard]] static Eigen::Matrix<double, 17, 17> n_systemNoiseCovarianceMatrix_Q(const Eigen::Vector3d& sigma2_ra, const Eigen::Vector3d& sigma2_rg,
587 const Eigen::Vector3d& sigma2_bad, const Eigen::Vector3d& sigma2_bgd,
588 const Eigen::Vector3d& tau_bad, const Eigen::Vector3d& tau_bgd,
589 const double& sigma2_cPhi, const double& sigma2_cf,
590 const Eigen::Matrix3d& n_F_21, const Eigen::Matrix3d& T_rn_p,
591 const Eigen::Matrix3d& n_Dcm_b, const double& tau_s);
592
606 [[nodiscard]] static Eigen::Matrix<double, 17, 17> e_systemNoiseCovarianceMatrix_Q(const Eigen::Vector3d& sigma2_ra, const Eigen::Vector3d& sigma2_rg,
607 const Eigen::Vector3d& sigma2_bad, const Eigen::Vector3d& sigma2_bgd,
608 const Eigen::Vector3d& tau_bad, const Eigen::Vector3d& tau_bgd,
609 const double& sigma2_cPhi, const double& sigma2_cf,
610 const Eigen::Matrix3d& e_F_21,
611 const Eigen::Matrix3d& e_Dcm_b, const double& tau_s);
612
613 // --------------------------------------- Error covariance matrix P -----------------------------------------
614
624 [[nodiscard]] Eigen::Matrix<double, 17, 17> initialErrorCovarianceMatrix_P0(const Eigen::Vector3d& variance_angles,
625 const Eigen::Vector3d& variance_vel,
626 const Eigen::Vector3d& variance_pos,
627 const Eigen::Vector3d& variance_accelBias,
628 const Eigen::Vector3d& variance_gyroBias,
629 const double& variance_clkPhase,
630 const double& variance_clkFreq) const;
631
632 // ###########################################################################################################
633 // Update
634 // ###########################################################################################################
635
643 [[nodiscard]] static Eigen::MatrixXd n_measurementMatrix_H(const double& R_N,
644 const double& R_E,
645 const Eigen::Vector3d& lla_position,
646 const std::vector<Eigen::Vector3d>& n_lineOfSightUnitVectors,
647 std::vector<double>& pseudoRangeRateObservations);
648
654 [[nodiscard]] static Eigen::MatrixXd measurementNoiseCovariance_R(const double& sigma_rhoZ,
655 const double& sigma_rZ,
656 const std::vector<double>& satElevation);
657
666 [[nodiscard]] static double sigma2(const double& satElevation,
667 const double& sigma_Z,
668 const double& sigma_C,
669 const double& sigma_A,
670 const double& CN0,
671 const double& rangeAccel);
672
679 [[nodiscard]] static Eigen::MatrixXd measurementInnovation_dz(const std::vector<double>& pseudoRangeObservations,
680 const std::vector<double>& pseudoRangeEstimates,
681 const std::vector<double>& pseudoRangeRateObservations,
682 const std::vector<double>& pseudoRangeRateEstimates);
683};
684
685} // namespace NAV
686
687*/