2
3
4
5
6
7
8
9
10
11
12
13
14
15
17
18
19
20
21
22
23
24
25
26
27
28
29
30
32#ifndef PLANET_RELATIVE_STATE_UTILS_HPP
33#define PLANET_RELATIVE_STATE_UTILS_HPP
37#include "core/macros.h"
38#include "core/clockwerkerrors.h"
39#include "core/CartesianVector.hpp"
40#include "six_dof_dynamics/Frame.hpp"
53 int pcrDeticToLla(
CartesianVector<T, 3> pos__pcr, T r_planet_equatorial, T flattening, T& lat_rad, T& lon_rad, T& alt);
62 std::vector<std::vector<
double>> pcr2lla(
const std::vector<
double> &pcr_x,
63 const std::vector<
double> &pcr_y,
64 const std::vector<
double> &pcr_z,
66 double flattening=(1.0/298.257223563));
75 CartesianVector<T, 3> llaCentricToPCR(T r_planet, T lat_rad, T lon_rad, T alt);
82 DCM<T> enuFromLatLonCentric(T lat_rad, T lon_rad);
89 DCM<T> enuFromLatLonDetic(T lat_rad, T lon_rad);
96 DCM<T> nedFromLatLonCentric(T lat_rad, T lon_rad);
102 template <
typename T>
103 DCM<T> nedFromLatLonDetic(T lat_rad, T lon_rad);
112 template <
typename T>
113 int heikkinenLla(
CartesianVector<T, 3> pos__pcr, T r_planet_equatorial, T flattening, T& lat_rad, T& lon_rad, T& alt);
121 template <
typename T>
122 int pcrToLlaCentric(
CartesianVector<T, 3> pos__pcr, T r_planet, T& lat_rad, T& lon_rad, T& alt);
124 template <
typename T>
125 int pcrDeticToLla(
CartesianVector<T, 3> pos__pcr, T r_planet_equatorial, T flattening, T& lat_rad, T& lon_rad, T& alt) {
126 T nav_e2 = (2.0 - flattening)*flattening;
129 lon_rad = atan2(pos__pcr[1], pos__pcr[0]);
132 T rhosqrd = pos__pcr[0]*pos__pcr[0] + pos__pcr[1]*pos__pcr[1];
134 int _error = safeSqrt(rhosqrd, rho);
135 if(_error) {
return _error;}
137 T templat = atan2(pos__pcr[2], rho);
138 T tempalt = sqrt(rhosqrd + pos__pcr[2]*pos__pcr[2]) - r_planet_equatorial;
149 T slat, clat, sqrt_q, q, r_n, drdl, aa, bb, cc, dd, invdet;
150 while((abs(rhoerror) > 1e-6) || (abs(zerror) > 1e-6)) {
153 q = 1.0 - nav_e2*slat*slat;
154 _error = safeSqrt(q, sqrt_q);
155 if(_error) {
return _error;}
156 _error = safeDivide(r_planet_equatorial, sqrt_q, r_n);
157 if(_error) {
return _error;}
158 _error = safeDivide(r_n*nav_e2*slat*clat , q, drdl);
159 if(_error) {
return _error;}
161 rhoerror = (r_n + tempalt)*clat - rho;
162 zerror = (r_n*(1.0 - nav_e2) + tempalt)*slat - pos__pcr[2];
164 aa = drdl*clat - (r_n + tempalt)*slat;
166 cc = (1.0 - nav_e2)*(drdl*slat + r_n*clat);
169 _error = safeDivide(1.0, aa*dd - bb*cc, invdet);
170 if(_error) {
return _error;}
171 templat = templat - invdet*(dd*rhoerror - bb*zerror);
172 tempalt = tempalt - invdet*(-cc*rhoerror + aa*zerror);
185 template <
typename T>
186 CartesianVector<T, 3> llaCentricToPCR(T r_planet, T lat_rad, T lon_rad, T alt) {
187 T r_tot = r_planet + alt;
189 r_tot*cos(lat_rad)*sin(lon_rad),
190 r_tot*sin(lat_rad)});
193 template <
typename T>
194 DCM<T> enuFromLatLonCentric(T lat_rad, T lon_rad) {
195 return DCM<T>({{-sin(lon_rad), cos(lon_rad), 0.0},
196 {-cos(lon_rad)*sin(lat_rad), -sin(lon_rad)*sin(lat_rad), cos(lat_rad)},
197 {cos(lon_rad)*cos(lat_rad), sin(lon_rad)*cos(lat_rad), sin(lat_rad)}});
200 template <
typename T>
201 int heikkinenLla(
CartesianVector<T, 3> pos__pcr, T r_planet_equatorial, T flattening, T& lat_rad, T& lon_rad, T& alt){
203 T b = r_planet_equatorial*(1.0-flattening);
204 T e_sqr = (2.0 - flattening)*flattening;
205 T E_sqr = e_sqr*r_planet_equatorial*r_planet_equatorial;
206 T ep_sqr = E_sqr/b/b;
207 T z_sqr = std::pow(pos__pcr[2],2.0);
209 _error = safeSqrt(std::pow(pos__pcr[0],2.0)+std::pow(pos__pcr[1],2.0), r);
211 T F = 54.0*b*b*z_sqr;
212 T G = r*r+(1-e_sqr)*z_sqr-e_sqr*E_sqr;
214 _error = safeDivide(e_sqr*e_sqr*F*r*r,std::pow(G,3.0),c);
219 _error = safeSqrt(c*c+2*c,tmpRes0);
222 _error = safeNroot(1.0+c+tmpRes0,3,s);
223 if (_error) {
return _error;}
225 _error = safeDivide(1.0,s,tmpRes1);
227 _error = safeDivide(F,3.0*std::pow(s+tmpRes1+1.0,2.0)*G*G,P);
230 _error = safeSqrt(1.0+2.0*e_sqr*e_sqr*P,Q);
233 _error = safeDivide(P*(1.0-e_sqr)*z_sqr,Q*(1.0+Q),tmpRes0);
236 _error = safeDivide(1.0,Q,tmpRes1);
238 _error = safeSqrt(0.5*r_planet_equatorial*r_planet_equatorial*(1.0+tmpRes1)-tmpRes0-0.5*P*r*r,r_0);
240 _error = safeDivide(P*e_sqr*r,1.0+Q,tmpRes0);
244 tmpRes0 = std::pow(r-e_sqr*r_0,2.0);
247 T U = std::sqrt(tmpRes0+z_sqr);
248 T V = std::sqrt(tmpRes0+(1.0-e_sqr)*z_sqr);
249 _error = safeDivide(b*b,r_planet_equatorial*V,tmpRes0);
252 T z_0 = pos__pcr[2]*tmpRes0;
254 lat_rad = atan2(pos__pcr[2] + ep_sqr*z_0, r);
255 lon_rad = atan2(pos__pcr[1], pos__pcr[0]);
256 alt = U*(1.0-tmpRes0);
261 template <
typename T>
262 int pcrToLlaCentric(
CartesianVector<T, 3> pos__pcr, T r_planet, T& lat_rad, T& lon_rad, T& alt){
267 _error = pos__pcr.normSquared(r_pos);
268 if (_error) {
return _error;}
270 _error = safeSqrt(r_pos,alt);
275 lon_rad = atan2(pos__pcr[1],pos__pcr[0]);
277 _error = safeSqrt(std::pow(pos__pcr[0],2.0)+std::pow(pos__pcr[1],2.0),tmpVal0);
281 lat_rad = atan2(pos__pcr[2],tmpVal0);
287 template <
typename T>
288 DCM<T> enuFromLatLonDetic(T lat_rad, T lon_rad) {
289 return DCM<T>({{-sin(lon_rad), cos(lon_rad), 0.0},
290 {-cos(lon_rad)*sin(lat_rad), -sin(lon_rad)*sin(lat_rad), cos(lat_rad)},
291 {cos(lon_rad)*cos(lat_rad), sin(lon_rad)*cos(lat_rad), sin(lat_rad)}});
294 template <
typename T>
295 DCM<T> nedFromLatLonCentric(T lat_rad, T lon_rad) {
296 return DCM<T>({{-sin(lat_rad)*cos(lon_rad), -sin(lat_rad)*sin(lon_rad), cos(lat_rad)},
297 {-sin(lon_rad), cos(lon_rad), 0.0},
298 {-cos(lat_rad)*cos(lon_rad), -cos(lat_rad)*sin(lon_rad), -sin(lat_rad)}});
302 template <
typename T>
303 DCM<T> nedFromLatLonDetic(T lat_rad, T lon_rad) {
304 return DCM<T>({{-sin(lat_rad)*cos(lon_rad), -sin(lat_rad)*sin(lon_rad), cos(lat_rad)},
305 {-sin(lon_rad), cos(lon_rad), 0.0},
306 {-cos(lat_rad)*cos(lon_rad), -cos(lat_rad)*sin(lon_rad), -sin(lat_rad)}});
Standard vector class derived from Matrix.
Definition CartesianVector.hpp:39
Class defining a direction cosine matrix inherited from Matrix.
Definition DCM.hpp:71
#define NO_ERROR
Definition clockwerkerrors.h:31
#define ERROR_NEGATIVE_SQRT
Definition clockwerkerrors.h:54
#define ERROR_INVALID_RANGE
Definition clockwerkerrors.h:50
#define ERROR_DIVIDE_BY_ZERO
Definition clockwerkerrors.h:46