📄 predict.c
字号:
/****************************************************************************
* PREDICT: A satellite tracking/orbital prediction program *
* Copyright John A. Magliacane, KD2BD 1991-2002 *
* Project started: 26-May-1991 *
* Ported from Linux to DOS: 28-Dec-1999 *
* Last update: 02-Nov-2002 *
*****************************************************************************
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License or any later *
* version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
*****************************************************************************/
#include <math.h>
#include <sys/time.h>
#include <curses.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <termios.h>
/* Constants used by SGP4/SDP4 code */
#define km2mi 0.621371 /* km to miles */
#define deg2rad 1.745329251994330E-2 /* Degrees to radians */
#define pi 3.14159265358979323846 /* Pi */
#define pio2 1.57079632679489656 /* Pi/2 */
#define x3pio2 4.71238898038468967 /* 3*Pi/2 */
#define twopi 6.28318530717958623 /* 2*Pi */
#define e6a 1.0E-6
#define tothrd 6.6666666666666666E-1 /* 2/3 */
#define xj2 1.0826158E-3 /* J2 Harmonic (WGS '72) */
#define xj3 -2.53881E-6 /* J3 Harmonic (WGS '72) */
#define xj4 -1.65597E-6 /* J4 Harmonic (WGS '72) */
#define xke 7.43669161E-2
#define xkmper 6.378137E3 /* WGS 84 Earth radius km */
#define xmnpda 1.44E3 /* Minutes per day */
#define ae 1.0
#define ck2 5.413079E-4
#define ck4 6.209887E-7
#define f 3.35281066474748E-3 /* Flattening factor */
#define ge 3.986008E5 /* Earth gravitational constant (WGS '72) */
#define s 1.012229
#define qoms2t 1.880279E-09
#define secday 8.6400E4 /* Seconds per day */
#define omega_E 1.00273790934 /* Earth rotations/siderial day */
#define omega_ER 6.3003879 /* Earth rotations, rads/siderial day */
#define zns 1.19459E-5
#define c1ss 2.9864797E-6
#define zes 1.675E-2
#define znl 1.5835218E-4
#define c1l 4.7968065E-7
#define zel 5.490E-2
#define zcosis 9.1744867E-1
#define zsinis 3.9785416E-1
#define zsings -9.8088458E-1
#define zcosgs 1.945905E-1
#define zcoshs 1
#define zsinhs 0
#define q22 1.7891679E-6
#define q31 2.1460748E-6
#define q33 2.2123015E-7
#define g22 5.7686396
#define g32 9.5240898E-1
#define g44 1.8014998
#define g52 1.0508330
#define g54 4.4108898
#define root22 1.7891679E-6
#define root32 3.7393792E-7
#define root44 7.3636953E-9
#define root52 1.1428639E-7
#define root54 2.1765803E-9
#define thdt 4.3752691E-3
#define rho 1.5696615E-1
#define mfactor 7.292115E-5
#define sr 6.96000E5 /* Solar radius - km (IAU 76) */
#define AU 1.49597870691E8 /* Astronomical unit - km (IAU 76) */
/* Entry points of Deep() */
#define dpinit 1 /* Deep-space initialization code */
#define dpsec 2 /* Deep-space secular code */
#define dpper 3 /* Deep-space periodic code */
/* Flow control flag definitions */
#define ALL_FLAGS -1
#define SGP_INITIALIZED_FLAG 0x000001 /* not used */
#define SGP4_INITIALIZED_FLAG 0x000002
#define SDP4_INITIALIZED_FLAG 0x000004
#define SGP8_INITIALIZED_FLAG 0x000008 /* not used */
#define SDP8_INITIALIZED_FLAG 0x000010 /* not used */
#define SIMPLE_FLAG 0x000020
#define DEEP_SPACE_EPHEM_FLAG 0x000040
#define LUNAR_TERMS_DONE_FLAG 0x000080
#define NEW_EPHEMERIS_FLAG 0x000100 /* not used */
#define DO_LOOP_FLAG 0x000200
#define RESONANCE_FLAG 0x000400
#define SYNCHRONOUS_FLAG 0x000800
#define EPOCH_RESTART_FLAG 0x001000
#define VISIBLE_FLAG 0x002000
#define SAT_ECLIPSED_FLAG 0x004000
/* Global Variables */
struct { char line1[70];
char line2[70];
char name[25];
long catnum;
long setnum;
char designator[10];
int year;
double refepoch;
double incl;
double raan;
double eccn;
double argper;
double meanan;
double meanmo;
double drag;
double nddot6;
double bstar;
long orbitnum;
} sat[24];
struct { char callsign[17];
double stnlat;
double stnlong;
int stnalt;
float utc_offset;
} qth;
struct { char name[25];
long catnum;
char squintflag;
double alat;
double alon;
unsigned char transponders;
char transponder_name[10][80];
double uplink_start[10];
double uplink_end[10];
double downlink_start[10];
double downlink_end[10];
unsigned char dayofweek[10];
int phase_start[10];
int phase_end[10];
} sat_db[24];
char qthfile[50], tlefile[50], temp[80], output[25],
serial_port[15], *version={"2.2.1"};
/* Global variables for sharing data among functions... */
double tsince, jul_epoch, jul_utc, eclipse_depth=0,
sat_azi, sat_ele, sat_range, sat_range_rate,
sat_lat, sat_lon, sat_alt, sat_vel, phase,
sun_azi, sun_ele, daynum, fm, fk, age, aostime,
lostime, ax, ay, az, rx, ry, rz, squint, alat, alon;
char qthfile[50], tlefile[50], dbfile[50], temp[80], output[25],
serial_port[15], resave=0, reload_tle=0, netport[6],
once_per_second=0, ephem[5], sat_sun_status, findsun,
calc_squint, database=0;
int indx, antfd, iaz, iel, ma256, isplat, isplong, socket_flag=0,
Flags=0;
long rv, irk;
unsigned char val[256];
/** Type definitions **/
/* Two-line-element satellite orbital data
structure used directly by the SGP4/SDP4 code. */
typedef struct {
double epoch, xndt2o, xndd6o, bstar, xincl,
xnodeo, eo, omegao, xmo, xno;
int catnr, elset, revnum;
char sat_name[25], idesg[9];
} tle_t;
/* Geodetic position structure used by SGP4/SDP4 code. */
typedef struct {
double lat, lon, alt, theta;
} geodetic_t;
/* General three-dimensional vector structure used by SGP4/SDP4 code. */
typedef struct {
double x, y, z, w;
} vector_t;
/* Common arguments between deep-space functions used by SGP4/SDP4 code. */
typedef struct {
/* Used by dpinit part of Deep() */
double eosq, sinio, cosio, betao, aodp, theta2,
sing, cosg, betao2, xmdot, omgdot, xnodot, xnodp;
/* Used by dpsec and dpper parts of Deep() */
double xll, omgadf, xnode, em, xinc, xn, t;
/* Used by thetg and Deep() */
double ds50;
} deep_arg_t;
/* Global structure used by SGP4/SDP4 code. */
geodetic_t obs_geodetic;
/* Two-line Orbital Elements for the satellite used by SGP4/SDP4 code. */
tle_t tle;
/* Functions for testing and setting/clearing flags used in SGP4/SDP4 code */
int isFlagSet(int flag)
{
return (Flags&flag);
}
int isFlagClear(int flag)
{
return (~Flags&flag);
}
void SetFlag(int flag)
{
Flags|=flag;
}
void ClearFlag(int flag)
{
Flags&=~flag;
}
/* Remaining SGP4/SDP4 code follows... */
int Sign(double arg)
{
/* Returns sign of a double */
if (arg>0)
return 1;
else if (arg<0)
return -1;
else
return 0;
}
double Sqr(double arg)
{
/* Returns square of a double */
return (arg*arg);
}
double Cube(double arg)
{
/* Returns cube of a double */
return (arg*arg*arg);
}
double Radians(double arg)
{
/* Returns angle in radians from argument in degrees */
return (arg*deg2rad);
}
double Degrees(double arg)
{
/* Returns angle in degrees from argument in radians */
return (arg/deg2rad);
}
double ArcSin(double arg)
{
/* Returns the arcsine of the argument */
if (fabs(arg)>=1.0)
return(Sign(arg)*pio2);
else
return(atan(arg/sqrt(1.0-arg*arg)));
}
double ArcCos(double arg)
{
/* Returns arccosine of argument */
return(pio2-ArcSin(arg));
}
void Magnitude(vector_t *v)
{
/* Calculates scalar magnitude of a vector_t argument */
v->w=sqrt(Sqr(v->x)+Sqr(v->y)+Sqr(v->z));
}
void Vec_Add(vector_t *v1, vector_t *v2, vector_t *v3)
{
/* Adds vectors v1 and v2 together to produce v3 */
v3->x=v1->x+v2->x;
v3->y=v1->y+v2->y;
v3->z=v1->z+v2->z;
Magnitude(v3);
}
void Vec_Sub(vector_t *v1, vector_t *v2, vector_t *v3)
{
/* Subtracts vector v2 from v1 to produce v3 */
v3->x=v1->x-v2->x;
v3->y=v1->y-v2->y;
v3->z=v1->z-v2->z;
Magnitude(v3);
}
void Scalar_Multiply(double k, vector_t *v1, vector_t *v2)
{
/* Multiplies the vector v1 by the scalar k to produce the vector v2 */
v2->x=k*v1->x;
v2->y=k*v1->y;
v2->z=k*v1->z;
v2->w=fabs(k)*v1->w;
}
void Scale_Vector(double k, vector_t *v)
{
/* Multiplies the vector v1 by the scalar k */
v->x*=k;
v->y*=k;
v->z*=k;
Magnitude(v);
}
double Dot(vector_t *v1, vector_t *v2)
{
/* Returns the dot product of two vectors */
return (v1->x*v2->x+v1->y*v2->y+v1->z*v2->z);
}
double Angle(vector_t *v1, vector_t *v2)
{
/* Calculates the angle between vectors v1 and v2 */
Magnitude(v1);
Magnitude(v2);
return(ArcCos(Dot(v1,v2)/(v1->w*v2->w)));
}
void Cross(vector_t *v1, vector_t *v2 ,vector_t *v3)
{
/* Produces cross product of v1 and v2, and returns in v3 */
v3->x=v1->y*v2->z-v1->z*v2->y;
v3->y=v1->z*v2->x-v1->x*v2->z;
v3->z=v1->x*v2->y-v1->y*v2->x;
Magnitude(v3);
}
void Normalize(vector_t *v)
{
/* Normalizes a vector */
v->x/=v->w;
v->y/=v->w;
v->z/=v->w;
}
double AcTan(double sinx, double cosx)
{
/* Four-quadrant arctan function */
if (cosx==0.0)
{
if (sinx>0.0)
return (pio2);
else
return (x3pio2);
}
else
{
if (cosx>0.0)
{
if (sinx>0.0)
return (atan(sinx/cosx));
else
return (twopi+atan(sinx/cosx));
}
else
return (pi+atan(sinx/cosx));
}
}
double FMod2p(double x)
{
/* Returns mod 2PI of argument */
int i;
double ret_val;
ret_val=x;
i=ret_val/twopi;
ret_val-=i*twopi;
if (ret_val<0.0)
ret_val+=twopi;
return ret_val;
}
double Modulus(double arg1, double arg2)
{
/* Returns arg1 mod arg2 */
int i;
double ret_val;
ret_val=arg1;
i=ret_val/arg2;
ret_val-=i*arg2;
if (ret_val<0.0)
ret_val+=arg2;
return ret_val;
}
double Frac(double arg)
{
/* Returns fractional part of double argument */
return(arg-floor(arg));
}
int Round(double arg)
{
/* Returns argument rounded up to nearest integer */
return((int)floor(arg+0.5));
}
double Int(double arg)
{
/* Returns the floor integer of a double arguement, as double */
return(floor(arg));
}
void Convert_Sat_State(vector_t *pos, vector_t *vel)
{
/* Converts the satellite's position and velocity */
/* vectors from normalized values to km and km/sec */
Scale_Vector(xkmper, pos);
Scale_Vector(xkmper*xmnpda/secday, vel);
}
double Julian_Date_of_Year(double year)
{
/* The function Julian_Date_of_Year calculates the Julian Date */
/* of Day 0.0 of {year}. This function is used to calculate the */
/* Julian Date of any date by using Julian_Date_of_Year, DOY, */
/* and Fraction_of_Day. */
/* Astronomical Formulae for Calculators, Jean Meeus, */
/* pages 23-25. Calculate Julian Date of 0.0 Jan year */
long A, B, i;
double jdoy;
year=year-1;
i=year/100;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -