ftp.nice.ch/pub/next/science/astronomy/usat-NeXT.N.bs.tar.gz#/usat/rsat.c

This is rsat.c in view mode; [Download] [Up]

/****************************************************************/
/* rsat.c							*/
/*								*/
/* The following program produces topocentric geocentric right	*/
/* ascension,  declination, altitude, and azimuth of the	*/
/* satellite .							*/
/****************************************************************/

/***** description
 *
 *	$Id: rsat.c,v 1.7 1993/05/12 18:55:31 craig Exp $
 *
 */

/***** modification history
 *
 *	$Log: rsat.c,v $
 * Revision 1.7  1993/05/12  18:55:31  craig
 * satreduce just returns the alt, az, ra, and dec now.  Moved all
 * of the decision making and printing to search.c..
 *
 * Added a new subroutine --- do_orbit which gets the geocentric
 * retangular coordinate using the NORAD software.
 *
 * Revision 1.6  1993/05/05  19:14:20  craig
 * Added an additional output option that only gives the satellite name
 * and time.
 *
 * Revision 1.4  1993/04/30  18:29:08  craig
 * Removed most of the error messages from rdelement ().
 *
 * Revision 1.3  1993/04/30  14:39:17  craig
 * rdelement has been moved to this file.
 *
 * Revision 1.2  1993/04/27  17:11:17  craig
 * Set prtflg to 0 so that only Topocentric coordinate info is
 * displayed.
 *
 * Revision 1.1  1993/04/26  19:26:24  craig
 * Initial revision
 *
 *
 */

/***** include files *****/

#include <string.h>
#include <ctype.h>
#include <math.h>
#include "satproto.h"
#include "satellite.h"
#include "aaproto.h"

/***** global variables *****/

/* from `driver' */

extern FILE *elefile;
extern FILE *outfile;

extern struct ELEMENT element;

/* from cnstinit.c */

extern int prtflg;

extern double JD;
extern double UT;
extern double TDT;
extern double dp[3];
extern double dradt;
extern double ddecdt;
extern double rearth[3];
extern double eapolar[3];

extern struct orbit earth;
extern struct PCONSTANTS pcnsts;
extern struct MCONSTANTS mcnsts;

/*************/
/* satreduce */
/*************/

int satreduce (double *alt, double *az, double *ra, double *dec)
{
    double p[3];	/* geocentric rectangular coords */
    double porig[3];    /* origional geocentric rect coords of epoch */
    double dporig[3];   /* origional velocity in km/s */
    double p0[3], temp[3], polar[3];
    double t, dist;

    register i;
    

    /* update the time */

    update (outfile);

    /* always calculate the heliocentric position of the earth */

    kepler (TDT, &earth, rearth, eapolar);

    /* fill in the origional geocentric rect coords of epoch */

    porig[0] = element.x;
    porig[1] = element.y;
    porig[2] = element.z;

    /* and the velocitys */

    dporig[0] = element.xdot;
    dporig[1] = element.ydot;
    dporig[2] = element.zdot;

    /* copy the origional coords and convert to au */

    for (i = 0; i < 3; i++)
    {
	p0[i] = porig[i] / pcnsts.kmpau;
    }

    /* precess coords to J2000 */

    precess (p0, element.epoch, 1);

    /* calculate the light time between the object and the earth */

    dist = 0.0;

    for (i = 0; i < 3; i++)
    {
	dist += p0[i] * p0[i];
    }

    dist = sqrt (dist);			/* in au */

    t = dist / pcnsts.caupda;

    if (prtflg == 1)
    {
        fprintf (outfile, "distance = %f km, light time = %f seconds\n", 
	    dist * pcnsts.kmpau, t * pcnsts.secpda);
    }

    /* final object-earth vector and the amount it changed */

    for (i = 0; i < 3; i++)
    {
	p[i] = porig[i] / pcnsts.kmpau + t * dporig[i] / pcnsts.kmpau *
	    pcnsts.secpda;
    }

    /* precess coords to J2000 */

    precess (p, element.epoch, 1);

    for (i = 0; i < 3; i++)
    {
	dp[i] = p[i] - p0[i];
    }

    showcor ("aberration", p0, dp);

    deltap (p0, p, &dradt, &ddecdt);

    dradt /= t;
    ddecdt /= t;

    /* Find unit vector from earth in direction of object */

    for (i = 0; i < 3; i++)
    {
	p[i] = p0[i] / dist;
	temp[i] = p[i];
    }

    if (prtflg)
    {
	/* Report astrometric position */

	showrd ("Astrometric J2000.0:", p, polar);

	/* Also in 1950 coordinates */

	precess (temp, pcnsts.B1950, -1);
	showrd ("Astrometric B1950.0:", temp, polar);
    }

    /* Correct for annual aberration */

    annuab (p);

    /* Precession of the equinox and ecliptic from J2000.0 to ephemeris
       date */

    precess (p, TDT, -1);

    /* Ajust for nutation at current ecliptic. */

    epsiln (TDT);
    nutate (TDT, p);

    /* Display the final apparent R.A. and Dec. for equinox of date. */

    showrd ("    Apparent:", p, polar);

    /* Go do topocentric reductions. */

    polar[2] = dist;
    altaz (polar, UT, alt, az, ra, dec);

    return (0);
}

