/** \brief SGP4SDP4 driver for doing AOS/LOS calculations.
 *  \param sat Pointer to the satellite data.
 *  \param qth Pointer to the QTH data.
 *  \param t The time for calculation (Julian Date)
 *
 */
void
predict_calc (sat_t *sat, qth_t *qth, gdouble t)
{
    obs_set_t     obs_set;
    geodetic_t    sat_geodetic;
    geodetic_t    obs_geodetic;
    double        age;


    obs_geodetic.lon = qth->lon * de2ra;
    obs_geodetic.lat = qth->lat * de2ra;
    obs_geodetic.alt = qth->alt / 1000.0;
    obs_geodetic.theta = 0;

    sat->jul_utc = t;
    sat->tsince = (sat->jul_utc - sat->jul_epoch) * xmnpda;

    /* call the norad routines according to the deep-space flag */
    if (sat->flags & DEEP_SPACE_EPHEM_FLAG)
        SDP4 (sat, sat->tsince);
    else
        SGP4 (sat, sat->tsince);

    Convert_Sat_State (&sat->pos, &sat->vel);

    /* get the velocity of the satellite */
    Magnitude (&sat->vel);
    sat->velo = sat->vel.w;
    Calculate_Obs (sat->jul_utc, &sat->pos, &sat->vel, &obs_geodetic, &obs_set);
    Calculate_LatLonAlt (sat->jul_utc, &sat->pos, &sat_geodetic);

    while (sat_geodetic.lon < -pi)
        sat_geodetic.lon += twopi;

    while (sat_geodetic.lon > (pi))
        sat_geodetic.lon -= twopi;

    sat->az = Degrees (obs_set.az);
    sat->el = Degrees (obs_set.el);
    sat->range = obs_set.range;
    sat->range_rate = obs_set.range_rate;
    sat->ssplat = Degrees (sat_geodetic.lat);
    sat->ssplon = Degrees (sat_geodetic.lon);
    sat->alt = sat_geodetic.alt;
    sat->ma = Degrees (sat->phase);
    sat->ma *= 256.0/360.0;
    sat->phase = Degrees (sat->phase);

    /* same formulas, but the one from predict is nicer */
    //sat->footprint = 2.0 * xkmper * acos (xkmper/sat->pos.w);
    sat->footprint = 12756.33 * acos (xkmper / (xkmper+sat->alt));
    age = sat->jul_utc - sat->jul_epoch;
    sat->orbit = (long) floor((sat->tle.xno * xmnpda/twopi +
                    age * sat->tle.bstar * ae) * age +
                    sat->tle.xmo/twopi) + sat->tle.revnum - 1;
}
Exemple #2
0
/** \brief Calculate satellite visibility.
 *  \param sat The satellite structure.
 *  \param qth The QTH
 *  \param jul_utc The time at which the visibility should be calculated.
 *  \return The visiblity code.
 *
 */
