2018-08-29 16:55:39 +00:00
|
|
|
/*!
|
|
|
|
* \file geofunctions.h
|
|
|
|
* \brief A set of coordinate transformations functions and helpers,
|
|
|
|
* some of them migrated from MATLAB, for geographic information systems.
|
|
|
|
* \author Javier Arribas, 2018. jarribas(at)cttc.es
|
|
|
|
*
|
|
|
|
* -------------------------------------------------------------------------
|
|
|
|
*
|
2019-07-26 10:38:20 +00:00
|
|
|
* Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
|
2018-08-29 16:55:39 +00:00
|
|
|
*
|
|
|
|
* GNSS-SDR is a software defined Global Navigation
|
|
|
|
* Satellite Systems receiver
|
|
|
|
*
|
|
|
|
* This file is part of GNSS-SDR.
|
|
|
|
*
|
|
|
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* GNSS-SDR is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with GNSS-SDR. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* -------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2018-08-30 17:24:28 +00:00
|
|
|
#ifndef GNSS_SDR_GEOFUNCTIONS_H
|
|
|
|
#define GNSS_SDR_GEOFUNCTIONS_H
|
2018-08-29 16:55:39 +00:00
|
|
|
|
2019-07-29 19:22:44 +00:00
|
|
|
#if ARMA_NO_BOUND_CHECKING
|
|
|
|
#define ARMA_NO_DEBUG 1
|
|
|
|
#endif
|
|
|
|
|
2018-08-29 16:55:39 +00:00
|
|
|
#include <armadillo>
|
2018-08-30 17:24:28 +00:00
|
|
|
|
|
|
|
arma::mat Skew_symmetric(const arma::vec &a); //!< Calculates skew-symmetric matrix
|
2018-08-29 16:55:39 +00:00
|
|
|
|
|
|
|
double WGS84_g0(double Lat_rad);
|
|
|
|
|
|
|
|
double WGS84_geocentric_radius(double Lat_geodetic_rad);
|
|
|
|
|
2018-08-30 17:24:28 +00:00
|
|
|
/*!
|
|
|
|
* \brief Transformation of vector dx into topocentric coordinate
|
|
|
|
* system with origin at x
|
|
|
|
* Inputs:
|
|
|
|
* x - vector origin coordinates (in ECEF system [X; Y; Z;])
|
|
|
|
* dx - vector ([dX; dY; dZ;]).
|
|
|
|
*
|
|
|
|
* Outputs:
|
|
|
|
* D - vector length. Units like the input
|
|
|
|
* Az - azimuth from north positive clockwise, degrees
|
|
|
|
* El - elevation angle, degrees
|
|
|
|
*
|
|
|
|
* Based on a Matlab function by Kai Borre
|
2018-08-29 16:55:39 +00:00
|
|
|
*/
|
|
|
|
int topocent(double *Az, double *El, double *D, const arma::vec &x, const arma::vec &dx);
|
|
|
|
|
2018-08-30 17:24:28 +00:00
|
|
|
/*!
|
|
|
|
* \brief Subroutine to calculate geodetic coordinates latitude, longitude,
|
|
|
|
* height given Cartesian coordinates X,Y,Z, and reference ellipsoid
|
|
|
|
* values semi-major axis (a) and the inverse of flattening (finv).
|
|
|
|
*
|
|
|
|
* The output units of angular quantities will be in decimal degrees
|
|
|
|
* (15.5 degrees not 15 deg 30 min). The output units of h will be the
|
|
|
|
* same as the units of X,Y,Z,a.
|
|
|
|
*
|
|
|
|
* Inputs:
|
|
|
|
* a - semi-major axis of the reference ellipsoid
|
|
|
|
* finv - inverse of flattening of the reference ellipsoid
|
|
|
|
* X,Y,Z - Cartesian coordinates
|
|
|
|
*
|
|
|
|
* Outputs:
|
|
|
|
* dphi - latitude
|
|
|
|
* dlambda - longitude
|
|
|
|
* h - height above reference ellipsoid
|
|
|
|
*
|
|
|
|
* Based in a Matlab function by Kai Borre
|
2018-08-29 16:55:39 +00:00
|
|
|
*/
|
|
|
|
int togeod(double *dphi, double *dlambda, double *h, double a, double finv, double X, double Y, double Z);
|
|
|
|
|
2019-07-25 21:35:10 +00:00
|
|
|
arma::vec Gravity_ECEF(const arma::vec &r_eb_e); //!< Calculates acceleration due to gravity resolved about ECEF-frame
|
2018-08-29 16:55:39 +00:00
|
|
|
|
2018-08-30 17:24:28 +00:00
|
|
|
/*!
|
|
|
|
* \brief Conversion of Cartesian coordinates (X,Y,Z) to geographical
|
|
|
|
* coordinates (latitude, longitude, h) on a selected reference ellipsoid.
|
|
|
|
*
|
|
|
|
* Choices of Reference Ellipsoid for Geographical Coordinates
|
|
|
|
* 0. International Ellipsoid 1924
|
|
|
|
* 1. International Ellipsoid 1967
|
|
|
|
* 2. World Geodetic System 1972
|
|
|
|
* 3. Geodetic Reference System 1980
|
|
|
|
* 4. World Geodetic System 1984
|
2018-08-29 16:55:39 +00:00
|
|
|
*/
|
2018-08-30 17:24:28 +00:00
|
|
|
arma::vec cart2geo(const arma::vec &XYZ, int elipsoid_selection);
|
2018-08-29 16:55:39 +00:00
|
|
|
|
2018-10-15 00:04:15 +00:00
|
|
|
arma::vec LLH_to_deg(const arma::vec &LLH);
|
2018-08-29 16:55:39 +00:00
|
|
|
|
|
|
|
double degtorad(double angleInDegrees);
|
|
|
|
|
|
|
|
double radtodeg(double angleInRadians);
|
|
|
|
|
|
|
|
double mstoknotsh(double MetersPerSeconds);
|
|
|
|
|
2019-02-21 09:33:20 +00:00
|
|
|
double mstokph(double MetersPerSeconds);
|
2018-08-29 16:55:39 +00:00
|
|
|
|
2018-10-15 00:04:15 +00:00
|
|
|
arma::vec CTM_to_Euler(const arma::mat &C);
|
2018-08-30 17:24:28 +00:00
|
|
|
|
|
|
|
arma::mat Euler_to_CTM(const arma::vec &eul);
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief From Geographic to ECEF coordinates
|
|
|
|
*
|
|
|
|
* Inputs:
|
|
|
|
* LLH latitude (rad), longitude (rad), height (m)
|
|
|
|
* v_eb_n velocity of body frame w.r.t. ECEF frame, resolved along
|
|
|
|
* north, east, and down (m/s)
|
|
|
|
* C_b_n body-to-NED coordinate transformation matrix
|
|
|
|
*
|
|
|
|
* Outputs:
|
|
|
|
* r_eb_e Cartesian position of body frame w.r.t. ECEF frame, resolved
|
|
|
|
* along ECEF-frame axes (m)
|
|
|
|
* v_eb_e velocity of body frame w.r.t. ECEF frame, resolved along
|
|
|
|
* ECEF-frame axes (m/s)
|
|
|
|
* C_b_e body-to-ECEF-frame coordinate transformation matrix
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
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);
|
|
|
|
|
2018-08-29 16:55:39 +00:00
|
|
|
|
2018-08-30 17:24:28 +00:00
|
|
|
/*!
|
|
|
|
* \brief Converts curvilinear to Cartesian position and velocity
|
|
|
|
* resolving axes from NED to ECEF
|
|
|
|
* This function created 11/4/2012 by Paul Groves
|
|
|
|
*
|
|
|
|
* Inputs:
|
|
|
|
* L_b latitude (rad)
|
|
|
|
* lambda_b longitude (rad)
|
|
|
|
* h_b height (m)
|
|
|
|
* v_eb_n velocity of body frame w.r.t. ECEF frame, resolved along
|
|
|
|
* north, east, and down (m/s)
|
|
|
|
*
|
|
|
|
* Outputs:
|
|
|
|
* r_eb_e Cartesian position of body frame w.r.t. ECEF frame, resolved
|
|
|
|
* along ECEF-frame axes (m)
|
|
|
|
* v_eb_e velocity of body frame w.r.t. ECEF frame, resolved along
|
|
|
|
* ECEF-frame axes (m/s)
|
|
|
|
*/
|
|
|
|
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);
|
2018-08-29 16:55:39 +00:00
|
|
|
|
2018-10-15 00:04:15 +00:00
|
|
|
|
2018-10-09 16:19:13 +00:00
|
|
|
/*!
|
|
|
|
* \brief The Haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes.
|
|
|
|
*/
|
|
|
|
double great_circle_distance(double lat1, double lon1, double lat2, double lon2);
|
|
|
|
|
2018-10-15 00:04:15 +00:00
|
|
|
|
2018-10-11 15:47:23 +00:00
|
|
|
/*!
|
|
|
|
* \brief Transformation of ECEF (X,Y,Z) to (E,N,U) in UTM, zone 'zone'.
|
|
|
|
*/
|
2018-10-15 00:04:15 +00:00
|
|
|
void cart2utm(const arma::vec &r_eb_e, int zone, arma::vec &r_enu);
|
2018-10-11 15:47:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function finds the UTM zone number for given longitude and latitude.
|
|
|
|
*/
|
|
|
|
int findUtmZone(double latitude_deg, double longitude_deg);
|
|
|
|
|
2018-10-15 00:04:15 +00:00
|
|
|
|
2018-10-11 15:47:23 +00:00
|
|
|
/*!
|
|
|
|
* \brief Clenshaw summation of sinus of argument.
|
|
|
|
*/
|
2018-10-15 00:04:15 +00:00
|
|
|
double clsin(const arma::colvec &ar, int degree, double argument);
|
2018-10-11 15:47:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Clenshaw summation of sinus with complex argument.
|
|
|
|
*/
|
2018-10-15 00:04:15 +00:00
|
|
|
void clksin(const arma::colvec &ar, int degree, double arg_real, double arg_imag, double *re, double *im);
|
2018-10-09 16:19:13 +00:00
|
|
|
|
2018-08-29 16:55:39 +00:00
|
|
|
#endif
|