/*************/
/* rdelement */
/*************/

int rdelement (void)
{

    int    idummy, csum;

    char   eline[80], tstrng[20];

    double ddummy;

    register i;

    for (i = 0; i < 80; i++)
    {
	eline[i] = '\0';
    }

    /***** read in mean elements from 2 card trans format *****/

    /*** read the first "card" into the line buffer ***/

    if (fgets (element.name, 70, elefile) == NULL)
    {
	return (-1);
    }

    /* fprintf (stdout, "%s\n", element.name); */

    /*** remove the carriage return from the name ***/

    for (i = 0; i < strlen (element.name); i++)
    {
	if (iscntrl (element.name[i]))
	{
	    element.name[i] = 0x20;		/* space */
	}
    }

    /*** read the second "card" into the line buffer ***/

    if (fread (eline, sizeof (char), 70, elefile) != 70)
    {
	return (-1);
    }

    /* fprintf (stdout, "%s\n", eline); */

    /*** check checksum ***/

    csum = 0;
    for (i = 0; i < 68; i++)
    {
	if (eline[i] == '-')
	{
	    csum++;
	}
	else
	{
	    idummy = (int) eline[i]; 
	    if (isdigit (idummy) != 0)
	    {
                if (sscanf (&eline[i], "%1d", &idummy) != 1)
                {
	            return (-1);
                }
		csum += idummy;
	    }
	}
    }
    csum = csum % 10;

    tstrng[0] = '\0';
    strncat (tstrng, &eline[68], 1);

    if (sscanf (tstrng, "%d", &idummy) != 1)
    {
	return (-1);
    }

    if (idummy != csum)
    {
	fprintf (stderr, "checksum error: %d != %d\n", csum, idummy);
	return (-1);
    }

    /*** epoch ***/

    tstrng[0] = '\0';
    strncat (tstrng, &eline[18], 2);

    if (sscanf (tstrng, "%d", &idummy) != 1)
    {
	return (-1);
    }

    tstrng[0] = '\0';
    strncat (tstrng, &eline[20], 12);

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    /* get the mjd day number for the epoch year */

    idummy += 1900;
    element.epoch = mjd (idummy, 1, 0.0);

    /* add the epoch julian day */

    element.epoch += ddummy;		/* modified julian day number */

    /*** xndt2o ***/

    tstrng[0] = '\0';
    strncat (tstrng, &eline[33], 10);

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    element.xndt2o = ddummy * mcnsts.twopi / pcnsts.xmnpda /
	pcnsts.xmnpda;

    /*** xndd6o ***/

    tstrng[0] = '\0';
    strncat (tstrng, &eline[44], 1);	/* sign field */
    tstrng[1] = '0';
    tstrng[2] = '.';
    tstrng[3] = '\0';
    strncat (tstrng, &eline[45], 5);	/* number field */

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    if (ddummy == 0.)
    {
	element.xndd6o = 0.;
    }
    else
    {
	tstrng[0] = '\0';
	strncat (tstrng, &eline[50], 2);/* exponent field */

	if (sscanf (tstrng, "%d", &idummy) != 1)
	{
	    return (-1);
	}

	element.xndd6o = ddummy * pow (10., (double) idummy);
	element.xndd6o = element.xndd6o * mcnsts.twopi /
	    pow (pcnsts.xmnpda, 3.);
    }

    /*** bstar ***/

    tstrng[0] = '\0';
    strncat (tstrng, &eline[53], 1);	/* sign field */
    tstrng[1] = '0';
    tstrng[2] = '.';
    tstrng[3] = '\0';
    strncat (tstrng, &eline[54], 5);	/* number field */

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    if (ddummy == 0.)
    {
	element.bstar = 0.;
    }
    else
    {
	tstrng[0] = '\0';
	strncat (tstrng, &eline[59], 2);/* exponent field */

	if (sscanf (tstrng, "%d", &idummy) != 1)
	{
	    return (-1);
	}

	element.bstar = ddummy * pow (10., (double) idummy) / pcnsts.ae;
    }

    /*** read the third "card" into the line buffer ***/

    if (fread (eline, sizeof (char), 70, elefile) != 70)
    {
	return (-1);
    }

    /* fprintf (stdout, "%s\n", eline); */

    /*** check checksum ***/

    csum = 0;
    for (i = 0; i < 68; i++)
    {
	if (eline[i] == '-')
	{
	    csum++;
	}
	else
	{
	    idummy = (int) eline[i]; 
	    if (isdigit (idummy) != 0)
	    {
                if (sscanf (&eline[i], "%1d", &idummy) != 1)
                {
	            return (-1);
                }
		csum += idummy;
	    }
	}
    }
    csum = csum % 10;

    tstrng[0] = '\0';
    strncat (tstrng, &eline[68], 1);

    if (sscanf (tstrng, "%d", &idummy) != 1)
    {
	return (-1);
    }

    if (idummy != csum)
    {
	fprintf (stderr, "checksum error: %d != %d\n", csum, idummy);
	return (-1);
    }

    /*** xincl ***/

    tstrng[0] = '\0';
    strncat (tstrng, &eline[8], 8);

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    element.xincl = ddummy * mcnsts.de2ra;

    /*** xnodeo ***/

    tstrng[0] = '\0';
    strncat (tstrng, &eline[17], 8);

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    element.xnodeo = ddummy * mcnsts.de2ra;

    /*** eo ***/

    tstrng[0] = '.';
    tstrng[1] = '\0';
    strncat (tstrng, &eline[26], 7);

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    element.eo = ddummy;

    /*** omegao ***/

    tstrng[0] = '\0';
    strncat (tstrng, &eline[34], 8);

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    element.omegao = ddummy * mcnsts.de2ra;

    /*** xmo ***/

    tstrng[0] = '\0';
    strncat (tstrng, &eline[43], 8);

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    element.xmo = ddummy * mcnsts.de2ra;

    /*** xno ***/

    tstrng[0] = '\0';
    strncat (tstrng, &eline[52], 11);

    if (sscanf (tstrng, "%lf", &ddummy) != 1)
    {
	return (-1);
    }

    element.xno = ddummy * mcnsts.twopi / pcnsts.xmnpda;

    /***** check for valid elements *****/

    if (element.xno <= 0.)
    {
	return (-1);
    }

    return (0);
}