sat_vis_t
get_sat_vis (sat_t *sat, qth_t *qth, gdouble jul_utc)
{
    gboolean sat_sun_status;
    gdouble  sun_el;
    gdouble  threshold;
    gdouble  eclipse_depth;
    sat_vis_t vis = SAT_VIS_NONE;
    vector_t zero_vector = {0,0,0,0};
    geodetic_t obs_geodetic;

    /* Solar ECI position vector  */
    vector_t solar_vector=zero_vector;

    /* Solar observed az and el vector  */
    obs_set_t solar_set;

    /* FIXME: could be passed as parameter */
    obs_geodetic.lon = qth->lon * de2ra;
    obs_geodetic.lat = qth->lat * de2ra;
    obs_geodetic.alt = qth->alt / 1000.0;
    obs_geodetic.theta = 0;


    Calculate_Solar_Position (jul_utc, &solar_vector);
    Calculate_Obs (jul_utc, &solar_vector, &zero_vector, &obs_geodetic, &solar_set);

    if (Sat_Eclipsed (&sat->pos, &solar_vector, &eclipse_depth)) {
        /* satellite is eclipsed */
        sat_sun_status = FALSE;
    }
    else {
        /* satellite in sunlight => may be visible */
        sat_sun_status = TRUE;
    }


    if (sat_sun_status) {
        sun_el = Degrees (solar_set.el);
        /* FIXME */
        /* threshold = (gdouble) sat_cfg_get_int (SAT_CFG_INT_PRED_TWILIGHT_THLD); */
        threshold = (gdouble) -6;
        
        if (sun_el <= threshold && sat->el >= 0.0)
            vis = SAT_VIS_VISIBLE;
        else
            vis = SAT_VIS_DAYLIGHT;
    }
    else
        vis = SAT_VIS_ECLIPSED;


    return vis;
}
Exemple #3
0
void
Calculate_RADec_and_Obs ( double _time,
			  vector_t *pos,
			  vector_t *vel,
			  geodetic_t *geodetic,
			  obs_astro_t *obs_set)
{
/* Reference:  Methods of Orbit Determination by  */
/*                Pedro Ramon Escobal, pp. 401-402 */

	double phi,theta,sin_theta,cos_theta,sin_phi,cos_phi,
		az,el,Lxh,Lyh,Lzh,Sx,Ex,Zx,Sy,Ey,Zy,Sz,Ez,Zz,
		Lx,Ly,Lz,cos_delta,sin_alpha,cos_alpha;

	obs_set_t obs;

	Calculate_Obs(_time,pos,vel,geodetic,&obs);

/*  if( isFlagSet(VISIBLE_FLAG) )
    {*/
	az = obs.az;
	el = obs.el;
	phi   = geodetic->lat;
	theta = FMod2p(ThetaG_JD(_time) + geodetic->lon);
	sin_theta = sin(theta);
	cos_theta = cos(theta);
	sin_phi = sin(phi);
	cos_phi = cos(phi);
	Lxh = -cos(az) * cos(el);
	Lyh =  sin(az) * cos(el);
	Lzh =  sin(el);
	Sx = sin_phi * cos_theta;
	Ex = -sin_theta;
	Zx = cos_theta * cos_phi;
	Sy = sin_phi * sin_theta;
	Ey = cos_theta;
	Zy = sin_theta*cos_phi;
	Sz = -cos_phi;
	Ez = 0;
	Zz = sin_phi;
	Lx = Sx*Lxh + Ex * Lyh + Zx*Lzh;
	Ly = Sy*Lxh + Ey * Lyh + Zy*Lzh;
	Lz = Sz*Lxh + Ez * Lyh + Zz*Lzh;
	obs_set->dec = ArcSin(Lz);  /* Declination (radians)*/
	cos_delta = sqrt(1 - Sqr(Lz));
	sin_alpha = Ly / cos_delta;
	cos_alpha = Lx / cos_delta;
	obs_set->ra = AcTan(sin_alpha,cos_alpha); /* Right Ascension (radians)*/
	obs_set->ra = FMod2p(obs_set->ra);
	/*}*/  /*if*/
} /* Procedure Calculate_RADec */
Exemple #4
0
void Calculate_RADec(double time, const double pos[3], const double vel[3], geodetic_t *geodetic, vector_t *obs_set)
{
	/* Reference:  Methods of Orbit Determination by  */
	/*             Pedro Ramon Escobal, pp. 401-402   */

	double	phi, theta, sin_theta, cos_theta, sin_phi, cos_phi, az, el,
		Lxh, Lyh, Lzh, Sx, Ex, Zx, Sy, Ey, Zy, Sz, Ez, Zz, Lx, Ly,
		Lz, cos_delta, sin_alpha, cos_alpha;

	Calculate_Obs(time,pos,vel,geodetic,obs_set);

	az=obs_set->x;
	el=obs_set->y;
	phi=geodetic->lat;
	theta=FMod2p(ThetaG_JD(time)+geodetic->lon);
	sin_theta=sin(theta);
	cos_theta=cos(theta);
	sin_phi=sin(phi);
	cos_phi=cos(phi);
	Lxh=-cos(az)*cos(el);
	Lyh=sin(az)*cos(el);
	Lzh=sin(el);
	Sx=sin_phi*cos_theta;
	Ex=-sin_theta;
	Zx=cos_theta*cos_phi;
	Sy=sin_phi*sin_theta;
	Ey=cos_theta;
	Zy=sin_theta*cos_phi;
	Sz=-cos_phi;
	Ez=0.0;
	Zz=sin_phi;
	Lx=Sx*Lxh+Ex*Lyh+Zx*Lzh;
	Ly=Sy*Lxh+Ey*Lyh+Zy*Lzh;
	Lz=Sz*Lxh+Ez*Lyh+Zz*Lzh;
	obs_set->y=ArcSin(Lz);  /* Declination (radians) */
	cos_delta=sqrt(1.0-Sqr(Lz));
	sin_alpha=Ly/cos_delta;
	cos_alpha=Lx/cos_delta;
	obs_set->x=AcTan(sin_alpha,cos_alpha); /* Right Ascension (radians) */
	obs_set->x=FMod2p(obs_set->x);
}
Exemple #5
0
/** \brief Initialise satellite data.
 *  \param sat The satellite to initialise.
 *  \param qth Optional QTH info, use (0,0) if NULL.
 *
 * This function calculates the satellite data at t = 0, ie. epoch time
 * The function is called automatically by gtk_sat_data_read_sat.
 */
