GNSS-SDR  0.0.13
An Open Source GNSS Software Defined Receiver
geofunctions.h
Go to the documentation of this file.
1 /*!
2  * \file geofunctions.h
3  * \brief A set of coordinate transformations functions and helpers,
4  * some of them migrated from MATLAB, for geographic information systems.
5  * \author Javier Arribas, 2018. jarribas(at)cttc.es
6  *
7  *
8  * -----------------------------------------------------------------------------
9  *
10  * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
11  *
12  * GNSS-SDR is a software defined Global Navigation
13  * Satellite Systems receiver
14  *
15  * This file is part of GNSS-SDR.
16  *
17  * SPDX-License-Identifier: GPL-3.0-or-later
18  *
19  * -----------------------------------------------------------------------------
20  */
21 
22 #ifndef GNSS_SDR_GEOFUNCTIONS_H
23 #define GNSS_SDR_GEOFUNCTIONS_H
24 
25 #if ARMA_NO_BOUND_CHECKING
26 #define ARMA_NO_DEBUG 1
27 #endif
28 
29 #include <armadillo>
30 
31 arma::mat Skew_symmetric(const arma::vec &a); //!< Calculates skew-symmetric matrix
32 
33 double WGS84_g0(double Lat_rad);
34 
35 double WGS84_geocentric_radius(double Lat_geodetic_rad);
36 
37 /*!
38  * \brief Transformation of vector dx into topocentric coordinate
39  * system with origin at x
40  * Inputs:
41  * x - vector origin coordinates (in ECEF system [X; Y; Z;])
42  * dx - vector ([dX; dY; dZ;]).
43  *
44  * Outputs:
45  * D - vector length. Units like the input
46  * Az - azimuth from north positive clockwise, degrees
47  * El - elevation angle, degrees
48  *
49  * Based on a Matlab function by Kai Borre
50  */
51 int topocent(double *Az, double *El, double *D, const arma::vec &x, const arma::vec &dx);
52 
53 /*!
54  * \brief Subroutine to calculate geodetic coordinates latitude, longitude,
55  * height given Cartesian coordinates X,Y,Z, and reference ellipsoid
56  * values semi-major axis (a) and the inverse of flattening (finv).
57  *
58  * The output units of angular quantities will be in decimal degrees
59  * (15.5 degrees not 15 deg 30 min). The output units of h will be the
60  * same as the units of X,Y,Z,a.
61  *
62  * Inputs:
63  * a - semi-major axis of the reference ellipsoid
64  * finv - inverse of flattening of the reference ellipsoid
65  * X,Y,Z - Cartesian coordinates
66  *
67  * Outputs:
68  * dphi - latitude
69  * dlambda - longitude
70  * h - height above reference ellipsoid
71  *
72  * Based in a Matlab function by Kai Borre
73  */
74 int togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z);
75 
76 arma::vec Gravity_ECEF(const arma::vec &r_eb_e); //!< Calculates acceleration due to gravity resolved about ECEF-frame
77 
78 /*!
79  * \brief Conversion of Cartesian coordinates (X,Y,Z) to geographical
80  * coordinates (latitude, longitude, h) on a selected reference ellipsoid.
81  *
82  * Choices of Reference Ellipsoid for Geographical Coordinates
83  * 0. International Ellipsoid 1924
84  * 1. International Ellipsoid 1967
85  * 2. World Geodetic System 1972
86  * 3. Geodetic Reference System 1980
87  * 4. World Geodetic System 1984
88  */
89 arma::vec cart2geo(const arma::vec &XYZ, int elipsoid_selection);
90 
91 arma::vec LLH_to_deg(const arma::vec &LLH);
92 
93 double degtorad(double angleInDegrees);
94 
95 double radtodeg(double angleInRadians);
96 
97 double mstoknotsh(double MetersPerSeconds);
98 
99 double mstokph(double MetersPerSeconds);
100 
101 arma::vec CTM_to_Euler(const arma::mat &C);
102 
103 arma::mat Euler_to_CTM(const arma::vec &eul);
104 
105 void ECEF_to_Geo(const arma::vec &r_eb_e, const arma::vec &v_eb_e, const arma::mat &C_b_e, arma::vec &LLH, arma::vec &v_eb_n, arma::mat &C_b_n);
106 
107 
108 /*!
109  * \brief From Geographic to ECEF coordinates
110  *
111  * Inputs:
112  * LLH latitude (rad), longitude (rad), height (m)
113  * v_eb_n velocity of body frame w.r.t. ECEF frame, resolved along
114  * north, east, and down (m/s)
115  * C_b_n body-to-NED coordinate transformation matrix
116  *
117  * Outputs:
118  * r_eb_e Cartesian position of body frame w.r.t. ECEF frame, resolved
119  * along ECEF-frame axes (m)
120  * v_eb_e velocity of body frame w.r.t. ECEF frame, resolved along
121  * ECEF-frame axes (m/s)
122  * C_b_e body-to-ECEF-frame coordinate transformation matrix
123  *
124  */
125 void Geo_to_ECEF(const arma::vec &LLH, const arma::vec &v_eb_n, const arma::mat &C_b_n, arma::vec &r_eb_e, arma::vec &v_eb_e, arma::mat &C_b_e);
126 
127 
128 /*!
129  * \brief Converts curvilinear to Cartesian position and velocity
130  * resolving axes from NED to ECEF
131  * This function created 11/4/2012 by Paul Groves
132  *
133  * Inputs:
134  * L_b latitude (rad)
135  * lambda_b longitude (rad)
136  * h_b height (m)
137  * v_eb_n velocity of body frame w.r.t. ECEF frame, resolved along
138  * north, east, and down (m/s)
139  *
140  * Outputs:
141  * r_eb_e Cartesian position of body frame w.r.t. ECEF frame, resolved
142  * along ECEF-frame axes (m)
143  * v_eb_e velocity of body frame w.r.t. ECEF frame, resolved along
144  * ECEF-frame axes (m/s)
145  */
146 void pv_Geo_to_ECEF(double L_b, double lambda_b, double h_b, const arma::vec &v_eb_n, arma::vec &r_eb_e, arma::vec &v_eb_e);
147 
148 
149 /*!
150  * \brief The Haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes.
151  */
152 double great_circle_distance(double lat1, double lon1, double lat2, double lon2);
153 
154 
155 /*!
156  * \brief Transformation of ECEF (X,Y,Z) to (E,N,U) in UTM, zone 'zone'.
157  */
158 void cart2utm(const arma::vec &r_eb_e, int zone, arma::vec &r_enu);
159 
160 
161 /*!
162  * \brief Function finds the UTM zone number for given longitude and latitude.
163  */
164 int findUtmZone(double latitude_deg, double longitude_deg);
165 
166 
167 /*!
168  * \brief Clenshaw summation of sinus of argument.
169  */
170 double clsin(const arma::colvec &ar, int degree, double argument);
171 
172 
173 /*!
174  * \brief Clenshaw summation of sinus with complex argument.
175  */
176 void clksin(const arma::colvec &ar, int degree, double arg_real, double arg_imag, double *re, double *im);
177 
178 #endif // GNSS_SDR_GEOFUNCTIONS_H
arma::vec cart2geo(const arma::vec &XYZ, int elipsoid_selection)
Conversion of Cartesian coordinates (X,Y,Z) to geographical coordinates (latitude, longitude, h) on a selected reference ellipsoid.
arma::vec Gravity_ECEF(const arma::vec &r_eb_e)
Calculates acceleration due to gravity resolved about ECEF-frame.
double great_circle_distance(double lat1, double lon1, double lat2, double lon2)
The Haversine formula determines the great-circle distance between two points on a sphere given their...
void cart2utm(const arma::vec &r_eb_e, int zone, arma::vec &r_enu)
Transformation of ECEF (X,Y,Z) to (E,N,U) in UTM, zone &#39;zone&#39;.
void pv_Geo_to_ECEF(double L_b, double lambda_b, double h_b, const arma::vec &v_eb_n, arma::vec &r_eb_e, arma::vec &v_eb_e)
Converts curvilinear to Cartesian position and velocity resolving axes from NED to ECEF This function...
void Geo_to_ECEF(const arma::vec &LLH, const arma::vec &v_eb_n, const arma::mat &C_b_n, arma::vec &r_eb_e, arma::vec &v_eb_e, arma::mat &C_b_e)
From Geographic to ECEF coordinates.
int togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z)
Subroutine to calculate geodetic coordinates latitude, longitude, height given Cartesian coordinates ...
int topocent(double *Az, double *El, double *D, const arma::vec &x, const arma::vec &dx)
Transformation of vector dx into topocentric coordinate system with origin at x Inputs: x - vector or...
double clsin(const arma::colvec &ar, int degree, double argument)
Clenshaw summation of sinus of argument.
arma::mat Skew_symmetric(const arma::vec &a)
Calculates skew-symmetric matrix.
void clksin(const arma::colvec &ar, int degree, double arg_real, double arg_imag, double *re, double *im)
Clenshaw summation of sinus with complex argument.
int findUtmZone(double latitude_deg, double longitude_deg)
Function finds the UTM zone number for given longitude and latitude.