Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
pprz_geodetic_int.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008-2009 Antoine Drouin <poinix@gmail.com>
3 * 2009-2014 Gautier Hattenberger <gautier.hattenberger@enac.fr>
4 * 2010-2014 Felix Ruess <felix.ruess@gmail.com>
5 *
6 * This file is part of paparazzi.
7 *
8 * paparazzi is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * paparazzi is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with paparazzi; see the file COPYING. If not, see
20 * <http://www.gnu.org/licenses/>.
21 */
22
30#include "pprz_geodetic_int.h"
31#include "pprz_algebra_int.h"
32
33
34void ltp_of_ecef_rmat_from_lla_i(struct Int32RMat *ltp_of_ecef, struct LlaCoor_i *lla)
35{
36
37#if USE_SINGLE_PRECISION_TRIG
42#else // use double precision by default
47#endif
48
49 ltp_of_ecef->m[0] = -sin_lon;
50 ltp_of_ecef->m[1] = cos_lon;
51 ltp_of_ecef->m[2] = 0; /* this element is always zero http://en.wikipedia.org/wiki/Geodetic_system#From_ECEF_to_ENU */
52 ltp_of_ecef->m[3] = (int32_t)((-(int64_t)sin_lat * (int64_t)cos_lon) >> HIGH_RES_TRIG_FRAC);
53 ltp_of_ecef->m[4] = (int32_t)((-(int64_t)sin_lat * (int64_t)sin_lon) >> HIGH_RES_TRIG_FRAC);
54 ltp_of_ecef->m[5] = cos_lat;
55 ltp_of_ecef->m[6] = (int32_t)(((int64_t)cos_lat * (int64_t)cos_lon) >> HIGH_RES_TRIG_FRAC);
56 ltp_of_ecef->m[7] = (int32_t)(((int64_t)cos_lat * (int64_t)sin_lon) >> HIGH_RES_TRIG_FRAC);
57 ltp_of_ecef->m[8] = sin_lat;
58}
59
60void ltp_def_from_ecef_i(struct LtpDef_i *def, struct EcefCoor_i *ecef)
61{
62
63 /* store the origin of the tangent plane */
64 VECT3_COPY(def->ecef, *ecef);
65 /* compute the lla representation of the origin */
66 lla_of_ecef_i(&def->lla, &def->ecef);
67 /* store the rotation matrix */
68 ltp_of_ecef_rmat_from_lla_i(&def->ltp_of_ecef, &def->lla);
69
70}
71
72void ltp_def_from_lla_i(struct LtpDef_i *def, struct LlaCoor_i *lla)
73{
74
75 /* store the origin of the tangent plane */
76 LLA_COPY(def->lla, *lla);
77 /* compute the ecef representation of the origin */
78 ecef_of_lla_i(&def->ecef, &def->lla);
79 /* store the rotation matrix */
80 ltp_of_ecef_rmat_from_lla_i(&def->ltp_of_ecef, &def->lla);
81
82}
83
84
90void enu_of_ecef_point_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct EcefCoor_i *ecef)
91{
92
93 struct EcefCoor_i delta;
94 VECT3_DIFF(delta, *ecef, def->ecef);
95 const int64_t tmpx = (int64_t)def->ltp_of_ecef.m[0] * delta.x +
96 (int64_t)def->ltp_of_ecef.m[1] * delta.y +
97 0; /* this element is always zero http://en.wikipedia.org/wiki/Geodetic_system#From_ECEF_to_ENU */
99 const int64_t tmpy = (int64_t)def->ltp_of_ecef.m[3] * delta.x +
100 (int64_t)def->ltp_of_ecef.m[4] * delta.y +
101 (int64_t)def->ltp_of_ecef.m[5] * delta.z;
103 const int64_t tmpz = (int64_t)def->ltp_of_ecef.m[6] * delta.x +
104 (int64_t)def->ltp_of_ecef.m[7] * delta.y +
105 (int64_t)def->ltp_of_ecef.m[8] * delta.z;
107
108}
109
110
116void ned_of_ecef_point_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct EcefCoor_i *ecef)
117{
118 struct EnuCoor_i enu;
119 enu_of_ecef_point_i(&enu, def, ecef);
121}
122
123
129void enu_of_ecef_pos_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct EcefCoor_i *ecef)
130{
131 struct EnuCoor_i enu_cm;
133
134 /* enu = (enu_cm / 100) << INT32_POS_FRAC
135 * to loose less range:
136 * enu_cm = enu << (INT32_POS_FRAC-2) / 25
137 * which puts max enu output Q23.8 range to 8388km / 25 = 335km
138 */
140 VECT3_SDIV(*enu, *enu, 25);
141}
142
143
149void ned_of_ecef_pos_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct EcefCoor_i *ecef)
150{
151 struct EnuCoor_i enu;
152 enu_of_ecef_pos_i(&enu, def, ecef);
154}
155
156
162void enu_of_ecef_vect_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct EcefCoor_i *ecef)
163{
164
165 const int64_t tmpx = (int64_t)def->ltp_of_ecef.m[0] * ecef->x +
166 (int64_t)def->ltp_of_ecef.m[1] * ecef->y +
167 0; /* this element is always zero http://en.wikipedia.org/wiki/Geodetic_system#From_ECEF_to_ENU */
169 const int64_t tmpy = (int64_t)def->ltp_of_ecef.m[3] * ecef->x +
170 (int64_t)def->ltp_of_ecef.m[4] * ecef->y +
171 (int64_t)def->ltp_of_ecef.m[5] * ecef->z;
173 const int64_t tmpz = (int64_t)def->ltp_of_ecef.m[6] * ecef->x +
174 (int64_t)def->ltp_of_ecef.m[7] * ecef->y +
175 (int64_t)def->ltp_of_ecef.m[8] * ecef->z;
177
178}
179
180
186void ned_of_ecef_vect_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct EcefCoor_i *ecef)
187{
188 struct EnuCoor_i enu;
189 enu_of_ecef_vect_i(&enu, def, ecef);
191}
192
193
199void ecef_of_enu_vect_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
200{
201
202 const int64_t tmpx = (int64_t)def->ltp_of_ecef.m[0] * enu->x +
203 (int64_t)def->ltp_of_ecef.m[3] * enu->y +
204 (int64_t)def->ltp_of_ecef.m[6] * enu->z;
205 ecef->x = (int32_t)(tmpx >> HIGH_RES_TRIG_FRAC);
206
207 const int64_t tmpy = (int64_t)def->ltp_of_ecef.m[1] * enu->x +
208 (int64_t)def->ltp_of_ecef.m[4] * enu->y +
209 (int64_t)def->ltp_of_ecef.m[7] * enu->z;
210 ecef->y = (int32_t)(tmpy >> HIGH_RES_TRIG_FRAC);
211
212 /* first element is always zero http://en.wikipedia.org/wiki/Geodetic_system#From_ENU_to_ECEF */
213 const int64_t tmpz = (int64_t)def->ltp_of_ecef.m[5] * enu->y +
214 (int64_t)def->ltp_of_ecef.m[8] * enu->z;
215 ecef->z = (int32_t)(tmpz >> HIGH_RES_TRIG_FRAC);
216
217}
218
219
225void ecef_of_ned_vect_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct NedCoor_i *ned)
226{
227 struct EnuCoor_i enu;
229 ecef_of_enu_vect_i(ecef, def, &enu);
230}
231
232
238void ecef_of_enu_point_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
239{
240 ecef_of_enu_vect_i(ecef, def, enu);
241 VECT3_ADD(*ecef, def->ecef);
242}
243
244
250void ecef_of_ned_point_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct NedCoor_i *ned)
251{
252 struct EnuCoor_i enu;
254 ecef_of_enu_point_i(ecef, def, &enu);
255}
256
257
263void ecef_of_enu_pos_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
264{
265 /* enu_cm = (enu * 100) >> INT32_POS_FRAC
266 * to loose less range:
267 * enu_cm = (enu * 25) >> (INT32_POS_FRAC-2)
268 * which puts max enu input Q23.8 range to 8388km / 25 = 335km
269 */
270 struct EnuCoor_i enu_cm;
271 VECT3_SMUL(enu_cm, *enu, 25);
274 VECT3_ADD(*ecef, def->ecef);
275}
276
277
283void ecef_of_ned_pos_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct NedCoor_i *ned)
284{
285 struct EnuCoor_i enu;
287 ecef_of_enu_pos_i(ecef, def, &enu);
288}
289
295void enu_of_lla_point_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct LlaCoor_i *lla)
296{
297 struct EcefCoor_i ecef;
298 ecef_of_lla_i(&ecef, lla);
299 enu_of_ecef_point_i(enu, def, &ecef);
300}
301
307void ned_of_lla_point_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct LlaCoor_i *lla)
308{
309 struct EcefCoor_i ecef;
310 ecef_of_lla_i(&ecef, lla);
311 ned_of_ecef_point_i(ned, def, &ecef);
312}
313
319void enu_of_lla_pos_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct LlaCoor_i *lla)
320{
321 struct EcefCoor_i ecef;
322 ecef_of_lla_i(&ecef, lla);
323 enu_of_ecef_pos_i(enu, def, &ecef);
324}
325
331void ned_of_lla_pos_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct LlaCoor_i *lla)
332{
333 struct EcefCoor_i ecef;
334 ecef_of_lla_i(&ecef, lla);
335 ned_of_ecef_pos_i(ned, def, &ecef);
336}
337
338void enu_of_lla_vect_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct LlaCoor_i *lla)
339{
340 struct EcefCoor_i ecef;
341 ecef_of_lla_i(&ecef, lla);
342 enu_of_ecef_vect_i(enu, def, &ecef);
343}
344
345void ned_of_lla_vect_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct LlaCoor_i *lla)
346{
347 struct EcefCoor_i ecef;
348 ecef_of_lla_i(&ecef, lla);
349 ned_of_ecef_vect_i(ned, def, &ecef);
350}
351
352/*
353 For now we cheat and call the floating point version
354 Anyone up for writing it in fixed point ?
355*/
356#include "pprz_geodetic_float.h"
357#include "pprz_geodetic_double.h"
358
363void lla_of_ecef_i(struct LlaCoor_i *out, struct EcefCoor_i *in)
364{
365
366#if USE_SINGLE_PRECISION_LLA_ECEF
367 /* convert our input to floating point */
368 struct EcefCoor_f in_f;
370 /* calls the floating point transformation */
371 struct LlaCoor_f out_f;
373 /* convert the output to fixed point */
374 LLA_BFP_OF_REAL(*out, out_f);
375#else // use double precision by default
376 /* convert our input to floating point */
377 struct EcefCoor_d in_d;
379 /* calls the floating point transformation */
380 struct LlaCoor_d out_d;
382 /* convert the output to fixed point */
383 LLA_BFP_OF_REAL(*out, out_d);
384#endif
385
386}
387
392void ecef_of_lla_i(struct EcefCoor_i *out, struct LlaCoor_i *in)
393{
394
395#if USE_SINGLE_PRECISION_LLA_ECEF
396 /* convert our input to floating point */
397 struct LlaCoor_f in_f;
399 /* calls the floating point transformation */
400 struct EcefCoor_f out_f;
402 /* convert the output to fixed point */
403 ECEF_BFP_OF_REAL(*out, out_f);
404#else // use double precision by default
405 /* convert our input to floating point */
406 struct LlaCoor_d in_d;
408 /* calls the floating point transformation */
409 struct EcefCoor_d out_d;
411 /* convert the output to fixed point */
412 ECEF_BFP_OF_REAL(*out, out_d);
413#endif
414
415}
416
418
423void utm_of_lla_i(struct UtmCoor_i *utm, struct LlaCoor_i *lla)
424{
425#if USE_SINGLE_PRECISION_LLA_UTM
426 /* convert our input to floating point */
427 struct LlaCoor_f lla_f;
428 LLA_FLOAT_OF_BFP(lla_f, *lla);
429 /* calls the floating point transformation */
430 struct UtmCoor_f utm_f;
431 utm_f.zone = utm->zone;
432 utm_of_lla_f(&utm_f, &lla_f);
433 /* convert the output to fixed point */
435#else // use double precision by default
436 /* convert our input to floating point */
437 struct LlaCoor_d lla_d;
439 /* calls the floating point transformation */
440 struct UtmCoor_d utm_d;
441 utm_d.zone = utm->zone;
443 /* convert the output to fixed point */
445#endif
446}
447
452void lla_of_utm_i(struct LlaCoor_i *lla, struct UtmCoor_i *utm)
453{
454#if USE_SINGLE_PRECISION_LLA_UTM
455 /* convert our input to floating point */
456 struct UtmCoor_f utm_f;
458 /* calls the floating point transformation */
459 struct LlaCoor_f lla_f;
460 lla_of_utm_f(&lla_f, &utm_f);
461 /* convert the output to fixed point */
462 LLA_BFP_OF_REAL(*lla, lla_f);
463#else // use double precision by default
464 /* convert our input to floating point */
465 struct UtmCoor_d utm_d;
467 /* calls the floating point transformation */
468 struct LlaCoor_d lla_d;
470 /* convert the output to fixed point */
471 LLA_BFP_OF_REAL(*lla, lla_d);
472#endif
473
474}
#define VECT3_SDIV(_vo, _vi, _s)
#define VECT3_SMUL(_vo, _vi, _s)
#define VECT3_COPY(_a, _b)
#define VECT3_DIFF(_c, _a, _b)
#define VECT3_ADD(_a, _b)
int32_t m[3 *3]
#define INT32_POS_FRAC
#define INT32_VECT3_RSHIFT(_o, _i, _r)
#define INT32_VECT3_LSHIFT(_o, _i, _l)
#define BFP_OF_REAL(_vr, _frac)
rotation matrix
uint8_t zone
UTM zone number.
void lla_of_utm_d(struct LlaCoor_d *lla, struct UtmCoor_d *utm)
void lla_of_ecef_d(struct LlaCoor_d *lla, struct EcefCoor_d *ecef)
void utm_of_lla_d(struct UtmCoor_d *utm, struct LlaCoor_d *lla)
void ecef_of_lla_d(struct EcefCoor_d *ecef, struct LlaCoor_d *lla)
vector in EarthCenteredEarthFixed coordinates
vector in Latitude, Longitude and Altitude
position in UTM coordinates Units: meters
#define LLA_COPY(_pos1, _pos2)
#define ENU_OF_TO_NED(_po, _pi)
int32_t lat
in degrees*1e7
int32_t z
in centimeters
int32_t x
in centimeters
int32_t y
in centimeters
int32_t lon
in degrees*1e7
#define UTM_DOUBLE_OF_BFP(_o, _i)
void ned_of_lla_pos_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct LlaCoor_i *lla)
Convert a point from LLA to local NED.
#define RAD_OF_EM7DEG(_r)
#define ECEF_FLOAT_OF_BFP(_o, _i)
void ecef_of_lla_i(struct EcefCoor_i *out, struct LlaCoor_i *in)
Convert a LLA to ECEF.
void lla_of_utm_i(struct LlaCoor_i *lla, struct UtmCoor_i *utm)
Convert a UTM to LLA.
#define ECEF_BFP_OF_REAL(_o, _i)
#define LLA_DOUBLE_OF_BFP(_o, _i)
#define LLA_BFP_OF_REAL(_o, _i)
void ned_of_ecef_pos_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct EcefCoor_i *ecef)
Convert a ECEF position to local NED.
void ned_of_lla_vect_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct LlaCoor_i *lla)
void enu_of_lla_vect_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct LlaCoor_i *lla)
void ltp_def_from_ecef_i(struct LtpDef_i *def, struct EcefCoor_i *ecef)
void ned_of_lla_point_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct LlaCoor_i *lla)
Convert a point from LLA to local NED.
void ltp_of_ecef_rmat_from_lla_i(struct Int32RMat *ltp_of_ecef, struct LlaCoor_i *lla)
#define HIGH_RES_TRIG_FRAC
void enu_of_ecef_pos_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct EcefCoor_i *ecef)
Convert a ECEF position to local ENU.
void enu_of_ecef_point_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct EcefCoor_i *ecef)
Convert a point from ECEF to local ENU.
#define UTM_BFP_OF_REAL(_o, _i)
void ned_of_ecef_point_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct EcefCoor_i *ecef)
Convert a point from ECEF to local NED.
void ecef_of_enu_vect_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
Rotate a vector from ENU to ECEF.
void ecef_of_enu_pos_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
Convert a local ENU position to ECEF.
void ecef_of_ned_vect_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct NedCoor_i *ned)
Rotate a vector from NED to ECEF.
void enu_of_lla_point_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct LlaCoor_i *lla)
Convert a point from LLA to local ENU.
void ned_of_ecef_vect_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct EcefCoor_i *ecef)
Rotate a vector from ECEF to NED.
#define ECEF_DOUBLE_OF_BFP(_o, _i)
#define LLA_FLOAT_OF_BFP(_o, _i)
void utm_of_lla_i(struct UtmCoor_i *utm, struct LlaCoor_i *lla)
Convert a LLA to UTM.
void ecef_of_enu_point_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
Convert a point in local ENU to ECEF.
void enu_of_lla_pos_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct LlaCoor_i *lla)
Convert a point from LLA to local ENU.
void ecef_of_ned_point_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct NedCoor_i *ned)
Convert a point in local NED to ECEF.
void lla_of_ecef_i(struct LlaCoor_i *out, struct EcefCoor_i *in)
Convert a ECEF to LLA.
void ltp_def_from_lla_i(struct LtpDef_i *def, struct LlaCoor_i *lla)
void enu_of_ecef_vect_i(struct EnuCoor_i *enu, struct LtpDef_i *def, struct EcefCoor_i *ecef)
Rotate a vector from ECEF to ENU.
#define UTM_FLOAT_OF_BFP(_o, _i)
void ecef_of_ned_pos_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct NedCoor_i *ned)
Convert a local NED position to ECEF.
vector in EarthCenteredEarthFixed coordinates
vector in East North Up coordinates
vector in Latitude, Longitude and Altitude
definition of the local (flat earth) coordinate system
vector in North East Down coordinates
position in UTM coordinates
uint16_t foo
Definition main_demo5.c:58
Paparazzi fixed point algebra.
Paparazzi double-precision floating point math for geodetic calculations.
void lla_of_utm_f(struct LlaCoor_f *lla, struct UtmCoor_f *utm)
void ecef_of_lla_f(struct EcefCoor_f *out, struct LlaCoor_f *in)
void lla_of_ecef_f(struct LlaCoor_f *out, struct EcefCoor_f *in)
void utm_of_lla_f(struct UtmCoor_f *utm, struct LlaCoor_f *lla)
Paparazzi floating point math for geodetic calculations.
uint8_t zone
UTM zone number.
vector in EarthCenteredEarthFixed coordinates
vector in Latitude, Longitude and Altitude
position in UTM coordinates Units: meters
Paparazzi fixed point math for geodetic calculations.
Constants UTM (Mercator) projections.
int int32_t
Typedef defining 32 bit int type.