0.2.0
Loading...
Searching...
No Matches
Ellipsoid.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
17
18namespace NAV
19{
20
27template<typename Scalar, typename = std::enable_if_t<std::is_floating_point_v<Scalar>>>
28[[nodiscard]] Scalar calcGeocentricRadius(const Scalar& latitude, const Scalar& R_E, const Scalar& e_squared = InsConst<Scalar>::WGS84::e_squared)
29{
30 return R_E * std::sqrt(std::pow(std::cos(latitude), 2) + std::pow((1.0 - e_squared) * std::sin(latitude), 2));
31}
32
40template<typename Scalar, typename = std::enable_if_t<std::is_floating_point_v<Scalar>>>
41[[nodiscard]] Scalar calcEarthRadius_N(const Scalar& latitude, const Scalar& a = InsConst<>::WGS84::a, const Scalar& e_squared = InsConst<>::WGS84::e_squared)
42{
43 Scalar k = std::sqrt(1 - e_squared * std::pow(std::sin(latitude), 2));
44
45 // North/South (meridian) earth radius [m]
46 return a * (1 - e_squared) / std::pow(k, 3);
47}
48
56template<typename Scalar, typename = std::enable_if_t<std::is_floating_point_v<Scalar>>>
57[[nodiscard]] Scalar calcEarthRadius_E(const Scalar& latitude, const Scalar& a = InsConst<Scalar>::WGS84::a, const Scalar& e_squared = InsConst<>::WGS84::e_squared)
58{
59 // East/West (prime vertical) earth radius [m]
60 return a / std::sqrt(1 - e_squared * std::pow(std::sin(latitude), 2));
61}
62
69template<typename Derived>
70[[nodiscard]] Eigen::Matrix3<typename Derived::Scalar> conversionMatrixCartesianCurvilinear(const Eigen::MatrixBase<Derived>& lla_position,
71 const typename Derived::Scalar& R_N, const typename Derived::Scalar& R_E)
72{
73 return Eigen::DiagonalMatrix<typename Derived::Scalar, 3>{ 1.0 / (R_N + lla_position(2)),
74 1.0 / ((R_E + lla_position(2)) * std::cos(lla_position(0))),
75 -1.0 };
76}
77
86template<typename Scalar, typename = std::enable_if_t<std::is_floating_point_v<Scalar>>>
87[[nodiscard]] Scalar calcGreatCircleDistance(Scalar lat1, Scalar lon1, Scalar lat2, Scalar lon2)
88{
89 Scalar R = calcGeocentricRadius(lat1, calcEarthRadius_E(lat1));
90 Scalar dLat = lat2 - lat1;
91 Scalar dLon = lon2 - lon1;
92 Scalar a = std::pow(std::sin(dLat / 2.0), 2) + std::cos(lat1) * std::cos(lat2) * std::pow(std::sin(dLon / 2.0), 2);
93 Scalar c = 2.0 * std::atan2(std::sqrt(a), std::sqrt(1.0 - a));
94 return R * c; // meters
95}
96
105template<typename Scalar, typename = std::enable_if_t<std::is_floating_point_v<Scalar>>>
106[[nodiscard]] Scalar calcGeographicalDistance(Scalar lat1, Scalar lon1, Scalar lat2, Scalar lon2)
107{
108 if (lat1 == lat2 && lon1 == lon2)
109 {
110 return 0;
111 }
112 // First convert the latitudes 𝜙₁,𝜙₂ of the two points to reduced latitudes 𝛽₁,𝛽₂
113 Scalar beta1 = std::atan((1 - InsConst<>::WGS84::f) * std::tan(lat1));
114 Scalar beta2 = std::atan((1 - InsConst<>::WGS84::f) * std::tan(lat2));
115
116 // Then calculate the central angle 𝜎 in radians between two points 𝛽₁,𝜆₁ and 𝛽₂,𝜆₂ on a sphere using the
117 // Great-circle distance method (law of cosines or haversine formula), with longitudes 𝜆₁ and 𝜆₂ being the same on the sphere as on the spheroid.
118 Scalar sigma = calcGreatCircleDistance(beta1, lon1, beta2, lon2)
120
121 Scalar P = (beta1 + beta2) / 2;
122 Scalar Q = (beta2 - beta1) / 2;
123
124 Scalar X = (sigma - std::sin(sigma)) * std::pow((std::sin(P) * std::cos(Q)) / std::cos(sigma / 2), 2);
125 Scalar Y = (sigma + std::sin(sigma)) * std::pow((std::cos(P) * std::sin(Q)) / std::sin(sigma / 2), 2);
126
127 return InsConst<>::WGS84::a * (sigma - InsConst<>::WGS84::f / 2.0 * (X + Y));
128}
129
130} // namespace NAV
Holds all Constants.
Scalar calcEarthRadius_E(const Scalar &latitude, const Scalar &a=InsConst< Scalar >::WGS84::a, const Scalar &e_squared=InsConst<>::WGS84::e_squared)
Calculates the East/West (prime vertical) earth radius.
Definition Ellipsoid.hpp:57
Scalar calcEarthRadius_N(const Scalar &latitude, const Scalar &a=InsConst<>::WGS84::a, const Scalar &e_squared=InsConst<>::WGS84::e_squared)
Calculates the North/South (meridian) earth radius.
Definition Ellipsoid.hpp:41
Scalar calcGeographicalDistance(Scalar lat1, Scalar lon1, Scalar lat2, Scalar lon2)
Measure the distance between two points over an ellipsoidal-surface.
Definition Ellipsoid.hpp:106
Eigen::Matrix3< typename Derived::Scalar > conversionMatrixCartesianCurvilinear(const Eigen::MatrixBase< Derived > &lla_position, const typename Derived::Scalar &R_N, const typename Derived::Scalar &R_E)
Conversion matrix between cartesian and curvilinear perturbations to the position.
Definition Ellipsoid.hpp:70
Scalar calcGeocentricRadius(const Scalar &latitude, const Scalar &R_E, const Scalar &e_squared=InsConst< Scalar >::WGS84::e_squared)
r_eS^e The distance of a point on the Earth's surface from the center of the Earth
Definition Ellipsoid.hpp:28
Scalar calcGreatCircleDistance(Scalar lat1, Scalar lon1, Scalar lat2, Scalar lon2)
Measure the distance between two points on a sphere.
Definition Ellipsoid.hpp:87
Constants.
Definition Constants.hpp:26