home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume11 / n3emo-orbit / part01 next >
Encoding:
Text File  |  1990-03-10  |  51.1 KB  |  1,872 lines

  1. Newsgroups: comp.sources.misc
  2. organization: Carnegie-Mellon University, CS/RI
  3. keywords: amateur radio, space, weather satellites
  4. subject: v11i020: orbit: track earth satellites
  5. from: rwb@vi.ri.cmu.edu (Bob Berger)
  6. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  7.  
  8. Posting-number: Volume 11, Issue 20
  9. Submitted-by: rwb@vi.ri.cmu.edu (Bob Berger)
  10. Archive-name: n3emo-orbit/part01
  11.  
  12. Here's a program to track earth satellites. It's been used by amateur radio
  13. operators for a few years. It's also useful for weather satellites, the space
  14. shuttle, etc.
  15.  
  16. #
  17. # type    sh orbit.shar   to unpack this archive.
  18. #
  19. echo extracting orbit.doc...
  20. cat >orbit.doc <<'!E!O!F!'
  21.                            THE N3EMO ORBIT SIMULATOR
  22.  
  23.                                   VERSION 3.7
  24.  
  25.                             Robert W. Berger, N3EMO
  26.  
  27.                                  March 7, 1990
  28.  
  29. 1 Introduction
  30.   The  N3EMO  orbit  program  simulates  the  motions  of earth satellites. The
  31. program was written for use by  amateur  radio  operators,  but  is  useful  to
  32. others,  such  as  astronomers  interested  in observing artificial satellites,
  33. space enthusiasts tracking shuttle missions, and meteorologists  using  weather
  34. satellites.  The  program  is distributed in source form in the C language, and
  35. has been used on a wide variety of computers, from micros to mainframes.
  36.  
  37. 2 Changes
  38.   The following changes have been made since the last public  release  (version
  39. 2.3):
  40.  
  41.    - The  internal  calculation  routines  have been rewritten to increase
  42.      performance, readability, and modularity.  This  facilitates  use  of
  43.      orbit's routines from other programs.
  44.  
  45.    - A  new sidereal time reference is generated for each run. This allows
  46.      the program to maintain its accuracy without  having  to  be  updated
  47.      every year.
  48.  
  49.    - Predicted  doppler  shifts  are much more accurate. The instantaneous
  50.      range-rate is now calculated  directly  instead  of  by  differencing
  51.      successive  range  samples.  The  doppler  shift displayed is now the
  52.      correct one for the sample time,  instead  of  an  average  from  the
  53.      preceding sample interval.
  54.  
  55.    - Eclipses are optionally reported.
  56.  
  57.    - Data for 0-180 degree elevation rotators is optionally provided.
  58.  
  59.    - Satellite names may contain spaces.
  60.  
  61.    - Single  character  abbreviations are provided for up to 62 satellites
  62.      (up from 26).
  63.  
  64.    - A program is provided to convert  NASA  two-line  keplerians  to  the
  65.      AMSAT format used by the program.
  66.  
  67. 3 Compiling Orbit
  68.   The  details  of  how  to compile the program vary with the host machine. The
  69. main program is in orbit.c, and the calculation subroutines  are  in  orbitr.c.
  70. These  two  files  should  be  compiled  and  linked together to form the orbit
  71. executable.
  72.  
  73. 4 Data Files
  74.   Two data files are required to run orbit; a  third  is  optional.  The  first
  75. required  data  file, called "kepler.dat", contains the database of satellites.
  76. "kepler.dat" is distributed by the Amateur Satellite Corporation (AMSAT), a non
  77. profit  organization  that  designs  and operates amateur radio satellites. The
  78. following is a sample entry from "kepler.dat":
  79.  
  80.     Satellite: AO-13
  81.     Catalog number: 19216
  82.     Epoch time:      90054.30232176
  83.     Element set:      77
  84.     Inclination:       57.0658 deg
  85.     RA of node:       167.4162 deg
  86.     Eccentricity:    0.6899473
  87.     Arg of perigee:   221.7453 deg
  88.     Mean anomaly:      57.5228 deg
  89.     Mean motion:    2.09701313 rev/day
  90.     Decay rate:      -9.10e-07 rev/day^2
  91.     Epoch rev:            1301
  92.  
  93.   Satellite keplerians are also distributed by NASA in a format called the NASA
  94. two-line  format.  The  program  in  nasa.c converts a file from NASA format to
  95. AMSAT format for use with orbit.
  96.  
  97.   Keplerian sets for various interesting satellites are regularly posted to the
  98. rec.ham-radio  and  sci.space  usenet  newsgroups.  The  Datalink RBBS at (214)
  99. 394-7438 has keplerians, as well as lots of other information  of  interest  to
  100. satellite and space enthusiasts.
  101.  
  102.   The  second  required  data file is a site file which describes the observers
  103. position and other station related data. Multiple  site  files  are  supported,
  104. with  each  one  named  after the corresponding observation site. The following
  105. file is "pgh.sit", a site file for station W3VC in Pittsburgh:
  106.  
  107.     W3VC  Pittsburgh
  108.     40.45361                Latitude
  109.     79.94417                Longitude
  110.     300                     Height (Meters)
  111.     0                       Min Elevation (Degrees)
  112.     Eclipse
  113.     Flip
  114.  
  115.   The first five lines are required,  and  give  the  name  of  the  site,  its
  116. geographic  location,  and  the  minimum  satellite elevation above the horizon
  117. which is to be considered visible.
  118.  
  119.   The last two lines contain optional keywords which  enable  features  of  the
  120. orbit program. "Eclipse" enables reporting of eclipse times for the satellites.
  121. "Flip"  enables  alternative  bearing/elevations  for  0-180   degree   antenna
  122. rotators, such as the Kenpro rotators. By offering a choice of two settings for
  123. any sky position, such rotators allow a satellite to be tracked through a  pass
  124. without  requiring  the bearing rotor to be reoriented after hitting a rotation
  125. stop.
  126.  
  127.   The optional data file, "mode.dat", allows orbit to  provide  scheduling  and
  128. operation data for a satellite. The following is an example of a "mode.dat":
  129.  
  130.     Satellite: UO-11
  131.     Beacon:           145.8260 MHz
  132.  
  133.     Satellite: AO-13
  134.     Beacon:           145.8260 MHz
  135.     Mode: B         from 0 to 165
  136.     Mode: JL        from 165 to 195
  137.     Mode: S         from 195 to 200
  138.     Mode: BS        from 200 to 205
  139.     Mode: B         from 205 to 256
  140.  
  141.     Satellite: MIR
  142.     Beacon:           143.6250 MHz
  143.  
  144.     Satellite: RS-10/11
  145.     Beacon:           29.357 MHz
  146.  
  147.   Mode.dat  may  contain data for multiple satellites. The most common entry is
  148. "Beacon", which is the frequency orbit uses for calculating doppler shifts.
  149.  
  150. 5 Running Orbit
  151.   When run, orbit  will  ask  which  satellite  in  "kepler.dat"  you  wish  to
  152. simulate.    Type  the full satellite name, or the single character next to the
  153. satellite name. Orbit will then ask for the name of the site. If your site file
  154. is  "foo.sit",  type  "foo".  Next  enter  the  UTC  date  of  the start of the
  155. simulation period. Years may be 2 or 4 digits. For example, 1990 may be entered
  156. as "1990" or simply "90". The UTC hour of the start of the simulation period is
  157. then entered. Next comes the duration in days, followed  by  the  time  between
  158. samples  in  minutes.  The  final input is the name of the file for the output;
  159. hitting the "Return" key places the output on the terminal. Here is  the  start
  160. of a sample run:
  161.  
  162. N3EMO Orbit Simulator  v3.7
  163. Available satellites:
  164.         a) AO-10
  165.         b) UO-11
  166.         c) RS-10/11
  167.         d) AO-13
  168.         e) UO-14
  169.         f) UO-15
  170.         g) AO-16
  171.         h) DO-17
  172.         i) WO-18
  173.         j) LO-19
  174.         k) FO-20
  175.         l) NOAA        n) MET-2/16
  176.         o) MET-2/17
  177.         p) MET-3/2
  178.         q) NOAA-11
  179.         r) MET-2/18
  180.         s) MET-3/3
  181.         t) SALYUT 7
  182.         u) MIR
  183. Letter or satellite name :d
  184. Site name :pgh
  185. Start date (UTC) (Month Day Year) :3 10 90
  186. Starting Hour (UTC) :0
  187. Duration (Days) :1
  188. Time Step (Minutes) :10
  189. Output file (RETURN for TTY) :
  190. AO-13 Element Set 77
  191. W3VC  Pittsburgh
  192.  
  193. Doppler calculated for freq = 145.826000 MHz
  194. Saturday 10 Mar 1990  ----Orbit # 1332-----
  195.  U.T.C.   Az  El   Az'  El' Doppler Range Height  Lat  Long  Phase(256)
  196. 0120:00  130   1  310  179   -1199  19383  14156  -15    32   24  B
  197. 0130:00  127   6  307  174   -1152  20834  16051  -10    31   28  B
  198. 0140:00  124  10  304  170   -1098  22222  17833   -6    31   32  B   Eclipse
  199.  
  200.   The  output  contains  a  line  for each sample time at which the satellite's
  201. elevation above the horizon is equal to or greater  than  the  "Min  Elevation"
  202. entry  in the site file. The first two columns are the bearing and elevation of
  203. the satellite from the observer's site. If "Flip"  is  enabled,  the  next  two
  204. columns are the alternate form of the bearing and elevation, with the elevation
  205. greater than 90 degrees. The next column is the doppler shift of the satellites
  206. beacon  frequency, followed by the range from the satellite to the observer, in
  207. meters, and the satellites height above the earth. Next  is  the  latitude  and
  208. longitude of the point on earth directly underneath the satellite. The phase is
  209. then printed, followed by any applicable operating modes  from  the  satellites
  210. "mode.dat"  entry.  If "Eclipse" is enabled in the site file, and the satellite
  211. is in the earth's shadow, the word "Eclipse" is printed.
  212.  
  213.   If the satellite is in a highly elliptical orbit, a separate line is  printed
  214. for the exact time of the apogee.
  215. !E!O!F!
  216. #
  217. # type    sh /usrvi0/rwb/orbit/orbit.shar   to unpack this archive.
  218. #
  219. echo extracting orbit.c...
  220. cat >orbit.c <<'!E!O!F!'
  221. /* Copyright (c) 1986,1987,1988,1989,1990 Robert W. Berger N3EMO
  222.    May be freely distributed, provided this notice remains intact. */
  223.  
  224. /* Change Log
  225.     3/7/1990    v3.7 Make Phase III style phase (0-255) the default.
  226.             Ignore case in satellite names.
  227.  
  228.     12/19/1989    v3.6 Use more direct calculations for dates.
  229.             Calculate a new sidereal time reference for each run.
  230.  
  231.     12/8/1988    v3.5 Allow multiple overlapping modes in "mode.dat".
  232.  
  233.     6/28/1988    v3.4 Cleaned up Eclipse code. Fixed leap year handling
  234.             for centesimal years. Added a heuristic to GetDay to
  235.             allow 2 or 4 digit year specifications.
  236.                   
  237.     1/25/1988    v3.2 Rewrote orbitr.c to improve modularity,
  238.             efficiency, and accuracy. Adopted geocentric
  239.             cartesian coordinates as the standard representation
  240.             for position and velocity. Added direct calculation
  241.              of range-rate for better doppler predections.
  242.  
  243.     12/1/1988    v3.1 Allow spaces in satellite names. Provide
  244.             single character aliases for 62 satellites 
  245.             (up from 26).
  246.  
  247.     4/7/87        v3.0 Added eclipses.
  248.  
  249.     4/1/87        v2.4 Added "Flip" option in site file for
  250.             0-180 elevation support.
  251.  
  252.     3/24/87        v2.3 Adapted for new kepler.dat format.
  253.             Allow beacon frequencies in mode.dat.
  254.             Use decay rate for drag compensation.
  255.  
  256.     5/10/86        v2.2 Added single character aliases for satellite
  257.             names.
  258.  
  259.     4/30/86        v2.1 Print blank line if satellite dips below
  260.             horizon and reappears during same orbit and day
  261.  
  262.     4/29/86        v2.0 Changed GetSatelliteParams() to use AMSAT's
  263.             "kepler.dat" file. Moved schedule to "mode.dat" file.
  264.  
  265.         4/22/86         v1.3  Inserted N8FJB's suggestions for variable naming
  266.                         which maintain 8 character uniqueness.
  267.                         Also removed "include" file orbitr.h, which had two
  268.                         definitions of external functions defined in orbit.c
  269.                 -K3MC 
  270.  
  271.         4/1/86          v1.2  Corrected a scanf conversion to %d for an int
  272.                         type.    -K3MC
  273.  
  274.         3/19/86         v1.1  Changed GetSatelliteParams to not pass NULL
  275.                         to sscanf.
  276.                                                                         */
  277.  
  278. #define DRAG 1
  279.  
  280. #include <stdio.h>
  281. #include <math.h>
  282. #include <ctype.h>
  283.  
  284. extern double Kepler();
  285. extern long GetDayNum();
  286.  
  287. #define LC(c) (isupper(c) ? tolower(c) : (c))
  288.  
  289. #ifndef PI
  290. #define PI 3.14159265
  291. #endif
  292.  
  293. #ifdef PI2
  294. #undef PI2
  295. #endif
  296.  
  297. #define PI2 (PI*2)
  298.  
  299. #define MinutesPerDay (24*60.0)
  300. #define SecondsPerDay (60*MinutesPerDay)
  301. #define HalfSecond (0.5/SecondsPerDay)
  302. #define EarthRadius 6378.16             /* Kilometers           */
  303. #define C 2.997925e5                    /* Kilometers/Second    */
  304. #define TropicalYear 365.24199        /* Mean solar days    */
  305. #define EarthEccentricity 0.016713
  306. #define DegreesPerRadian (180/PI)
  307. #define RadiansPerDegree (PI/180)
  308. #define ABS(x) ((x) < 0 ? (-(x)) : (x))
  309. #define SQR(x) ((x)*(x))
  310.  
  311. #define MaxModes 10
  312. typedef struct {
  313.                 int MinPhase,MaxPhase;
  314.                 char ModeStr[20];
  315.                }  ModeRec;
  316.  
  317. char VersionStr[] = "N3EMO Orbit Simulator  v3.7";
  318.  
  319.     /*  Keplerian Elements and misc. data for the satellite              */
  320.     double  EpochDay;                   /* time of epoch                 */
  321.     double EpochMeanAnomaly;            /* Mean Anomaly at epoch         */
  322.     long EpochOrbitNum;                 /* Integer orbit # of epoch      */
  323.     double EpochRAAN;                   /* RAAN at epoch                 */
  324.     double epochMeanMotion;             /* Revolutions/day               */
  325.     double OrbitalDecay;                /* Revolutions/day^2             */
  326.     double EpochArgPerigee;             /* argument of perigee at epoch  */
  327.     double Eccentricity;
  328.     double Inclination;
  329.     char SatName[100];
  330.     int ElementSet;
  331.     double BeaconFreq;                  /* Mhz, used for doppler calc    */
  332.     double MaxPhase;                    /* Phase units in 1 orbit        */
  333.     double perigeePhase;
  334.     int NumModes;
  335.     ModeRec Modes[MaxModes];
  336.     int PrintApogee;
  337.     int PrintEclipses;
  338.     int Flip;
  339.  
  340.     /* Simulation Parameters */
  341.  
  342.     double StartTime,EndTime, StepTime; /* In Days, 1 = New Year        */
  343.                                         /*      of reference year       */
  344.  
  345.     /* Site Parameters */
  346.     char SiteName[100];
  347.     double SiteLat,SiteLong,SiteAltitude,SiteMinElev;
  348.  
  349.  
  350. /* List the satellites in kepler.dat, and return the number found */
  351. ListSatellites()
  352. {
  353.     char str[100];
  354.     FILE *InFile;
  355.     char satchar;
  356.     int NumSatellites;
  357.  
  358.     printf("Available satellites:\n");
  359.  
  360.     if ((InFile = fopen("kepler.dat","r")) == 0)
  361.         {
  362.     printf("\"kepler.dat\" not found\n");
  363.     exit(-1);
  364.     }
  365.  
  366.     satchar = 'a';
  367.     NumSatellites = 0;
  368.     while (fgets(str,100,InFile))
  369.     if (strncmp(str,"Satellite: ",11) == 0)
  370.         {
  371.         printf("    %c) %s",satchar,&str[11]);
  372.         if (satchar == 'z')
  373.         satchar = 'A';
  374.                else if (satchar == 'Z')
  375.            satchar = '0';
  376.                 else satchar++;
  377.         NumSatellites++;
  378.         }
  379.  
  380.     fclose(InFile);
  381.  
  382.     return NumSatellites;
  383. }
  384.  
  385. /* Match and skip over a string in the input file. Exits on failure. */
  386.  
  387. MatchStr(InFile,FileName,Target)
  388. FILE *InFile;
  389. char *FileName,*Target;
  390. {
  391.     char str[100];
  392.  
  393.     fgets(str,strlen(Target)+1,InFile);
  394.     if (strcmp(Target,str))
  395.        {
  396.        printf("%s: found \"%s\" while expecting \"%s\n\"",FileName,str,Target);
  397.        exit(-1);
  398.        }
  399. }
  400.  
  401. LetterNum(c)
  402. char c;
  403. {
  404.     if (c >= 'a' && c <= 'z')
  405.     return c - 'a' + 1;
  406.       else if (c >= 'A' && c <= 'Z')
  407.        return c - 'A'+ 27;
  408.     else if (c >= '0' && c <= '9')
  409.       return c - '0' + 53;
  410. }
  411.       
  412. /* Case insensitive strncmp */
  413. cstrncmp(str1,str2,l)
  414. char *str1,*str2;
  415. {
  416.     int i;
  417.  
  418.     for (i = 0; i < l; i++)
  419.     if (LC(str1[i]) != LC(str2[i]))
  420.         return 1;
  421.  
  422.     return 0;
  423. }
  424.  
  425.  
  426. cstrcmp(str1,str2)
  427. char *str1,*str2;
  428. {
  429.     int i,l;
  430.  
  431.     l = strlen(str1);
  432.     if (strlen(str2) != l)
  433.     return 1;
  434.  
  435.     for (i = 0; i < l; i++)
  436.     if (LC(str1[i]) != LC(str2[i]))
  437.         return 1;
  438.  
  439.     return 0;
  440. }
  441.  
  442.  
  443. GetSatelliteParams()
  444. {
  445.     FILE *InFile;
  446.     char str[100];
  447.     int EpochYear;
  448.     double EpochHour,EpochMinute,EpochSecond;
  449.     int found;
  450.     int i,NumSatellites;
  451.     char satchar;
  452.  
  453.     NumSatellites = ListSatellites();
  454.  
  455.     found = 0;
  456.  
  457.     while (!found)
  458.     {
  459.     printf("Letter or satellite name :");
  460.     gets(SatName);
  461.  
  462.     if ((InFile = fopen("kepler.dat","r")) == 0)
  463.         {
  464.         printf("kepler.dat not found\n");
  465.         exit(-1);
  466.         }
  467.  
  468.     if (strlen(SatName) == 1)
  469.         {            /* use single character label */
  470.         satchar = SatName[0];
  471.         if (LetterNum(satchar) > NumSatellites)
  472.             {
  473.             printf("'%c' is out of range\n",satchar);
  474.         fclose(InFile);
  475.         continue;
  476.         }
  477.  
  478.         for (i = 1; i <= LetterNum(satchar); i++)
  479.         {
  480.         do  /* find line beginning with "Satellite: " */
  481.             fgets(str,100,InFile);
  482.         while (strncmp(str,"Satellite: ",11) != 0);
  483.         }
  484.         found = 1;
  485.         strncpy(SatName,&str[11],strlen(str)-12);
  486.         }
  487.         
  488.      else 
  489.          {
  490.          while (!found)  /* use satellite name */
  491.                 {
  492.             if (! fgets(str,100,InFile))
  493.                 break;    /* EOF */
  494.  
  495.             if (strncmp(str,"Satellite: ",11) == 0)
  496.            if (cstrncmp(SatName,&str[11],strlen(SatName)) == 0)
  497.             found = 1;
  498.             }
  499.  
  500.         if (!found)
  501.         {
  502.         printf("Satellite %s not found\n",SatName);
  503.         fclose(InFile);
  504.         }
  505.         }
  506.     }
  507.  
  508.     BeaconFreq = 146.0;  /* Default value */
  509.  
  510.     fgets(str,100,InFile);    /* Skip line */
  511.  
  512.     MatchStr(InFile,"kepler.dat","Epoch time:");
  513.     fgets(str,100,InFile);
  514.     sscanf(str,"%lf",&EpochDay);
  515.  
  516.     EpochYear = EpochDay / 1000.0;
  517.     EpochDay -= EpochYear*1000.0;
  518.     EpochDay += GetDayNum(EpochYear,1,0);
  519.     fgets(str,100,InFile);
  520.  
  521.     if (sscanf(str,"Element set: %ld",&ElementSet) == 0)
  522.        {   /* Old style kepler.dat */
  523.        MatchStr(InFile,"kepler.dat","Element set:");
  524.        fgets(str,100,InFile);
  525.        sscanf(str,"%d",&ElementSet);
  526.        }
  527.  
  528.     MatchStr(InFile,"kepler.dat","Inclination:");
  529.     fgets(str,100,InFile);
  530.     sscanf(str,"%lf",&Inclination);
  531.     Inclination *= RadiansPerDegree;
  532.  
  533.     MatchStr(InFile,"kepler.dat","RA of node:");
  534.     fgets(str,100,InFile);
  535.     sscanf(str,"%lf",&EpochRAAN);
  536.     EpochRAAN *= RadiansPerDegree;
  537.  
  538.     MatchStr(InFile,"kepler.dat","Eccentricity:");
  539.     fgets(str,100,InFile);
  540.     sscanf(str,"%lf",&Eccentricity);
  541.  
  542.     MatchStr(InFile,"kepler.dat","Arg of perigee:");
  543.     fgets(str,100,InFile);
  544.     sscanf(str,"%lf",&EpochArgPerigee);
  545.     EpochArgPerigee *= RadiansPerDegree;
  546.  
  547.     MatchStr(InFile,"kepler.dat","Mean anomaly:");
  548.     fgets(str,100,InFile);
  549.     sscanf(str,"%lf",&EpochMeanAnomaly);
  550.     EpochMeanAnomaly *= RadiansPerDegree;
  551.  
  552.     MatchStr(InFile,"kepler.dat","Mean motion:");
  553.     fgets(str,100,InFile);
  554.     sscanf(str,"%lf",&epochMeanMotion);
  555.  
  556.     MatchStr(InFile,"kepler.dat","Decay rate:");
  557.     fgets(str,100,InFile);
  558.     sscanf(str,"%lf",&OrbitalDecay);
  559.  
  560.     MatchStr(InFile,"kepler.dat","Epoch rev:");
  561.     fgets(str,100,InFile);
  562.     sscanf(str,"%ld",&EpochOrbitNum);
  563.  
  564.     while (1)
  565.         {
  566.         if (! fgets(str,100,InFile))
  567.         break;    /* EOF */
  568.         if (strlen(str) <= 2)
  569.             break;  /* Blank line */
  570.         sscanf(str,"Beacon: %lf",&BeaconFreq);
  571.         }
  572.  
  573.     PrintApogee = (Eccentricity >= 0.3);
  574.  
  575.     perigeePhase = 0; MaxPhase = 256; /* Default values */
  576.     NumModes = 0;
  577.  
  578.     if ((InFile = fopen("mode.dat","r")) == 0)
  579.     return;
  580.  
  581.     found = 0;
  582.     while (!found)
  583.         {
  584.     if (! fgets(str,100,InFile))
  585.         break;    /* EOF */
  586.     if (sscanf(str,"Satellite: %s",str) == 1
  587.         && cstrcmp(SatName,str) == 0)
  588.         found = 1;
  589.     }
  590.     
  591.     if (found)
  592.     {
  593.     while (1)
  594.         {
  595.         if (! fgets(str,100,InFile))
  596.         break;    /* EOF */
  597.         if (strlen(str) <= 2)
  598.             break;  /* Blank line */
  599.         sscanf(str,"Beacon: %lf",&BeaconFreq);
  600.         sscanf(str,"Perigee phase: %lf",&perigeePhase);
  601.         sscanf(str,"Max phase: %lf",&MaxPhase);
  602.  
  603.         if (sscanf(str,"Mode: %20s from %d to %d",Modes[NumModes].ModeStr,
  604.         &Modes[NumModes].MinPhase,&Modes[NumModes].MaxPhase) == 3
  605.           && NumModes < MaxModes)
  606.           NumModes++;
  607.         }
  608.     fclose(InFile);
  609.     }
  610. }
  611.  
  612.  
  613. GetSiteParams()
  614. {
  615.     FILE *InFile;
  616.     char name[100],str[100];
  617.  
  618.     printf("Site name :");
  619.     gets(name);
  620.     strcat(name,".sit");
  621.  
  622.     if ((InFile = fopen(name,"r")) == 0)
  623.         {
  624.         printf("%s not found\n",name);
  625.         exit(-1);
  626.         }
  627.  
  628.     fgets(SiteName,100,InFile);
  629.  
  630.     fgets(str,100,InFile);
  631.     sscanf(str,"%lf",&SiteLat);
  632.     SiteLat *= RadiansPerDegree;
  633.  
  634.     fgets(str,100,InFile);
  635.     sscanf(str,"%lf",&SiteLong);
  636.     SiteLong *= RadiansPerDegree;
  637.  
  638.     fgets(str,100,InFile);
  639.     sscanf(str,"%lf",&SiteAltitude);
  640.     SiteAltitude /= 1000;   /* convert to km */
  641.  
  642.     fgets(str,100,InFile);
  643.     sscanf(str,"%lf",&SiteMinElev);
  644.     SiteMinElev *= RadiansPerDegree;
  645.  
  646.     Flip = PrintEclipses = 0;
  647.     while (fgets(str,100,InFile))
  648.     {
  649.     if (strncmp(str,"Flip",4) == 0)
  650.         Flip = 1;
  651.       else if (strncmp(str,"Eclipse",7) == 0)
  652.         PrintEclipses = 1;
  653.        else printf("\"%s\" unknown option: %s",name,str);
  654.     }
  655. }
  656.  
  657. GetSimulationParams()
  658. {
  659.     double hour,duration;
  660.     int Month,Day,Year;
  661.  
  662.     printf("Start date (UTC) (Month Day Year) :");
  663.     scanf("%d%d%d",&Month,&Day,&Year);
  664.  
  665.     StartTime = GetDayNum(Year,Month,Day);
  666.     printf("Starting Hour (UTC) :");
  667.     scanf("%lf",&hour);
  668.     StartTime += hour/24;
  669.  
  670.     printf("Duration (Days) :");
  671.     scanf("%lf",&duration);
  672.     EndTime = StartTime + duration;
  673.  
  674.     printf("Time Step (Minutes) :");
  675.     scanf("%lf",&StepTime);
  676.     StepTime /= MinutesPerDay;
  677. }
  678.  
  679. PrintMode(OutFile,Phase)
  680. FILE *OutFile;
  681. {
  682.     int CurMode;
  683.  
  684.     for (CurMode = 0; CurMode < NumModes; CurMode++)
  685.         if ((Phase >= Modes[CurMode].MinPhase
  686.                 && Phase < Modes[CurMode].MaxPhase)
  687.               || ((Modes[CurMode].MinPhase > Modes[CurMode].MaxPhase)
  688.                   && (Phase >= Modes[CurMode].MinPhase
  689.                         || Phase < Modes[CurMode].MaxPhase)))
  690.             {
  691.             fprintf(OutFile,"%s ",Modes[CurMode].ModeStr);
  692.             }
  693. }
  694.  
  695.  
  696. main()
  697. {
  698.     double ReferenceOrbit;      /* Floating point orbit # at epoch */
  699.     double CurrentTime;         /* In Days                         */
  700.     double CurrentOrbit;
  701.     double AverageMotion,       /* Corrected for drag              */
  702.         CurrentMotion;
  703.     double MeanAnomaly,TrueAnomaly;
  704.     double SemiMajorAxis;
  705.     double Radius;              /* From geocenter                  */
  706.     double SatX,SatY,SatZ;    /* In Right Ascension based system */
  707.     double SatVX,SatVY,SatVZ;   /* Kilometers/second           */
  708.     double SiteX,SiteY,SiteZ;
  709.     double SiteVX,SiteVY;
  710.     double SiteMatrix[3][3];
  711.     double Height;
  712.     double RAANPrecession,PerigeePrecession;
  713.     double SSPLat,SSPLong;
  714.     long OrbitNum,PrevOrbitNum;
  715.     long Day,PrevDay;
  716.     double Azimuth,Elevation,Range;
  717.     double RangeRate,Doppler;
  718.     int Phase;
  719.     char FileName[100];
  720.     FILE *OutFile;
  721.     int DidApogee;
  722.     double TmpTime,PrevTime;
  723.     int PrevVisible;
  724.  
  725.     printf("%s\n",VersionStr);
  726.  
  727.  
  728.     GetSatelliteParams();
  729.     GetSiteParams();
  730.     GetSimulationParams();
  731.  
  732.     InitOrbitRoutines((StartTime+EndTime)/2);
  733.  
  734.     printf("Output file (RETURN for TTY) :");
  735.     gets(FileName);     /* Skip previous RETURN */
  736.     gets(FileName);
  737.  
  738.  
  739.     if (strlen(FileName) > 0)
  740.         {
  741.         if ((OutFile = fopen(FileName,"w")) == 0)
  742.             {
  743.             printf("Can't write to %s\n",FileName);
  744.             exit(-1);
  745.             }
  746.         }
  747.       else OutFile = stdout;
  748.  
  749.     fprintf(OutFile,"%s Element Set %d\n",SatName,ElementSet);
  750.  
  751.     fprintf(OutFile,"%s\n",SiteName);
  752.  
  753.     fprintf(OutFile,"Doppler calculated for freq = %lf MHz\n",BeaconFreq);
  754.  
  755.     SemiMajorAxis = 331.25 * exp(2*log(MinutesPerDay/epochMeanMotion)/3);
  756.     GetPrecession(SemiMajorAxis,Eccentricity,Inclination,&RAANPrecession,
  757.                         &PerigeePrecession);
  758.  
  759.     ReferenceOrbit = EpochMeanAnomaly/PI2 + EpochOrbitNum;
  760.  
  761.     PrevDay = -10000; PrevOrbitNum = -10000;
  762.     PrevTime = StartTime-2*StepTime;
  763.  
  764.     BeaconFreq *= 1E6;          /* Convert to Hz */
  765.  
  766.     DidApogee = 0;
  767.  
  768.     for (CurrentTime = StartTime; CurrentTime <= EndTime;
  769.                 CurrentTime += StepTime)
  770.         {
  771.  
  772.         AverageMotion = epochMeanMotion
  773.        + (CurrentTime-EpochDay)*OrbitalDecay/2;
  774.         CurrentMotion = epochMeanMotion
  775.        + (CurrentTime-EpochDay)*OrbitalDecay;
  776.  
  777.         SemiMajorAxis = 331.25 * exp(2*log(MinutesPerDay/CurrentMotion)/3);
  778.  
  779.         CurrentOrbit = ReferenceOrbit +
  780.                         (CurrentTime-EpochDay)*AverageMotion;
  781.         OrbitNum = CurrentOrbit;
  782.  
  783.         MeanAnomaly = (CurrentOrbit-OrbitNum)*PI2;
  784.  
  785.         TmpTime = CurrentTime;
  786.         if (MeanAnomaly < PI)
  787.             DidApogee = 0;
  788.         if (PrintApogee && !DidApogee && MeanAnomaly > PI)
  789.             {                   /* Calculate Apogee */
  790.             TmpTime -= StepTime;   /* So we pick up later where we left off */
  791.             MeanAnomaly = PI;
  792.             CurrentTime=EpochDay+(OrbitNum-ReferenceOrbit+0.5)/AverageMotion;
  793.             }
  794.  
  795.         TrueAnomaly = Kepler(MeanAnomaly,Eccentricity);
  796.  
  797.     GetSatPosition(EpochDay,EpochRAAN,EpochArgPerigee,SemiMajorAxis,
  798.         Inclination,Eccentricity,RAANPrecession,PerigeePrecession,
  799.         CurrentTime,TrueAnomaly,&SatX,&SatY,&SatZ,&Radius,
  800.         &SatVX,&SatVY,&SatVZ);
  801.  
  802.     GetSitPosition(SiteLat,SiteLong,SiteAltitude,CurrentTime,
  803.         &SiteX,&SiteY,&SiteZ,&SiteVX,&SiteVY,SiteMatrix);
  804.  
  805.  
  806.     GetBearings(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,
  807.         &Azimuth,&Elevation);
  808.  
  809.  
  810.         if (Elevation >= SiteMinElev && CurrentTime >= StartTime)
  811.             {
  812.  
  813.             Day = CurrentTime + HalfSecond;
  814.             if (((double) Day) > CurrentTime+HalfSecond)
  815.                 Day -= 1;    /* Correct for truncation of negative values */
  816.  
  817.         if (OrbitNum == PrevOrbitNum && Day == PrevDay && !PrevVisible)
  818.             fprintf(OutFile,"\n");    /* Dipped out of sight; print blank */
  819.  
  820.             if (OrbitNum != PrevOrbitNum || Day != PrevDay)
  821.                 {                       /* Print Header */
  822.         PrintDayOfWeek(OutFile,(long) Day);
  823.         fprintf(OutFile," ");
  824.                 PrintDate(OutFile,(long) Day);
  825.                 fprintf(OutFile,"  ----Orbit # %ld-----\n",OrbitNum);
  826.                 fprintf(OutFile," U.T.C.   Az  El  ");
  827.         if (Flip)
  828.                     fprintf(OutFile," Az'  El' ");
  829.  
  830.         fprintf(OutFile,"Doppler Range");
  831.                 fprintf(OutFile," Height  Lat  Long  Phase(%3.0lf)\n",
  832.                                 MaxPhase);
  833.                 }
  834.             PrevOrbitNum = OrbitNum; PrevDay = Day;
  835.             PrintTime(OutFile,CurrentTime + HalfSecond);
  836.  
  837.             fprintf(OutFile,"  %3.0lf %3.0lf",Azimuth*DegreesPerRadian,
  838.                 Elevation*DegreesPerRadian);
  839.         if (Flip)
  840.         {
  841.         Azimuth += PI;
  842.         if (Azimuth >= PI2)
  843.             Azimuth -= PI2;
  844.         Elevation = PI-Elevation;
  845.         fprintf(OutFile,"  %3.0lf  %3.0lf",Azimuth*DegreesPerRadian,
  846.             Elevation*DegreesPerRadian);
  847.         }
  848.  
  849.           GetRange(SiteX,SiteY,SiteZ,SiteVX,SiteVY,
  850.         SatX,SatY,SatZ,SatVX,SatVY,SatVZ,&Range,&RangeRate);
  851.             Doppler = -BeaconFreq*RangeRate/C;
  852.             fprintf(OutFile,"  %6.0lf %6.0lf",Doppler,Range);
  853.  
  854.         GetSubSatPoint(SatX,SatY,SatZ,CurrentTime,
  855.             &SSPLat,&SSPLong,&Height);
  856.             fprintf(OutFile," %6.0lf  %3.0lf  %4.0lf",
  857.                 Height,SSPLat*DegreesPerRadian,
  858.                 SSPLong*DegreesPerRadian);
  859.  
  860.             Phase = (MeanAnomaly/PI2*MaxPhase + perigeePhase);
  861.             while (Phase < 0)
  862.                 Phase += MaxPhase;
  863.             while (Phase >= MaxPhase)
  864.                 Phase -= MaxPhase;
  865.  
  866.             fprintf(OutFile," %4d  ", Phase);
  867.             PrintMode(OutFile,Phase);
  868.  
  869.             if (PrintApogee && (MeanAnomaly == PI))
  870.                 fprintf(OutFile,"    Apogee");
  871.  
  872.         if (PrintEclipses)
  873.         if (Eclipsed(SatX,SatY,SatZ,Radius,CurrentTime))
  874.             fprintf(OutFile,"  Eclipse");
  875.  
  876.             fprintf(OutFile,"\n");
  877.         PrevVisible = 1;
  878.             }
  879.      else
  880.         PrevVisible = 0;    
  881.         if (PrintApogee && (MeanAnomaly == PI))
  882.             DidApogee = 1;
  883.  
  884.  
  885.         PrevTime = CurrentTime;
  886.         CurrentTime = TmpTime;
  887.         }
  888.     fclose(OutFile);
  889. }
  890. !E!O!F!
  891. #
  892. # type    sh /usrvi0/rwb/orbit/orbit.shar   to unpack this archive.
  893. #
  894. echo extracting orbitr.c...
  895. cat >orbitr.c <<'!E!O!F!'
  896. /* N3EMO Orbit Simulator routines  v3.7 */
  897.  
  898. /* Copyright (c) 1986,1987,1988,1989,1990 Robert W. Berger N3EMO
  899.    May be freely distributed, provided this notice remains intact. */
  900.  
  901. #include <stdio.h>
  902. #include <math.h>
  903.  
  904. #define SSPELLIPSE 0        /* If non zero, use ellipsoidal earth model
  905.                    when calculating longitude, latitude, and
  906.                    height */
  907.  
  908. #ifndef PI
  909. #define PI 3.14159265
  910. #endif
  911.  
  912. #ifdef PI2
  913. #undef PI2
  914. #endif
  915.  
  916. #ifdef E
  917. #undef E
  918. #endif
  919.  
  920. typedef double mat3x3[3][3];
  921.  
  922. #define PI2 (PI*2)
  923. #define MinutesPerDay (24*60.0)
  924. #define SecondsPerDay (60*MinutesPerDay)
  925. #define HalfSecond (0.5/SecondsPerDay)
  926. #define EarthRadius 6378.16             /* Kilometers, at equator */
  927.  
  928. #define EarthFlat (1/298.25)            /* Earth Flattening Coeff. */
  929. #define SiderealSolar 1.0027379093
  930. #define SidRate (PI2*SiderealSolar/SecondsPerDay)    /* radians/second */
  931. #define GM 398600            /* Kilometers^3/seconds^2 */
  932. #define DegreesPerRadian (180/PI)
  933. #define RadiansPerDegree (PI/180)
  934. #define ABS(x) ((x) < 0 ? (-(x)) : (x))
  935. #define SQR(x) ((x)*(x))
  936.  
  937. #define Epsilon (RadiansPerDegree/3600)     /* 1 arc second */
  938. #define SunRadius 695000        
  939. #define SunSemiMajorAxis  149598845.0          /* Kilometers            */
  940.  
  941.  
  942. double SidDay,SidReference;    /* Date and sidereal time    */
  943.  
  944. /* Keplerian elements for the sun */
  945. double SunEpochTime,SunInclination,SunRAAN,SunEccentricity,
  946.        SunArgPerigee,SunMeanAnomaly,SunMeanMotion;
  947.  
  948. /* values for shadow geometry */
  949. double SinPenumbra,CosPenumbra;
  950.  
  951.  
  952. /* Solve Kepler's equation                                      */
  953. /* Inputs:                                                      */
  954. /*      MeanAnomaly     Time Since last perigee, in radians.    */
  955. /*                      PI2 = one complete orbit.               */
  956. /*      Eccentricity    Eccentricity of orbit's ellipse.        */
  957. /* Output:                                                      */
  958. /*      TrueAnomaly     Angle between perigee, geocenter, and   */
  959. /*                      current position.                       */
  960.  
  961. long calls = 0;
  962. long iters = 0;
  963.  
  964. dumpstats()
  965. {
  966. printf("Average iterations = %lf\n",((double) iters)/calls);
  967. }
  968.  
  969. double Kepler(MeanAnomaly,Eccentricity)
  970. register double MeanAnomaly,Eccentricity;
  971.  
  972. {
  973. register double E;              /* Eccentric Anomaly                    */
  974. register double Error;
  975. register double TrueAnomaly;
  976.  
  977. calls++;
  978.  
  979.     E = MeanAnomaly ;/*+ Eccentricity*sin(MeanAnomaly);   /* Initial guess */
  980.     do
  981.         {
  982.         Error = (E - Eccentricity*sin(E) - MeanAnomaly)
  983.                 / (1 - Eccentricity*cos(E));
  984.         E -= Error;
  985. iters++;
  986.         }
  987.    while (ABS(Error) >= Epsilon);
  988.  
  989.     if (ABS(E-PI) < Epsilon)
  990.         TrueAnomaly = PI;
  991.       else
  992.         TrueAnomaly = 2*atan(sqrt((1+Eccentricity)/(1-Eccentricity))
  993.                                 *tan(E/2));
  994.     if (TrueAnomaly < 0)
  995.         TrueAnomaly += PI2;
  996.  
  997.     return TrueAnomaly;
  998. }
  999.  
  1000. GetSubSatPoint(SatX,SatY,SatZ,Time,Latitude,Longitude,Height)
  1001. double SatX,SatY,SatZ,Time;
  1002. double *Latitude,*Longitude,*Height;
  1003. {
  1004.     double r;
  1005.     long i;
  1006.  
  1007.     r = sqrt(SQR(SatX) + SQR(SatY) + SQR(SatZ));
  1008.  
  1009.     *Longitude = PI2*((Time-SidDay)*SiderealSolar + SidReference)
  1010.             - atan2(SatY,SatX);
  1011.  
  1012.     /* i = floor(Longitude/2*pi)        */
  1013.     i = *Longitude/PI2;
  1014.     if(i < 0)
  1015.         i--;
  1016.  
  1017.     *Longitude -= i*PI2;
  1018.  
  1019.     *Latitude = atan(SatZ/sqrt(SQR(SatX) + SQR(SatY)));
  1020.  
  1021. #if SSPELLIPSE
  1022. #else
  1023.     *Height = r - EarthRadius;
  1024. #endif
  1025. }
  1026.  
  1027.  
  1028. GetPrecession(SemiMajorAxis,Eccentricity,Inclination,
  1029.         RAANPrecession,PerigeePrecession)
  1030. double SemiMajorAxis,Eccentricity,Inclination;
  1031. double *RAANPrecession,*PerigeePrecession;
  1032. {
  1033.   *RAANPrecession = 9.95*pow(EarthRadius/SemiMajorAxis,3.5) * cos(Inclination)
  1034.                  / SQR(1-SQR(Eccentricity)) * RadiansPerDegree;
  1035.  
  1036.   *PerigeePrecession = 4.97*pow(EarthRadius/SemiMajorAxis,3.5)
  1037.          * (5*SQR(cos(Inclination))-1)
  1038.                  / SQR(1-SQR(Eccentricity)) * RadiansPerDegree;
  1039. }
  1040.  
  1041. /* Compute the satellite postion and velocity in the RA based coordinate
  1042.    system */
  1043.  
  1044. GetSatPosition(EpochTime,EpochRAAN,EpochArgPerigee,SemiMajorAxis,
  1045.     Inclination,Eccentricity,RAANPrecession,PerigeePrecession,
  1046.     Time,TrueAnomaly,X,Y,Z,Radius,VX,VY,VZ)
  1047.  
  1048. double EpochTime,EpochRAAN,EpochArgPerigee;
  1049. double SemiMajorAxis,Inclination,Eccentricity;
  1050. double RAANPrecession,PerigeePrecession,Time, TrueAnomaly;
  1051. double *X,*Y,*Z,*Radius,*VX,*VY,*VZ;
  1052.  
  1053. {
  1054.     double RAAN,ArgPerigee;
  1055.  
  1056.  
  1057.     double Xw,Yw,VXw,VYw;    /* In orbital plane */
  1058.     double Tmp;
  1059.     double Px,Qx,Py,Qy,Pz,Qz;    /* Escobal transformation 31 */
  1060.     double CosArgPerigee,SinArgPerigee;
  1061.     double CosRAAN,SinRAAN,CoSinclination,SinInclination;
  1062.  
  1063.         *Radius = SemiMajorAxis*(1-SQR(Eccentricity))
  1064.                         / (1+Eccentricity*cos(TrueAnomaly));
  1065.  
  1066.  
  1067.     Xw = *Radius * cos(TrueAnomaly);
  1068.     Yw = *Radius * sin(TrueAnomaly);
  1069.     
  1070.     Tmp = sqrt(GM/(SemiMajorAxis*(1-SQR(Eccentricity))));
  1071.  
  1072.     VXw = -Tmp*sin(TrueAnomaly);
  1073.     VYw = Tmp*(cos(TrueAnomaly) + Eccentricity);
  1074.  
  1075.     ArgPerigee = EpochArgPerigee + (Time-EpochTime)*PerigeePrecession;
  1076.     RAAN = EpochRAAN - (Time-EpochTime)*RAANPrecession;
  1077.  
  1078.     CosRAAN = cos(RAAN); SinRAAN = sin(RAAN);
  1079.     CosArgPerigee = cos(ArgPerigee); SinArgPerigee = sin(ArgPerigee);
  1080.     CoSinclination = cos(Inclination); SinInclination = sin(Inclination);
  1081.     
  1082.     Px = CosArgPerigee*CosRAAN - SinArgPerigee*SinRAAN*CoSinclination;
  1083.     Py = CosArgPerigee*SinRAAN + SinArgPerigee*CosRAAN*CoSinclination;
  1084.     Pz = SinArgPerigee*SinInclination;
  1085.     Qx = -SinArgPerigee*CosRAAN - CosArgPerigee*SinRAAN*CoSinclination;
  1086.     Qy = -SinArgPerigee*SinRAAN + CosArgPerigee*CosRAAN*CoSinclination;
  1087.     Qz = CosArgPerigee*SinInclination;
  1088.  
  1089.     *X = Px*Xw + Qx*Yw;        /* Escobal, transformation #31 */
  1090.     *Y = Py*Xw + Qy*Yw;
  1091.     *Z = Pz*Xw + Qz*Yw;
  1092.  
  1093.     *VX = Px*VXw + Qx*VYw;
  1094.     *VY = Py*VXw + Qy*VYw;
  1095.     *VZ = Pz*VXw + Qz*VYw;
  1096. }
  1097.  
  1098. /* Compute the site postion and velocity in the RA based coordinate
  1099.    system. SiteMatrix is set to a matrix which is used by GetTopoCentric
  1100.    to convert geocentric coordinates to topocentric (observer-centered)
  1101.     coordinates. */
  1102.  
  1103. GetSitPosition(SiteLat,SiteLong,SiteElevation,CurrentTime,
  1104.              SiteX,SiteY,SiteZ,SiteVX,SiteVY,SiteMatrix)
  1105.  
  1106. double SiteLat,SiteLong,SiteElevation,CurrentTime;
  1107. double *SiteX,*SiteY,*SiteZ,*SiteVX,*SiteVY;
  1108. mat3x3 SiteMatrix;
  1109.  
  1110. {
  1111.     static double G1,G2; /* Used to correct for flattening of the Earth */
  1112.     static double CosLat,SinLat;
  1113.     static double OldSiteLat = -100000;  /* Used to avoid unneccesary recomputation */
  1114.     static double OldSiteElevation = -100000;
  1115.     double Lat;
  1116.     double SiteRA;    /* Right Ascension of site            */
  1117.     double CosRA,SinRA;
  1118.  
  1119.     if ((SiteLat != OldSiteLat) || (SiteElevation != OldSiteElevation))
  1120.     {
  1121.     OldSiteLat = SiteLat;
  1122.     OldSiteElevation = SiteElevation;
  1123.     Lat = atan(1/(1-SQR(EarthFlat))*tan(SiteLat));
  1124.  
  1125.     CosLat = cos(Lat);
  1126.     SinLat = sin(Lat);
  1127.  
  1128.     G1 = EarthRadius/(sqrt(1-(2*EarthFlat-SQR(EarthFlat))*SQR(SinLat)));
  1129.     G2 = G1*SQR(1-EarthFlat);
  1130.     G1 += SiteElevation;
  1131.     G2 += SiteElevation;
  1132.     }
  1133.  
  1134.  
  1135.     SiteRA = PI2*((CurrentTime-SidDay)*SiderealSolar + SidReference)
  1136.              - SiteLong;
  1137.     CosRA = cos(SiteRA);
  1138.     SinRA = sin(SiteRA);
  1139.     
  1140.  
  1141.     *SiteX = G1*CosLat*CosRA;
  1142.     *SiteY = G1*CosLat*SinRA;
  1143.     *SiteZ = G2*SinLat;
  1144.     *SiteVX = -SidRate * *SiteY;
  1145.     *SiteVY = SidRate * *SiteX;
  1146.  
  1147.     SiteMatrix[0][0] = SinLat*CosRA;
  1148.     SiteMatrix[0][1] = SinLat*SinRA;
  1149.     SiteMatrix[0][2] = -CosLat;
  1150.     SiteMatrix[1][0] = -SinRA;
  1151.     SiteMatrix[1][1] = CosRA;
  1152.     SiteMatrix[1][2] = 0.0;
  1153.     SiteMatrix[2][0] = CosRA*CosLat;
  1154.     SiteMatrix[2][1] = SinRA*CosLat;
  1155.     SiteMatrix[2][2] = SinLat;
  1156. }
  1157.  
  1158. GetRange(SiteX,SiteY,SiteZ,SiteVX,SiteVY,
  1159.     SatX,SatY,SatZ,SatVX,SatVY,SatVZ,Range,RangeRate)
  1160.  
  1161. double SiteX,SiteY,SiteZ,SiteVX,SiteVY;
  1162. double SatX,SatY,SatZ,SatVX,SatVY,SatVZ;
  1163. double *Range,*RangeRate;
  1164. {
  1165.     double DX,DY,DZ;
  1166.  
  1167.     DX = SatX - SiteX; DY = SatY - SiteY; DZ = SatZ - SiteZ;
  1168.  
  1169.     *Range = sqrt(SQR(DX)+SQR(DY)+SQR(DZ));    
  1170.  
  1171.     *RangeRate = ((SatVX-SiteVX)*DX + (SatVY-SiteVY)*DY + SatVZ*DZ)
  1172.             / *Range;
  1173. }
  1174.  
  1175. /* Convert from geocentric RA based coordinates to topocentric
  1176.    (observer centered) coordinates */
  1177.  
  1178. GetTopocentric(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,X,Y,Z)
  1179. double SatX,SatY,SatZ,SiteX,SiteY,SiteZ;
  1180. double *X,*Y,*Z;
  1181. mat3x3 SiteMatrix;
  1182. {
  1183.     SatX -= SiteX;
  1184.     SatY -= SiteY;
  1185.     SatZ -= SiteZ;
  1186.  
  1187.     *X = SiteMatrix[0][0]*SatX + SiteMatrix[0][1]*SatY
  1188.     + SiteMatrix[0][2]*SatZ; 
  1189.     *Y = SiteMatrix[1][0]*SatX + SiteMatrix[1][1]*SatY
  1190.     + SiteMatrix[1][2]*SatZ; 
  1191.     *Z = SiteMatrix[2][0]*SatX + SiteMatrix[2][1]*SatY
  1192.     + SiteMatrix[2][2]*SatZ; 
  1193. }
  1194.  
  1195. GetBearings(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,Azimuth,Elevation)
  1196. double SatX,SatY,SatZ,SiteX,SiteY,SiteZ;
  1197. mat3x3 SiteMatrix;
  1198. double *Azimuth,*Elevation;
  1199. {
  1200.     double x,y,z;
  1201.  
  1202.     GetTopocentric(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,&x,&y,&z);
  1203.  
  1204.     *Elevation = atan(z/sqrt(SQR(x) + SQR(y)));
  1205.  
  1206.     *Azimuth = PI - atan2(y,x);
  1207.  
  1208.     if (*Azimuth < 0)
  1209.     *Azimuth += PI;
  1210. }
  1211.  
  1212. Eclipsed(SatX,SatY,SatZ,SatRadius,CurrentTime)
  1213. double SatX,SatY,SatZ,SatRadius,CurrentTime;
  1214. {
  1215.     double MeanAnomaly,TrueAnomaly;
  1216.     double SunX,SunY,SunZ,SunRad;
  1217.     double vx,vy,vz;
  1218.     double CosTheta;
  1219.  
  1220.     MeanAnomaly = SunMeanAnomaly+ (CurrentTime-SunEpochTime)*SunMeanMotion*PI2;
  1221.     TrueAnomaly = Kepler(MeanAnomaly,SunEccentricity);
  1222.  
  1223.     GetSatPosition(SunEpochTime,SunRAAN,SunArgPerigee,SunSemiMajorAxis,
  1224.         SunInclination,SunEccentricity,0.0,0.0,CurrentTime,
  1225.         TrueAnomaly,&SunX,&SunY,&SunZ,&SunRad,&vx,&vy,&vz);
  1226.  
  1227.     CosTheta = (SunX*SatX + SunY*SatY + SunZ*SatZ)/(SunRad*SatRadius)
  1228.          *CosPenumbra + (SatRadius/EarthRadius)*SinPenumbra;
  1229.  
  1230.     if (CosTheta < 0)
  1231.         if (CosTheta < -sqrt(SQR(SatRadius)-SQR(EarthRadius))/SatRadius
  1232.                 *CosPenumbra + (SatRadius/EarthRadius)*SinPenumbra)
  1233.       
  1234.         return 1;
  1235.     return 0;
  1236. }
  1237.  
  1238. /* Initialize the Sun's keplerian elements for a given epoch.
  1239.    Formulas are from "Explanatory Supplement to the Astronomical Ephemeris".
  1240.    Also init the sidereal reference                */
  1241.  
  1242. InitOrbitRoutines(EpochDay)
  1243. double EpochDay;
  1244. {
  1245.     double T,T2,T3,Omega;
  1246.     int n;
  1247.     double SunTrueAnomaly,SunDistance;
  1248.  
  1249.     T = (floor(EpochDay)-0.5)/36525;
  1250.     T2 = T*T;
  1251.     T3 = T2*T;
  1252.  
  1253.     SidDay = floor(EpochDay);
  1254.  
  1255.     SidReference = (6.6460656 + 2400.051262*T + 0.00002581*T2)/24;
  1256.     SidReference -= floor(SidReference);
  1257.  
  1258.     /* Omega is used to correct for the nutation and the abberation */
  1259.     Omega = (259.18 - 1934.142*T) * RadiansPerDegree;
  1260.     n = Omega / PI2;
  1261.     Omega -= n*PI2;
  1262.  
  1263.     SunEpochTime = EpochDay;
  1264.     SunRAAN = 0;
  1265.  
  1266.     SunInclination = (23.452294 - 0.0130125*T - 0.00000164*T2
  1267.             + 0.000000503*T3 +0.00256*cos(Omega)) * RadiansPerDegree;
  1268.     SunEccentricity = (0.01675104 - 0.00004180*T - 0.000000126*T2);
  1269.     SunArgPerigee = (281.220833 + 1.719175*T + 0.0004527*T2
  1270.             + 0.0000033*T3) * RadiansPerDegree;
  1271.     SunMeanAnomaly = (358.475845 + 35999.04975*T - 0.00015*T2
  1272.             - 0.00000333333*T3) * RadiansPerDegree;
  1273.     n = SunMeanAnomaly / PI2;
  1274.     SunMeanAnomaly -= n*PI2;
  1275.  
  1276.     SunMeanMotion = 1/(365.24219879 - 0.00000614*T);
  1277.  
  1278.     SunTrueAnomaly = Kepler(SunMeanAnomaly,SunEccentricity);
  1279.     SunDistance = SunSemiMajorAxis*(1-SQR(SunEccentricity))
  1280.             / (1+SunEccentricity*cos(SunTrueAnomaly));
  1281.  
  1282.     SinPenumbra = (SunRadius-EarthRadius)/SunDistance;
  1283.     CosPenumbra = sqrt(1-SQR(SinPenumbra));
  1284. }
  1285.  
  1286.  
  1287. SPrintTime(Str,Time)
  1288. char *Str;
  1289. double Time;
  1290. {
  1291.     int day,hours,minutes,seconds;
  1292.  
  1293.     day = Time;
  1294.     Time -= day;
  1295.     if (Time < 0)
  1296.         Time += 1.0;   /* Correct for truncation problems with negatives */
  1297.  
  1298.     hours = Time*24;
  1299.     Time -=  hours/24.0;
  1300.  
  1301.     minutes = Time*MinutesPerDay;
  1302.     Time -= minutes/MinutesPerDay;
  1303.  
  1304.     seconds = Time*SecondsPerDay;
  1305.     seconds -= seconds/SecondsPerDay;
  1306.  
  1307.     sprintf(Str,"%02d%02d:%02d",hours,minutes,seconds);
  1308. }
  1309.  
  1310. PrintTime(OutFile,Time)
  1311. FILE *OutFile;
  1312. double Time;
  1313. {
  1314.     char str[100];
  1315.  
  1316.     SPrintTime(str,Time);
  1317.     fprintf(OutFile,"%s",str);
  1318. }
  1319.  
  1320.  
  1321. /* Get the Day Number for a given date. January 1 of the reference year
  1322.    is day 0. Note that the Day Number may be negative, if the sidereal
  1323.    reference is in the future.                                          */
  1324.  
  1325. /* Date calculation routines
  1326.   Robert Berger @ Carnegie Mellon
  1327.  
  1328.   January 1, 1900 is day 0
  1329.   valid from 1900 through 2099 */
  1330.  
  1331. /* #include <stdio.h> */
  1332.  
  1333. char *MonthNames[] = { "Jan","Feb","Mar","Apr","May","Jun","Jul",
  1334.                         "Aug","Sep","Oct","Nov","Dec" };
  1335.  
  1336. int MonthDays[] = {0,31,59,90,120,151,181,212,243,273,304,334};
  1337.         
  1338.  
  1339. char *DayNames[] = { "Sunday","Monday","Tuesday","Wednesday","Thursday",
  1340.                         "Friday","Saturday"};
  1341.  
  1342.  
  1343. long GetDayNum(Year,Month,Day)
  1344. {
  1345.     long Result;
  1346.     
  1347.     /* Heuristic to allow 4 or 2 digit year specifications */
  1348.     if (Year < 50)
  1349.     Year += 2000;
  1350.       else if (Year < 100)
  1351.     Year += 1900;
  1352.     
  1353.     Result = ((((long) Year-1901)*1461)>>2) + MonthDays[Month-1] + Day + 365;
  1354.     if (Year%4 == 0 && Month > 2)
  1355.         Result++;
  1356.  
  1357.     return Result;
  1358. }
  1359.  
  1360. GetDate(DayNum,Year,Month,Day)
  1361. long DayNum;
  1362. int *Year,*Month,*Day;    
  1363. {
  1364.     int M,L;
  1365.     long Y;
  1366.     
  1367.     Y = 4*DayNum;
  1368.     Y /= 1461;
  1369.  
  1370.     DayNum =  DayNum -365 - (((Y-1)*1461)>>2);
  1371.     
  1372.     L = 0;
  1373.     if (Y%4 == 0 && DayNum > MonthDays[2])
  1374.         L = 1;
  1375.     
  1376.     M = 1;
  1377.          
  1378.     while (DayNum > MonthDays[M]+L)
  1379.     M++;
  1380.     
  1381.     DayNum -= (MonthDays[M-1]);
  1382.     if (M > 2)
  1383.         DayNum -= L;
  1384.    
  1385.     *Year = Y+1900;
  1386.     *Month = M;
  1387.     *Day = DayNum;
  1388. }    
  1389.  
  1390. /* Sunday = 0 */
  1391. GetDayOfWeek(DayNum)
  1392. long DayNum;
  1393. {
  1394.     return DayNum % 7;
  1395. }    
  1396.  
  1397. SPrintDate(Str,DayNum)
  1398. char *Str;
  1399. long DayNum;
  1400. {
  1401.     int Month,Day,Year;
  1402.     
  1403.     GetDate(DayNum,&Year,&Month,&Day);
  1404.     sprintf(Str,"%d %s %d",Day,
  1405.                 MonthNames[Month-1],Year);
  1406.  
  1407. SPrintDayOfWeek(Str,DayNum)
  1408. char *Str;
  1409. long DayNum;
  1410. {
  1411.     strcpy(Str,DayNames[DayNum%7]);
  1412. }
  1413.  
  1414. PrintDate(OutFile,DayNum)
  1415. FILE *OutFile;
  1416. long DayNum;
  1417. {
  1418.     char str[100];
  1419.  
  1420.     SPrintDate(str,DayNum);
  1421.     fprintf(OutFile,"%s",str);
  1422. }
  1423.  
  1424. PrintDayOfWeek(OutFile,DayNum)
  1425. FILE *OutFile;
  1426. long DayNum;
  1427. {
  1428.     fprintf(OutFile,"%s",DayNames[DayNum%7]);
  1429. }    
  1430.   
  1431. !E!O!F!
  1432. #
  1433. # type    sh /usrvi0/rwb/orbit/orbit.shar   to unpack this archive.
  1434. #
  1435. echo extracting nasa.c...
  1436. cat >nasa.c <<'!E!O!F!'
  1437. /* nasa.c   convert file of NASA keplerians to AMSAT format
  1438.  7/12/87  Robert W. Berger N3EMO            */
  1439.  
  1440. /* 11/30/88    v3.5    Incorporate Greg Troxel's fix for reading epoch
  1441.             times with imbedded spaces        */
  1442.  
  1443. #include <stdio.h>
  1444.  
  1445. main()
  1446. {   char SatName[100],line1[100],line2[100];
  1447.     FILE *InFile,*OutFile;
  1448.     int LineNum,SatNum,ElementSet,EpochRev;
  1449.     double EpochDay,DecayRate,Inclination,RAAN,Eccentricity;
  1450.     double ArgPerigee,MeanAnomaly,MeanMotion;
  1451.     double EpochYear;
  1452.  
  1453.     if ((InFile = fopen("nasa.dat","r")) == 0)
  1454.         {
  1455.     printf("\"nasa.dat\" not found\n");
  1456.     exit(-1);
  1457.     }
  1458.  
  1459.     if ((OutFile = fopen("kepler.dat","w")) == 0)
  1460.         {
  1461.     printf("Can't write \"kepler.dat\"\n");
  1462.     exit(-1);
  1463.     }
  1464.  
  1465.  
  1466.     while (fgets(SatName,100,InFile))
  1467.     {
  1468.     printf("%s",SatName);
  1469.     fgets(line1,100,InFile);
  1470.     fgets(line2,100,InFile);
  1471.     
  1472.         sscanf(line1,"%1d",&LineNum);
  1473.       if (LineNum != 1)
  1474.         {
  1475.         printf("Line 1 not present for satellite %s",SatName);
  1476.         exit(-1);
  1477.         }
  1478.         sscanf(line2,"%1d",&LineNum);
  1479.       if (LineNum != 2)
  1480.         {
  1481.         printf("Line 2 not present for satellite %s",SatName);
  1482.         exit(-1);
  1483.         }
  1484.  
  1485.     sscanf(line1,"%*2c%5d%*10c%2lf%12lf%10lf%*21c%5d",
  1486.         &SatNum,&EpochYear,&EpochDay,&DecayRate,&ElementSet);
  1487.     EpochDay += EpochYear *1000;
  1488.  
  1489.     ElementSet /= 10;   /* strip off checksum */
  1490.  
  1491.     sscanf(line2,"%*8c%8lf%8lf%7lf%8lf%8lf%11lf%5d",
  1492.        &Inclination,&RAAN,&Eccentricity,&ArgPerigee,&MeanAnomaly,
  1493.        &MeanMotion,&EpochRev);
  1494.     EpochRev /= 10;   /* strip off checksum */
  1495.     Eccentricity *= 1E-7;
  1496.  
  1497.  
  1498.     fprintf(OutFile,"Satellite: %s",SatName);
  1499.     fprintf(OutFile,"Catalog number: %d\n",SatNum);
  1500.     fprintf(OutFile,"Epoch time: %lf\n",EpochDay);
  1501.     fprintf(OutFile,"Element set: %d\n",ElementSet);
  1502.     fprintf(OutFile,"Inclination: %lf deg\n",Inclination);
  1503.     fprintf(OutFile,"RA of node: %lf deg\n",RAAN);
  1504.     fprintf(OutFile,"Eccentricity: %lf\n",Eccentricity);
  1505.     fprintf(OutFile,"Arg of perigee: %lf deg\n",ArgPerigee);
  1506.     fprintf(OutFile,"Mean anomaly: %lf deg\n",MeanAnomaly);
  1507.     fprintf(OutFile,"Mean motion: %lf rev/day\n",MeanMotion);
  1508.     fprintf(OutFile,"Decay rate: %le rev/day^2\n",DecayRate);
  1509.     fprintf(OutFile,"Epoch rev: %d\n",EpochRev);
  1510.     fprintf(OutFile,"\n");
  1511.     }
  1512.  
  1513.     fclose(InFile);
  1514.     fclose(OutFile);
  1515.  
  1516. }
  1517.         
  1518. !E!O!F!
  1519. #
  1520. # type    sh /usrvi0/rwb/orbit/orbit.shar   to unpack this archive.
  1521. #
  1522. echo extracting kepler.dat...
  1523. cat >kepler.dat <<'!E!O!F!'
  1524. HR AMSAT ORBITAL ELEMENTS FOR OSCAR SATELLITES
  1525. FROM N3FKV LORENA, TX      MARCH 3, 1990
  1526. TO ALL RADIO AMATEURS BT
  1527.  
  1528. Satellite: AO-10
  1529. Catalog number: 14129
  1530. Epoch time:      90049.80793411
  1531. Element set:     456
  1532. Inclination:       25.9253 deg
  1533. RA of node:       218.0969 deg
  1534. Eccentricity:    0.5995939
  1535. Arg of perigee:   119.7301 deg
  1536. Mean anomaly:     312.5438 deg
  1537. Mean motion:    2.05881409 rev/day
  1538. Decay rate:       0.00e+00 rev/day^2
  1539. Epoch rev:            5029
  1540.  
  1541. Satellite: UO-11
  1542. Catalog number: 14781
  1543. Epoch time:      90060.18781917
  1544. Element set:     621
  1545. Inclination:       97.9647 deg
  1546. RA of node:       116.2327 deg
  1547. Eccentricity:    0.0012630
  1548. Arg of perigee:   224.1641 deg
  1549. Mean anomaly:     135.8969 deg
  1550. Mean motion:   14.64947016 rev/day
  1551. Decay rate:      2.418e-05 rev/day^2
  1552. Epoch rev:           32015
  1553.  
  1554. Satellite: RS-10/11
  1555. Catalog number: 18129
  1556. Epoch time:      90059.94953892
  1557. Element set:      51
  1558. Inclination:       82.9235 deg
  1559. RA of node:        48.4869 deg
  1560. Eccentricity:    0.0013322
  1561. Arg of perigee:    62.4188 deg
  1562. Mean anomaly:     297.8336 deg
  1563. Mean motion:   13.72063512 rev/day
  1564. Decay rate:       1.65e-06 rev/day^2
  1565. Epoch rev:           13460
  1566.  
  1567. Satellite: AO-13
  1568. Catalog number: 19216
  1569. Epoch time:      90054.30232176
  1570. Element set:      77
  1571. Inclination:       57.0658 deg
  1572. RA of node:       167.4162 deg
  1573. Eccentricity:    0.6899473
  1574. Arg of perigee:   221.7453 deg
  1575. Mean anomaly:      57.5228 deg
  1576. Mean motion:    2.09701313 rev/day
  1577. Decay rate:      -9.10e-07 rev/day^2
  1578. Epoch rev:            1301
  1579.  
  1580. Satellite: UO-14
  1581. Catalog number: 20437
  1582. Epoch time:      90051.20925581
  1583. Element set:      19
  1584. Inclination:       98.7074 deg
  1585. RA of node:       127.6262 deg
  1586. Eccentricity:    0.0011863
  1587. Arg of perigee:   133.4472 deg
  1588. Mean anomaly:     226.7691 deg
  1589. Mean motion:   14.28489200 rev/day
  1590. Decay rate:       1.36e-06 rev/day^2
  1591. Epoch rev:             416
  1592.  
  1593. Satellite: UO-15
  1594. Catalog number: 20438
  1595. Epoch time:      90052.26456850
  1596. Element set:      18
  1597. Inclination:       98.7128 deg
  1598. RA of node:       128.6765 deg
  1599. Eccentricity:    0.0010460
  1600. Arg of perigee:   127.9180 deg
  1601. Mean anomaly:     232.2949 deg
  1602. Mean motion:   14.28268284 rev/day
  1603. Decay rate:       2.23e-06 rev/day^2
  1604. Epoch rev:             431
  1605.  
  1606. Satellite: AO-16
  1607. Catalog number: 20439
  1608. Epoch time:      90051.27752383
  1609. Element set:      20
  1610. Inclination:       98.7160 deg
  1611. RA of node:       127.7169 deg
  1612. Eccentricity:    0.0011872
  1613. Arg of perigee:   133.0620 deg
  1614. Mean anomaly:     227.1560 deg
  1615. Mean motion:   14.28579197 rev/day
  1616. Decay rate:       3.36e-06 rev/day^2
  1617. Epoch rev:             417
  1618.  
  1619. Satellite: DO-17
  1620. Catalog number: 20440
  1621. Epoch time:      90052.25739911
  1622. Element set:      11
  1623. Inclination:       98.7153 deg
  1624. RA of node:       128.6947 deg
  1625. Eccentricity:    0.0011993
  1626. Arg of perigee:   130.0555 deg
  1627. Mean anomaly:     230.1712 deg
  1628. Mean motion:   14.28613842 rev/day
  1629. Decay rate:       4.17e-06 rev/day^2
  1630. Epoch rev:             431
  1631.  
  1632. Satellite: WO-18
  1633. Catalog number: 20441
  1634. Epoch time:      90053.23543324
  1635. Element set:      12
  1636. Inclination:       98.7114 deg
  1637. RA of node:       129.6772 deg
  1638. Eccentricity:    0.0012817
  1639. Arg of perigee:   128.9972 deg
  1640. Mean anomaly:     231.2353 deg
  1641. Mean motion:   14.28729505 rev/day
  1642. Decay rate:       5.43e-06 rev/day^2
  1643. Epoch rev:             445
  1644.  
  1645. Satellite: LO-19
  1646. Catalog number: 20442
  1647. Epoch time:      90051.20312279
  1648. Element set:      16
  1649. Inclination:       98.7143 deg
  1650. RA of node:       127.6484 deg
  1651. Eccentricity:    0.0012798
  1652. Arg of perigee:   133.6862 deg
  1653. Mean anomaly:     226.5403 deg
  1654. Mean motion:   14.28793437 rev/day
  1655. Decay rate:       3.49e-06 rev/day^2
  1656. Epoch rev:             416
  1657.  
  1658. Satellite: FO-20
  1659. Catalog number: 20480
  1660. Epoch time:      90056.04185854
  1661. Element set:      14
  1662. Inclination:       99.0553 deg
  1663. RA of node:       123.6579 deg
  1664. Eccentricity:    0.0540918
  1665. Arg of perigee:   302.5752 deg
  1666. Mean anomaly:      52.4250 deg
  1667. Mean motion:   12.83114314 rev/day
  1668. Decay rate:       4.30e-07 rev/day^2
  1669. Epoch rev:             236
  1670.  
  1671. /EX
  1672. SB ALL @ AMSAT  $ORBS-062.W
  1673. Orbital Elements   062.WEATHER
  1674.  
  1675. HR AMSAT ORBITAL ELEMENTS FOR WEATHER SATELLITES
  1676. FROM N3FKV LORENA, TX      MARCH 3, 1990
  1677. TO ALL RADIO AMATEURS BT
  1678.  
  1679. Satellite: NOAA-9
  1680. Catalog number: 15427
  1681. Epoch time:      90060.45603462
  1682. Element set:     486
  1683. Inclination:       99.1648 deg
  1684. RA of node:        57.8071 deg
  1685. Eccentricity:    0.0014466
  1686. Arg of perigee:   314.1835 deg
  1687. Mean anomaly:      45.8150 deg
  1688. Mean motion:   14.12457910 rev/day
  1689. Decay rate:       9.40e-06 rev/day^2
  1690. Epoch rev:           26877
  1691.  
  1692. Satellite: NOAA-10
  1693. Catalog number: 16969
  1694. Epoch time:      90060.52697286
  1695. Element set:     346
  1696. Inclination:       98.6135 deg
  1697. RA of node:        90.8378 deg
  1698. Eccentricity:    0.0012702
  1699. Arg of perigee:   221.3159 deg
  1700. Mean anomaly:     138.7082 deg
  1701. Mean motion:   14.23474323 rev/day
  1702. Decay rate:       6.46e-06 rev/day^2
  1703. Epoch rev:           17929
  1704.  
  1705. Satellite: MET-2/16
  1706. Catalog number: 18312
  1707. Epoch time:      90058.91549732
  1708. Element set:     374
  1709. Inclination:       82.5506 deg
  1710. RA of node:        16.8901 deg
  1711. Eccentricity:    0.0010421
  1712. Arg of perigee:   196.7088 deg
  1713. Mean anomaly:     163.3733 deg
  1714. Mean motion:   13.83602617 rev/day
  1715. Decay rate:       2.18e-06 rev/day^2
  1716. Epoch rev:           12787
  1717.  
  1718. Satellite: MET-2/17
  1719. Catalog number: 18820
  1720. Epoch time:      90058.98423229
  1721. Element set:     202
  1722. Inclination:       82.5413 deg
  1723. RA of node:        77.2737 deg
  1724. Eccentricity:    0.0015284
  1725. Arg of perigee:   274.0695 deg
  1726. Mean anomaly:      85.8720 deg
  1727. Mean motion:   13.84296367 rev/day
  1728. Decay rate:       1.48e-06 rev/day^2
  1729. Epoch rev:           10507
  1730.  
  1731. Satellite: MET-3/2
  1732. Catalog number: 19336
  1733. Epoch time:      90057.87193849
  1734. Element set:     379
  1735. Inclination:       82.5488 deg
  1736. RA of node:       355.4769 deg
  1737. Eccentricity:    0.0015984
  1738. Arg of perigee:   226.0902 deg
  1739. Mean anomaly:     133.8903 deg
  1740. Mean motion:   13.16876329 rev/day
  1741. Decay rate:       3.91e-06 rev/day^2
  1742. Epoch rev:            7643
  1743.  
  1744. Satellite: NOAA-11
  1745. Catalog number: 19531
  1746. Epoch time:      90060.35370320
  1747. Element set:     203
  1748. Inclination:       98.9706 deg
  1749. RA of node:         8.6194 deg
  1750. Eccentricity:    0.0011513
  1751. Arg of perigee:   225.0782 deg
  1752. Mean anomaly:     134.9451 deg
  1753. Mean motion:   14.11467817 rev/day
  1754. Decay rate:       8.90e-06 rev/day^2
  1755. Epoch rev:            7375
  1756.  
  1757. Satellite: MET-2/18
  1758. Catalog number: 19851
  1759. Epoch time:      90058.20440967
  1760. Element set:     153
  1761. Inclination:       82.5234 deg
  1762. RA of node:       316.0960 deg
  1763. Eccentricity:    0.0013491
  1764. Arg of perigee:   319.0705 deg
  1765. Mean anomaly:      40.9448 deg
  1766. Mean motion:   13.83938725 rev/day
  1767. Decay rate:       1.88e-06 rev/day^2
  1768. Epoch rev:            5035
  1769.  
  1770. Satellite: MET-3/3
  1771. Catalog number: 20305
  1772. Epoch time:      90060.01873175
  1773. Element set:      54
  1774. Inclination:       82.5545 deg
  1775. RA of node:       294.3024 deg
  1776. Eccentricity:    0.0015118
  1777. Arg of perigee:   240.3269 deg
  1778. Mean anomaly:     119.6305 deg
  1779. Mean motion:   13.15851639 rev/day
  1780. Decay rate:       4.60e-07 rev/day^2
  1781. Epoch rev:            1672
  1782.  
  1783. /EX
  1784. SB ALL @ AMSAT  $ORBS-062.M
  1785. Orbital Elements   062.MISC
  1786.  
  1787. HR AMSAT ORBITAL ELEMENTS FOR MANNED AND MISCELLANEOUS SATELLITES
  1788. FROM N3FKV LORENA, TX      MARCH 3, 1990
  1789. TO ALL RADIO AMATEURS BT
  1790.  
  1791. Satellite: SALYUT 7
  1792. Catalog number: 13138
  1793. Epoch time:      90060.28992269
  1794. Element set:      76
  1795. Inclination:       51.6040 deg
  1796. RA of node:       127.0926 deg
  1797. Eccentricity:    0.0000717
  1798. Arg of perigee:    43.7023 deg
  1799. Mean anomaly:     316.3899 deg
  1800. Mean motion:   15.55378681 rev/day
  1801. Decay rate:      8.612e-05 rev/day^2
  1802. Epoch rev:           44801
  1803.  
  1804. Satellite: MIR
  1805. Catalog number: 16609
  1806. Epoch time:      90060.29778265
  1807. Element set:     434
  1808. Inclination:       51.6177 deg
  1809. RA of node:       153.8856 deg
  1810. Eccentricity:    0.0016747
  1811. Arg of perigee:   220.9865 deg
  1812. Mean anomaly:     138.9686 deg
  1813. Mean motion:   15.58930728 rev/day
  1814. Decay rate:     -7.013e-05 rev/day^2
  1815. Epoch rev:           23125
  1816.  
  1817. !E!O!F!
  1818. #
  1819. # type    sh /usrvi0/rwb/orbit/orbit.shar   to unpack this archive.
  1820. #
  1821. echo extracting mode.dat...
  1822. cat >mode.dat <<'!E!O!F!'
  1823. Satellite: UO-11
  1824. Beacon:           145.8260 MHz
  1825.  
  1826. Satellite: AO-13
  1827. Beacon:           145.8260 MHz
  1828. Mode: B        from 0 to 165
  1829. Mode: JL    from 165 to 195
  1830. Mode: S        from 195 to 200
  1831. Mode: BS    from 200 to 205
  1832. Mode: B        from 205 to 256
  1833.  
  1834. Satellite: NOAA-9
  1835. Beacon:           137.6200 MHz
  1836.  
  1837. Satellite: NOAA-10
  1838. Beacon:           137.5000 MHz
  1839.  
  1840. Satellite: MIR
  1841. Beacon:           143.6250 MHz
  1842.  
  1843. Satellite: RS-10/11
  1844. Beacon:           29.357 MHz
  1845. !E!O!F!
  1846. #
  1847. # type    sh /usrvi0/rwb/orbit/orbit.shar   to unpack this archive.
  1848. #
  1849. echo extracting pgh.sit...
  1850. cat >pgh.sit <<'!E!O!F!'
  1851. W3VC  Pittsburgh
  1852. 40.45361        Latitude
  1853. 79.94417        Longitude
  1854. 300            Height (Meters)
  1855. 0            Min Elevation (Degrees)
  1856. Eclipse
  1857. Flip
  1858. !E!O!F!
  1859. #
  1860. # type    sh /usrvi0/rwb/orbit/orbit.shar   to unpack this archive.
  1861. #
  1862. echo extracting Makefile...
  1863. cat >Makefile <<'!E!O!F!'
  1864. CFLAGS = -O
  1865.  
  1866. orbit:: orbit.o orbitr.o
  1867.     cc orbit.o orbitr.o -lm -o orbit
  1868.  
  1869. !E!O!F!
  1870.  
  1871.