void
gtk_sat_data_init_sat (sat_t *sat, qth_t *qth)
{
    geodetic_t obs_geodetic;
    obs_set_t obs_set;
    geodetic_t sat_geodetic;
    double jul_utc, age;

    g_return_if_fail (sat != NULL);

    jul_utc = Julian_Date_of_Epoch (sat->tle.epoch); // => tsince = 0.0
    sat->jul_epoch = jul_utc;

    /* initialise observer location */
    if (qth != NULL) {
        obs_geodetic.lon = qth->lon * de2ra;
        obs_geodetic.lat = qth->lat * de2ra;
        obs_geodetic.alt = qth->alt / 1000.0;
        obs_geodetic.theta = 0;
    }
    else {
        obs_geodetic.lon = 0.0;
        obs_geodetic.lat = 0.0;
        obs_geodetic.alt = 0.0;
        obs_geodetic.theta = 0;
    }

    /* execute computations */
    if (sat->flags & DEEP_SPACE_EPHEM_FLAG)
        SDP4 (sat, 0.0);
    else
        SGP4 (sat, 0.0);

    /* scale position and velocity to km and km/sec */
    Convert_Sat_State (&sat->pos, &sat->vel);

    /* get the velocity of the satellite */
    Magnitude (&sat->vel);
    sat->velo = sat->vel.w;
    Calculate_Obs (jul_utc, &sat->pos, &sat->vel, &obs_geodetic, &obs_set);
    Calculate_LatLonAlt (jul_utc, &sat->pos, &sat_geodetic);

    while (sat_geodetic.lon < -pi)
        sat_geodetic.lon += twopi;
    
    while (sat_geodetic.lon > (pi))
        sat_geodetic.lon -= twopi;

    sat->az = Degrees (obs_set.az);
    sat->el = Degrees (obs_set.el);
    sat->range = obs_set.range;
    sat->range_rate = obs_set.range_rate;
    sat->ssplat = Degrees (sat_geodetic.lat);
    sat->ssplon = Degrees (sat_geodetic.lon);
    sat->alt = sat_geodetic.alt;
    sat->ma = Degrees (sat->phase);
    sat->ma *= 256.0/360.0;
    sat->footprint = 2.0 * xkmper * acos (xkmper/sat->pos.w);
    age = 0.0;
    sat->orbit = (long) floor((sat->tle.xno * xmnpda/twopi +
                               age * sat->tle.bstar * ae) * age +
                              sat->tle.xmo/twopi) + sat->tle.revnum - 1;

    /* orbit type */
    sat->otype = get_orbit_type (sat);
}
Exemple #6
0
/* Main program */
  int
