My Project 1.0
Holistic Fusion: A Generic Framework for Multimodal Sensor Fusion
Loading...
Searching...
No Matches
Gnss.cpp
Go to the documentation of this file.
1/*
2Copyright 2017 by Dominic Jud, Robotic Systems Lab, ETH Zurich.
3All rights reserved.
4This file is released under the "BSD-3-Clause License".
5Please see the LICENSE file that has been included as part of this package.
6 */
7
9
10namespace holistic_fusion {
11
15
17 // calculate earth radii
18 const double temp = 1.0 / (1.0 - excentricity2_ * sin(referenceLatitude_ * M_PI / 180.0) * sin(referenceLatitude_ * M_PI / 180.0));
19 const double prime_vertical_radius = equatorialRadius_ * sqrt(temp);
20 earthRadiusN_ = prime_vertical_radius * (1 - excentricity2_) * temp;
21 earthRadiusE_ = prime_vertical_radius * cos(referenceLatitude_ * M_PI / 180.0);
22}
23
24void Gnss::setReference(const double& referenceLatitude, const double& referenceLongitude, const double& referenceAltitude,
25 const double& referenceHeading) {
26 // Lat Long Altitude Heading
27 referenceLatitude_ = referenceLatitude;
28 referenceLongitude_ = referenceLongitude;
29 referenceAltitude_ = referenceAltitude;
30 referenceHeading_ = referenceHeading;
31
32 // Conversion parameters
34
35 // LV03
37}
38
39void Gnss::setMercatorReferenceFrame(const Eigen::Vector3d newReferencePoint) {
40 xyzOffset_ = newReferencePoint;
41}
42
43// Conversion methods ---------------------------------------------------------
44// Default
45Eigen::Vector3d Gnss::gnssToCartesian(const double& latitudeInDegrees, const double& longitudeInDegrees, const double& altitude) {
46 const double cn = cos(referenceHeading_);
47 const double sn = sin(referenceHeading_);
48 const double kn = 180.0 / earthRadiusN_ / M_PI;
49 const double ke = 180.0 / earthRadiusE_ / M_PI;
50 const double lat_tmp = (latitudeInDegrees - referenceLatitude_) / kn;
51 const double lon_tmp = (longitudeInDegrees - referenceLongitude_) / ke;
52
53 Eigen::Vector3d position;
54 position(0) = cn * lat_tmp + sn * lon_tmp;
55 position(1) = sn * lat_tmp - cn * lon_tmp;
56 position(2) = altitude - referenceAltitude_;
57
58 return position;
59}
60
61Eigen::Vector3d Gnss::cartesianToGps(const Eigen::Matrix<double, 3, 1> position) const {
62 Eigen::Vector3d gpsCoordinates;
63 gpsCoordinates(0) =
64 referenceLatitude_ + (cos(referenceHeading_) * position(0) + sin(referenceHeading_) * position(1)) / earthRadiusN_ * 180.0 / M_PI;
65 gpsCoordinates(1) =
66 referenceLongitude_ - (-sin(referenceHeading_) * position(0) + cos(referenceHeading_) * position(1)) / earthRadiusE_ * 180.0 / M_PI;
67 gpsCoordinates(2) = referenceAltitude_ + position(2);
68
69 return gpsCoordinates;
70}
71
72Eigen::Vector3d Gnss::besselEllipsoidToMercator(const double& latitudeInRad, const double& longitudeInRad, const double& altitude) {
73 // Ellipsoid to Sphere (Gauss)
74 const double S = alpha_ * log(tan(M_PI_4 + latitudeInRad / 2.0)) -
75 alpha_ * sqrt(e2_) / 2.0 * log((1 + sqrt(e2_) * sin(latitudeInRad)) / (1 - sqrt(e2_) * sin(latitudeInRad))) + k_;
76 const double b = 2 * (atan(exp(S)) - M_PI_4);
77 const double l = alpha_ * (longitudeInRad - lambda0_);
78
79 // Equator to Pseudoequator (Rotation)
80 const double lHat = atan(sin(l) / (sin(b0_) * tan(b) + cos(b0_) * cos(l)));
81 const double bHat = asin(cos(b0_) * sin(b) - sin(b0_) * cos(b) * cos(l));
82
83 // Sphere to Plane (Mercator)
84 const double Y = r_ * lHat;
85 const double X = r_ / 2.0 * log((1 + sin(bHat)) / (1 - sin(bHat)));
86
87 return Eigen::Vector3d(Y, X, altitude) - xyzOffset_; // Yes, this is correct. A point in swiss coordinates is denoted as (y,x). See
88 // https://en.wikipedia.org/wiki/Swiss_coordinate_system
89}
90
91// LV03
92Eigen::Vector3d Gnss::gnssToLv03(const double latitudeInDegrees, const double longitudeInDegrees, const double altitude) {
93 Eigen::Vector3d position = gnssToLv03Raw(latitudeInDegrees, longitudeInDegrees, altitude);
94 Eigen::Vector3d positionOut = Eigen::Vector3d::Zero();
95 positionOut(0) = position(0) - referencePointLv03_(0);
96 positionOut(1) = position(1) - referencePointLv03_(1);
97 positionOut(2) = position(2) - referencePointLv03_(2);
98
99 return positionOut;
100}
101
102Eigen::Vector3d Gnss::gnssToLv03Raw(const double latitudeInDegrees, const double longitudeInDegrees, const double altitude) {
103 double east = wGStoCHy(latitudeInDegrees, longitudeInDegrees);
104 double north = wGStoCHx(latitudeInDegrees, longitudeInDegrees);
105 return Eigen::Vector3d(east, north, altitude);
106}
107
108double Gnss::wGStoCHx(double lat, double lon) {
111
112 // Axiliary values (% Bern)
113 const double latAux = (lat - 169028.66) / 10000.0;
114 const double lonAux = (lon - 26782.5) / 10000.0;
115
116 double x = (200147.07 + (308807.95 * latAux) + (3745.25 * std::pow(lonAux, 2)) + (76.63 * std::pow(latAux, 2)) -
117 (194.56 * std::pow(lonAux, 2) * latAux) + (119.79 * std::pow(latAux, 3)));
118 return x;
119}
120
121double Gnss::wGStoCHy(double lat, double lon) {
124
125 const double latAux = (lat - 169028.66) / 10000.0;
126 const double lonAux = (lon - 26782.5) / 10000.0;
127
128 double y = (600072.37 + (211455.93 * lonAux) - (10938.51 * lonAux * latAux) - (0.36 * lonAux * std::pow(latAux, 2)) -
129 (44.54 * std::pow(lonAux, 3)));
130 return y;
131}
132
133double Gnss::decToSexAngle(double dec) {
134 int degree = std::floor(dec);
135 int minute = std::floor((dec - degree) * 60.0);
136 double second = (((dec - degree) * 60.0) - minute) * 60.0;
137 return degree + (static_cast<double>(minute) / 100.0) + (second / 10000.0);
138}
139
140double Gnss::sexAngleToSeconds(double dms) {
141 int degree = std::floor(dms);
142 int minute = std::floor((dms - degree) * 100.0);
143 double second = (((dms - degree) * 100.0) - minute) * 100.0;
144 return second + (minute * 60.0) + (degree * 3600.0);
145}
146
147} // namespace holistic_fusion
double wGStoCHy(double lat, double lng)
Definition Gnss.cpp:121
double referenceLatitude_
Reference latitude of the GPS measurements [deg].
Definition Gnss.h:53
Eigen::Vector3d besselEllipsoidToMercator(const double &latitudeInRad, const double &longitudeInRad, const double &altitude)
Definition Gnss.cpp:72
const double alpha_
Definition Gnss.h:87
double sexAngleToSeconds(double dms)
Definition Gnss.cpp:140
Eigen::Vector3d referencePointLv03_
Definition Gnss.h:62
const double b0_
Definition Gnss.h:89
double earthRadiusN_
Definition Gnss.h:65
double referenceAltitude_
Reference altitude of the GPS measurements [m].
Definition Gnss.h:56
void setMercatorReferenceFrame(const Eigen::Vector3d newReferencePoint)
Definition Gnss.cpp:39
Eigen::Vector3d xyzOffset_
Definition Gnss.h:94
const double excentricity2_
Definition Gnss.h:72
double referenceLongitude_
Reference longitude of the GPS measurements [deg].
Definition Gnss.h:50
Eigen::Vector3d gnssToLv03(const double latitude_in_degrees, const double longitude_in_degrees, const double altitude)
Definition Gnss.cpp:92
const double k_
Definition Gnss.h:91
void setReference(const double &referenceLatitude, const double &referenceLongitude, const double &referenceAltitude, const double &referenceHeading)
Definition Gnss.cpp:24
const double r_
Definition Gnss.h:85
double referenceHeading_
Reference heading for the GPS measurements [rad].
Definition Gnss.h:59
Eigen::Vector3d cartesianToGps(const Eigen::Matrix< double, 3, 1 > position) const
Definition Gnss.cpp:61
const double e2_
Definition Gnss.h:79
double wGStoCHx(double lat, double lng)
Definition Gnss.cpp:108
const double lambda0_
Definition Gnss.h:83
double earthRadiusE_
Definition Gnss.h:66
Eigen::Vector3d gnssToCartesian(const double &latitudeInDegrees, const double &longitudeInDegrees, const double &altitude)
Definition Gnss.cpp:45
void calculateConversionParameters()
Definition Gnss.cpp:16
Eigen::Vector3d gnssToLv03Raw(const double latitude_in_degrees, const double longitude_in_degrees, const double altitude)
Definition Gnss.cpp:102
double decToSexAngle(double dec)
Definition Gnss.cpp:133
const double equatorialRadius_
Definition Gnss.h:69