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 Mechanization.hpp | ||
10 | /// @brief Inertial Navigation Mechanization Functions in ECEF frame | ||
11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
12 | /// @date 2022-06-12 | ||
13 | |||
14 | #pragma once | ||
15 | |||
16 | #include "Navigation/Gravity/Gravity.hpp" | ||
17 | |||
18 | #include <Eigen/Core> | ||
19 | #include <Eigen/Dense> | ||
20 | |||
21 | #include "Navigation/Constants.hpp" | ||
22 | #include "Navigation/Ellipsoid/Ellipsoid.hpp" | ||
23 | #include "Navigation/INS/Functions.hpp" | ||
24 | #include "Navigation/INS/Mechanization.hpp" | ||
25 | #include "Navigation/Math/Math.hpp" | ||
26 | #include "Navigation/Transformations/CoordinateFrames.hpp" | ||
27 | #include "util/Logger.hpp" | ||
28 | |||
29 | #include <cmath> | ||
30 | |||
31 | namespace NAV | ||
32 | { | ||
33 | /// @brief Calculates the time derivative of the quaternion e_Quat_b | ||
34 | /// | ||
35 | /// \anchor eq-INS-Mechanization-e_Quat_b-dot \f{equation}{ \label{eq:eq-INS-Mechanization-e_Quat_b-dot} | ||
36 | /// \mathbf{\dot{q}}_b^e | ||
37 | /// = \begin{bmatrix} \dot{w} \\ \dot{x} \\ \dot{y} \\ \dot{z} \end{bmatrix} | ||
38 | /// = \frac{1}{2} \begin{bmatrix} 0 & -\omega_{eb,x}^b & -\omega_{eb,y}^b & -\omega_{eb,z}^b \\ | ||
39 | /// \omega_{eb,x}^b & 0 & \omega_{eb,z}^b & -\omega_{eb,y}^b \\ | ||
40 | /// \omega_{eb,y}^b & -\omega_{eb,z}^b & 0 & \omega_{eb,x}^b \\ | ||
41 | /// \omega_{eb,z}^b & \omega_{eb,y}^b & -\omega_{eb,x}^b & 0 \end{bmatrix} | ||
42 | /// \begin{bmatrix} w \\ x \\ y \\ z \end{bmatrix} | ||
43 | /// \f} | ||
44 | /// | ||
45 | /// @param[in] b_omega_eb ω_eb_b Body rate with respect to the ECEF frame, expressed in the body frame | ||
46 | /// @param[in] e_Quat_b_coeffs Coefficients of the quaternion e_Quat_b in order w, x, y, z (q = w + ix + jy + kz) | ||
47 | /// @return The time derivative of the coefficients of the quaternion e_Quat_b in order w, x, y, z (q = w + ix + jy + kz) | ||
48 | /// | ||
49 | /// @note See \ref ImuIntegrator-Mechanization-e-Attitude-Quaternion equation \ref eq-ImuIntegrator-Mechanization-e-Attitude-Quaternion-matrix | ||
50 | template<typename DerivedA, typename DerivedB> | ||
51 | 38664 | Eigen::Vector4<typename DerivedA::Scalar> calcTimeDerivativeFor_e_Quat_b(const Eigen::MatrixBase<DerivedA>& b_omega_eb, | |
52 | const Eigen::MatrixBase<DerivedB>& e_Quat_b_coeffs) | ||
53 | { | ||
54 | // Angular rates in matrix form (Titterton (2005), eq. (11.35)) | ||
55 |
1/2✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
|
38664 | Eigen::Matrix4<typename DerivedA::Scalar> A; |
56 | |||
57 | // clang-format off | ||
58 |
7/14✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38664 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 38664 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 38664 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 38664 times.
✗ Branch 20 not taken.
|
38664 | A << 0.0 , -b_omega_eb(0), -b_omega_eb(1), -b_omega_eb(2), |
59 |
7/14✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38664 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 38664 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 38664 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 38664 times.
✗ Branch 20 not taken.
|
38664 | b_omega_eb(0), 0.0 , b_omega_eb(2), -b_omega_eb(1), |
60 |
7/14✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38664 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 38664 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 38664 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 38664 times.
✗ Branch 20 not taken.
|
38664 | b_omega_eb(1), -b_omega_eb(2), 0.0 , b_omega_eb(0), |
61 |
7/14✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38664 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 38664 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 38664 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 38664 times.
✗ Branch 20 not taken.
|
38664 | b_omega_eb(2), b_omega_eb(1), -b_omega_eb(0), 0.0 ; |
62 | // clang-format on | ||
63 | |||
64 | // Propagation of an attitude Quaternion with time (Titterton, ch. 11.2.5, eq. 11.33-11.35, p. 319) | ||
65 |
3/6✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
|
77328 | return 0.5 * A * e_Quat_b_coeffs; // (w, x, y, z) |
66 | } | ||
67 | |||
68 | /// @brief Calculates the time derivative of the velocity in ECEF frame coordinates | ||
69 | /// | ||
70 | /// \anchor eq-INS-Mechanization-v_e-dot \f{equation}{ \label{eq:eq-INS-Mechanization-v_e-dot} | ||
71 | /// \boldsymbol{\dot{v}}^e | ||
72 | /// = \overbrace{\boldsymbol{f}^e}^{\text{measured}} | ||
73 | /// -\ \underbrace{2 \boldsymbol{\omega}_{ie}^e \times \boldsymbol{v}^e}_{\text{coriolis acceleration}} | ||
74 | /// +\ \overbrace{\mathbf{g}^e}^{\text{gravitation}} | ||
75 | /// -\ \underbrace{\left(\boldsymbol{\omega}_{ie}^e \times [ \boldsymbol{\omega}_{ie}^e \times \mathbf{x}^e ] \right)}_{\text{centrifugal acceleration}} | ||
76 | /// \f} | ||
77 | /// | ||
78 | /// @param[in] e_measuredForce f_e Specific force vector as measured by a triad of accelerometers and resolved into ECEF frame coordinates | ||
79 | /// @param[in] e_coriolisAcceleration Coriolis acceleration in ECEF coordinates in [m/s^2] | ||
80 | /// @param[in] e_gravitation Local gravitation vector (caused by effects of mass attraction) in ECEF frame coordinates [m/s^2] | ||
81 | /// @param[in] e_centrifugalAcceleration Centrifugal acceleration in ECEF coordinates in [m/s^2] | ||
82 | /// @return The time derivative of the velocity in ECEF frame coordinates | ||
83 | /// | ||
84 | /// @note See \ref ImuIntegrator-Mechanization-e-Velocity equation \ref eq-ImuIntegrator-Mechanization-e-Velocity | ||
85 | template<typename DerivedA, typename DerivedB, typename DerivedC, typename DerivedD> | ||
86 | 38664 | Eigen::Vector3<typename DerivedA::Scalar> e_calcTimeDerivativeForVelocity(const Eigen::MatrixBase<DerivedA>& e_measuredForce, | |
87 | const Eigen::MatrixBase<DerivedB>& e_coriolisAcceleration, | ||
88 | const Eigen::MatrixBase<DerivedC>& e_gravitation, | ||
89 | const Eigen::MatrixBase<DerivedD>& e_centrifugalAcceleration) | ||
90 | { | ||
91 | return e_measuredForce | ||
92 | - e_coriolisAcceleration | ||
93 | + e_gravitation | ||
94 |
4/8✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38664 times.
✗ Branch 11 not taken.
|
38664 | - e_centrifugalAcceleration; |
95 | } | ||
96 | |||
97 | /// @brief Calculates the time derivative of the ECEF position | ||
98 | /// | ||
99 | /// \anchor eq-INS-Mechanization-x_e-dot \f{equation}{ \label{eq:eq-INS-Mechanization-x_e-dot} | ||
100 | /// \boldsymbol{\dot{x}}^e = \boldsymbol{v}^e | ||
101 | /// \f} | ||
102 | /// | ||
103 | /// @param[in] e_velocity Velocity with respect to the Earth in ECEF frame coordinates [m/s] | ||
104 | /// @return The time derivative of the ECEF position | ||
105 | /// | ||
106 | /// @note See \ref ImuIntegrator-Mechanization-e-Position equation \ref eq-ImuIntegrator-Mechanization-e-Position | ||
107 | template<typename Derived> | ||
108 | 38664 | Eigen::Vector3<typename Derived::Scalar> e_calcTimeDerivativeForPosition(const Eigen::MatrixBase<Derived>& e_velocity) | |
109 | { | ||
110 | 38664 | return e_velocity; | |
111 | } | ||
112 | |||
113 | /// @brief Calculates the derivative of the quaternion, velocity and position in ECEF coordinates | ||
114 | /// @param[in] y [w, x, y, z, v_x, v_y, v_z, x, y, z]^T | ||
115 | /// @param[in] z [fx, fy, fz, ωx, ωy, ωz]^T | ||
116 | /// @param[in] c Constant values needed to calculate the derivatives | ||
117 | /// @return The derivative ∂/∂t [w, x, y, z, v_x, v_y, v_z, x, y, z]^T | ||
118 | template<std::floating_point Scalar> | ||
119 | 38664 | Eigen::Vector<Scalar, 10> e_calcPosVelAttDerivative(const Eigen::Vector<Scalar, 10>& y, const Eigen::Vector<Scalar, 6>& z, const PosVelAttDerivativeConstants<Scalar>& c, Scalar /* t */ = 0.0) | |
120 | { | ||
121 | // 0 1 2 3 4 5 6 7 8 9 | ||
122 | // ∂/∂t [w, x, y, z, v_x, v_y, v_z, x, y, z]^T | ||
123 |
2/4✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
|
38664 | Eigen::Vector<Scalar, 10> y_dot = Eigen::Vector<Scalar, 10>::Zero(); |
124 | |||
125 |
2/4✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
|
38664 | Eigen::Vector3<Scalar> lla_position = trafo::ecef2lla_WGS84(y.template segment<3>(7)); |
126 | |||
127 |
5/10✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38664 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 38664 times.
✗ Branch 14 not taken.
|
38664 | Eigen::Quaternion<Scalar> e_Quat_b{ y(0), y(1), y(2), y(3) }; |
128 |
1/2✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
|
38664 | e_Quat_b.normalize(); |
129 |
3/6✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
|
38664 | Eigen::Quaternion<Scalar> n_Quat_e = trafo::n_Quat_e(lla_position(0), lla_position(1)); |
130 | |||
131 |
1/2✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
|
38664 | Eigen::Quaternion<Scalar> b_Quat_e = e_Quat_b.conjugate(); |
132 |
1/2✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
|
38664 | Eigen::Quaternion<Scalar> e_Quat_n = n_Quat_e.conjugate(); |
133 | |||
134 | LOG_DATA("e_velocity = {} [m/s]", y.template segment<3>(4).transpose()); | ||
135 | LOG_DATA("e_position = {} [m]", y.template segment<3>(7).transpose()); | ||
136 | |||
137 | // ω_eb_b = ω_ib_b - C_be * ω_ie_e | ||
138 |
4/8✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38664 times.
✗ Branch 11 not taken.
|
38664 | Eigen::Vector3<Scalar> b_omega_eb = z.template segment<3>(3) |
139 |
2/8✓ Branch 0 taken 38664 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 38664 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
38664 | - b_Quat_e * (c.angularRateEarthRotationCompensationEnabled ? InsConst::e_omega_ie : Eigen::Vector3<Scalar>::Zero()); |
140 | LOG_DATA("b_omega_eb = {} [rad/s]", b_omega_eb.transpose()); | ||
141 | |||
142 | // Coriolis acceleration in [m/s^2] (acceleration due to motion in rotating reference frame) | ||
143 |
1/6✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
38664 | Eigen::Vector3<Scalar> e_coriolisAcceleration = c.coriolisAccelerationCompensationEnabled |
144 |
2/4✓ Branch 0 taken 38664 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 38664 times.
✗ Branch 4 not taken.
|
38664 | ? e_calcCoriolisAcceleration(InsConst::e_omega_ie, y.template segment<3>(4)) |
145 | : Eigen::Vector3<Scalar>::Zero(); | ||
146 | LOG_DATA("e_coriolisAcceleration = {} [m/s^2]", e_coriolisAcceleration.transpose()); | ||
147 | // Centrifugal acceleration in [m/s^2] (acceleration that makes a body follow a curved path) | ||
148 |
1/6✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
38664 | Eigen::Vector3<Scalar> e_centrifugalAcceleration = c.centrifgalAccelerationCompensationEnabled |
149 |
2/4✓ Branch 0 taken 38664 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 38664 times.
✗ Branch 4 not taken.
|
38664 | ? e_calcCentrifugalAcceleration(y.template segment<3>(7), InsConst::e_omega_ie) |
150 | : Eigen::Vector3<Scalar>::Zero(); | ||
151 | LOG_DATA("e_centrifugalAcceleration = {} [m/s^2]", e_centrifugalAcceleration.transpose()); | ||
152 | |||
153 |
2/4✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
|
38664 | Eigen::Vector3<Scalar> e_gravitation = e_Quat_n * n_calcGravitation(lla_position, c.gravitationModel); |
154 | LOG_DATA("e_gravitation = {} [m/s^2] ({})", e_gravitation.transpose(), to_string(c.gravitationModel)); | ||
155 | |||
156 |
3/6✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
|
38664 | y_dot.template segment<4>(0) = calcTimeDerivativeFor_e_Quat_b(b_omega_eb, // ω_eb_b Body rate with respect to the ECEF frame, expressed in the body frame |
157 |
1/2✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
|
38664 | y.template segment<4>(0)); // e_Quat_b_coeffs Coefficients of the quaternion e_Quat_b in order w, x, y, z (q = w + ix + jy + kz) |
158 | |||
159 |
5/10✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38664 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 38664 times.
✗ Branch 14 not taken.
|
38664 | y_dot.template segment<3>(4) = e_calcTimeDerivativeForVelocity(e_Quat_b * z.template segment<3>(0), // f_n Specific force vector as measured by a triad of accelerometers and resolved into ECEF frame coordinates |
160 | e_coriolisAcceleration, // Coriolis acceleration in ECEF coordinates in [m/s^2] | ||
161 | e_gravitation, // Local gravitation vector (caused by effects of mass attraction) in ECEF frame coordinates [m/s^2] | ||
162 | e_centrifugalAcceleration); // Centrifugal acceleration in ECEF coordinates in [m/s^2] | ||
163 | |||
164 |
4/8✓ Branch 1 taken 38664 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38664 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38664 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38664 times.
✗ Branch 11 not taken.
|
38664 | y_dot.template segment<3>(7) = e_calcTimeDerivativeForPosition(y.template segment<3>(4)); // Velocity with respect to the Earth in ECEF frame coordinates [m/s] |
165 | |||
166 | LOG_DATA("e_Quat_b_dot = {} ", y_dot.template segment<4>(0).transpose()); | ||
167 | LOG_DATA("e_velocity_dot = {} [m/s^2]", y_dot.template segment<3>(4).transpose()); | ||
168 | LOG_DATA("e_position_dot = {} [m/s]", y_dot.template segment<3>(7).transpose()); | ||
169 | |||
170 | 77328 | return y_dot; | |
171 | } | ||
172 | |||
173 | } // namespace NAV | ||
174 |