summaryrefslogtreecommitdiff
path: root/mbglib/common/mbggeo.h
blob: 57468d04fee34453bede1385544fa87dbb0f013c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

/**************************************************************************
 *
 *  $Id: mbggeo.h 1.13 2017/01/27 08:57:58 martin REL_M $
 *
 *  Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
 *
 *  Description:
 *    Definitions and prototypes for mbggeo.c.
 *
 *  Terms used:
 *
 *     WGS84   World Geodetic System of 1984
 *
 *     XYZ     WGS84 earth centered, earth fixed (ECEF) kartesian
 *             coordinates
 *
 *     LLA     longitude, latitude, altitude depending on the reference
 *             ellipsoid used.
 *
 *     DMS     degrees, minutes, seconds
 *
 * -----------------------------------------------------------------------
 *  $Log: mbggeo.h $
 *  Revision 1.13  2017/01/27 08:57:58  martin
 *  Fixed macro syntax.
 *  Revision 1.12  2016/10/31 16:50:56  martin
 *  Fixed a typo.
 *  Updated doxygen comments.
 *  Revision 1.11  2011/06/22 10:18:10  martin
 *  Cleaned up handling of pragma pack().
 *  Revision 1.10  2008/09/03 14:54:28  martin
 *  Added macros to swap endianess of structures.
 *  Revision 1.9  2008/01/17 09:31:33  daniel
 *  Made comments compatible for doxygen parser.
 *  No sourcecode changes.
 *  Revision 1.8  2004/11/09 14:16:00Z  martin
 *  Redefined interface data types using C99 fixed-size definitions.
 *  Revision 1.7  2003/02/14 13:23:04Z  martin
 *  Omit inclusion of mystd.h.
 *  Revision 1.6  2003/01/13 15:17:15  martin
 *  Structures were defined with default alignment which
 *  could result in different data sizes on different platforms.
 *  Revision 1.5  2002/12/18 14:46:41Z  martin
 *  Removed variable USER_POS meinberg.
 *  Updated function prototypes.
 *  Revision 1.4  2002/12/12 12:04:25Z  martin
 *  Moved some definitions here.
 *  Use standard file format.
 *
 **************************************************************************/

#ifndef _MBGGEO_H
#define _MBGGEO_H


/* Other headers to be included */

#include <gpsdefs.h>
#include <use_pack.h>

#ifdef _MBGGEO
 #define _ext
 #define _DO_INIT
#else
 #define _ext extern
#endif


/* Start of header body */

#if defined( _USE_PACK )
  #pragma pack( 1 )      // set byte alignment
  #define _USING_BYTE_ALIGNMENT
#endif


/**
 * @brief Geographic longitude or latitude in [degrees, minutes, seconds]
 *
 * Longitude East and latitude North are positive angles, South or West
 * angles are negative.
 */
typedef struct
{
  uint16_t prefix;  ///< 'N', 'E', 'S' or 'W'
  uint16_t deg;     ///< [0...90 (lat) or 0...180 (lon)]
  uint16_t min;     ///< [0...59]
  double sec;       ///< [0...59.99999...]

} DMS;

#define _mbg_swab_dms( _p )        \
do                                 \
{                                  \
  _mbg_swab16( &(_p)->prefix );    \
  _mbg_swab16( &(_p)->deg );       \
  _mbg_swab16( &(_p)->min );       \
  _mbg_swab_double( &(_p)->sec );  \
} while ( 0 )



/**
 * @brief A geographic position represented in different formats
 */
typedef struct
{
  XYZ xyz;           ///< Always WGS84 ECEF coordinates
  LLA lla;           ///< Longitude, latitude and altitude, depending on the ellipsoid used for reference
  DMS longitude;     ///< Longitude broken down to degrees, minutes, seconds
  DMS latitude;      ///< Latitude broken down to degrees, minutes, seconds
  int16_t ellipsoid; ///< Ellipsoid used for reference, see ::ELLIPSOIDS

} POS;

#define _mbg_swab_pos( _p )           \
do                                    \
{                                     \
  _mbg_swab_xyz( (_p)->xyz );         \
  _mbg_swab_lla( (_p)->lla );         \
  _mbg_swab_dms( &(_p)->longitude );  \
  _mbg_swab_dms( &(_p)->latitude );   \
  _mbg_swab16( &(_p)->ellipsoid );    \
} while ( 0 )



/**
 * @brief A structure used internally to compute a geographic position
 *
 * Also contains intermediate results useful for the computation.
 */
