]> git.mxchange.org Git - flightgear.git/blob - LaRCsim/ls_geodesy.c
Initial Flight Gear revision.
[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.1  1997/05/29 00:09:56  curt
44 Initial Flight Gear revision.
45
46  * Revision 1.5  1994/01/11  18:47:05  bjax
47  * Changed include files to use types and constants, not ls_eom.h
48  * Also changed DATA type to SCALAR type.
49  *
50  * Revision 1.4  1993/12/14  21:06:47  bjax
51  * Removed global variable references Altitude and Latitude.   EBJ
52  *
53  * Revision 1.3  1993/06/02  15:03:40  bjax
54  * Made new subroutine for calculating geodetic to geocentric; changed name
55  * of forward conversion routine from ls_geodesy to ls_geoc_to_geod.
56  *
57
58 ----------------------------------------------------------------------------
59
60         REFERENCES:
61
62                 [ 1]    Stevens, Brian L.; and Lewis, Frank L.: "Aircraft 
63                         Control and Simulation", Wiley and Sons, 1992.
64                         ISBN 0-471-61397-5                    
65
66
67 ----------------------------------------------------------------------------
68
69         CALLED BY:      ls_aux
70
71 ----------------------------------------------------------------------------
72
73         CALLS TO:
74
75 ----------------------------------------------------------------------------
76
77         INPUTS: 
78                 lat_geoc        Geocentric latitude, radians, + = North
79                 radius          C.G. radius to earth center, ft
80
81 ----------------------------------------------------------------------------
82
83         OUTPUTS:
84                 lat_geod        Geodetic latitude, radians, + = North
85                 alt             C.G. altitude above mean sea level, ft
86                 sea_level_r     radius from earth center to sea level at
87                                 local vertical (surface normal) of C.G.
88
89 --------------------------------------------------------------------------*/
90
91 #include "ls_types.h"
92 #include "ls_constants.h"
93 #include <math.h>
94
95 /* ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator */
96 #define ONE_SECOND 4.848136811E-6
97 #define HALF_PI 0.5*PI
98
99
100 void ls_geoc_to_geod(  lat_geoc, radius, lat_geod, alt, sea_level_r )
101      SCALAR lat_geoc;
102      SCALAR radius;
103      SCALAR *lat_geod;
104      SCALAR *alt;
105      SCALAR *sea_level_r;
106 {
107         SCALAR  t_lat, x_alpha, mu_alpha, delt_mu, r_alpha, l_point, rho_alpha;
108         SCALAR  sin_mu_a, denom,delt_lambda, lambda_sl, sin_lambda_sl;
109
110         if(   ( (HALF_PI - lat_geoc) < ONE_SECOND )     /* near North pole */
111            || ( (HALF_PI + lat_geoc) < ONE_SECOND ) )   /* near South pole */
112           {
113             *lat_geod = lat_geoc;
114             *sea_level_r = EQUATORIAL_RADIUS*E;
115             *alt = radius - *sea_level_r;
116           }
117         else
118           {
119             t_lat = tan(lat_geoc);
120             x_alpha = E*EQUATORIAL_RADIUS/sqrt(t_lat*t_lat + E*E);
121             mu_alpha = atan2(sqrt(RESQ - x_alpha*x_alpha),E*x_alpha);
122             if (lat_geoc < 0) mu_alpha = - mu_alpha;
123             sin_mu_a = sin(mu_alpha);
124             delt_lambda = mu_alpha - lat_geoc;
125             r_alpha = x_alpha/cos(lat_geoc);
126             l_point = radius - r_alpha;
127             *alt = l_point*cos(delt_lambda);
128             denom = sqrt(1-EPS*EPS*sin_mu_a*sin_mu_a);
129             rho_alpha = EQUATORIAL_RADIUS*(1-EPS)/
130               (denom*denom*denom);
131             delt_mu = atan2(l_point*sin(delt_lambda),rho_alpha + *alt);
132             *lat_geod = mu_alpha - delt_mu;
133             lambda_sl = atan( E*E * tan(*lat_geod) ); /* SL geoc. latitude */
134             sin_lambda_sl = sin( lambda_sl );
135             *sea_level_r = sqrt(RESQ
136                            /(1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
137           }
138 }
139
140 void ls_geod_to_geoc( lat_geod, alt, sl_radius, lat_geoc )
141     SCALAR lat_geod;
142     SCALAR alt;
143     SCALAR *sl_radius;
144     SCALAR *lat_geoc;
145 {
146     SCALAR lambda_sl, sin_lambda_sl, cos_lambda_sl, sin_mu, cos_mu, px, py;
147     
148     lambda_sl = atan( E*E * tan(lat_geod) ); /* sea level geocentric latitude */
149     sin_lambda_sl = sin( lambda_sl );
150     cos_lambda_sl = cos( lambda_sl );
151     sin_mu = sin(lat_geod);     /* Geodetic (map makers') latitude */
152     cos_mu = cos(lat_geod);
153     *sl_radius = sqrt(RESQ
154         /(1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
155     py = *sl_radius*sin_lambda_sl + alt*sin_mu;
156     px = *sl_radius*cos_lambda_sl + alt*cos_mu;
157     *lat_geoc = atan2( py, px );
158 }