main(void)
{
  /* TLE source file */
  char tle_file[] = "./rax.txt";

  /* Observer's geodetic co-ordinates.      */
  /* Lat North, Lon East in rads, Alt in km */
  geodetic_t obs_geodetic = {0.7368, -1.4615, 0.251, 0.0};

  /* Two-line Orbital Elements for the satellite */
  tle_t tle ;

  /* Zero vector for initializations */
  vector_t zero_vector = {0,0,0,0};

  /* Satellite position and velocity vectors */
  vector_t vel = zero_vector;
  vector_t pos = zero_vector;
  /* Satellite Az, El, Range, Range rate */
  vector_t obs_set;

  /* Solar ECI position vector  */
  vector_t solar_vector = zero_vector;
  /* Solar observed azi and ele vector  */
  vector_t solar_set;

  /* Calendar date and time (UTC) */
  struct tm utc;

  /* Satellite's predicted geodetic position */
  geodetic_t sat_geodetic;

  double
	tsince,            /* Time since epoch (in minutes) */
	jul_epoch,         /* Julian date of epoch          */
	jul_utc,           /* Julian UTC date               */
	eclipse_depth = 0, /* Depth of satellite eclipse    */
	/* Satellite's observed position, range, range rate */
	sat_azi, sat_ele, sat_range, sat_range_rate,
	/* Satellites geodetic position and velocity */
	sat_lat, sat_lon, sat_alt, sat_vel,
	/* Solar azimuth and elevation */
	sun_azi, sun_ele;

  /* Used for storing function return codes */
  int flg;

  char
	ephem[5],       /* Ephemeris in use string  */
	sat_status[12]; /* Satellite eclipse status */


  /* Input one (first!) TLE set from file */
  flg = Input_Tle_Set(tle_file, &tle);

  /* Abort if file open fails */
  if( flg == -1 )
  {
	printf(" File open failed - Exiting!\n");
	exit(-1);
  }

  /* Print satellite name and TLE read status */
  printf(" %s: ", tle.sat_name);
  if( flg == -2 )
  {
	printf("TLE set bad - Exiting!\n");
	exit(-2);
  }
  else
	printf("TLE set good - Happy Tracking!\n");

  /* Printout of tle set data for tests if needed */
  /*  printf("\n %s %s %i  %i  %i\n"
	  " %14f %10f %8f %8f\n"
	  " %8f %8f %9f %8f %8f %12f\n",
	  tle.sat_name, tle.idesg, tle.catnr, tle.elset, tle.revnum,
	  tle.epoch, tle.xndt2o, tle.xndd6o, tle.bstar,
	  tle.xincl, tle.xnodeo, tle.eo, tle.omegao, tle.xmo, tle.xno);
   */

  /** !Clear all flags! **/
  /* Before calling a different ephemeris  */
  /* or changing the TLE set, flow control */
  /* flags must be cleared in main().      */
  ClearFlag(ALL_FLAGS);

  /** Select ephemeris type **/
  /* Will set or clear the DEEP_SPACE_EPHEM_FLAG       */
  /* depending on the TLE parameters of the satellite. */
  /* It will also pre-process tle members for the      */
  /* ephemeris functions SGP4 or SDP4 so this function */
  /* must be called each time a new tle set is used    */
  select_ephemeris(&tle);

  do  /* Loop */
  {
	/* Get UTC calendar and convert to Julian */
	UTC_Calendar_Now(&utc);
	jul_utc = Julian_Date(&utc);

	/* Convert satellite's epoch time to Julian  */
	/* and calculate time since epoch in minutes */
	jul_epoch = Julian_Date_of_Epoch(tle.epoch);
	tsince = (jul_utc - jul_epoch) * xmnpda;

	/* Copy the ephemeris type in use to ephem string */
	if( isFlagSet(DEEP_SPACE_EPHEM_FLAG) )
	  strcpy(ephem,"SDP4");
	else
	  strcpy(ephem,"SGP4");

	/* Call NORAD routines according to deep-space flag */
	if( isFlagSet(DEEP_SPACE_EPHEM_FLAG) )
	  SDP4(tsince, &tle, &pos, &vel);
	else
	  SGP4(tsince, &tle, &pos, &vel);

	/* Scale position and velocity vectors to km and km/sec */
	Convert_Sat_State( &pos, &vel );

	/* Calculate velocity of satellite */
	Magnitude( &vel );
	sat_vel = vel.w;

	/** All angles in rads. Distance in km. Velocity in km/s **/
	/* Calculate satellite Azi, Ele, Range and Range-rate */
	Calculate_Obs(jul_utc, &pos, &vel, &obs_geodetic, &obs_set);

	/* Calculate satellite Lat North, Lon East and Alt. */
	Calculate_LatLonAlt(jul_utc, &pos, &sat_geodetic);

	/* Calculate solar position and satellite eclipse depth */
	/* Also set or clear the satellite eclipsed flag accordingly */
	Calculate_Solar_Position(jul_utc, &solar_vector);
	Calculate_Obs(jul_utc,&solar_vector,&zero_vector,&obs_geodetic,&solar_set);

	if( Sat_Eclipsed(&pos, &solar_vector, &eclipse_depth) )
	  SetFlag( SAT_ECLIPSED_FLAG );
	else
	  ClearFlag( SAT_ECLIPSED_FLAG );

	/* Copy a satellite eclipse status string in sat_status */
	if( isFlagSet( SAT_ECLIPSED_FLAG ) )
	  strcpy( sat_status, "Eclipsed" );
	else
	  strcpy( sat_status, "In Sunlight" );

	/* Convert and print satellite and solar data */
	sat_azi = Degrees(obs_set.x);
	sat_ele = Degrees(obs_set.y);
	sat_range = obs_set.z;
	sat_range_rate = obs_set.w;
	sat_lat = Degrees(sat_geodetic.lat);
	sat_lon = Degrees(sat_geodetic.lon);
	sat_alt = sat_geodetic.alt;

	sun_azi = Degrees(solar_set.x);
	sun_ele = Degrees(solar_set.y);

	printf("\n Date: %02d/%02d/%04d UTC: %02d:%02d:%02d  Ephemeris: %s"
		"\n Azi=%6.1f Ele=%6.1f Range=%8.1f Range Rate=%6.2f"
		"\n Lat=%6.1f Lon=%6.1f  Alt=%8.1f  Vel=%8.3f"
		"\n Stellite Status: %s - Depth: %2.3f"
		"\n Sun Azi=%6.1f Sun Ele=%6.1f\n",
		utc.tm_mday, utc.tm_mon, utc.tm_year,
		utc.tm_hour, utc.tm_min, utc.tm_sec, ephem,
		sat_azi, sat_ele, sat_range, sat_range_rate,
		sat_lat, sat_lon, sat_alt, sat_vel,
		sat_status, eclipse_depth,
		sun_azi, sun_ele);

	sleep(1);
  }  /* End of do */
  while( 1 ); /* This stops Compaq ccc 'unreachcode' warning! */

  return(0);
} /* End of main() */