1 /*
2  *  - - - - - - - - - - - - -
3  *   g a l _ s g p 4 i n i t
4  *  - - - - - - - - - - - - -
5  *
6  *  This routine is part of the General Astrodynamics Library
7  *
8  *  Description:
9  *
10  *     This routine initializes the variables for gal_sgp4.
11  *
12  *  Status:
13  *
14  *     SGP4 support routine.
15  *
16  *  Given:
17  *
18  *     *gm           gal_gm_t       Gravity Model
19  *     *tle          gal_tle_t      TLE parameters
20  *
21  *  Returned:
22  *
23  *     *sgp4        gal_sgp4_t      Common values for subsequent calls
24  *     gal_sgp4init     i           GAL_SUCCESS if OK
25  *                                  1 = mean elements, ecc >= 1.0 or ecc < -0.001 or a < 0.95 er
26  *                                  2 = mean motion less than 0.0
27  *                                  3 = pert elements, ecc < 0.0  or  ecc > 1.0
28  *                                  4 = semi-latus rectum < 0.0
29  *                                  5 = epoch elements are sub-orbital
30  *                                  6 = satellite has decayed
31  *
32  *  Notes:
33  *
34  *  1) This routine is based on a translation from c++ to c of David Vallado's SGP4UNIT.sgp4init
35  *     routine ( 2007 November 16 ).
36  *
37  *  Called:
38  *
39  *     gal_sgp4gm       Get gravity model parameters for SGP4
40  *     gal_initsgp4p    Initialize SGP4 propagator
41  *     gal_dscom
42  *     gal_dpper
43  *     gal_dsinit
44  *     gal_sgp4         SGP4 orbit propagator
45  *     gal_days2cal     Convert day of year to calendar date
46  *     gal_cal2jd       Convert calendar date to Julian Date
47  *
48  *  References:
49  *
50  *     NORAD Spacetrack Report #3 1980
51  *     Hoots, Roehrich
52  *
53  *     NORAD Spacetrack Report #6 1986
54  *     Hoots
55  *
56  *     Hoots, Schumacher and Glover 2004
57  *
58  *     Revisting Spacetrack Report #3
59  *     Vallado, David, Crawford, Paul, Hujsak, Richard, Kelso, T.S.
60  *     AIAA 2006-6753
61  *
62  *  This revision:
63  *
64  *     2008 April 6
65  *
66  *  Copyright (C) 2008 Paul C. L. Willmott. See notes at end.
67  *
68  *-----------------------------------------------------------------------
69  */
70 
71 #include <math.h>
72 #include <strings.h>
73 #include "gal_const.h"
74 #include "gal_sgp4init.h"
75 #include "gal_days2cal.h"
76 #include "gal_cal2jd.h"
77 
78 int
gal_sgp4init(gal_gm_t * gm,gal_tle_t * tle,gal_sgp4_t * sgp4)79 gal_sgp4init
80   (
81     gal_gm_t *gm,
82     gal_tle_t *tle,
83     gal_sgp4_t *sgp4
84   )
85 
86 {
87 
88   double ao,     ainv,   con42 , cosio, sinio, cosio2, eccsq,
89          omeosq, posq,   rp,     rteosq,
90          cnodm , snodm , cosim , sinim , cosomm, sinomm, cc1sq ,
91          cc2   , cc3   , coef  , coef1 , cosio4, day   , dndt  ,
92          em    , emsq  , eeta  , etasq , gam   , argpm , nodem ,
93          inclm , mm    , nm    , perige, pinvsq, psisq , qzms24,
94          rtemsq, s1    , s2    , s3    , s4    , s5    , s6    ,
95          s7    , sfour , ss1   , ss2   , ss3   , ss4   , ss5   ,
96          ss6   , ss7   , sz1   , sz2   , sz3   , sz11  , sz12  ,
97          sz13  , sz21  , sz22  , sz23  , sz31  , sz32  , sz33  ,
98          tc    , temp  , temp1 , temp2 , temp3 , tsi   , xpidot,
99          xhdot1, z1    , z2    , z3    , z11   , z12   , z13   ,
100          z21   , z22   , z23   , z31   , z32   , z33,
101          qzms2t, ss, x2o3, pv[2][3] ;
102 
103   const double xpdotp = 1440.0 / GAL_2PI ;
104 
105   int iy, im, id ;
106   double fd ;
107 
108 /*
109  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
110  */
111 
112 /*
113  * Initialization
114  */
115 
116 /*
117  * sgp4fix divisor for divide by zero check on inclination
118  */
119 
120   const double temp4    =   1.0 + cos ( GAL_PI - 1.0e-9 ) ;
121 
122 /*
123  * Set all near earth variables to zero
124  */
125 
126   sgp4->isimp   = 0   ; sgp4->method = 'n' ; sgp4->aycof    = 0.0 ;
127   sgp4->con41   = 0.0 ; sgp4->cc1    = 0.0 ; sgp4->cc4      = 0.0 ;
128   sgp4->cc5     = 0.0 ; sgp4->d2     = 0.0 ; sgp4->d3       = 0.0 ;
129   sgp4->d4      = 0.0 ; sgp4->delmo  = 0.0 ; sgp4->eta      = 0.0 ;
130   sgp4->argpdot = 0.0 ; sgp4->omgcof = 0.0 ; sgp4->sinmao   = 0.0 ;
131   sgp4->t       = 0.0 ; sgp4->t2cof  = 0.0 ; sgp4->t3cof    = 0.0 ;
132   sgp4->t4cof   = 0.0 ; sgp4->t5cof  = 0.0 ; sgp4->x1mth2   = 0.0 ;
133   sgp4->x7thm1  = 0.0 ; sgp4->mdot   = 0.0 ; sgp4->nodedot  = 0.0 ;
134   sgp4->xlcof   = 0.0 ; sgp4->xmcof  = 0.0 ; sgp4->nodecf   = 0.0 ;
135 
136 /*
137  * Set all deep space variables to zero
138  */
139 
140   sgp4->irez  = 0   ; sgp4->d2201 = 0.0 ; sgp4->d2211 = 0.0 ;
141   sgp4->d3210 = 0.0 ; sgp4->d3222 = 0.0 ; sgp4->d4410 = 0.0 ;
142   sgp4->d4422 = 0.0 ; sgp4->d5220 = 0.0 ; sgp4->d5232 = 0.0 ;
143   sgp4->d5421 = 0.0 ; sgp4->d5433 = 0.0 ; sgp4->dedt  = 0.0 ;
144   sgp4->del1  = 0.0 ; sgp4->del2  = 0.0 ; sgp4->del3  = 0.0 ;
145   sgp4->didt  = 0.0 ; sgp4->dmdt  = 0.0 ; sgp4->dnodt = 0.0 ;
146   sgp4->domdt = 0.0 ; sgp4->e3    = 0.0 ; sgp4->ee2   = 0.0 ;
147   sgp4->peo   = 0.0 ; sgp4->pgho  = 0.0 ; sgp4->pho   = 0.0 ;
148   sgp4->pinco = 0.0 ; sgp4->plo   = 0.0 ; sgp4->se2   = 0.0 ;
149   sgp4->se3   = 0.0 ; sgp4->sgh2  = 0.0 ; sgp4->sgh3  = 0.0 ;
150   sgp4->sgh4  = 0.0 ; sgp4->sh2   = 0.0 ; sgp4->sh3   = 0.0 ;
151   sgp4->si2   = 0.0 ; sgp4->si3   = 0.0 ; sgp4->sl2   = 0.0 ;
152   sgp4->sl3   = 0.0 ; sgp4->sl4   = 0.0 ; sgp4->gsto  = 0.0 ;
153   sgp4->xfact = 0.0 ; sgp4->xgh2  = 0.0 ; sgp4->xgh3  = 0.0 ;
154   sgp4->xgh4  = 0.0 ; sgp4->xh2   = 0.0 ; sgp4->xh3   = 0.0 ;
155   sgp4->xi2   = 0.0 ; sgp4->xi3   = 0.0 ; sgp4->xl2   = 0.0 ;
156   sgp4->xl3   = 0.0 ; sgp4->xl4   = 0.0 ; sgp4->xlamo = 0.0 ;
157   sgp4->zmol  = 0.0 ; sgp4->zmos  = 0.0 ; sgp4->atime = 0.0 ;
158   sgp4->xli   = 0.0 ; sgp4->xni   = 0.0 ;
159 
160 /*
161  * Earth constants
162  */
163 
164   gal_sgp4gm
165     (
166       gm,
167       &sgp4->tumin,
168       &sgp4->mu,
169       &sgp4->radiusearthkm,
170       &sgp4->xke,
171       &sgp4->j2,
172       &sgp4->j3,
173       &sgp4->j4,
174       &sgp4->j3oj2
175     ) ;
176 
177   ss     = 78.0 / sgp4->radiusearthkm + 1.0 ;
178   qzms2t = pow ( ( ( 120.0 - 78.0 ) / sgp4->radiusearthkm ), 4 ) ;
179   x2o3   =  2.0 / 3.0 ;
180   sgp4->vkmpersec = sgp4->radiusearthkm * sgp4->xke / 60.0 ;
181 
182 /*
183  * Gain TLE Information
184  */
185 
186   sgp4->satnum         = tle->satnum                                  ;
187   sgp4->classification = tle->classification                          ;
188   sgp4->ephtype        = tle->ephtype                                 ;
189   sgp4->setnum         = tle->setnum                                  ;
190   sgp4->revnum         = tle->revnum                                  ;
191   sgp4->bstar          = tle->bstar                                   ;
192   sgp4->ecco           = tle->ecco                                    ;
193   sgp4->argpo          = tle->argpo * GAL_D2R                         ;
194   sgp4->inclo          = tle->inclo * GAL_D2R                         ;
195   sgp4->mo	           = tle->mo    * GAL_D2R                         ;
196   sgp4->nodeo          = tle->nodeo * GAL_D2R                         ;
197   sgp4->no	           = tle->no / xpdotp                             ;  /* rad/min */
198   sgp4->a              = pow ( sgp4->no * sgp4->tumin, -x2o3 )        ;
199   sgp4->alta           = sgp4->a * ( 1.0 + sgp4->ecco ) - 1.0         ;
200   sgp4->altp           = sgp4->a * ( 1.0 - sgp4->ecco ) - 1.0         ;
201   sgp4->ndot           = sgp4->ndot  / ( xpdotp * GAL_D2M )           ;  /* ? * minperday */
202   sgp4->nddot          = sgp4->nddot / ( xpdotp * GAL_D2M * GAL_D2M ) ;
203   sgp4->epochyr        = tle->epochyr                                 ;
204   sgp4->epochdays      = tle->epochdays                               ;
205 
206   strcpy(sgp4->intldesg, tle->intldesg) ;
207 
208   gal_days2cal ( sgp4->epochyr, sgp4->epochdays, &iy, &im, &id, &fd ) ;
209 
210   gal_cal2jd ( iy, im, id, &sgp4->jdepoch1, &sgp4->jdepoch2 ) ;
211 
212   sgp4->jdepoch2 += fd ;
213 
214   sgp4->epoch = ( sgp4->jdepoch1 - 2433281.5 ) + sgp4->jdepoch2 ;
215 
216   sgp4->init = 'y' ;
217   sgp4->t	 = 0.0 ;
218 
219   gal_initsgp4p
220     (
221       sgp4->satnum,
222       gm,
223       sgp4->ecco,
224       sgp4->epoch,
225       sgp4->inclo,
226       &sgp4->no,
227       &sgp4->method,
228       &ainv,
229       &ao,
230       &sgp4->con41,
231       &con42,
232       &cosio,
233       &cosio2,
234       &eccsq,
235       &omeosq,
236       &posq,
237       &rp,
238       &rteosq,
239       &sinio,
240       &sgp4->gsto
241     ) ;
242 
243   sgp4->error = GAL_SUCCESS ;
244 
245   if (rp < 1.0) {
246     sgp4->error = 5 ;
247   }
248 
249   if ( omeosq >= 0.0 || sgp4->no >= 0.0 ) {
250     sgp4->isimp = 0;
251     if (rp < (220.0 / sgp4->radiusearthkm + 1.0)) {
252       sgp4->isimp = 1 ;
253     }
254     sfour  = ss ;
255     qzms24 = qzms2t ;
256     perige = ( rp - 1.0 ) * sgp4->radiusearthkm ;
257 
258 /*
259  * For perigees below 156 km, s and qoms2t are altered
260  */
261 
262     if ( perige < 156.0 ) {
263       sfour = perige - 78.0 ;
264       if (perige < 98.0) {
265         sfour = 20.0 ;
266       }
267       qzms24 = pow ( ( ( 120.0 - sfour ) / sgp4->radiusearthkm ), 4.0 ) ;
268       sfour  = sfour / sgp4->radiusearthkm + 1.0 ;
269     }
270     pinvsq = 1.0 / posq ;
271 
272     tsi  = 1.0 / ( ao - sfour ) ;
273     sgp4->eta  = ao * sgp4->ecco * tsi ;
274     etasq = sgp4->eta * sgp4->eta ;
275     eeta  = sgp4->ecco * sgp4->eta ;
276     psisq = fabs ( 1.0 - etasq ) ;
277     coef  = qzms24 * pow ( tsi, 4.0 ) ;
278     coef1 = coef / pow ( psisq, 3.5 ) ;
279     cc2   = coef1 * sgp4->no * ( ao * ( 1.0 + 1.5 * etasq + eeta * ( 4.0 + etasq ) )
280           + 0.375 * sgp4->j2 * tsi / psisq * sgp4->con41 * ( 8.0 + 3.0 * etasq * ( 8.0 + etasq ) ) ) ;
281     sgp4->cc1   = sgp4->bstar * cc2 ;
282     cc3   = 0.0 ;
283     if (sgp4->ecco > 1.0e-4) {
284       cc3 = -2.0 * coef * tsi * sgp4->j3oj2 * sgp4->no * sinio / sgp4->ecco ;
285     }
286     sgp4->x1mth2 = 1.0 - cosio2 ;
287     sgp4->cc4    = 2.0 * sgp4->no * coef1 * ao * omeosq *
288                            ( sgp4->eta * ( 2.0 + 0.5 * etasq ) + sgp4->ecco *
289                            ( 0.5 + 2.0 * etasq ) - sgp4->j2 * tsi / ( ao * psisq ) *
290                            ( -3.0 * sgp4->con41 * ( 1.0 - 2.0 * eeta + etasq *
291                            ( 1.5 - 0.5 * eeta ) ) + 0.75 * sgp4->x1mth2 *
292                            ( 2.0 * etasq - eeta * ( 1.0 + etasq ) ) * cos ( 2.0 * sgp4->argpo ) ) ) ;
293     sgp4->cc5 = 2.0 * coef1 * ao * omeosq * ( 1.0 + 2.75 * ( etasq + eeta ) + eeta * etasq ) ;
294     cosio4 = cosio2 * cosio2 ;
295     temp1  = 1.5 * sgp4->j2 * pinvsq * sgp4->no ;
296     temp2  = 0.5 * temp1 * sgp4->j2 * pinvsq ;
297     temp3  = -0.46875 * sgp4->j4 * pinvsq * pinvsq * sgp4->no ;
298     sgp4->mdot    = sgp4->no + 0.5 * temp1 * rteosq * sgp4->con41 + 0.0625 *
299                      temp2 * rteosq * ( 13.0 - 78.0 * cosio2 + 137.0 * cosio4 ) ;
300     sgp4->argpdot = -0.5 * temp1 * con42 + 0.0625 * temp2 *
301                     ( 7.0 - 114.0 * cosio2 + 395.0 * cosio4 ) +
302                       temp3 * (3.0 - 36.0 * cosio2 + 49.0 * cosio4 ) ;
303     xhdot1        = -temp1 * cosio ;
304     sgp4->nodedot = xhdot1 + ( 0.5 * temp2 * ( 4.0 - 19.0 * cosio2 ) +
305                               2.0 * temp3 * ( 3.0 - 7.0 * cosio2 ) ) * cosio ;
306     xpidot        = sgp4->argpdot + sgp4->nodedot ;
307     sgp4->omgcof  = sgp4->bstar * cc3 * cos ( sgp4->argpo ) ;
308     sgp4->xmcof   = 0.0 ;
309     if (sgp4->ecco > 1.0e-4) {
310       sgp4->xmcof = -x2o3 * coef * sgp4->bstar / eeta ;
311     }
312     sgp4->nodecf = 3.5 * omeosq * xhdot1 * sgp4->cc1 ;
313     sgp4->t2cof  = 1.5 * sgp4->cc1 ;
314 
315 /*
316  * sgp4fix for divide by zero with xinco = 180 deg
317  */
318 
319     if (fabs(cosio+1.0) > 1.5e-12) {
320       sgp4->xlcof = -0.25 * sgp4->j3oj2 * sinio * ( 3.0 + 5.0 * cosio ) / ( 1.0 + cosio ) ;
321     }
322     else {
323       sgp4->xlcof = -0.25 * sgp4->j3oj2 * sinio * ( 3.0 + 5.0 * cosio ) / temp4 ;
324     }
325     sgp4->aycof   = -0.5 * sgp4->j3oj2 * sinio;
326     sgp4->delmo   = pow ( ( 1.0 + sgp4->eta * cos ( sgp4->mo ) ), 3 ) ;
327     sgp4->sinmao  = sin ( sgp4->mo ) ;
328     sgp4->x7thm1  = 7.0 * cosio2 - 1.0 ;
329 
330 /*
331  * Deep space initialization
332  */
333 
334     if ( ( GAL_2PI / sgp4->no ) >= 225.0) {
335 
336       sgp4->method = 'd'         ;
337       sgp4->isimp  = 1           ;
338       tc           =  0.0        ;
339       inclm        = sgp4->inclo ;
340 
341       gal_dscom
342         (
343           sgp4->epoch,
344           sgp4->ecco,
345           sgp4->argpo,
346           tc,
347           sgp4->inclo,
348           sgp4->nodeo,
349           sgp4->no,
350           &snodm,
351           &cnodm,
352           &sinim,
353           &cosim,
354           &sinomm,
355           &cosomm,
356           &day,
357           &sgp4->e3,
358           &sgp4->ee2,
359           &em,
360           &emsq,
361           &gam,
362           &sgp4->peo,
363           &sgp4->pgho,
364           &sgp4->pho,
365           &sgp4->pinco,
366           &sgp4->plo,
367           &rtemsq,
368           &sgp4->se2,
369           &sgp4->se3,
370           &sgp4->sgh2,
371           &sgp4->sgh3,
372           &sgp4->sgh4,
373           &sgp4->sh2,
374           &sgp4->sh3,
375           &sgp4->si2,
376           &sgp4->si3,
377           &sgp4->sl2,
378           &sgp4->sl3,
379           &sgp4->sl4,
380           &s1,
381           &s2,
382           &s3,
383           &s4,
384           &s5,
385           &s6,
386           &s7,
387           &ss1,
388           &ss2,
389           &ss3,
390           &ss4,
391           &ss5,
392           &ss6,
393           &ss7,
394           &sz1,
395           &sz2,
396           &sz3,
397           &sz11,
398           &sz12,
399           &sz13,
400           &sz21,
401           &sz22,
402           &sz23,
403           &sz31,
404           &sz32,
405           &sz33,
406           &sgp4->xgh2,
407           &sgp4->xgh3,
408           &sgp4->xgh4,
409           &sgp4->xh2,
410           &sgp4->xh3,
411           &sgp4->xi2,
412           &sgp4->xi3,
413           &sgp4->xl2,
414           &sgp4->xl3,
415           &sgp4->xl4,
416           &nm,
417           &z1,
418           &z2,
419           &z3,
420           &z11,
421           &z12,
422           &z13,
423           &z21,
424           &z22,
425           &z23,
426           &z31,
427           &z32,
428           &z33,
429           &sgp4->zmol,
430           &sgp4->zmos
431         ) ;
432 
433       gal_dpper
434         (
435           sgp4->e3,
436           sgp4->ee2,
437           sgp4->peo,
438           sgp4->pgho,
439           sgp4->pho,
440           sgp4->pinco,
441           sgp4->plo,
442           sgp4->se2,
443           sgp4->se3,
444           sgp4->sgh2,
445           sgp4->sgh3,
446           sgp4->sgh4,
447           sgp4->sh2,
448           sgp4->sh3,
449           sgp4->si2,
450           sgp4->si3,
451           sgp4->sl2,
452           sgp4->sl3,
453           sgp4->sl4,
454           sgp4->t,
455           sgp4->xgh2,
456           sgp4->xgh3,
457           sgp4->xgh4,
458           sgp4->xh2,
459           sgp4->xh3,
460           sgp4->xi2,
461           sgp4->xi3,
462           sgp4->xl2,
463           sgp4->xl3,
464           sgp4->xl4,
465           sgp4->zmol,
466           sgp4->zmos,
467           inclm,
468           sgp4->init,
469           &sgp4->ecco,
470           &sgp4->inclo,
471           &sgp4->nodeo,
472           &sgp4->argpo,
473           &sgp4->mo
474         ) ;
475 
476       argpm  = 0.0 ;
477       nodem  = 0.0 ;
478       mm     = 0.0 ;
479 
480       gal_dsinit
481         (
482           gm,
483           cosim,
484           emsq,
485           sgp4->argpo,
486           s1,
487           s2,
488           s3,
489           s4,
490           s5,
491           sinim,
492           ss1,
493           ss2,
494           ss3,
495           ss4,
496           ss5,
497           sz1,
498           sz3,
499           sz11,
500           sz13,
501           sz21,
502           sz23,
503           sz31,
504           sz33,
505           sgp4->t,
506           tc,
507           sgp4->gsto,
508           sgp4->mo,
509           sgp4->mdot,
510           sgp4->no,
511           sgp4->nodeo,
512           sgp4->nodedot,
513           xpidot,
514           z1,
515           z3,
516           z11,
517           z13,
518           z21,
519           z23,
520           z31,
521           z33,
522           sgp4->ecco,
523           eccsq,
524           &em,
525           &argpm,
526           &inclm,
527           &mm,
528           &nm,
529           &nodem,
530           &sgp4->irez,
531           &sgp4->atime,
532           &sgp4->d2201,
533           &sgp4->d2211,
534           &sgp4->d3210,
535           &sgp4->d3222,
536           &sgp4->d4410,
537           &sgp4->d4422,
538           &sgp4->d5220,
539           &sgp4->d5232,
540           &sgp4->d5421,
541           &sgp4->d5433,
542           &sgp4->dedt,
543           &sgp4->didt,
544           &sgp4->dmdt,
545           &dndt,
546           &sgp4->dnodt,
547           &sgp4->domdt,
548           &sgp4->del1,
549           &sgp4->del2,
550           &sgp4->del3,
551           &sgp4->xfact,
552           &sgp4->xlamo,
553           &sgp4->xli,
554           &sgp4->xni
555         ) ;
556     }
557 
558 /*
559  * Set variables if not deep space
560  */
561 
562     if (sgp4->isimp != 1) {
563 
564       cc1sq       = sgp4->cc1 * sgp4->cc1 ;
565 
566       sgp4->d2    = 4.0 * ao * tsi * cc1sq ;
567 
568       temp        = sgp4->d2 * tsi * sgp4->cc1 / 3.0 ;
569 
570       sgp4->d3    = ( 17.0 * ao + sfour ) * temp ;
571 
572       sgp4->d4    = 0.5 * temp * ao * tsi * ( 221.0 * ao + 31.0 * sfour ) * sgp4->cc1 ;
573 
574       sgp4->t3cof = sgp4->d2 + 2.0 * cc1sq;
575 
576       sgp4->t4cof = 0.25 * ( 3.0 * sgp4->d3 + sgp4->cc1 * ( 12.0 * sgp4->d2 + 10.0 * cc1sq ) ) ;
577 
578       sgp4->t5cof = 0.2 * (  3.0 * sgp4->d4 +
579                             12.0 * sgp4->cc1 * sgp4->d3 +
580                              6.0 * sgp4->d2  * sgp4->d2 +
581                             15.0 * cc1sq * (2.0 * sgp4->d2 + cc1sq ) ) ;
582     }
583 
584   } /* if omeosq = 0 ... */
585 
586 /*
587  * Finally propogate to zero epoch to initialise all others.
588  */
589 
590   if ( sgp4->error == 0 ) {
591     gal_sgp4
592       (
593         sgp4,
594         sgp4->jdepoch1,
595         sgp4->jdepoch2,
596         pv
597       ) ;
598   }
599 
600   sgp4->init = 'n';
601 
602   return sgp4->error ;
603 
604 /*
605  * Finished.
606  */
607 
608 }
609 
610 /*
611  *  gal - General Astrodynamics Library
612  *  Copyright (C) 2008 Paul C. L. Willmott
613  *
614  *  This program is free software; you can redistribute it and/or modify
615  *  it under the terms of the GNU General Public License as published by
616  *  the Free Software Foundation; either version 2 of the License, or
617  *  (at your option) any later version.
618  *
619  *  This program is distributed in the hope that it will be useful,
620  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
621  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
622  *  GNU General Public License for more details.
623  *
624  *  You should have received a copy of the GNU General Public License along
625  *  with this program; if not, write to the Free Software Foundation, Inc.,
626  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
627  *
628  *  Contact:
629  *
630  *  Paul Willmott
631  *  vp9mu@amsat.org
632  */
633 
634