]> git.mxchange.org Git - flightgear.git/blob - LaRCsim/ls_geodesy.c
Tons of little changes to clean up the code and to remove fatal errors
[flightgear.git] / LaRCsim / ls_geodesy.c
1 /***************************************************************************
2
3         TITLE:  ls_geodesy
4         
5 ----------------------------------------------------------------------------
6
7         FUNCTION:       Converts geocentric coordinates to geodetic positions
8
9 ----------------------------------------------------------------------------
10
11         MODULE STATUS:  developmental
12
13 ----------------------------------------------------------------------------
14
15         GENEALOGY:      Written as part of LaRCSim project by E. B. Jackson
16
17 ----------------------------------------------------------------------------
18
19         DESIGNED BY:    E. B. Jackson
20         
21         CODED BY:       E. B. Jackson
22         
23         MAINTAINED BY:  E. B. Jackson
24
25 ----------------------------------------------------------------------------
26
27         MODIFICATION HISTORY:
28         
29         DATE    PURPOSE                                         BY
30         
31         930208  Modified to avoid singularity near polar region.        EBJ
32         930602  Moved backwards calcs here from ls_step.                EBJ
33         931214  Changed erroneous Latitude and Altitude variables to 
34                 *lat_geod and *alt in routine ls_geoc_to_geod.          EBJ
35         940111  Changed header files from old ls_eom.h style to ls_types, 
36                 and ls_constants.  Also replaced old DATA type with new
37                 SCALAR type.                                            EBJ
38
39         CURRENT RCS HEADER:
40
41 $Header$
42 $Log$
43 Revision 1.2  1998/01/19 18:40:25  curt
44 Tons of little changes to clean up the code and to remove fatal errors
45 when building with the c++ compiler.
46
47 Revision 1.1  1997/05/29 00:09:56  curt
48 Initial Flight Gear revision.
49
50  * Revision 1.5  1994/01/11  18:47:05  bjax
51  * Changed include files to use types and constants, not ls_eom.h
52  * Also changed DATA type to SCALAR type.
53  *
54  * Revision 1.4  1993/12/14  21:06:47  bjax
55  * Removed global variable references Altitude and Latitude.   EBJ
56  *
57  * Revision 1.3  1993/06/02  15:03:40  bjax
58  * Made new subroutine for calculating geodetic to geocentric; changed name
59  * of forward conversion routine from ls_geodesy to ls_geoc_to_geod.
60  *
61
62 ----------------------------------------------------------------------------
63
64         REFERENCES:
65
66                 [ 1]    Stevens, Brian L.; and Lewis, Frank L.: "Aircraft 
67                         Control and Simulation", Wiley and Sons, 1992.
68                         ISBN 0-471-61397-5                    
69
70
71 ----------------------------------------------------------------------------
72
73         CALLED BY:      ls_aux
74
75 ----------------------------------------------------------------------------
76
77         CALLS TO:
78
79 ----------------------------------------------------------------------------
80
81         INPUTS: 
82                 lat_geoc        Geocentric latitude, radians, + = North
83                 radius          C.G. radius to earth center, ft
84
85 ----------------------------------------------------------------------------
86
87         OUTPUTS:
88                 lat_geod        Geodetic latitude, radians, + = North
89                 alt             C.G. altitude above mean sea level, ft
90                 sea_level_r     radius from earth center to sea level at
91                                 local vertical (surface normal) of C.G.
92
93 --------------------------------------------------------------------------*/
94
95 #include "ls_types.h"
96 #include "ls_constants.h"
97 #include "ls_geodesy.h"
98 #include <math.h>
99
100 /* ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator */
101 #define ONE_SECOND 4.848136811E-6
102 #define HALF_PI 0.5*PI
103
104
105 void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius, SCALAR *lat_geod, 
106                       SCALAR *alt, SCALAR *sea_level_r )
107 {
108         SCALAR  t_lat, x_alpha, mu_alpha, delt_mu, r_alpha, l_point, rho_alpha;
109         SCALAR  sin_mu_a, denom,delt_lambda, lambda_sl, sin_lambda_sl;
110
111         if(   ( (HALF_PI - lat_geoc) < ONE_SECOND )     /* near North pole */
112            || ( (HALF_PI + lat_geoc) < ONE_SECOND ) )   /* near South pole */
113           {
114             *lat_geod = lat_geoc;
115             *sea_level_r = EQUATORIAL_RADIUS*E;
116             *alt = radius - *sea_level_r;
117           }
118         else
119           {
120             t_lat = tan(lat_geoc);
121             x_alpha = E*EQUATORIAL_RADIUS/sqrt(t_lat*t_lat + E*E);
122             mu_alpha = atan2(sqrt(RESQ - x_alpha*x_alpha),E*x_alpha);
123             if (lat_geoc < 0) mu_alpha = - mu_alpha;
124             sin_mu_a = sin(mu_alpha);
125             delt_lambda = mu_alpha - lat_geoc;
126             r_alpha = x_alpha/cos(lat_geoc);
127             l_point = radius - r_alpha;
128             *alt = l_point*cos(delt_lambda);
129             denom = sqrt(1-EPS*EPS*sin_mu_a*sin_mu_a);
130             rho_alpha = EQUATORIAL_RADIUS*(1-EPS)/
131               (denom*denom*denom);
132             delt_mu = atan2(l_point*sin(delt_lambda),rho_alpha + *alt);
133             *lat_geod = mu_alpha - delt_mu;
134             lambda_sl = atan( E*E * tan(*lat_geod) ); /* SL geoc. latitude */
135             sin_lambda_sl = sin( lambda_sl );
136             *sea_level_r = sqrt(RESQ
137                            /(1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
138           }
139 }
140
141
142 void ls_geod_to_geoc( SCALAR lat_geod, SCALAR alt, 
143                       SCALAR *sl_radius, SCALAR *lat_geoc )
144 {
145     SCALAR lambda_sl, sin_lambda_sl, cos_lambda_sl, sin_mu, cos_mu, px, py;
146     
147     lambda_sl = atan( E*E * tan(lat_geod) ); /* sea level geocentric latitude */
148     sin_lambda_sl = sin( lambda_sl );
149     cos_lambda_sl = cos( lambda_sl );
150     sin_mu = sin(lat_geod);     /* Geodetic (map makers') latitude */
151     cos_mu = cos(lat_geod);
152     *sl_radius = sqrt(RESQ
153         /(1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
154     py = *sl_radius*sin_lambda_sl + alt*sin_mu;
155     px = *sl_radius*cos_lambda_sl + alt*cos_mu;
156     *lat_geoc = atan2( py, px );
157 }