/***********************************************************/
/* do_orbit						   */
/*							   */
/* update the satellite geocentric rectangular coordinates */
/***********************************************************/

void do_orbit (int iflag, int orbflag)
{
    double tsince;


    tsince = (JD - element.epoch) * pcnsts.xmnpda;

    switch (orbflag)
    {
      case 1:

	sgp (&iflag, tsince);
	break;

      case 2:

	sgp4 (&iflag, tsince);
	break;

      case 3:

	sdp4 (&iflag, tsince);
	break;

      case 4:

	sgp8 (&iflag, tsince);
	break;

      case 5:

	sdp8 (&iflag, tsince);
	break;
    }

    element.x = element.x * pcnsts.xkmper / pcnsts.ae;

    element.y = element.y * pcnsts.xkmper / pcnsts.ae;

    element.z = element.z * pcnsts.xkmper / pcnsts.ae;

    element.xdot = element.xdot * pcnsts.xkmper / pcnsts.ae *
	pcnsts.xmnpda / pcnsts.secpda;

    element.ydot = element.ydot * pcnsts.xkmper / pcnsts.ae *
	pcnsts.xmnpda / pcnsts.secpda;

    element.zdot = element.zdot * pcnsts.xkmper / pcnsts.ae *
	pcnsts.xmnpda / pcnsts.secpda;

    return;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.