typedef struct
{
  CSUM csum;        ///< Checksum of the remaining bytes
  int16_t valid;    ///< Indicator if data is valid

  char name[40];    ///< Informational string
  POS pos;          ///< The position in WGS84 ECEF coords and ::LLA
  double det;


  // The components below hold the results of intermediate terms
  // computed in complete_user_pos().

  // The sin.., cos.., nt.. and ut.. variables are used to compute the
  // enu_dcos[] parameters of a SV structure in xyz_to_ead().

  // The e_radius.. variables are used to compute the latitude, longitude
  // and altitude from ECEF coordinates in lla_to_xyz().

  double sin_lat;       ///< sin( latitude )
  double cos_lat;       ///< cos( latitude )
  double sin_lon;       ///< sin( longitude )
  double cos_lon;       ///< cos( longitude )

  double nt1;           ///< -sin_lat * cos_lon
  double nt2;           ///< -sin_lat * sin_lon
  double utx;           ///<  cos_lat * cos_lon
  double uty;           ///<  cos_lat * sin_lon

  double e_radius;      ///< N
  double e_radius_alt;  ///< N + h

} USER_POS;



/**
 * @brief Characteristics of a geographic reference ellipsoid
 */
typedef struct
{
  CSUM csum;           ///< Checksum of the remaining bytes
  int16_t valid;       ///< Indicator if data is valid

  char name[40];
  XYZ dxyz;            ///< Offset from the WGS84 ECEF coords
  double a;            ///< Semi major axis
  double rcp_f;        ///< Reciproke of flatness

  // The variables below are computed in the init_mbggeo() function:

  double f;            ///< Flatness
  double b;            ///< Semi minor axis
  double sqr_e;        ///< Square of numerical eccentricity

} ELLIPSOID;



/**
 * @brief An enumeration of known ellipsoids
 */
enum ELLIPSOIDS
{
  WGS84,
  BESSEL,
  N_ELLIPSOIDS
};


_ext ELLIPSOID ellipsoid[N_ELLIPSOIDS]
#ifdef _DO_INIT
 = { { 0, 0,
       "WGS 84",
       { 0.0, 0.0, 0.0 },
       6378137.0,
       298.257223563
     },

     { 0, 0,
       "Bessel",
       { -128.0, 481.0, 664.0 },
       6377397.0,
       299.15
     }

   }
#endif
;


// WGS84 constants used

_ext double OMEGADOTe   // Earth's rotation rate  [rad/sec]
#ifdef _DO_INIT
  = 7.2921151467e-5
#endif
;

_ext double mue         // Earth's gravitational constant  [m^3/sec^2]
#ifdef _DO_INIT
  = 3.986005e14
#endif
;



_ext double vr_to_doppler;


_ext double gps_pi
#ifdef _DO_INIT
  = 3.1415926535898
#endif
;

_ext double gps_c0
#ifdef _DO_INIT
  = 2.99792458e8
#endif
;


#ifndef PI
  #define PI 3.1415926535897932
#endif


_ext double pi
#ifdef _DO_INIT
 = PI
#endif
;


_ext double r2d
#ifdef _DO_INIT
  = 180.0 / PI
#endif
;


_ext double d2r
#ifdef _DO_INIT
  = PI / 180.0
#endif
;


// Variables for simplifying computations

_ext double gps_two_pi;
_ext double sqrt_mue;         // sqrt( mue )



/* function prototypes: */

#ifdef __cplusplus
extern "C" {
#endif

/* ----- function prototypes begin ----- */

/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */

 void dms_to_rad( const DMS *dms, double *rad ) ;
 void rad_to_dms( const double *rad, DMS *dms, const char prefix ) ;
 void dms_to_lla( POS *pos ) ;
 void lla_to_dms( POS *pos ) ;
 void lla_to_xyz( USER_POS *pos ) ;
 void xyz_to_lla( POS *pos, void (*cyclic_func)( void ) ) ;
 void dms_to_xyz( USER_POS *pos ) ;
 void setup_user_pos_from_dms( USER_POS *user ) ;
 void setup_user_pos_from_lla( USER_POS *user ) ;
 void setup_user_pos_from_xyz( USER_POS *user, void (*cyclic_func)( void ) ) ;
 double distance( XYZ xyz_1, XYZ xyz_2 ) ;
 void init_mbggeo( void ) ;

/* ----- function prototypes end ----- */

#ifdef __cplusplus
}
#endif


#if defined( _USING_BYTE_ALIGNMENT )
  #pragma pack()      // set default alignment
  #undef _USING_BYTE_ALIGNMENT
#endif

/* End of header body */

#undef _ext
#undef _DO_INIT

#endif  /* _MBGGEO_H */