1
0
Fork 0

Format sattools C code with GNU indent...

giza-pure
Jeff Moe 2022-08-06 22:23:15 -06:00
parent db0415128c
commit 556aa1cca3
60 changed files with 21375 additions and 18006 deletions

File diff suppressed because it is too large Load Diff

View File

@ -11,383 +11,439 @@
#define R2D 180.0/M_PI
#define XKMPAU 149597879.691 // AU in km
struct map {
struct map
{
int site_id;
double mjd;
float saltmin,alt;
char nfd[LIM],observer[32],datadir[LIM];
double lat,lng;
float saltmin, alt;
char nfd[LIM], observer[32], datadir[LIM];
double lat, lng;
float length;
} m;
void allnight(void);
void sunpos_xyz(double,xyz_t *,double *,double *);
double modulo(double,double);
void equatorial2horizontal(double,double,double,double *,double *);
void mjd2date(double mjd,char *date);
double gmst(double mjd);
void nfd_now(char *s);
double nfd2mjd(char *date);
void get_site(int site_id);
double date2mjd(int year,int month,double day);
void usage(void);
void allnight (void);
void sunpos_xyz (double, xyz_t *, double *, double *);
double modulo (double, double);
void equatorial2horizontal (double, double, double, double *, double *);
void mjd2date (double mjd, char *date);
double gmst (double mjd);
void nfd_now (char *s);
double nfd2mjd (char *date);
void get_site (int site_id);
double date2mjd (int year, int month, double day);
void usage (void);
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int arg=0;
int arg = 0;
char *env;
// Default settings
strcpy(m.observer,"Unknown");
m.site_id=0;
m.mjd=-1.0;
m.saltmin=-6.0;
m.alt=0.0;
m.lat=0.0;
m.lng=0.0;
strcpy (m.observer, "Unknown");
m.site_id = 0;
m.mjd = -1.0;
m.saltmin = -6.0;
m.alt = 0.0;
m.lat = 0.0;
m.lng = 0.0;
// Get default site
env=getenv("ST_DATADIR");
if (env!=NULL) {
strcpy(m.datadir,env);
} else {
printf("ST_DATADIR environment variable not found.\n");
env = getenv ("ST_DATADIR");
if (env != NULL)
{
strcpy (m.datadir, env);
}
env=getenv("ST_COSPAR");
if (env!=NULL) {
get_site(atoi(env));
} else {
printf("ST_COSPAR environment variable not found.\n");
else
{
printf ("ST_DATADIR environment variable not found.\n");
}
env = getenv ("ST_COSPAR");
if (env != NULL)
{
get_site (atoi (env));
}
else
{
printf ("ST_COSPAR environment variable not found.\n");
}
// Get current time
nfd_now(m.nfd);
m.mjd=nfd2mjd(m.nfd);
nfd_now (m.nfd);
m.mjd = nfd2mjd (m.nfd);
// Decode options
while ((arg=getopt(argc,argv,"t:s:S:h"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "t:s:S:h")) != -1)
{
switch (arg)
{
case 't':
strcpy(m.nfd,optarg);
m.mjd=nfd2mjd(m.nfd);
strcpy (m.nfd, optarg);
m.mjd = nfd2mjd (m.nfd);
break;
case 'S':
m.saltmin=atof(optarg);
m.saltmin = atof (optarg);
break;
case 's':
get_site(atoi(optarg));
get_site (atoi (optarg));
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
// Compute set/rise times of sun
allnight();
allnight ();
return 0;
}
// Usage
void usage(void)
void
usage (void)
{
printf("allnight t:s:S:\n\n");
printf("t date/time (yyyy-mm-ddThh:mm:ss.sss) [default: now]\n");
printf("S Minimum sun altitude\n");
printf("s site (COSPAR)\n");
printf ("allnight t:s:S:\n\n");
printf ("t date/time (yyyy-mm-ddThh:mm:ss.sss) [default: now]\n");
printf ("S Minimum sun altitude\n");
printf ("s site (COSPAR)\n");
return;
}
// Convert equatorial into horizontal coordinates
void equatorial2horizontal(double mjd,double ra,double de,double *azi,double *alt)
void
equatorial2horizontal (double mjd, double ra, double de, double *azi,
double *alt)
{
double h;
h=gmst(mjd)+m.lng-ra;
h = gmst (mjd) + m.lng - ra;
*azi=modulo(atan2(sin(h*D2R),cos(h*D2R)*sin(m.lat*D2R)-tan(de*D2R)*cos(m.lat*D2R))*R2D,360.0);
*alt=asin(sin(m.lat*D2R)*sin(de*D2R)+cos(m.lat*D2R)*cos(de*D2R)*cos(h*D2R))*R2D;
*azi =
modulo (atan2
(sin (h * D2R),
cos (h * D2R) * sin (m.lat * D2R) -
tan (de * D2R) * cos (m.lat * D2R)) * R2D, 360.0);
*alt =
asin (sin (m.lat * D2R) * sin (de * D2R) +
cos (m.lat * D2R) * cos (de * D2R) * cos (h * D2R)) * R2D;
return;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Solar position
void sunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de)
void
sunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de)
{
double jd,t,l0,m,e,c,r;
double n,s,ecl;
double jd, t, l0, m, e, c, r;
double n, s, ecl;
jd=mjd+2400000.5;
t=(jd-2451545.0)/36525.0;
l0=modulo(280.46646+t*(36000.76983+t*0.0003032),360.0)*D2R;
m=modulo(357.52911+t*(35999.05029-t*0.0001537),360.0)*D2R;
e=0.016708634+t*(-0.000042037-t*0.0000001267);
c=(1.914602+t*(-0.004817-t*0.000014))*sin(m)*D2R;
c+=(0.019993-0.000101*t)*sin(2.0*m)*D2R;
c+=0.000289*sin(3.0*m)*D2R;
jd = mjd + 2400000.5;
t = (jd - 2451545.0) / 36525.0;
l0 = modulo (280.46646 + t * (36000.76983 + t * 0.0003032), 360.0) * D2R;
m = modulo (357.52911 + t * (35999.05029 - t * 0.0001537), 360.0) * D2R;
e = 0.016708634 + t * (-0.000042037 - t * 0.0000001267);
c = (1.914602 + t * (-0.004817 - t * 0.000014)) * sin (m) * D2R;
c += (0.019993 - 0.000101 * t) * sin (2.0 * m) * D2R;
c += 0.000289 * sin (3.0 * m) * D2R;
r=1.000001018*(1.0-e*e)/(1.0+e*cos(m+c));
n=modulo(125.04-1934.136*t,360.0)*D2R;
s=l0+c+(-0.00569-0.00478*sin(n))*D2R;
ecl=(23.43929111+(-46.8150*t-0.00059*t*t+0.001813*t*t*t)/3600.0+0.00256*cos(n))*D2R;
r = 1.000001018 * (1.0 - e * e) / (1.0 + e * cos (m + c));
n = modulo (125.04 - 1934.136 * t, 360.0) * D2R;
s = l0 + c + (-0.00569 - 0.00478 * sin (n)) * D2R;
ecl =
(23.43929111 +
(-46.8150 * t - 0.00059 * t * t + 0.001813 * t * t * t) / 3600.0 +
0.00256 * cos (n)) * D2R;
*ra=atan2(cos(ecl)*sin(s),cos(s))*R2D;
*de=asin(sin(ecl)*sin(s))*R2D;
*ra = atan2 (cos (ecl) * sin (s), cos (s)) * R2D;
*de = asin (sin (ecl) * sin (s)) * R2D;
pos->x=r*cos(*de*D2R)*cos(*ra*D2R)*XKMPAU;
pos->y=r*cos(*de*D2R)*sin(*ra*D2R)*XKMPAU;
pos->z=r*sin(*de*D2R)*XKMPAU;
pos->x = r * cos (*de * D2R) * cos (*ra * D2R) * XKMPAU;
pos->y = r * cos (*de * D2R) * sin (*ra * D2R) * XKMPAU;
pos->z = r * sin (*de * D2R) * XKMPAU;
return;
}
void allnight(void)
void
allnight (void)
{
int flag;
xyz_t sunpos;
double ra,de,azi,alt,alt0;
double mjd,mjdrise=-1.0,mjdset=-1.0;
double ra, de, azi, alt, alt0;
double mjd, mjdrise = -1.0, mjdset = -1.0;
char nfd[32];
// Find solar altitude at reference time
sunpos_xyz(m.mjd,&sunpos,&ra,&de);
equatorial2horizontal(m.mjd,ra,de,&azi,&alt);
sunpos_xyz (m.mjd, &sunpos, &ra, &de);
equatorial2horizontal (m.mjd, ra, de, &azi, &alt);
// Sun below limit, find rise, then set
if (alt<m.saltmin) {
for (flag=0,mjd=m.mjd;mjd<m.mjd+0.5;mjd+=1.0/86400) {
sunpos_xyz(mjd,&sunpos,&ra,&de);
equatorial2horizontal(mjd,ra,de,&azi,&alt);
if (alt < m.saltmin)
{
for (flag = 0, mjd = m.mjd; mjd < m.mjd + 0.5; mjd += 1.0 / 86400)
{
sunpos_xyz (mjd, &sunpos, &ra, &de);
equatorial2horizontal (mjd, ra, de, &azi, &alt);
if (flag!=0) {
if (alt>m.saltmin && alt0<=m.saltmin)
mjdrise=mjd;
if (flag != 0)
{
if (alt > m.saltmin && alt0 <= m.saltmin)
mjdrise = mjd;
}
if (flag==0)
flag=1;
if (flag == 0)
flag = 1;
alt0=alt;
alt0 = alt;
}
for (flag=0,mjd=m.mjd-0.5;mjd<m.mjd;mjd+=1.0/86400) {
sunpos_xyz(mjd,&sunpos,&ra,&de);
equatorial2horizontal(mjd,ra,de,&azi,&alt);
for (flag = 0, mjd = m.mjd - 0.5; mjd < m.mjd; mjd += 1.0 / 86400)
{
sunpos_xyz (mjd, &sunpos, &ra, &de);
equatorial2horizontal (mjd, ra, de, &azi, &alt);
if (flag!=0) {
if (alt<m.saltmin && alt0>=m.saltmin)
mjdset=mjd;
if (flag != 0)
{
if (alt < m.saltmin && alt0 >= m.saltmin)
mjdset = mjd;
}
if (flag==0)
flag=1;
if (flag == 0)
flag = 1;
alt0=alt;
alt0 = alt;
}
// Sun above limit, find set, and rise
} else {
for (flag=0,mjd=m.mjd;mjd<m.mjd+1.0;mjd+=1.0/86400) {
sunpos_xyz(mjd,&sunpos,&ra,&de);
equatorial2horizontal(mjd,ra,de,&azi,&alt);
}
else
{
for (flag = 0, mjd = m.mjd; mjd < m.mjd + 1.0; mjd += 1.0 / 86400)
{
sunpos_xyz (mjd, &sunpos, &ra, &de);
equatorial2horizontal (mjd, ra, de, &azi, &alt);
if (flag!=0) {
if (alt>m.saltmin && alt0<=m.saltmin)
mjdrise=mjd;
if (alt<m.saltmin && alt0>=m.saltmin)
mjdset=mjd;
if (flag != 0)
{
if (alt > m.saltmin && alt0 <= m.saltmin)
mjdrise = mjd;
if (alt < m.saltmin && alt0 >= m.saltmin)
mjdset = mjd;
}
if (flag==0)
flag=1;
if (flag == 0)
flag = 1;
alt0=alt;
alt0 = alt;
}
}
m.mjd=mjdset;
mjd2date(m.mjd,m.nfd);
mjd2date(mjdrise,nfd);
printf("%s %s\n",m.nfd,nfd);
m.mjd = mjdset;
mjd2date (m.mjd, m.nfd);
mjd2date (mjdrise, nfd);
printf ("%s %s\n", m.nfd, nfd);
return;
}
// Compute Date from Julian Day
void mjd2date(double mjd,char *date)
void
mjd2date (double mjd, char *date)
{
double f,jd,dday;
int z,alpha,a,b,c,d,e;
int year,month,day,hour,min;
float sec,x;
double f, jd, dday;
int z, alpha, a, b, c, d, e;
int year, month, day, hour, min;
float sec, x;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
dday=b-d-floor(30.6001*e)+f;
if (e<14)
month=e-1;
dday = b - d - floor (30.6001 * e) + f;
if (e < 14)
month = e - 1;
else
month=e-13;
month = e - 13;
if (month>2)
year=c-4716;
if (month > 2)
year = c - 4716;
else
year=c-4715;
year = c - 4715;
day=(int) floor(dday);
x=24.0*(dday-day);
x=3600.*fabs(x)+0.0001;
sec=fmod(x,60.);
x=(x-sec)/60.;
min=fmod(x,60.);
x=(x-min)/60.;
hour=x;
sec=floor(1000.0*sec)/1000.0;
day = (int) floor (dday);
x = 24.0 * (dday - day);
x = 3600. * fabs (x) + 0.0001;
sec = fmod (x, 60.);
x = (x - sec) / 60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
hour = x;
sec = floor (1000.0 * sec) / 1000.0;
sprintf(date,"%04d-%02d-%02dT%02d:%02d:%02.0f",year,month,day,hour,min,sec);
sprintf (date, "%04d-%02d-%02dT%02d:%02d:%02.0f", year, month, day, hour,
min, sec);
return;
}
// Greenwich Mean Sidereal Time
double gmst(double mjd)
double
gmst (double mjd)
{
double t,gmst;
double t, gmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0);
gmst =
modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) +
t * t * (0.000387933 - t / 38710000), 360.0);
return gmst;
}
// Present nfd
void nfd_now(char *s)
void
nfd_now (char *s)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
time(&rawtime);
ptm=gmtime(&rawtime);
time (&rawtime);
ptm = gmtime (&rawtime);
sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900,
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
ptm->tm_sec);
return;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// Get observing site
void get_site(int site_id)
void
get_site (int site_id)
{
int i=0;
int i = 0;
char line[LIM];
FILE *file;
int id;
double lat,lng;
double lat, lng;
float alt;
char abbrev[3],observer[64],filename[LIM];
char abbrev[3], observer[64], filename[LIM];
sprintf(filename,"%s/data/sites.txt",m.datadir);
file=fopen(filename,"r");
if (file==NULL) {
printf("File with site information not found!\n");
sprintf (filename, "%s/data/sites.txt", m.datadir);
file = fopen (filename, "r");
if (file == NULL)
{
printf ("File with site information not found!\n");
return;
}
while (fgets(line,LIM,file)!=NULL) {
while (fgets (line, LIM, file) != NULL)
{
// Skip
if (strstr(line,"#")!=NULL)
if (strstr (line, "#") != NULL)
continue;
// Strip newline
line[strlen(line)-1]='\0';
line[strlen (line) - 1] = '\0';
// Read data
sscanf(line,"%4d %2s %lf %lf %f",
&id,abbrev,&lat,&lng,&alt);
strcpy(observer,line+38);
sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt);
strcpy (observer, line + 38);
// Change to km
alt/=1000.0;
alt /= 1000.0;
if (id==site_id) {
m.lat=lat;
m.lng=lng;
m.alt=alt;
m.site_id=id;
strcpy(m.observer,observer);
if (id == site_id)
{
m.lat = lat;
m.lng = lng;
m.alt = alt;
m.site_id = id;
strcpy (m.observer, observer);
}
}
fclose(file);
fclose (file);
return;
}

View File

@ -6,159 +6,181 @@
#define LIM 80
void dec2s(double,char *,int,int);
double s2dec(char *);
void reverse(double,double,double,double,double *,double *);
void forward(double,double,double,double,double *,double *);
void dec2s (double, char *, int, int);
double s2dec (char *);
void reverse (double, double, double, double, double *, double *);
void forward (double, double, double, double, double *, double *);
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int i;
double ra1,de1,ra2,de2;
double rx,ry;
char sra[15],sde[15];
double ra1, de1, ra2, de2;
double rx, ry;
char sra[15], sde[15];
if (argc==1) {
printf("Usage: %s <ra1> <de1> <ra2> <de2>\n",argv[0]);
printf(" Computes angular offset\n");
printf("Usage: %s -d <ra1> <de1> <dra> <dde>\n",argv[0]);
printf(" Applies angular offset\n");
printf("Usage: %s -x <ra1> <de1> <ra2> <de2>\n",argv[0]);
printf(" Computes x-offset only\n");
printf("Usage: %s -y <ra1> <de1> <ra2> <de2>\n",argv[0]);
printf(" Computes y-offset only\n");
if (argc == 1)
{
printf ("Usage: %s <ra1> <de1> <ra2> <de2>\n", argv[0]);
printf (" Computes angular offset\n");
printf ("Usage: %s -d <ra1> <de1> <dra> <dde>\n", argv[0]);
printf (" Applies angular offset\n");
printf ("Usage: %s -x <ra1> <de1> <ra2> <de2>\n", argv[0]);
printf (" Computes x-offset only\n");
printf ("Usage: %s -y <ra1> <de1> <ra2> <de2>\n", argv[0]);
printf (" Computes y-offset only\n");
return -1;
}
if (strcmp(argv[1],"-d")==0) {
if (strchr(argv[2],':')!=NULL)
ra1=15.*s2dec(argv[2]);
if (strcmp (argv[1], "-d") == 0)
{
if (strchr (argv[2], ':') != NULL)
ra1 = 15. * s2dec (argv[2]);
else
ra1=atof(argv[2]);
if (strchr(argv[3],':')!=NULL)
de1=s2dec(argv[3]);
ra1 = atof (argv[2]);
if (strchr (argv[3], ':') != NULL)
de1 = s2dec (argv[3]);
else
de1=atof(argv[3]);
de1 = atof (argv[3]);
rx=(double) atof(argv[4]);
ry=(double) atof(argv[5]);
rx = (double) atof (argv[4]);
ry = (double) atof (argv[5]);
reverse(ra1,de1,rx,ry,&ra2,&de2);
reverse (ra1, de1, rx, ry, &ra2, &de2);
dec2s(ra2/15.0,sra,0,7);
dec2s(de2,sde,0,6);
dec2s (ra2 / 15.0, sra, 0, 7);
dec2s (de2, sde, 0, 6);
printf("%s %s\n",sra,sde);
} else if (strcmp(argv[1],"-x")==0) {
if (strchr(argv[2],':')!=NULL)
ra1=15.*s2dec(argv[2]);
printf ("%s %s\n", sra, sde);
}
else if (strcmp (argv[1], "-x") == 0)
{
if (strchr (argv[2], ':') != NULL)
ra1 = 15. * s2dec (argv[2]);
else
ra1=atof(argv[2]);
if (strchr(argv[3],':')!=NULL)
de1=s2dec(argv[3]);
ra1 = atof (argv[2]);
if (strchr (argv[3], ':') != NULL)
de1 = s2dec (argv[3]);
else
de1=atof(argv[3]);
if (strchr(argv[4],':')!=NULL)
ra2=15.*s2dec(argv[4]);
de1 = atof (argv[3]);
if (strchr (argv[4], ':') != NULL)
ra2 = 15. * s2dec (argv[4]);
else
ra2=atof(argv[4]);
if (strchr(argv[5],':')!=NULL)
de2=s2dec(argv[5]);
ra2 = atof (argv[4]);
if (strchr (argv[5], ':') != NULL)
de2 = s2dec (argv[5]);
else
de2=atof(argv[5]);
de2 = atof (argv[5]);
forward(ra1,de1,ra2,de2,&rx,&ry);
forward (ra1, de1, ra2, de2, &rx, &ry);
printf("%8.3f\n",rx);
} else if (strcmp(argv[1],"-y")==0) {
if (strchr(argv[2],':')!=NULL)
ra1=15.*s2dec(argv[2]);
printf ("%8.3f\n", rx);
}
else if (strcmp (argv[1], "-y") == 0)
{
if (strchr (argv[2], ':') != NULL)
ra1 = 15. * s2dec (argv[2]);
else
ra1=atof(argv[2]);
if (strchr(argv[3],':')!=NULL)
de1=s2dec(argv[3]);
ra1 = atof (argv[2]);
if (strchr (argv[3], ':') != NULL)
de1 = s2dec (argv[3]);
else
de1=atof(argv[3]);
if (strchr(argv[4],':')!=NULL)
ra2=15.*s2dec(argv[4]);
de1 = atof (argv[3]);
if (strchr (argv[4], ':') != NULL)
ra2 = 15. * s2dec (argv[4]);
else
ra2=atof(argv[4]);
if (strchr(argv[5],':')!=NULL)
de2=s2dec(argv[5]);
ra2 = atof (argv[4]);
if (strchr (argv[5], ':') != NULL)
de2 = s2dec (argv[5]);
else
de2=atof(argv[5]);
de2 = atof (argv[5]);
forward(ra1,de1,ra2,de2,&rx,&ry);
forward (ra1, de1, ra2, de2, &rx, &ry);
printf("%8.3f\n",ry);
} else {
if (strchr(argv[1],':')!=NULL)
ra1=15.*s2dec(argv[1]);
printf ("%8.3f\n", ry);
}
else
ra1=atof(argv[1]);
if (strchr(argv[2],':')!=NULL)
de1=s2dec(argv[2]);
{
if (strchr (argv[1], ':') != NULL)
ra1 = 15. * s2dec (argv[1]);
else
de1=atof(argv[2]);
if (strchr(argv[3],':')!=NULL)
ra2=15.*s2dec(argv[3]);
ra1 = atof (argv[1]);
if (strchr (argv[2], ':') != NULL)
de1 = s2dec (argv[2]);
else
ra2=atof(argv[3]);
if (strchr(argv[4],':')!=NULL)
de2=s2dec(argv[4]);
de1 = atof (argv[2]);
if (strchr (argv[3], ':') != NULL)
ra2 = 15. * s2dec (argv[3]);
else
de2=atof(argv[4]);
ra2 = atof (argv[3]);
if (strchr (argv[4], ':') != NULL)
de2 = s2dec (argv[4]);
else
de2 = atof (argv[4]);
forward(ra1,de1,ra2,de2,&rx,&ry);
forward (ra1, de1, ra2, de2, &rx, &ry);
printf("%8.3f %8.3f %8.3f\n",rx,ry,sqrt(rx*rx+ry*ry));
printf ("%8.3f %8.3f %8.3f\n", rx, ry, sqrt (rx * rx + ry * ry));
}
return 0;
}
// Convert Decimal into Sexagesimal
void dec2s(double x,char *s,int f,int len)
void
dec2s (double x, char *s, int f, int len)
{
int i;
double sec,deg,min;
double sec, deg, min;
char sign;
char *form[]={":: ",",, ","hms"," "};
char *form[] = { ":: ", ",, ", "hms", " " };
sign=(x<0 ? '-' : ' ');
x=3600.*fabs(x);
sign = (x < 0 ? '-' : ' ');
x = 3600. * fabs (x);
sec=fmod(x,60.);
x=(x-sec)/60.;
min=fmod(x,60.);
x=(x-min)/60.;
sec = fmod (x, 60.);
x = (x - sec) / 60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
// deg=fmod(x,60.);
deg=x;
deg = x;
if (len==7) sprintf(s,"%c%02i%c%02i%c%07.4f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]);
if (len==6) sprintf(s,"%c%02i%c%02i%c%06.3f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]);
if (len==5) sprintf(s,"%c%02i%c%02i%c%05.2f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]);
if (len==4) sprintf(s,"%c%02i%c%02i%c%04.1f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]);
if (len==2) sprintf(s,"%c%02i%c%02i%c%02i%c",sign,(int) deg,form[f][0],(int) min,form[f][1],(int) floor(sec),form[f][2]);
if (len == 7)
sprintf (s, "%c%02i%c%02i%c%07.4f%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], sec, form[f][2]);
if (len == 6)
sprintf (s, "%c%02i%c%02i%c%06.3f%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], sec, form[f][2]);
if (len == 5)
sprintf (s, "%c%02i%c%02i%c%05.2f%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], sec, form[f][2]);
if (len == 4)
sprintf (s, "%c%02i%c%02i%c%04.1f%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], sec, form[f][2]);
if (len == 2)
sprintf (s, "%c%02i%c%02i%c%02i%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], (int) floor (sec), form[f][2]);
return;
}
// Convert Sexagesimal into Decimal
double s2dec(char *s)
double
s2dec (char *s)
{
double x;
float deg,min,sec;
float deg, min, sec;
char t[LIM];
strcpy(t,s);
strcpy (t, s);
deg=fabs(atof(strtok(t," :")));
min=fabs(atof(strtok(NULL," :")));
sec=fabs(atof(strtok(NULL," :")));
deg = fabs (atof (strtok (t, " :")));
min = fabs (atof (strtok (NULL, " :")));
sec = fabs (atof (strtok (NULL, " :")));
x=(double) deg+(double) min/60.+(double) sec/3600.;
if (s[0]=='-') x= -x;
x = (double) deg + (double) min / 60. + (double) sec / 3600.;
if (s[0] == '-')
x = -x;
return x;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,81 +14,91 @@
#define XMNPDA 1440.0 /* Minutes per day */
#define XKE 0.743669161e-1
int fgetline(FILE *file,char *s,int lim);
void mjd2date(double mjd,int *year,int *month,double *day);
double date2mjd(int year,int month,double day);
double mjd2doy(double mjd,int *yr);
void format_tle(orbit_t orb,char *line1,char *line2);
double modulo(double x,double y);
int fgetline (FILE * file, char *s, int lim);
void mjd2date (double mjd, int *year, int *month, double *day);
double date2mjd (int year, int month, double day);
double mjd2doy (double mjd, int *yr);
void format_tle (orbit_t orb, char *line1, char *line2);
double modulo (double x, double y);
void convert(char *line)
void
convert (char *line)
{
int no,so;
int year,month,day,hour,min,sec;
int foy,fom,fod,gap;
float sma,incl,raan,ecc,argl,argp,a2m,mag,dm;
double mjd,doy;
int no, so;
int year, month, day, hour, min, sec;
int foy, fom, fod, gap;
float sma, incl, raan, ecc, argl, argp, a2m, mag, dm;
double mjd, doy;
orbit_t orb;
char line1[70],line2[70],line0[70];
double e,v;
float perigee,apogee;
char line1[70], line2[70], line0[70];
double e, v;
float perigee, apogee;
dm=5.0*log10(1000.0/40000.0);
dm = 5.0 * log10 (1000.0 / 40000.0);
// Read line
sscanf(line,"%4d,%6d,%2d%2d%4d,%2d%2d%4d %2d%2d%2d,%4d,%f,%f,%f,%f,%f,%f,%f,%f",&no,&so,&fod,&fom,&foy,&day,&month,&year,&hour,&min,&sec,&gap,&sma,&incl,&raan,&ecc,&argl,&argp,&a2m,&mag);
sscanf (line,
"%4d,%6d,%2d%2d%4d,%2d%2d%4d %2d%2d%2d,%4d,%f,%f,%f,%f,%f,%f,%f,%f",
&no, &so, &fod, &fom, &foy, &day, &month, &year, &hour, &min, &sec,
&gap, &sma, &incl, &raan, &ecc, &argl, &argp, &a2m, &mag);
// Use date of first observed as a designation
mjd=date2mjd(foy,fom,fod);
doy=mjd2doy(mjd,&foy);
if (foy>=2000)
sprintf(orb.desig,"%02d%3.0fA",foy-2000,doy+500);
mjd = date2mjd (foy, fom, fod);
doy = mjd2doy (mjd, &foy);
if (foy >= 2000)
sprintf (orb.desig, "%02d%3.0fA", foy - 2000, doy + 500);
else
sprintf(orb.desig,"%02d%3.0fA",foy-1900,doy+500);
sprintf (orb.desig, "%02d%3.0fA", foy - 1900, doy + 500);
// Find epoch
mjd=date2mjd(year,month,day+hour/24.0+min/1440.0+sec/86400.0);
orb.ep_day=mjd2doy(mjd,&orb.ep_year);
mjd =
date2mjd (year, month, day + hour / 24.0 + min / 1440.0 + sec / 86400.0);
orb.ep_day = mjd2doy (mjd, &orb.ep_year);
// Set values
orb.satno=no;
orb.eqinc=incl*D2R;
orb.argp=argp*D2R;
orb.ascn=raan*D2R;
orb.ecc=ecc;
orb.bstar=0.0;
orb.rev=XKE*pow(sma/XKMPER,-1.5)*XMNPDA/(2.0*M_PI);
orb.satno = no;
orb.eqinc = incl * D2R;
orb.argp = argp * D2R;
orb.ascn = raan * D2R;
orb.ecc = ecc;
orb.bstar = 0.0;
orb.rev = XKE * pow (sma / XKMPER, -1.5) * XMNPDA / (2.0 * M_PI);
// Mean anomaly
v=argl-argp;
e=2*atan(sqrt((1.0-ecc)/(1.0+ecc))*tan(v*D2R/2.0));
orb.mnan=modulo((e-ecc*sin(e)),2.0*M_PI);
v = argl - argp;
e = 2 * atan (sqrt ((1.0 - ecc) / (1.0 + ecc)) * tan (v * D2R / 2.0));
orb.mnan = modulo ((e - ecc * sin (e)), 2.0 * M_PI);
// Orbit
perigee=sma*(1.0-ecc)-XKMPER;
apogee=sma*(1.0+ecc)-XKMPER;
perigee = sma * (1.0 - ecc) - XKMPER;
apogee = sma * (1.0 + ecc) - XKMPER;
sprintf(line0,"SO %6d %4.1f %7.0fkm x%7.0fkm",so,mag+dm,perigee,apogee);
sprintf (line0,
"SO %6d %4.1f %7.0fkm x%7.0fkm",
so, mag + dm, perigee, apogee);
// Format line
format_tle(orb,line1,line2);
printf("%s\n%s\n%s\n",line0,line1,line2);
format_tle (orb, line1, line2);
printf ("%s\n%s\n%s\n", line0, line1, line2);
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
FILE *file;
char line[LIM],*fname;
int arg=0;
char line[LIM], *fname;
int arg = 0;
// Decode options
while ((arg=getopt(argc,argv,"f:"))!=-1) {
switch(arg) {
while ((arg = getopt (argc, argv, "f:")) != -1)
{
switch (arg)
{
case 'f':
fname=optarg;
fname = optarg;
break;
default:
@ -96,20 +106,21 @@ int main(int argc,char *argv[])
}
}
file=fopen(fname,"r");
while (fgetline(file,line,LIM)>0)
convert(line);
fclose(file);
file = fopen (fname, "r");
while (fgetline (file, line, LIM) > 0)
convert (line);
fclose (file);
return 0;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
@ -118,123 +129,150 @@ int fgetline(FILE *file,char *s,int lim)
}
// Compute Date from Julian Day
void mjd2date(double mjd,int *year,int *month,double *day)
void
mjd2date (double mjd, int *year, int *month, double *day)
{
double f,jd;
int z,alpha,a,b,c,d,e;
double f, jd;
int z, alpha, a, b, c, d, e;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
*day=b-d-floor(30.6001*e)+f;
if (e<14)
*month=e-1;
*day = b - d - floor (30.6001 * e) + f;
if (e < 14)
*month = e - 1;
else
*month=e-13;
*month = e - 13;
if (*month>2)
*year=c-4716;
if (*month > 2)
*year = c - 4716;
else
*year=c-4715;
*year = c - 4715;
return;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// MJD to DOY
double mjd2doy(double mjd,int *yr)
double
mjd2doy (double mjd, int *yr)
{
int year,month,k=2;
double day,doy;
int year, month, k = 2;
double day, doy;
mjd2date(mjd,&year,&month,&day);
mjd2date (mjd, &year, &month, &day);
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30;
doy =
floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30;
*yr=year;
*yr = year;
return doy;
}
// Format TLE
void format_tle(orbit_t orb,char *line1,char *line2)
void
format_tle (orbit_t orb, char *line1, char *line2)
{
int i,csum;
char sbstar[]=" 00000-0",bstar[13];
int i, csum;
char sbstar[] = " 00000-0", bstar[13];
// Format Bstar term
if (fabs(orb.bstar)>1e-9) {
sprintf(bstar,"%11.4e",10*orb.bstar);
sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4];
sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0';
if (fabs (orb.bstar) > 1e-9)
{
sprintf (bstar, "%11.4e", 10 * orb.bstar);
sbstar[0] = bstar[0];
sbstar[1] = bstar[1];
sbstar[2] = bstar[3];
sbstar[3] = bstar[4];
sbstar[4] = bstar[5];
sbstar[5] = bstar[6];
sbstar[6] = bstar[8];
sbstar[7] = bstar[10];
sbstar[8] = '\0';
}
// Print lines
sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar);
sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev);
sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",
orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar);
sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",
orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc,
DEG (orb.argp), DEG (orb.mnan), orb.rev);
// Compute checksums
for (i=0,csum=0;i<strlen(line1);i++) {
if (isdigit(line1[i]))
csum+=line1[i]-'0';
else if (line1[i]=='-')
for (i = 0, csum = 0; i < strlen (line1); i++)
{
if (isdigit (line1[i]))
csum += line1[i] - '0';
else if (line1[i] == '-')
csum++;
}
sprintf(line1,"%s%d",line1,csum%10);
for (i=0,csum=0;i<strlen(line2);i++) {
if (isdigit(line2[i]))
csum+=line2[i]-'0';
else if (line2[i]=='-')
sprintf (line1, "%s%d", line1, csum % 10);
for (i = 0, csum = 0; i < strlen (line2); i++)
{
if (isdigit (line2[i]))
csum += line2[i] - '0';
else if (line2[i] == '-')
csum++;
}
sprintf(line2,"%s%d",line2,csum%10);
sprintf (line2, "%s%d", line2, csum % 10);
return;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}

View File

@ -4,54 +4,60 @@
#include <string.h>
#include <math.h>
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int h=0;
double sec,deg,min;
char c,sign,d=' ';
int h = 0;
double sec, deg, min;
char c, sign, d = ' ';
double x;
char s[14];
if (argc==1) {
printf("Usage: dec2s [options] <x>\n\nCompute sexagesimal from decimal input x.\n");
printf("Options: -r gives hours instead of degrees\n");
printf(" -d<a> uses character a as delimiter\n");
printf(" -h uses hms as delimiters\n");
printf(" -s always prints sign\n\n");
if (argc == 1)
{
printf
("Usage: dec2s [options] <x>\n\nCompute sexagesimal from decimal input x.\n");
printf ("Options: -r gives hours instead of degrees\n");
printf (" -d<a> uses character a as delimiter\n");
printf (" -h uses hms as delimiters\n");
printf (" -s always prints sign\n\n");
return -1;
}
// Get Decimal Value
x=(double) atof(argv[--argc]);
sign=(x<0 ? '-' : ' ');
x = (double) atof (argv[--argc]);
sign = (x < 0 ? '-' : ' ');
// Get Options
while (--argc > 0 && (*++argv)[0] == '-') {
while (c = *++argv[0]) {
while (--argc > 0 && (*++argv)[0] == '-')
{
while (c = *++argv[0])
{
if (c == 'r')
x /= 15.;
if (c == 's')
sign=(x<0 ? '-' : '+');
sign = (x < 0 ? '-' : '+');
if (c == 'd')
if (strlen(argv[0])!=1)
d=(*argv)[1];
if (strlen (argv[0]) != 1)
d = (*argv)[1];
if (c == 'h')
h++;
}
}
x=3600.*fabs(x);
sec=fmod(x,60.);
x=(x-sec)/60.;
min=fmod(x,60.);
x=(x-min)/60.;
deg=x;
x = 3600. * fabs (x);
sec = fmod (x, 60.);
x = (x - sec) / 60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
deg = x;
if (h==0)
printf("%c%02i%c%02i%c%06.3f\n",sign,(int) deg,d,(int) min,d,(float) sec);
if (h == 0)
printf ("%c%02i%c%02i%c%06.3f\n", sign, (int) deg, d, (int) min, d,
(float) sec);
else
printf("%c%02ih%02im%06.3fs\n",sign,(int) deg,(int) min,(float) sec);
printf ("%c%02ih%02im%06.3fs\n", sign, (int) deg, (int) min, (float) sec);
return 0;
}

View File

@ -55,7 +55,8 @@
#include <stdio.h>
#include <stdlib.h>
static const char SCCSid[] = "@(#)deep.c 3.04 (C) 1995 psc SatLib: Deep Space effects";
static const char SCCSid[] =
"@(#)deep.c 3.04 (C) 1995 psc SatLib: Deep Space effects";
#ifndef NO_DEEP_SPACE
@ -65,9 +66,9 @@ extern int Set_LS_zero; /* From sgdp4.c */
/* ======================= Function prototypes ====================== */
static void dot_terms_calculated(void);
static void compute_LunarSolar(double tsince);
static void thetag(double ep, real *thegr, double *days50);
static void dot_terms_calculated (void);
static void compute_LunarSolar (double tsince);
static void thetag (double ep, real * thegr, double *days50);
/* ===================== Strange constants, etc ===================== */
@ -112,7 +113,7 @@ static void thetag(double ep, real *thegr, double *days50);
static real eo; /* copy of original eccentricity. */
static real xincl; /* copy of original equatorial inclination. */
static int isynfl=0, iresfl=0;
static int isynfl = 0, iresfl = 0;
static double atime, xli, xni, xnq, xfact;
@ -127,11 +128,11 @@ static real xnddt0, xndot0, xldot0; /* Integrator at epoch. */
/* ======== Global Variables used by dpper(), from dpinit(). ======= */
static int ilsd=0, ilsz=0;
static int ilsd = 0, ilsz = 0;
static real zmos, se2, se3, si2, si3, sl2, sl3, sl4;
static real sgh2, sgh3, sgh4, sh2, sh3;
static real zmol, ee2, e3 ,xi2, xi3, xl2, xl3, xl4;
static real zmol, ee2, e3, xi2, xi3, xl2, xl3, xl4;
static real xgh2, xgh3, xgh4, xh2, xh3;
static real pe, pinc, pgh, ph, pl;
@ -156,29 +157,31 @@ static real pgh0, ph0, pe0, pinc0, pl0; /* Added terms to save the epoch values
================================================================== */
sgdp4_mode_t SGDP4_dpinit(double epoch, real omegao, real xnodeo, real xmo,
sgdp4_mode_t
SGDP4_dpinit (double epoch, real omegao, real xnodeo, real xmo,
real orb_eo, real orb_xincl, real aodp, double xlldot,
real omgdot, real xnodot, double xnodp)
{
LOCAL_DOUBLE ds50, day, xnodce, bfact=0, gam, c;
LOCAL_REAL ctem, sinq, cosq, aqnv, xmao, stem, eqsq, xnoi, ainv2;
LOCAL_REAL zcosg, zsing, zcosi, zsini, zcosh, zsinh;
LOCAL_REAL cosomo, zcosgl, zcoshl, zcosil, sinomo;
LOCAL_REAL xpidot, zsinil, siniq2, cosiq2;
LOCAL_REAL rteqsq, zsinhl, zsingl;
LOCAL_REAL eoc, sgh, g200, bsq, xno2;
LOCAL_REAL a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
LOCAL_REAL x1, x2, x3, x4, x5, x6, x7, x8;
LOCAL_REAL z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33;
LOCAL_REAL s1, s2, s3, s4, s5, s6, s7, cc, ao, eq, se, shdq, si, sl;
LOCAL_REAL zx, zy, ze, zn;
LOCAL_REAL g201, g211, g310, g300, g322, g410, g422, g520, g533, g521, g532;
LOCAL_REAL f220, f221, f311, f321, f322, f330, f441, f442, f522, f523, f542, f543;
real siniq, cosiq;
real temp0, temp1;
int ls;
sgdp4_mode_t imode = SGDP4_NOT_INIT;
int ishq;
LOCAL_DOUBLE ds50, day, xnodce, bfact = 0, gam, c;
LOCAL_REAL ctem, sinq, cosq, aqnv, xmao, stem, eqsq, xnoi, ainv2;
LOCAL_REAL zcosg, zsing, zcosi, zsini, zcosh, zsinh;
LOCAL_REAL cosomo, zcosgl, zcoshl, zcosil, sinomo;
LOCAL_REAL xpidot, zsinil, siniq2, cosiq2;
LOCAL_REAL rteqsq, zsinhl, zsingl;
LOCAL_REAL eoc, sgh, g200, bsq, xno2;
LOCAL_REAL a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
LOCAL_REAL x1, x2, x3, x4, x5, x6, x7, x8;
LOCAL_REAL z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33;
LOCAL_REAL s1, s2, s3, s4, s5, s6, s7, cc, ao, eq, se, shdq, si, sl;
LOCAL_REAL zx, zy, ze, zn;
LOCAL_REAL g201, g211, g310, g300, g322, g410, g422, g520, g533, g521, g532;
LOCAL_REAL f220, f221, f311, f321, f322, f330, f441, f442, f522, f523, f542,
f543;
real siniq, cosiq;
real temp0, temp1;
int ls;
sgdp4_mode_t imode = SGDP4_NOT_INIT;
int ishq;
/*
Copy the supplied orbital elements to "local" (static to this file)
@ -189,20 +192,22 @@ int ishq;
/* Decide on direct or Lyddane Lunar-Solar perturbations. */
ilsd = 0;
if(xincl >= (real)0.2) ilsd = 1;
if (xincl >= (real) 0.2)
ilsd = 1;
/* Drop some terms below 3 deg inclination. */
ishq = 0;
#define SHQT 0.052359877
if (xincl >= (real)SHQT) ishq = 1; /* As per reoprt #3. */
if (xincl >= (real) SHQT)
ishq = 1; /* As per reoprt #3. */
SINCOS(omegao, &sinomo, &cosomo);
SINCOS(xnodeo, &sinq, &cosq);
SINCOS(xincl, &siniq, &cosiq);
SINCOS (omegao, &sinomo, &cosomo);
SINCOS (xnodeo, &sinq, &cosq);
SINCOS (xincl, &siniq, &cosiq);
if (fabs(siniq) <= SIN_EPS)
if (fabs (siniq) <= SIN_EPS)
{
siniq = SIGN(SIN_EPS, siniq);
siniq = SIGN (SIN_EPS, siniq);
}
cosiq2 = cosiq * cosiq;
@ -211,14 +216,14 @@ int ishq;
ao = aodp;
omgdt = omgdot;
eqsq = eo * eo;
bsq = (real)1.0 - eqsq;
rteqsq = SQRT(bsq);
thetag(epoch, &thgr, &ds50);
bsq = (real) 1.0 - eqsq;
rteqsq = SQRT (bsq);
thetag (epoch, &thgr, &ds50);
/*printf("# epoch = %.8f ds50 = %.8f thgr = %f\n", epoch, ds50, DEG(thgr));*/
/*printf("# epoch = %.8f ds50 = %.8f thgr = %f\n", epoch, ds50, DEG(thgr)); */
xnq = xnodp;
aqnv = (real)1.0 / ao;
aqnv = (real) 1.0 / ao;
xmao = xmo;
xpidot = omgdt + xnodot;
omegaq = omegao;
@ -228,22 +233,22 @@ int ishq;
day = ds50 + 18261.5;
xnodce = 4.523602 - day * 9.2422029e-4;
temp0 = (real)fmod(xnodce, TWOPI);
SINCOS(temp0, &stem, &ctem);
temp0 = (real) fmod (xnodce, TWOPI);
SINCOS (temp0, &stem, &ctem);
zcosil = (real)0.91375164 - ctem * (real)0.03568096;
zsinil = SQRT((real)1.0 - zcosil * zcosil);
zsinhl = stem * (real)0.089683511 / zsinil;
zcoshl = SQRT((real)1.0 - zsinhl * zsinhl);
zcosil = (real) 0.91375164 - ctem * (real) 0.03568096;
zsinil = SQRT ((real) 1.0 - zcosil * zcosil);
zsinhl = stem * (real) 0.089683511 / zsinil;
zcoshl = SQRT ((real) 1.0 - zsinhl * zsinhl);
c = day * 0.2299715 + 4.7199672;
gam = day * 0.001944368 + 5.8351514;
zmol = (real)MOD2PI(c - gam);
zx = stem * (real)0.39785416 / zsinil;
zy = zcoshl * ctem + zsinhl * (real)0.91744867 * stem;
zx = ATAN2(zx, zy);
zx = (real)fmod(gam + zx - xnodce, TWOPI);
SINCOS(zx, &zsingl, &zcosgl);
zmos = (real)MOD2PI(day * 0.017201977 + 6.2565837);
zmol = (real) MOD2PI (c - gam);
zx = stem * (real) 0.39785416 / zsinil;
zy = zcoshl * ctem + zsinhl * (real) 0.91744867 *stem;
zx = ATAN2 (zx, zy);
zx = (real) fmod (gam + zx - xnodce, TWOPI);
SINCOS (zx, &zsingl, &zcosgl);
zmos = (real) MOD2PI (day * 0.017201977 + 6.2565837);
/* DO SOLAR TERMS */
@ -256,9 +261,9 @@ int ishq;
cc = C1SS;
zn = ZNS;
ze = ZES;
xnoi = (real)(1.0 / xnq);
xnoi = (real) (1.0 / xnq);
for(ls = 0; ls < 2; ls++)
for (ls = 0; ls < 2; ls++)
{
a1 = zcosg * zcosh + zsing * zcosi * zsinh;
a3 = -zsing * zcosh + zcosg * zcosi * zsinh;
@ -280,60 +285,69 @@ int ishq;
x7 = a5 * cosomo;
x8 = a6 * cosomo;
z31 = x1 * (real)12.0 * x1 - x3 * (real)3.0 * x3;
z32 = x1 * (real)24.0 * x2 - x3 * (real)6.0 * x4;
z33 = x2 * (real)12.0 * x2 - x4 * (real)3.0 * x4;
z1 = (a1 * a1 + a2 * a2) * (real)3.0 + z31 * eqsq;
z2 = (a1 * a3 + a2 * a4) * (real)6.0 + z32 * eqsq;
z3 = (a3 * a3 + a4 * a4) * (real)3.0 + z33 * eqsq;
z11 = a1 * (real)-6.0 * a5 + eqsq * (x1 * (real)-24.0 * x7 - x3 *
(real)6.0 * x5);
z12 = (a1 * a6 + a3 * a5) * (real)-6.0 + eqsq * ((x2 * x7 +
x1 * x8) * (real)-24.0 - (x3 * x6 + x4 * x5) * (real)6.0);
z13 = a3 * (real)-6.0 * a6 + eqsq * (x2 * (real)-24.0 * x8 - x4 *
(real)6.0 * x6);
z21 = a2 * (real)6.0 * a5 + eqsq * (x1 * (real)24.0 * x5 -
x3 * (real)6.0 * x7);
z22 = (a4 * a5 + a2 * a6) * (real)6.0 + eqsq * ((x2 * x5 + x1 * x6) *
(real)24.0 - (x4 * x7 + x3 * x8) * (real)6.0);
z23 = a4 * (real)6.0 * a6 + eqsq * (x2 * (real)24.0 * x6 - x4 *
(real)6.0 * x8);
z31 = x1 * (real) 12.0 *x1 - x3 * (real) 3.0 *x3;
z32 = x1 * (real) 24.0 *x2 - x3 * (real) 6.0 *x4;
z33 = x2 * (real) 12.0 *x2 - x4 * (real) 3.0 *x4;
z1 = (a1 * a1 + a2 * a2) * (real) 3.0 + z31 * eqsq;
z2 = (a1 * a3 + a2 * a4) * (real) 6.0 + z32 * eqsq;
z3 = (a3 * a3 + a4 * a4) * (real) 3.0 + z33 * eqsq;
z11 = a1 * (real) - 6.0 * a5 + eqsq * (x1 * (real) - 24.0 * x7 - x3 *
(real) 6.0 * x5);
z12 = (a1 * a6 + a3 * a5) * (real) - 6.0 + eqsq * ((x2 * x7 +
x1 * x8) * (real) -
24.0 - (x3 * x6 +
x4 * x5) *
(real) 6.0);
z13 =
a3 * (real) - 6.0 * a6 + eqsq * (x2 * (real) - 24.0 * x8 -
x4 * (real) 6.0 * x6);
z21 =
a2 * (real) 6.0 *a5 + eqsq * (x1 * (real) 24.0 * x5 -
x3 * (real) 6.0 * x7);
z22 =
(a4 * a5 + a2 * a6) * (real) 6.0 +
eqsq * ((x2 * x5 + x1 * x6) * (real) 24.0 -
(x4 * x7 + x3 * x8) * (real) 6.0);
z23 =
a4 * (real) 6.0 *a6 + eqsq * (x2 * (real) 24.0 * x6 -
x4 * (real) 6.0 * x8);
z1 = z1 + z1 + bsq * z31;
z2 = z2 + z2 + bsq * z32;
z3 = z3 + z3 + bsq * z33;
s3 = cc * xnoi;
s2 = s3 * (real)-0.5 / rteqsq;
s2 = s3 * (real) - 0.5 / rteqsq;
s4 = s3 * rteqsq;
s1 = eq * (real)-15.0 * s4;
s1 = eq * (real) - 15.0 * s4;
s5 = x1 * x3 + x2 * x4;
s6 = x2 * x3 + x1 * x4;
s7 = x2 * x4 - x1 * x3;
se = s1 * zn * s5;
si = s2 * zn * (z11 + z13);
sl = -zn * s3 * (z1 + z3 - (real)14.0 - eqsq * (real)6.0);
sgh = s4 * zn * (z31 + z33 - (real)6.0);
sl = -zn * s3 * (z1 + z3 - (real) 14.0 - eqsq * (real) 6.0);
sgh = s4 * zn * (z31 + z33 - (real) 6.0);
shdq = 0;
if(ishq)
if (ishq)
{
real sh = -zn * s2 * (z21 + z23);
shdq = sh / siniq;
}
ee2 = s1 * (real)2.0 * s6;
e3 = s1 * (real)2.0 * s7;
xi2 = s2 * (real)2.0 * z12;
xi3 = s2 * (real)2.0 * (z13 - z11);
xl2 = s3 * (real)-2.0 * z2;
xl3 = s3 * (real)-2.0 * (z3 - z1);
xl4 = s3 * (real)-2.0 * ((real)-21.0 - eqsq * (real)9.0) * ze;
xgh2 = s4 * (real)2.0 * z32;
xgh3 = s4 * (real)2.0 * (z33 - z31);
xgh4 = s4 * (real)-18.0 * ze;
xh2 = s2 * (real)-2.0 * z22;
xh3 = s2 * (real)-2.0 * (z23 - z21);
ee2 = s1 * (real) 2.0 *s6;
e3 = s1 * (real) 2.0 *s7;
xi2 = s2 * (real) 2.0 *z12;
xi3 = s2 * (real) 2.0 *(z13 - z11);
xl2 = s3 * (real) - 2.0 * z2;
xl3 = s3 * (real) - 2.0 * (z3 - z1);
xl4 = s3 * (real) - 2.0 * ((real) - 21.0 - eqsq * (real) 9.0) * ze;
xgh2 = s4 * (real) 2.0 *z32;
xgh3 = s4 * (real) 2.0 *(z33 - z31);
xgh4 = s4 * (real) - 18.0 * ze;
xh2 = s2 * (real) - 2.0 * z22;
xh3 = s2 * (real) - 2.0 * (z23 - z21);
if (ls == 1) break;
if (ls == 1)
break;
/* DO LUNAR TERMS */
@ -376,94 +390,142 @@ int ishq;
/* 24h SYNCHRONOUS RESONANCE TERMS INITIALIZATION */
iresfl = 1;
isynfl = 1;
g200 = eqsq * (eqsq * (real)0.8125 - (real)2.5) + (real)1.0;
g310 = eqsq * (real)2.0 + (real)1.0;
g300 = eqsq * (eqsq * (real)6.60937 - (real)6.0) + (real)1.0;
f220 = (cosiq + (real)1.0) * (real)0.75 * (cosiq + (real)1.0);
f311 = siniq * (real)0.9375 * siniq * (cosiq * (real)3.0 +
(real)1.0) - (cosiq + (real)1.0) * (real)0.75;
f330 = cosiq + (real)1.0;
f330 = f330 * (real)1.875 * f330 * f330;
del1 = (real)3.0 * (real)(xnq * xnq * aqnv * aqnv);
del2 = del1 * (real)2.0 * f220 * g200 * Q22;
del3 = del1 * (real)3.0 * f330 * g300 * Q33 * aqnv;
g200 = eqsq * (eqsq * (real) 0.8125 - (real) 2.5) + (real) 1.0;
g310 = eqsq * (real) 2.0 + (real) 1.0;
g300 = eqsq * (eqsq * (real) 6.60937 - (real) 6.0) + (real) 1.0;
f220 = (cosiq + (real) 1.0) * (real) 0.75 *(cosiq + (real) 1.0);
f311 = siniq * (real) 0.9375 *siniq * (cosiq * (real) 3.0 +
(real) 1.0) - (cosiq +
(real) 1.0) *
(real) 0.75;
f330 = cosiq + (real) 1.0;
f330 = f330 * (real) 1.875 *f330 * f330;
del1 = (real) 3.0 *(real) (xnq * xnq * aqnv * aqnv);
del2 = del1 * (real) 2.0 *f220 * g200 * Q22;
del3 = del1 * (real) 3.0 *f330 * g300 * Q33 * aqnv;
del1 = del1 * f311 * g310 * Q31 * aqnv;
fasx2 = (real)0.13130908;
fasx4 = (real)2.8843198;
fasx6 = (real)0.37448087;
fasx2 = (real) 0.13130908;
fasx4 = (real) 2.8843198;
fasx6 = (real) 0.37448087;
xlamo = xmao + xnodeo + omegao - thgr;
bfact = xlldot + xpidot - THDT;
bfact += (double)(ssl + ssg + ssh);
bfact += (double) (ssl + ssg + ssh);
}
else if (xnq >= 0.00826 && xnq <= 0.00924 && eq >= (real)0.5)
else if (xnq >= 0.00826 && xnq <= 0.00924 && eq >= (real) 0.5)
{
/* GEOPOTENTIAL RESONANCE INITIALIZATION FOR 12 HOUR ORBITS */
iresfl = 1;
isynfl = 0;
eoc = eq * eqsq;
g201 = (real)-0.306 - (eq - (real)0.64) * (real)0.44;
g201 = (real) - 0.306 - (eq - (real) 0.64) * (real) 0.44;
if (eq <= (real)0.65)
if (eq <= (real) 0.65)
{
g211 = (real)3.616 - eq * (real)13.247 + eqsq * (real)16.29;
g310 = eq * (real)117.39 - (real)19.302 - eqsq * (real)228.419 + eoc * (real)156.591;
g322 = eq * (real)109.7927 - (real)18.9068 - eqsq * (real)214.6334 + eoc * (real)146.5816;
g410 = eq * (real)242.694 - (real)41.122 - eqsq * (real)471.094 + eoc * (real)313.953;
g422 = eq * (real)841.88 - (real)146.407 - eqsq * (real)1629.014 + eoc * (real)1083.435;
g520 = eq * (real)3017.977 - (real)532.114 - eqsq * 5740.032 + eoc * (real)3708.276;
g211 = (real) 3.616 - eq * (real) 13.247 + eqsq * (real) 16.29;
g310 =
eq * (real) 117.39 - (real) 19.302 - eqsq * (real) 228.419 +
eoc * (real) 156.591;
g322 =
eq * (real) 109.7927 - (real) 18.9068 - eqsq * (real) 214.6334 +
eoc * (real) 146.5816;
g410 =
eq * (real) 242.694 - (real) 41.122 - eqsq * (real) 471.094 +
eoc * (real) 313.953;
g422 =
eq * (real) 841.88 - (real) 146.407 - eqsq * (real) 1629.014 +
eoc * (real) 1083.435;
g520 =
eq * (real) 3017.977 - (real) 532.114 - eqsq * 5740.032 +
eoc * (real) 3708.276;
}
else
{
g211 = eq * (real)331.819 - (real)72.099 - eqsq * (real)508.738 + eoc * (real)266.724;
g310 = eq * (real)1582.851 - (real)346.844 - eqsq * (real)2415.925 + eoc * (real)1246.113;
g322 = eq * (real)1554.908 - (real)342.585 - eqsq * (real)2366.899 + eoc * (real)1215.972;
g410 = eq * (real)4758.686 - (real)1052.797 - eqsq * (real)7193.992 + eoc * (real)3651.957;
g422 = eq * (real)16178.11 - (real)3581.69 - eqsq * (real)24462.77 + eoc * (real)12422.52;
g211 =
eq * (real) 331.819 - (real) 72.099 - eqsq * (real) 508.738 +
eoc * (real) 266.724;
g310 =
eq * (real) 1582.851 - (real) 346.844 - eqsq * (real) 2415.925 +
eoc * (real) 1246.113;
g322 =
eq * (real) 1554.908 - (real) 342.585 - eqsq * (real) 2366.899 +
eoc * (real) 1215.972;
g410 =
eq * (real) 4758.686 - (real) 1052.797 - eqsq * (real) 7193.992 +
eoc * (real) 3651.957;
g422 =
eq * (real) 16178.11 - (real) 3581.69 - eqsq * (real) 24462.77 +
eoc * (real) 12422.52;
if (eq <= (real)0.715)
if (eq <= (real) 0.715)
{
g520 = (real)1464.74 - eq * (real)4664.75 + eqsq * (real)3763.64;
g520 =
(real) 1464.74 - eq * (real) 4664.75 + eqsq * (real) 3763.64;
}
else
{
g520 = eq * (real)29936.92 - (real)5149.66 - eqsq * (real)54087.36 + eoc * (real)31324.56;
g520 =
eq * (real) 29936.92 - (real) 5149.66 -
eqsq * (real) 54087.36 + eoc * (real) 31324.56;
}
}
if (eq < (real)0.7)
if (eq < (real) 0.7)
{
g533 = eq * (real)4988.61 - (real)919.2277 - eqsq * (real)9064.77 + eoc * (real)5542.21;
g521 = eq * (real)4568.6173 - (real)822.71072 - eqsq * (real)8491.4146 + eoc * (real)5337.524;
g532 = eq * (real)4690.25 - (real)853.666 - eqsq * (real)8624.77 + eoc * (real)5341.4;
g533 =
eq * (real) 4988.61 - (real) 919.2277 - eqsq * (real) 9064.77 +
eoc * (real) 5542.21;
g521 =
eq * (real) 4568.6173 - (real) 822.71072 -
eqsq * (real) 8491.4146 + eoc * (real) 5337.524;
g532 =
eq * (real) 4690.25 - (real) 853.666 - eqsq * (real) 8624.77 +
eoc * (real) 5341.4;
}
else
{
g533 = eq * (real)161616.52 - (real)37995.78 - eqsq * (real)229838.2 + eoc * (real)109377.94;
g521 = eq * (real)218913.95 - (real)51752.104 - eqsq * (real)309468.16 + eoc * (real)146349.42;
g532 = eq * (real)170470.89 - (real)40023.88 - eqsq * (real)242699.48 + eoc * (real)115605.82;
g533 =
eq * (real) 161616.52 - (real) 37995.78 - eqsq * (real) 229838.2 +
eoc * (real) 109377.94;
g521 =
eq * (real) 218913.95 - (real) 51752.104 -
eqsq * (real) 309468.16 + eoc * (real) 146349.42;
g532 =
eq * (real) 170470.89 - (real) 40023.88 -
eqsq * (real) 242699.48 + eoc * (real) 115605.82;
}
f220 = (cosiq * (real)2.0 + (real)1.0 + cosiq2) * (real)0.75;
f221 = siniq2 * (real)1.5;
f321 = siniq * (real)1.875 * ((real)1.0 - cosiq * (real)2.0 - cosiq2 * (real)3.0);
f322 = siniq * (real)-1.875 * (cosiq * (real)2.0 + (real)1.0 - cosiq2 * (real)3.0);
f441 = siniq2 * (real)35.0 * f220;
f442 = siniq2 * (real)39.375 * siniq2;
f522 = siniq * (real)9.84375 * (siniq2 * ((real)1.0 - cosiq *
(real)2.0 - cosiq2 * (real)5.0) + (cosiq * (real)4.0 -
(real)2.0 + cosiq2 * (real)6.0) * (real)0.33333333);
f523 = siniq * (siniq2 * (real)4.92187512 * ((real)-2.0 - cosiq *
(real)4.0 + cosiq2 * (real)10.0) + (cosiq * (real)2.0 +
(real)1.0 - cosiq2 * (real)3.0) * (real)6.56250012);
f542 = siniq * (real)29.53125 * ((real)2.0 - cosiq * (real)8.0 +
cosiq2 * (cosiq * (real)8.0 - (real)12.0 + cosiq2 *
(real)10.0));
f543 = siniq * (real)29.53125 * ((real)-2.0 - cosiq * (real)8.0 +
cosiq2 * (cosiq * (real)8.0 + (real)12.0 - cosiq2 *
(real)10.0));
xno2 = (real)(xnq * xnq);
f220 = (cosiq * (real) 2.0 + (real) 1.0 + cosiq2) * (real) 0.75;
f221 = siniq2 * (real) 1.5;
f321 =
siniq * (real) 1.875 *((real) 1.0 - cosiq * (real) 2.0 -
cosiq2 * (real) 3.0);
f322 =
siniq * (real) - 1.875 * (cosiq * (real) 2.0 + (real) 1.0 -
cosiq2 * (real) 3.0);
f441 = siniq2 * (real) 35.0 *f220;
f442 = siniq2 * (real) 39.375 *siniq2;
f522 = siniq * (real) 9.84375 *(siniq2 * ((real) 1.0 - cosiq *
(real) 2.0 -
cosiq2 * (real) 5.0) +
(cosiq * (real) 4.0 - (real) 2.0 +
cosiq2 * (real) 6.0) *
(real) 0.33333333);
f523 =
siniq * (siniq2 * (real) 4.92187512 *
((real) - 2.0 - cosiq * (real) 4.0 + cosiq2 * (real) 10.0) +
(cosiq * (real) 2.0 + (real) 1.0 -
cosiq2 * (real) 3.0) * (real) 6.56250012);
f542 =
siniq * (real) 29.53125 *((real) 2.0 - cosiq * (real) 8.0 +
cosiq2 * (cosiq * (real) 8.0 - (real) 12.0 +
cosiq2 * (real) 10.0));
f543 =
siniq * (real) 29.53125 *((real) - 2.0 - cosiq * (real) 8.0 +
cosiq2 * (cosiq * (real) 8.0 + (real) 12.0 -
cosiq2 * (real) 10.0));
xno2 = (real) (xnq * xnq);
ainv2 = aqnv * aqnv;
temp1 = xno2 * (real)3.0 * ainv2;
temp1 = xno2 * (real) 3.0 *ainv2;
temp0 = temp1 * ROOT22;
d2201 = temp0 * f220 * g201;
d2211 = temp0 * f221 * g211;
@ -472,19 +534,19 @@ int ishq;
d3210 = temp0 * f321 * g310;
d3222 = temp0 * f322 * g322;
temp1 *= aqnv;
temp0 = temp1 * (real)2.0 * ROOT44;
temp0 = temp1 * (real) 2.0 *ROOT44;
d4410 = temp0 * f441 * g410;
d4422 = temp0 * f442 * g422;
temp1 *= aqnv;
temp0 = temp1 * ROOT52;
d5220 = temp0 * f522 * g520;
d5232 = temp0 * f523 * g532;
temp0 = temp1 * (real)2.0 * ROOT54;
temp0 = temp1 * (real) 2.0 *ROOT54;
d5421 = temp0 * f542 * g521;
d5433 = temp0 * f543 * g533;
xlamo = xmao + xnodeo + xnodeo - thgr - thgr;
bfact = xlldot + xnodot + xnodot - THDT - THDT;
bfact += (double)(ssl + ssh + ssh);
bfact += (double) (ssl + ssh + ssh);
}
else
{
@ -493,7 +555,7 @@ int ishq;
isynfl = 0;
}
if(iresfl == 0)
if (iresfl == 0)
{
/* Non-resonant orbits. */
imode = SGDP4_DEEP_NORM;
@ -502,11 +564,11 @@ int ishq;
{
/* INITIALIZE INTEGRATOR */
xfact = bfact - xnq;
xli = (double)xlamo;
xli = (double) xlamo;
xni = xnq;
atime = 0.0;
dot_terms_calculated();
dot_terms_calculated ();
/* Save the "dot" terms for integrator re-start. */
xnddt0 = xnddt;
@ -521,15 +583,15 @@ int ishq;
/* Set up for original mode (LS terms at epoch non-zero). */
ilsz = 0;
pgh0 = ph0 = pe0 = pinc0 = pl0 = (real)0.0;
pgh0 = ph0 = pe0 = pinc0 = pl0 = (real) 0.0;
if(Set_LS_zero)
if (Set_LS_zero)
{
/* Save the epoch case Lunar-Solar terms to remove this bias for
* actual computations later on.
* Not sure if this is a good idea.
*/
compute_LunarSolar(0.0);
compute_LunarSolar (0.0);
pgh0 = pgh;
ph0 = ph;
@ -540,7 +602,7 @@ int ishq;
}
return imode;
return imode;
} /* SGDP4_dpinit */
/* =====================================================================
@ -559,11 +621,12 @@ return imode;
===================================================================== */
int SGDP4_dpsec(double *xll, real *omgasm, real *xnodes, real *em,
real *xinc, double *xn, double tsince)
int
SGDP4_dpsec (double *xll, real * omgasm, real * xnodes, real * em,
real * xinc, double *xn, double tsince)
{
LOCAL_DOUBLE delt, ft, xl;
real temp0;
LOCAL_DOUBLE delt, ft, xl;
real temp0;
*xll += ssl * tsince;
*omgasm += ssg * tsince;
@ -571,7 +634,8 @@ real temp0;
*em += sse * tsince;
*xinc += ssi * tsince;
if (iresfl == 0) return 0;
if (iresfl == 0)
return 0;
/*
* A minor increase in some efficiency can be had by restarting if
@ -585,14 +649,14 @@ real temp0;
/* Most accurate (OK, most _consistant_) method. Restart if need to
* integrate 'backwards' significantly from current point.
*/
if(fabs(tsince) < STEP ||
if (fabs (tsince) < STEP ||
(atime > 0.0 && tsince < atime - AHYST) ||
(atime < 0.0 && tsince > atime + AHYST))
{
/* Epoch restart if we are at, or have crossed, tsince==0 */
atime = 0.0;
xni = xnq;
xli = (double)xlamo;
xli = (double) xlamo;
/* Restore the old "dot" terms. */
xnddt = xnddt0;
xndot = xndot0;
@ -601,13 +665,13 @@ real temp0;
ft = tsince - atime;
if (fabs(ft) > MAX_INTEGRATE)
if (fabs (ft) > MAX_INTEGRATE)
{
fatal_error("SGDP4_dpsec: Integration limit reached");
fatal_error ("SGDP4_dpsec: Integration limit reached");
return -1;
}
if (fabs(ft) >= STEP)
if (fabs (ft) >= STEP)
{
/*
Do integration if required. Find the step direction to
@ -615,21 +679,23 @@ real temp0;
*/
delt = (tsince >= atime ? STEP : -STEP);
do {
do
{
/* INTEGRATOR (using the last "dot" terms). */
xli += delt * (xldot + delt * (real)0.5 * xndot);
xni += delt * (xndot + delt * (real)0.5 * xnddt);
xli += delt * (xldot + delt * (real) 0.5 * xndot);
xni += delt * (xndot + delt * (real) 0.5 * xnddt);
atime += delt;
dot_terms_calculated();
dot_terms_calculated ();
/* Are we close enough now ? */
ft = tsince - atime;
} while (fabs(ft) >= STEP);
}
while (fabs (ft) >= STEP);
}
xl = xli + ft * (xldot + ft * (real)0.5 * xndot);
*xn = xni + ft * (xndot + ft * (real)0.5 * xnddt);
xl = xli + ft * (xldot + ft * (real) 0.5 * xndot);
*xn = xni + ft * (xndot + ft * (real) 0.5 * xnddt);
temp0 = -(*xnodes) + thgr + tsince * THDT;
@ -638,7 +704,7 @@ real temp0;
else
*xll = xl - *omgasm + temp0;
return 0;
return 0;
} /* SGDP4_dpsec */
/* =====================================================================
@ -649,20 +715,21 @@ return 0;
===================================================================== */
static void dot_terms_calculated(void)
static void
dot_terms_calculated (void)
{
LOCAL_DOUBLE x2li, x2omi, xomi;
LOCAL_DOUBLE x2li, x2omi, xomi;
/* DOT TERMS CALCULATED */
if (isynfl)
{
xndot = del1 * SIN(xli - fasx2)
+ del2 * SIN((xli - fasx4) * (real)2.0)
+ del3 * SIN((xli - fasx6) * (real)3.0);
xndot = del1 * SIN (xli - fasx2)
+ del2 * SIN ((xli - fasx4) * (real) 2.0)
+ del3 * SIN ((xli - fasx6) * (real) 3.0);
xnddt = del1 * COS(xli - fasx2)
+ del2 * COS((xli - fasx4) * (real)2.0) * (real)2.0
+ del3 * COS((xli - fasx6) * (real)3.0) * (real)3.0;
xnddt = del1 * COS (xli - fasx2)
+ del2 * COS ((xli - fasx4) * (real) 2.0) * (real) 2.0
+ del3 * COS ((xli - fasx6) * (real) 3.0) * (real) 3.0;
}
else
{
@ -670,30 +737,29 @@ LOCAL_DOUBLE x2li, x2omi, xomi;
x2omi = xomi + xomi;
x2li = xli + xli;
xndot = d2201 * SIN(x2omi + xli - G22)
+ d2211 * SIN(xli - G22)
+ d3210 * SIN(xomi + xli - G32)
+ d3222 * SIN(-xomi + xli - G32)
+ d5220 * SIN(xomi + xli - G52)
+ d5232 * SIN(-xomi + xli - G52)
+ d4410 * SIN(x2omi + x2li - G44)
+ d4422 * SIN(x2li - G44)
+ d5421 * SIN(xomi + x2li - G54)
+ d5433 * SIN(-xomi + x2li - G54);
xndot = d2201 * SIN (x2omi + xli - G22)
+ d2211 * SIN (xli - G22)
+ d3210 * SIN (xomi + xli - G32)
+ d3222 * SIN (-xomi + xli - G32)
+ d5220 * SIN (xomi + xli - G52)
+ d5232 * SIN (-xomi + xli - G52)
+ d4410 * SIN (x2omi + x2li - G44)
+ d4422 * SIN (x2li - G44)
+ d5421 * SIN (xomi + x2li - G54) + d5433 * SIN (-xomi + x2li - G54);
xnddt = d2201 * COS(x2omi + xli - G22)
+ d2211 * COS(xli - G22)
+ d3210 * COS(xomi + xli - G32)
+ d3222 * COS(-xomi + xli - G32)
+ d5220 * COS(xomi + xli - G52)
+ d5232 * COS(-xomi + xli - G52)
+ (d4410 * COS(x2omi + x2li - G44)
+ d4422 * COS(x2li - G44)
+ d5421 * COS(xomi + x2li - G54)
+ d5433 * COS(-xomi + x2li - G54)) * (real)2.0;
xnddt = d2201 * COS (x2omi + xli - G22)
+ d2211 * COS (xli - G22)
+ d3210 * COS (xomi + xli - G32)
+ d3222 * COS (-xomi + xli - G32)
+ d5220 * COS (xomi + xli - G52)
+ d5232 * COS (-xomi + xli - G52)
+ (d4410 * COS (x2omi + x2li - G44)
+ d4422 * COS (x2li - G44)
+ d5421 * COS (xomi + x2li - G54)
+ d5433 * COS (-xomi + x2li - G54)) * (real) 2.0;
}
xldot = (real)(xni + xfact);
xldot = (real) (xni + xfact);
xnddt *= xldot;
} /* dot_terms_calculated */
@ -711,12 +777,13 @@ LOCAL_DOUBLE x2li, x2omi, xomi;
===================================================================== */
int SGDP4_dpper(real *em, real *xinc, real *omgasm, real *xnodes,
int
SGDP4_dpper (real * em, real * xinc, real * omgasm, real * xnodes,
double *xll, double tsince)
{
real sinis, cosis;
real sinis, cosis;
compute_LunarSolar(tsince);
compute_LunarSolar (tsince);
*xinc += pinc;
*em += pe;
@ -725,7 +792,7 @@ real sinis, cosis;
* added to xinc (oldxinc), but apparently report # 6 has then
* from after they are added.
*/
SINCOS(*xinc, &sinis, &cosis);
SINCOS (*xinc, &sinis, &cosis);
if (ilsd)
{
@ -745,27 +812,27 @@ real sinis, cosis;
int ishift;
real oldxnode = (*xnodes);
SINCOS(*xnodes, &sinok, &cosok);
SINCOS (*xnodes, &sinok, &cosok);
alfdp = sinis * sinok;
betdp = sinis * cosok;
dalf = ph * cosok + pinc * cosis * sinok;
dbet = -ph * sinok + pinc * cosis * cosok;
alfdp += dalf;
betdp += dbet;
xls = (real)*xll + *omgasm + cosis * *xnodes;
xls = (real) * xll + *omgasm + cosis * *xnodes;
dls = pl + pgh - pinc * *xnodes * sinis;
xls += dls;
*xnodes = ATAN2(alfdp, betdp);
*xnodes = ATAN2 (alfdp, betdp);
/* Get perturbed xnodes in to same quadrant as original. */
ishift = NINT((oldxnode - (*xnodes))/TWOPI);
*xnodes += (real)(TWOPI * ishift);
ishift = NINT ((oldxnode - (*xnodes)) / TWOPI);
*xnodes += (real) (TWOPI * ishift);
*xll += (double)pl;
*omgasm = xls - (real)*xll - cosis * (*xnodes);
*xll += (double) pl;
*omgasm = xls - (real) * xll - cosis * (*xnodes);
}
return 0;
return 0;
} /* SGDP4_dpper */
/* =====================================================================
@ -778,19 +845,20 @@ return 0;
code).
===================================================================== */
static void compute_LunarSolar(double tsince)
static void
compute_LunarSolar (double tsince)
{
LOCAL_REAL sinzf, coszf;
LOCAL_REAL f2, f3, zf, zm;
LOCAL_REAL sel, sil, ses, sll, sis, sls;
LOCAL_REAL sghs, shs, sghl, shl;
LOCAL_REAL sinzf, coszf;
LOCAL_REAL f2, f3, zf, zm;
LOCAL_REAL sel, sil, ses, sll, sis, sls;
LOCAL_REAL sghs, shs, sghl, shl;
/* Update Solar terms. */
zm = zmos + ZNS * tsince;
zf = zm + ZES * (real)2.0 * SIN(zm);
SINCOS(zf, &sinzf, &coszf);
f2 = sinzf * (real)0.5 * sinzf - (real)0.25;
f3 = sinzf * (real)-0.5 * coszf;
zf = zm + ZES * (real) 2.0 *SIN (zm);
SINCOS (zf, &sinzf, &coszf);
f2 = sinzf * (real) 0.5 *sinzf - (real) 0.25;
f3 = sinzf * (real) - 0.5 * coszf;
ses = se2 * f2 + se3 * f3;
sis = si2 * f2 + si3 * f3;
sls = sl2 * f2 + sl3 * f3 + sl4 * sinzf;
@ -800,10 +868,10 @@ LOCAL_REAL sghs, shs, sghl, shl;
/* Update Lunar terms. */
zm = zmol + ZNL * tsince;
zf = zm + ZEL * (real)2.0 * SIN(zm);
SINCOS(zf, &sinzf, &coszf);
f2 = sinzf * (real)0.5 * sinzf - (real)0.25;
f3 = sinzf * (real)-0.5 * coszf;
zf = zm + ZEL * (real) 2.0 *SIN (zm);
SINCOS (zf, &sinzf, &coszf);
f2 = sinzf * (real) 0.5 *sinzf - (real) 0.25;
f3 = sinzf * (real) - 0.5 * coszf;
sel = ee2 * f2 + e3 * f3;
sil = xi2 * f2 + xi3 * f3;
sll = xl2 * f2 + xl3 * f3 + xl4 * sinzf;
@ -856,20 +924,22 @@ LOCAL_REAL sghs, shs, sghl, shl;
#define FK5R (5.07551419432269442E-15)
static void thetag(double ep, real *thegr, double *days50)
static void
thetag (double ep, real * thegr, double *days50)
{
double d;
long n, jy;
double theta;
double d;
long n, jy;
double theta;
jy = (long)((ep + 2.0e-7) * 0.001); /* Extract the year. */
jy = (long) ((ep + 2.0e-7) * 0.001); /* Extract the year. */
d = ep - jy * 1.0e3; /* And then the day of year. */
/* Assume " 8" is 1980, or more sensibly 2008 ? */
/*
if (jy < 10) jy += 80;
*/
if (jy < 50) jy += 100;
if (jy < 50)
jy += 100;
if (jy < 70) /* Fix for leap years ? */
n = (jy - 72) / 4;
@ -887,15 +957,18 @@ double theta;
{
const double omega_E = 1.00273790934; /* Earth rotations per sidereal day (non-constant) */
const double jd = d + J1900 + jy * 365. + ((jy - 1) / 4);
const double UT = fmod(jd + 0.5, 1.0);
const double UT = fmod (jd + 0.5, 1.0);
double t_cen, GMST;
t_cen = (jd - UT - 2451545.0) / 36525.0;
GMST = 24110.54841 + t_cen * (8640184.812866 + t_cen * (0.093104 - t_cen * 6.2E-6));
GMST =
24110.54841 + t_cen * (8640184.812866 +
t_cen * (0.093104 - t_cen * 6.2E-6));
GMST = fmod( GMST + SECDAY * omega_E * UT, SECDAY);
GMST = fmod (GMST + SECDAY * omega_E * UT, SECDAY);
if(GMST < 0.0) GMST += SECDAY;
if (GMST < 0.0)
GMST += SECDAY;
theta = TWOPI * GMST / SECDAY;
}
@ -906,22 +979,23 @@ double theta;
long ids70;
ts70 = (*days50) - 7305.0;
ids70 = (long)(ts70 + 1.0e-8);
ids70 = (long) (ts70 + 1.0e-8);
ds70 = ids70;
trfac = ts70 - ds70;
/* CALCULATE GREENWICH LOCATION AT EPOCH */
theta = THGR70 + C1*ds70 + C1P2P*trfac + ts70*ts70*FK5R;
theta = THGR70 + C1 * ds70 + C1P2P * trfac + ts70 * ts70 * FK5R;
}
#else
#error 'Unknown method for theta-G calculation'
#endif
theta = fmod(theta, TWOPI);
if (theta < 0.0) theta += TWOPI;
theta = fmod (theta, TWOPI);
if (theta < 0.0)
theta += TWOPI;
*thegr = (real)theta;
*thegr = (real) theta;
} /* thetag */

View File

@ -8,68 +8,75 @@
#include <jpeglib.h>
#include <getopt.h>
struct image {
int naxis1,naxis2,naxis3;
struct image
{
int naxis1, naxis2, naxis3;
float *z;
float zmin,zmax;
double ra0,de0;
float avg,std;
float x0,y0;
float a[3],b[3],xrms,yrms;
float zmin, zmax;
double ra0, de0;
float avg, std;
float x0, y0;
float a[3], b[3], xrms, yrms;
float exptime;
double mjd;
char nfd[32];
int cospar;
};
struct jpeg_image {
int nx,ny,nz;
struct jpeg_image
{
int nx, ny, nz;
float *z;
};
struct jpeg_image read_jpg(char *filename);
void write_jpg(char *filename,struct jpeg_image img);
struct image read_fits(char *filename,int pnum);
void forward(double ra0,double de0,double ra,double de,double *x,double *y);
void reverse(double ra0,double de0,double x,double y,double *ra,double *de);
struct jpeg_image read_jpg (char *filename);
void write_jpg (char *filename, struct jpeg_image img);
struct image read_fits (char *filename, int pnum);
void forward (double ra0, double de0, double ra, double de, double *x,
double *y);
void reverse (double ra0, double de0, double x, double y, double *ra,
double *de);
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int i,j,k,l,m;
int i, j, k, l, m;
struct image img;
struct jpeg_image jpg,out;
double rx,ry,ra,de,rx0,ry0;
double x,y,d;
double drx=-10.0,dry=10.0;
double ra0=237.0,de0=12.5;
int arg=0;
char *fitsfile,*jpgfile,*outfile;
struct jpeg_image jpg, out;
double rx, ry, ra, de, rx0, ry0;
double x, y, d;
double drx = -10.0, dry = 10.0;
double ra0 = 237.0, de0 = 12.5;
int arg = 0;
char *fitsfile, *jpgfile, *outfile;
// Decode options
while ((arg=getopt(argc,argv,"j:f:o:R:D:s:"))!=-1) {
switch(arg) {
while ((arg = getopt (argc, argv, "j:f:o:R:D:s:")) != -1)
{
switch (arg)
{
case 'j':
jpgfile=optarg;
jpgfile = optarg;
break;
case 'f':
fitsfile=optarg;
fitsfile = optarg;
break;
case 'o':
outfile=optarg;
outfile = optarg;
break;
case 'R':
ra0=atof(optarg);
ra0 = atof (optarg);
break;
case 'D':
de0=atof(optarg);
de0 = atof (optarg);
break;
case 's':
dry=atof(optarg);
drx=-dry;
dry = atof (optarg);
drx = -dry;
break;
default:
@ -79,12 +86,12 @@ int main(int argc,char *argv[])
// Read image
img=read_fits(fitsfile,0);
jpg=read_jpg(jpgfile);
img = read_fits (fitsfile, 0);
jpg = read_jpg (jpgfile);
out.nx=3000;
out.ny=6000;
out.nz=3;
out.nx = 3000;
out.ny = 6000;
out.nz = 3;
/*
img.x0*=4.0;
@ -94,57 +101,61 @@ int main(int argc,char *argv[])
img.b[1]/=4.0;
img.b[2]/=4.0;
*/
out.z=(float *) malloc(sizeof(float)*out.nx*out.ny*out.nz);
out.z = (float *) malloc (sizeof (float) * out.nx * out.ny * out.nz);
for (i=0;i<out.nx;i++) {
for (j=0;j<out.ny;j++) {
for (i = 0; i < out.nx; i++)
{
for (j = 0; j < out.ny; j++)
{
// Set rx,ry
rx=drx*(float) (i-0.5*out.nx);
ry=dry*(float) (j-0.5*out.ny);
rx = drx * (float) (i - 0.5 * out.nx);
ry = dry * (float) (j - 0.5 * out.ny);
// Obtain ra/dec for output image
reverse(ra0,de0,rx,ry,&ra,&de);
reverse (ra0, de0, rx, ry, &ra, &de);
// Obtain rx/ry for input image
forward(img.ra0,img.de0,ra,de,&rx0,&ry0);
forward (img.ra0, img.de0, ra, de, &rx0, &ry0);
// Compute pixel position
d=img.a[1]*img.b[2]-img.a[2]*img.b[1];
x=(+rx0*img.b[2]-ry0*img.a[2])/d+img.x0;
y=(-rx0*img.b[1]+ry0*img.a[1])/d+img.y0;
d = img.a[1] * img.b[2] - img.a[2] * img.b[1];
x = (+rx0 * img.b[2] - ry0 * img.a[2]) / d + img.x0;
y = (-rx0 * img.b[1] + ry0 * img.a[1]) / d + img.y0;
// Fill image
for (k=0;k<jpg.nz;k++) {
l=out.nz*(i+out.nx*(out.ny-j-1))+k;
m=jpg.nz*((int) x+jpg.nx*(int) (jpg.ny-y-1))+k;
if (x>0.0 && x<jpg.nx && y>0.0 && y<jpg.ny)
out.z[l]=jpg.z[m];
for (k = 0; k < jpg.nz; k++)
{
l = out.nz * (i + out.nx * (out.ny - j - 1)) + k;
m = jpg.nz * ((int) x + jpg.nx * (int) (jpg.ny - y - 1)) + k;
if (x > 0.0 && x < jpg.nx && y > 0.0 && y < jpg.ny)
out.z[l] = jpg.z[m];
else
out.z[l]=0.0;
out.z[l] = 0.0;
}
}
}
// Dump
write_jpg(outfile,out);
write_jpg (outfile, out);
// Free
free(img.z);
free(jpg.z);
free(out.z);
free (img.z);
free (jpg.z);
free (out.z);
return 0;
}
// Read fits image
struct image read_fits(char *filename,int pnum)
struct image
read_fits (char *filename, int pnum)
{
int i,j,k,l,m;
int i, j, k, l, m;
qfitsloader ql;
char key[FITS_LINESZ+1] ;
char key[FITS_LINESZ + 1];
struct image img;
float s1,s2,avg,std;
float s1, s2, avg, std;
// Set plane
ql.xtnum = 0;
@ -154,172 +165,191 @@ struct image read_fits(char *filename,int pnum)
ql.ptype = PTYPE_FLOAT;
// Set filename
ql.filename=filename;
ql.filename = filename;
// Image size
img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1"));
img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2"));
img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1"));
img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2"));
// MJD
img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS"));
strcpy(img.nfd,qfits_query_hdr(filename,"DATE-OBS"));
img.exptime=atof(qfits_query_hdr(filename,"EXPTIME"));
img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS"));
strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS"));
img.exptime = atof (qfits_query_hdr (filename, "EXPTIME"));
// COSPAR ID
img.cospar=atoi(qfits_query_hdr(filename,"COSPAR"));
img.cospar = atoi (qfits_query_hdr (filename, "COSPAR"));
// Transformation
img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS"));
img.ra0=atof(qfits_query_hdr(filename,"CRVAL1"));
img.de0=atof(qfits_query_hdr(filename,"CRVAL2"));
img.x0=atof(qfits_query_hdr(filename,"CRPIX1"));
img.y0=atof(qfits_query_hdr(filename,"CRPIX2"));
img.a[0]=0.0;
img.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1"));
img.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2"));
img.b[0]=0.0;
img.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1"));
img.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2"));
img.xrms=3600.0*atof(qfits_query_hdr(filename,"CRRES1"));
img.yrms=3600.0*atof(qfits_query_hdr(filename,"CRRES2"));
img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS"));
img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1"));
img.de0 = atof (qfits_query_hdr (filename, "CRVAL2"));
img.x0 = atof (qfits_query_hdr (filename, "CRPIX1"));
img.y0 = atof (qfits_query_hdr (filename, "CRPIX2"));
img.a[0] = 0.0;
img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1"));
img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2"));
img.b[0] = 0.0;
img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1"));
img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2"));
img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1"));
img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2"));
// Initialize load
if (qfitsloader_init(&ql) != 0)
printf("Error initializing data loading\n");
if (qfitsloader_init (&ql) != 0)
printf ("Error initializing data loading\n");
// Test load
if (qfits_loadpix(&ql) != 0)
printf("Error loading actual data\n");
if (qfits_loadpix (&ql) != 0)
printf ("Error loading actual data\n");
// Allocate image memory
img.z=(float *) malloc(sizeof(float) * img.naxis1*img.naxis2);
img.z = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
// Fill z array
for (i=0,l=0,m=0;i<img.naxis1;i++) {
for (j=0;j<img.naxis2;j++) {
img.z[l]=ql.fbuf[l];
for (i = 0, l = 0, m = 0; i < img.naxis1; i++)
{
for (j = 0; j < img.naxis2; j++)
{
img.z[l] = ql.fbuf[l];
l++;
}
}
// Get levels
for (i=0,s1=0.0,s2=0.0;i<img.naxis1*img.naxis2;i++) {
s1+=img.z[i];
s2+=img.z[i]*img.z[i];
for (i = 0, s1 = 0.0, s2 = 0.0; i < img.naxis1 * img.naxis2; i++)
{
s1 += img.z[i];
s2 += img.z[i] * img.z[i];
}
img.avg=s1/(float) (img.naxis1*img.naxis2);
img.std=sqrt(s2/(float) (img.naxis1*img.naxis2)-img.avg*img.avg);
img.zmin=img.avg-4.0*img.std;
img.zmax=img.avg+12.0*img.std;
img.avg = s1 / (float) (img.naxis1 * img.naxis2);
img.std = sqrt (s2 / (float) (img.naxis1 * img.naxis2) - img.avg * img.avg);
img.zmin = img.avg - 4.0 * img.std;
img.zmax = img.avg + 12.0 * img.std;
return img;
}
struct jpeg_image read_jpg(char *filename)
struct jpeg_image
read_jpg (char *filename)
{
int i=0,j,k,l,m;
unsigned long location=0;
int i = 0, j, k, l, m;
unsigned long location = 0;
struct jpeg_image img;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
unsigned char *raw_image=NULL;
unsigned char *raw_image = NULL;
FILE *file;
// Open file
file=fopen(filename,"rb");
file = fopen (filename, "rb");
if (!file)
perror("Error opening file");
perror ("Error opening file");
// Get header info, decompress
cinfo.err=jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo,file);
jpeg_read_header(&cinfo,TRUE);
jpeg_start_decompress(&cinfo);
cinfo.err = jpeg_std_error (&jerr);
jpeg_create_decompress (&cinfo);
jpeg_stdio_src (&cinfo, file);
jpeg_read_header (&cinfo, TRUE);
jpeg_start_decompress (&cinfo);
// Allocate memory
raw_image=(unsigned char *) malloc(cinfo.output_width*cinfo.output_height*cinfo.num_components);
raw_image =
(unsigned char *) malloc (cinfo.output_width * cinfo.output_height *
cinfo.num_components);
// Read image, one scan at a time
row_pointer[0]=(unsigned char *) malloc(cinfo.output_width*cinfo.num_components);
while(cinfo.output_scanline<cinfo.image_height) {
jpeg_read_scanlines(&cinfo,row_pointer,1);
for(i=0;i<cinfo.image_width*cinfo.num_components;i++)
raw_image[location++]=row_pointer[0][i];
row_pointer[0] =
(unsigned char *) malloc (cinfo.output_width * cinfo.num_components);
while (cinfo.output_scanline < cinfo.image_height)
{
jpeg_read_scanlines (&cinfo, row_pointer, 1);
for (i = 0; i < cinfo.image_width * cinfo.num_components; i++)
raw_image[location++] = row_pointer[0][i];
}
// wrap up decompression, destroy objects, free pointers and close open files
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
jpeg_finish_decompress (&cinfo);
jpeg_destroy_decompress (&cinfo);
// Copy image to image struct
img.nx=cinfo.image_width;
img.ny=cinfo.image_height;
img.nz=cinfo.num_components;
img.z=(float *) malloc(sizeof(float)*img.nx*img.ny*img.nz);
img.nx = cinfo.image_width;
img.ny = cinfo.image_height;
img.nz = cinfo.num_components;
img.z = (float *) malloc (sizeof (float) * img.nx * img.ny * img.nz);
// Fill image
for (i=0;i<img.nx;i++) {
for (j=0;j<img.ny;j++) {
for (k=0;k<img.nz;k++) {
l=img.nz*(i+img.nx*j)+k;
img.z[l]=(float) raw_image[l];
for (i = 0; i < img.nx; i++)
{
for (j = 0; j < img.ny; j++)
{
for (k = 0; k < img.nz; k++)
{
l = img.nz * (i + img.nx * j) + k;
img.z[l] = (float) raw_image[l];
}
}
}
// Free allocated memory
free(row_pointer[0]);
free(raw_image);
free (row_pointer[0]);
free (raw_image);
// Close file
fclose(file);
fclose (file);
return img;
}
// Write jpg
void write_jpg(char *filename,struct jpeg_image img)
void
write_jpg (char *filename, struct jpeg_image img)
{
int i,j,k,l,m;
int i, j, k, l, m;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
FILE *outfile;
unsigned char *raw_image=NULL;
unsigned char *raw_image = NULL;
outfile=fopen(filename,"wb");
cinfo.err=jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo,outfile);
cinfo.image_width=img.nx;
cinfo.image_height=img.ny;
cinfo.input_components=3;
cinfo.in_color_space=JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_start_compress(&cinfo,TRUE);
outfile = fopen (filename, "wb");
cinfo.err = jpeg_std_error (&jerr);
jpeg_create_compress (&cinfo);
jpeg_stdio_dest (&cinfo, outfile);
cinfo.image_width = img.nx;
cinfo.image_height = img.ny;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults (&cinfo);
jpeg_start_compress (&cinfo, TRUE);
// Allocate memory
raw_image=(unsigned char *) malloc(cinfo.image_width*cinfo.image_height*cinfo.input_components);
raw_image =
(unsigned char *) malloc (cinfo.image_width * cinfo.image_height *
cinfo.input_components);
// Fill image
for (i=0;i<img.nx;i++) {
for (j=0;j<img.ny;j++) {
for (k=0;k<img.nz;k++) {
l=img.nz*(i+img.nx*j)+k;
raw_image[l]=(unsigned char) img.z[l];
for (i = 0; i < img.nx; i++)
{
for (j = 0; j < img.ny; j++)
{
for (k = 0; k < img.nz; k++)
{
l = img.nz * (i + img.nx * j) + k;
raw_image[l] = (unsigned char) img.z[l];
}
}
}
while(cinfo.next_scanline<cinfo.image_height) {
row_pointer[0]=&raw_image[cinfo.next_scanline*cinfo.image_width*cinfo.input_components];
jpeg_write_scanlines(&cinfo,row_pointer,1);
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] =
&raw_image[cinfo.next_scanline * cinfo.image_width *
cinfo.input_components];
jpeg_write_scanlines (&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
fclose(outfile);
jpeg_finish_compress (&cinfo);
jpeg_destroy_compress (&cinfo);
fclose (outfile);
return;
}

File diff suppressed because it is too large Load Diff

View File

@ -7,118 +7,140 @@
#define SWAP(a,b) {(a)+=(b);(b)=(a)-(b);(a)-=(b);}
// Downhill Simplex Minimization
int dsmin(double **p,double *y,int n,double ftol,double (*func)(double *))
int
dsmin (double **p, double *y, int n, double ftol, double (*func) (double *))
{
int i,j,nfunk=0;
int ihi,ilo,ise;
double *ptry,*pmid,*psum;
double tol,ytry,rtol,ysave;
double *vector_sum(double **,int);
double dsmod(double **,double *,double *,int,double (*func)(double *),int,double);
int i, j, nfunk = 0;
int ihi, ilo, ise;
double *ptry, *pmid, *psum;
double tol, ytry, rtol, ysave;
double *vector_sum (double **, int);
double dsmod (double **, double *, double *, int, double (*func) (double *),
int, double);
// Allocate memory
psum=(double *) malloc(sizeof(double) * n);
psum = (double *) malloc (sizeof (double) * n);
// Get function values
for (i=0;i<=n;i++)
y[i]=func(p[i]);
for (i = 0; i <= n; i++)
y[i] = func (p[i]);
// Sum vectors
psum=vector_sum(p,n);
psum = vector_sum (p, n);
// Start forever loop
for (;;) {
for (;;)
{
// Find high and low point
ilo=0;
ihi = (y[0]>y[1]) ? (ise=1,0) : (ise=0,1);
for (i=0;i<=n;i++) {
if (y[i]<=y[ilo]) ilo=i;
if (y[i]>y[ihi]) {
ise=ihi;
ihi=i;
} else if (y[i]>y[ise] && i!=ihi) ise=i;
ilo = 0;
ihi = (y[0] > y[1]) ? (ise = 1, 0) : (ise = 0, 1);
for (i = 0; i <= n; i++)
{
if (y[i] <= y[ilo])
ilo = i;
if (y[i] > y[ihi])
{
ise = ihi;
ihi = i;
}
else if (y[i] > y[ise] && i != ihi)
ise = i;
}
// Compute fractional range from highest to lowest point
rtol=2.0*fabs(y[ihi]-y[ilo])/(fabs(y[ihi])+fabs(y[ilo])+TINY);
rtol =
2.0 * fabs (y[ihi] - y[ilo]) / (fabs (y[ihi]) + fabs (y[ilo]) + TINY);
// Return if fractional tolerance is acceptable
if (rtol<ftol)
if (rtol < ftol)
break;
if (nfunk>=NMAX) {
printf("dsmin: NMAX exceeded!\n");
if (nfunk >= NMAX)
{
printf ("dsmin: NMAX exceeded!\n");
return -1;
}
nfunk+=2;
nfunk += 2;
// Reflect simplex
ytry=dsmod(p,y,psum,n,func,ihi,-1.0);
ytry = dsmod (p, y, psum, n, func, ihi, -1.0);
if (ytry<=y[ilo]) // Goes right direction, extrapolate by factor 2
ytry=dsmod(p,y,psum,n,func,ihi,2.0);
else if (ytry>=y[ise]) { // 1D contraction
ysave=y[ihi];
ytry=dsmod(p,y,psum,n,func,ihi,0.5);
if (ytry>=ysave) {
for (i=0;i<=n;i++) {
if (i!=ilo) {
for (j=0;j<n;j++)
p[i][j]=psum[j]=0.5*(p[i][j]+p[ilo][j]);
y[i]=(*func)(psum);
if (ytry <= y[ilo]) // Goes right direction, extrapolate by factor 2
ytry = dsmod (p, y, psum, n, func, ihi, 2.0);
else if (ytry >= y[ise])
{ // 1D contraction
ysave = y[ihi];
ytry = dsmod (p, y, psum, n, func, ihi, 0.5);
if (ytry >= ysave)
{
for (i = 0; i <= n; i++)
{
if (i != ilo)
{
for (j = 0; j < n; j++)
p[i][j] = psum[j] = 0.5 * (p[i][j] + p[ilo][j]);
y[i] = (*func) (psum);
}
}
nfunk+=n;
nfunk += n;
psum=vector_sum(p,n);
psum = vector_sum (p, n);
}
} else --nfunk;
}
free(psum);
else
--nfunk;
}
free (psum);
return nfunk;
}
// Sum vectors
double *vector_sum(double **p,int n)
double *
vector_sum (double **p, int n)
{
int i,j;
double sum,*psum;
int i, j;
double sum, *psum;
psum=(double *) malloc(sizeof(double) * n);
psum = (double *) malloc (sizeof (double) * n);
for (i=0;i<n;i++) {
sum=0.;
for (j=0;j<=n;j++)
sum+=p[j][i];
psum[i]=sum;
for (i = 0; i < n; i++)
{
sum = 0.;
for (j = 0; j <= n; j++)
sum += p[j][i];
psum[i] = sum;
}
return psum;
}
// Simplex modification
double dsmod(double **p,double *y,double *psum,int n,double (*func)(double *),int ihi,double fac)
double
dsmod (double **p, double *y, double *psum, int n, double (*func) (double *),
int ihi, double fac)
{
int i;
double fac1,fac2,ytry,*ptry;
double fac1, fac2, ytry, *ptry;
ptry=(double *) malloc(sizeof(double) * n);
fac1=(1.0-fac)/(double) n;
fac2=fac1-fac;
ptry = (double *) malloc (sizeof (double) * n);
fac1 = (1.0 - fac) / (double) n;
fac2 = fac1 - fac;
for (i=0;i<n;i++)
ptry[i]=psum[i]*fac1-p[ihi][i]*fac2;
ytry=(*func)(ptry);
if (ytry<y[ihi]) {
y[ihi]=ytry;
for (i=0;i<n;i++) {
psum[i] += ptry[i]-p[ihi][i];
p[ihi][i]=ptry[i];
for (i = 0; i < n; i++)
ptry[i] = psum[i] * fac1 - p[ihi][i] * fac2;
ytry = (*func) (ptry);
if (ytry < y[ihi])
{
y[ihi] = ytry;
for (i = 0; i < n; i++)
{
psum[i] += ptry[i] - p[ihi][i];
p[ihi][i] = ptry[i];
}
}
free(ptry);
free (ptry);
return ytry;
}

View File

@ -14,136 +14,151 @@
#define XKMPAU 149597879.691 // AU in km
#define FLAT (1.0/298.257)
long Isat=0;
long Isatsel=0;
long Isat = 0;
long Isatsel = 0;
extern double SGDP4_jd0;
struct site {
struct site
{
int id;
double lng,lat;
double lng, lat;
float alt;
char observer[64];
};
struct site get_site(int site_id);
int fgetline(FILE *file,char *s,int lim);
double modulo(double x,double y);
double gmst(double mjd);
double dgmst(double mjd);
double date2mjd(int year,int month,double day);
void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de);
void obspos_xyz(double mjd,double lng,double lat,float alt,xyz_t *pos,xyz_t *vel);
void mjd2date(double mjd,char *date);
double nfd2mjd(char *date);
void dec2s(double x,char *s,int type);
double doy2mjd(int year,double doy);
struct site get_site (int site_id);
int fgetline (FILE * file, char *s, int lim);
double modulo (double x, double y);
double gmst (double mjd);
double dgmst (double mjd);
double date2mjd (int year, int month, double day);
void precess (double mjd0, double ra0, double de0, double mjd, double *ra,
double *de);
void obspos_xyz (double mjd, double lng, double lat, float alt, xyz_t * pos,
xyz_t * vel);
void mjd2date (double mjd, char *date);
double nfd2mjd (char *date);
void dec2s (double x, char *s, int type);
double doy2mjd (int year, double doy);
void compute_position(double mjd,xyz_t satpos,struct site s,int satno,char *desig,int precess_flag)
void
compute_position (double mjd, xyz_t satpos, struct site s, int satno,
char *desig, int precess_flag)
{
char sra[15],sde[15],nfd[32];
xyz_t obspos,obsvel;
double dx,dy,dz,mjd0=51544.5;
double ra,de,ra0,de0,r;
char sra[15], sde[15], nfd[32];
xyz_t obspos, obsvel;
double dx, dy, dz, mjd0 = 51544.5;
double ra, de, ra0, de0, r;
// Compute positions
obspos_xyz(mjd,s.lng,s.lat,s.alt,&obspos,&obsvel);
obspos_xyz (mjd, s.lng, s.lat, s.alt, &obspos, &obsvel);
// compute difference vector
dx=satpos.x-obspos.x;
dy=satpos.y-obspos.y;
dz=satpos.z-obspos.z;
dx = satpos.x - obspos.x;
dy = satpos.y - obspos.y;
dz = satpos.z - obspos.z;
// Celestial position
r=sqrt(dx*dx+dy*dy+dz*dz);
ra=modulo(atan2(dy,dx)*R2D,360.0);
de=asin(dz/r)*R2D;
r = sqrt (dx * dx + dy * dy + dz * dz);
ra = modulo (atan2 (dy, dx) * R2D, 360.0);
de = asin (dz / r) * R2D;
// Precess position
if (precess_flag==1) {
precess(mjd,ra,de,mjd0,&ra0,&de0);
} else {
ra0=ra;
de0=de;
if (precess_flag == 1)
{
precess (mjd, ra, de, mjd0, &ra0, &de0);
}
else
{
ra0 = ra;
de0 = de;
}
// Angle format 2: RA/DEC = HHMMmmm+DDMMmm MX (MX in minutes of arc)
dec2s(ra0/15.0,sra,0);
dec2s(de0,sde,1);
dec2s (ra0 / 15.0, sra, 0);
dec2s (de0, sde, 1);
// Get date
mjd2date(mjd,nfd);
mjd2date (mjd, nfd);
// Format output
printf("%05d %.2s %-6s %04d G %s 17 25 %s%s 37 S\n",satno,desig,desig+2,s.id,nfd,sra,sde);
printf ("%05d %.2s %-6s %04d G %s 17 25 %s%s 37 S\n", satno, desig,
desig + 2, s.id, nfd, sra, sde);
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int arg=0,satno=99999;
int arg = 0, satno = 99999;
struct site s;
double mjd=0;
char nfd[32],tlefile[LIM],*fname,line[LIM],desig[10]="14999A";
int i,imode;
double mjd = 0;
char nfd[32], tlefile[LIM], *fname, line[LIM], desig[10] = "14999A";
int i, imode;
FILE *file;
orbit_t orb;
xyz_t satpos,satvel;
xyz_t satpos, satvel;
char *env;
int usefile=0,usepos=0,status,gmat=0,precess_flag=1;
int usefile = 0, usepos = 0, status, gmat = 0, precess_flag = 1;
// Get site
env=getenv("ST_COSPAR");
if (env!=NULL) {
s=get_site(atoi(env));
} else {
printf("ST_COSPAR environment variable not found.\n");
env = getenv ("ST_COSPAR");
if (env != NULL)
{
s = get_site (atoi (env));
}
else
{
printf ("ST_COSPAR environment variable not found.\n");
}
// Decode options
while ((arg=getopt(argc,argv,"t:c:i:s:f:p:d:m:gP"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "t:c:i:s:f:p:d:m:gP")) != -1)
{
switch (arg)
{
case 't':
strcpy(nfd,optarg);
mjd=nfd2mjd(nfd);
strcpy (nfd, optarg);
mjd = nfd2mjd (nfd);
break;
case 'g':
gmat=1;
gmat = 1;
break;
case 'P':
precess_flag=0;
precess_flag = 0;
break;
case 'm':
mjd=atof(optarg);
mjd = atof (optarg);
break;
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 's':
s=get_site(atoi(optarg));
s = get_site (atoi (optarg));
break;
case 'f':
fname=optarg;
usefile=1;
fname = optarg;
usefile = 1;
break;
case 'p':
fname=optarg;
usepos=1;
fname = optarg;
usepos = 1;
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'd':
strcpy(desig,optarg);
strcpy (desig, optarg);
break;
default:
@ -152,229 +167,266 @@ int main(int argc,char *argv[])
}
// Get start mjd for finding elset
if (usefile==1 && usepos==0) {
file=fopen(fname,"r");
fgetline(file,line,LIM);
status=sscanf(line,"%lf",&mjd);
fclose(file);
if (usefile == 1 && usepos == 0)
{
file = fopen (fname, "r");
fgetline (file, line, LIM);
status = sscanf (line, "%lf", &mjd);
fclose (file);
}
// Open catalog
if (usepos==0) {
file=fopen(tlefile,"r");
if (file==NULL)
fatal_error("Failed to open %s\n",tlefile);
if (usepos == 0)
{
file = fopen (tlefile, "r");
if (file == NULL)
fatal_error ("Failed to open %s\n", tlefile);
// Read TLE
do {
status=read_twoline(file,satno,&orb);
} while (doy2mjd(orb.ep_year,orb.ep_day)<mjd && status!=-1);
fclose(file);
do
{
status = read_twoline (file, satno, &orb);
}
while (doy2mjd (orb.ep_year, orb.ep_day) < mjd && status != -1);
fclose (file);
// Check for match
if (orb.satno!=satno) {
if (orb.satno != satno)
{
// fprintf(stderr,"object %d not found in %s\n",p.satno,filename);
return 0;
}
// Initialize
imode=init_sgdp4(&orb);
if (imode==SGDP4_ERROR) {
fprintf(stderr,"Error initializing SGDP4\n");
exit(0);
imode = init_sgdp4 (&orb);
if (imode == SGDP4_ERROR)
{
fprintf (stderr, "Error initializing SGDP4\n");
exit (0);
}
// Compute
if (usefile==0) {
satpos_xyz(mjd+2400000.5,&satpos,&satvel);
compute_position(mjd,satpos,s,orb.satno,orb.desig,precess_flag);
} else {
if (usefile == 0)
{
satpos_xyz (mjd + 2400000.5, &satpos, &satvel);
compute_position (mjd, satpos, s, orb.satno, orb.desig,
precess_flag);
}
else
{
file=fopen(fname,"r");
while (fgetline(file,line,LIM)>0) {
status=sscanf(line,"%lf",&mjd);
satpos_xyz(mjd+2400000.5,&satpos,&satvel);
strcpy(orb.desig,"14999A"); // FIX!
compute_position(mjd,satpos,s,orb.satno,orb.desig,precess_flag);
file = fopen (fname, "r");
while (fgetline (file, line, LIM) > 0)
{
status = sscanf (line, "%lf", &mjd);
satpos_xyz (mjd + 2400000.5, &satpos, &satvel);
strcpy (orb.desig, "14999A"); // FIX!
compute_position (mjd, satpos, s, orb.satno, orb.desig,
precess_flag);
}
fclose(file);
fclose (file);
}
} else {
file=fopen(fname,"r");
while (fgetline(file,line,LIM)>0) {
if (!isdigit(line[0]))
}
else
{
file = fopen (fname, "r");
while (fgetline (file, line, LIM) > 0)
{
if (!isdigit (line[0]))
continue;
if (line[10]=='T') {
status=sscanf(line,"%s %lf %lf %lf",nfd,&satpos.x,&satpos.y,&satpos.z);
mjd=nfd2mjd(nfd);
} else {
status=sscanf(line,"%lf %lf %lf %lf",&mjd,&satpos.x,&satpos.y,&satpos.z);
if (gmat==1)
mjd+=29999.5;
if (line[10] == 'T')
{
status =
sscanf (line, "%s %lf %lf %lf", nfd, &satpos.x, &satpos.y,
&satpos.z);
mjd = nfd2mjd (nfd);
}
compute_position(mjd,satpos,s,satno,desig,precess_flag);
else
{
status =
sscanf (line, "%lf %lf %lf %lf", &mjd, &satpos.x, &satpos.y,
&satpos.z);
if (gmat == 1)
mjd += 29999.5;
}
fclose(file);
compute_position (mjd, satpos, s, satno, desig, precess_flag);
}
fclose (file);
}
return 0;
}
// Get observing site
struct site get_site(int site_id)
struct site
get_site (int site_id)
{
int i=0;
int i = 0;
char line[LIM];
FILE *file;
int id;
double lat,lng;
double lat, lng;
float alt;
char abbrev[3],observer[64];
char abbrev[3], observer[64];
struct site s;
char *env,filename[LIM];
char *env, filename[LIM];
env=getenv("ST_DATADIR");
sprintf(filename,"%s/data/sites.txt",env);
file=fopen(filename,"r");
if (file==NULL) {
printf("File with site information not found!\n");
env = getenv ("ST_DATADIR");
sprintf (filename, "%s/data/sites.txt", env);
file = fopen (filename, "r");
if (file == NULL)
{
printf ("File with site information not found!\n");
return s;
}
while (fgets(line,LIM,file)!=NULL) {
while (fgets (line, LIM, file) != NULL)
{
// Skip
if (strstr(line,"#")!=NULL)
if (strstr (line, "#") != NULL)
continue;
// Strip newline
line[strlen(line)-1]='\0';
line[strlen (line) - 1] = '\0';
// Read data
sscanf(line,"%4d %2s %lf %lf %f",
&id,abbrev,&lat,&lng,&alt);
strcpy(observer,line+38);
sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt);
strcpy (observer, line + 38);
// Change to km
alt/=1000.0;
alt /= 1000.0;
// Copy site
if (id==site_id) {
s.lat=lat;
s.lng=lng;
s.alt=alt;
s.id=id;
strcpy(s.observer,observer);
if (id == site_id)
{
s.lat = lat;
s.lng = lng;
s.alt = alt;
s.id = id;
strcpy (s.observer, observer);
}
}
fclose(file);
fclose (file);
return s;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Greenwich Mean Sidereal Time
double gmst(double mjd)
double
gmst (double mjd)
{
double t,gmst;
double t, gmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0);
gmst =
modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) +
t * t * (0.000387933 - t / 38710000), 360.0);
return gmst;
}
// Greenwich Mean Sidereal Time
double dgmst(double mjd)
double
dgmst (double mjd)
{
double t,dgmst;
double t, dgmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
dgmst=360.98564736629+t*(0.000387933-t/38710000);
dgmst = 360.98564736629 + t * (0.000387933 - t / 38710000);
return dgmst;
}
// Observer position
void obspos_xyz(double mjd,double lng,double lat,float alt,xyz_t *pos,xyz_t *vel)
void
obspos_xyz (double mjd, double lng, double lat, float alt, xyz_t * pos,
xyz_t * vel)
{
double ff,gc,gs,theta,s,dtheta;
double ff, gc, gs, theta, s, dtheta;
s=sin(lat*D2R);
ff=sqrt(1.0-FLAT*(2.0-FLAT)*s*s);
gc=1.0/ff+alt/XKMPER;
gs=(1.0-FLAT)*(1.0-FLAT)/ff+alt/XKMPER;
s = sin (lat * D2R);
ff = sqrt (1.0 - FLAT * (2.0 - FLAT) * s * s);
gc = 1.0 / ff + alt / XKMPER;
gs = (1.0 - FLAT) * (1.0 - FLAT) / ff + alt / XKMPER;
theta=gmst(mjd)+lng;
dtheta=dgmst(mjd)*D2R/86400;
theta = gmst (mjd) + lng;
dtheta = dgmst (mjd) * D2R / 86400;
pos->x=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER;
pos->y=gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER;
pos->z=gs*sin(lat*D2R)*XKMPER;
vel->x=-gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER*dtheta;
vel->y=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER*dtheta;
vel->z=0.0;
pos->x = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER;
pos->y = gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER;
pos->z = gs * sin (lat * D2R) * XKMPER;
vel->x = -gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER * dtheta;
vel->y = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER * dtheta;
vel->z = 0.0;
return;
}
// Precess a celestial position
void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de)
void
precess (double mjd0, double ra0, double de0, double mjd, double *ra,
double *de)
{
double t0,t;
double zeta,z,theta;
double a,b,c;
double t0, t;
double zeta, z, theta;
double a, b, c;
// Angles in radians
ra0*=D2R;
de0*=D2R;
ra0 *= D2R;
de0 *= D2R;
// Time in centuries
t0=(mjd0-51544.5)/36525.0;
t=(mjd-mjd0)/36525.0;
t0 = (mjd0 - 51544.5) / 36525.0;
t = (mjd - mjd0) / 36525.0;
// Precession angles
zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t;
zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t;
zeta*=D2R/3600.0;
z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t;
z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t;
z*=D2R/3600.0;
theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t;
theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t;
theta*=D2R/3600.0;
zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t;
zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t;
zeta *= D2R / 3600.0;
z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t;
z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t;
z *= D2R / 3600.0;
theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t;
theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t;
theta *= D2R / 3600.0;
a=cos(de0)*sin(ra0+zeta);
b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0);
c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0);
a = cos (de0) * sin (ra0 + zeta);
b = cos (theta) * cos (de0) * cos (ra0 + zeta) - sin (theta) * sin (de0);
c = sin (theta) * cos (de0) * cos (ra0 + zeta) + cos (theta) * sin (de0);
*ra=(atan2(a,b)+z)*R2D;
*de=asin(c)*R2D;
*ra = (atan2 (a, b) + z) * R2D;
*de = asin (c) * R2D;
if (*ra<360.0)
*ra+=360.0;
if (*ra>360.0)
*ra-=360.0;
if (*ra < 360.0)
*ra += 360.0;
if (*ra > 360.0)
*ra -= 360.0;
return;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\t')
c=' ';
c = ' ';
if (c == '\n')
s[i++] = c;
s[i] = '\0';
@ -382,136 +434,152 @@ int fgetline(FILE *file,char *s,int lim)
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// Compute Date from Julian Day
void mjd2date(double mjd,char *date)
void
mjd2date (double mjd, char *date)
{
double f,jd,dday;
int z,alpha,a,b,c,d,e;
int year,month,day,hour,min;
float sec,x;
double f, jd, dday;
int z, alpha, a, b, c, d, e;
int year, month, day, hour, min;
float sec, x;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
dday=b-d-floor(30.6001*e)+f;
if (e<14)
month=e-1;
dday = b - d - floor (30.6001 * e) + f;
if (e < 14)
month = e - 1;
else
month=e-13;
month = e - 13;
if (month>2)
year=c-4716;
if (month > 2)
year = c - 4716;
else
year=c-4715;
year = c - 4715;
day=(int) floor(dday);
x=24.0*(dday-day);
x=3600.*fabs(x)+0.0001;
sec=fmod(x,60.);
x=(x-sec)/60.;
min=fmod(x,60.);
x=(x-min)/60.;
hour=x;
sec=floor(1000.0*sec)/1000.0;
day = (int) floor (dday);
x = 24.0 * (dday - day);
x = 3600. * fabs (x) + 0.0001;
sec = fmod (x, 60.);
x = (x - sec) / 60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
hour = x;
sec = floor (1000.0 * sec) / 1000.0;
sprintf(date,"%04d%02d%02d%02d%02d%05.0f",year,month,day,hour,min,sec*1000);
sprintf (date, "%04d%02d%02d%02d%02d%05.0f", year, month, day, hour, min,
sec * 1000);
return;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min;
int year, month, day, hour, min;
float sec;
double mjd,dday;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%f",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%f", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
// Convert Decimal into Sexagesimal
void dec2s(double x,char *s,int type)
void
dec2s (double x, char *s, int type)
{
int i;
double sec,deg,min,fmin;
double sec, deg, min, fmin;
char sign;
sign=(x<0 ? '-' : '+');
x=60.*fabs(x);
sign = (x < 0 ? '-' : '+');
x = 60. * fabs (x);
min=fmod(x,60.);
x=(x-min)/60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
// deg=fmod(x,60.);
deg=x;
if (type==0)
fmin=1000.0*(min-floor(min));
deg = x;
if (type == 0)
fmin = 1000.0 * (min - floor (min));
else
fmin=100.0*(min-floor(min));
fmin = 100.0 * (min - floor (min));
if (type==0)
sprintf(s,"%02.0f%02.0f%03.0f",deg,floor(min),floor(fmin));
if (type == 0)
sprintf (s, "%02.0f%02.0f%03.0f", deg, floor (min), floor (fmin));
else
sprintf(s,"%c%02.0f%02.0f%02.0f",sign,deg,floor(min),floor(fmin));
sprintf (s, "%c%02.0f%02.0f%02.0f", sign, deg, floor (min), floor (fmin));
return;
}
// DOY to MJD
double doy2mjd(int year,double doy)
double
doy2mjd (int year, double doy)
{
int month,k=2;
int month, k = 2;
double day;
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
month=floor(9.0*(k+doy)/275.0+0.98);
month = floor (9.0 * (k + doy) / 275.0 + 0.98);
if (doy<32)
month=1;
if (doy < 32)
month = 1;
day=doy-floor(275.0*month/9.0)+k*floor((month+9.0)/12.0)+30.0;
day =
doy - floor (275.0 * month / 9.0) + k * floor ((month + 9.0) / 12.0) +
30.0;
return date2mjd(year,month,day);
return date2mjd (year, month, day);
}

View File

@ -16,286 +16,325 @@
#define D2R M_PI/180.0
extern double SGDP4_jd0;
void orbit(orbit_t orb,float *aodp,float *perigee,float *apogee,float *period);
void format_tle(orbit_t orb,char *line1,char *line2);
double mjd2doy(double mjd,int *yr);
double nfd2mjd(char *date);
double date2mjd(int year,int month,double day);
void mjd2date(double mjd,int *year,int *month,double *day);
double gmst(double mjd);
double modulo(double x,double y);
void orbit (orbit_t orb, float *aodp, float *perigee, float *apogee,
float *period);
void format_tle (orbit_t orb, char *line1, char *line2);
double mjd2doy (double mjd, int *yr);
double nfd2mjd (char *date);
double date2mjd (int year, int month, double day);
void mjd2date (double mjd, int *year, int *month, double *day);
double gmst (double mjd);
double modulo (double x, double y);
void usage(void)
void
usage (void)
{
printf("faketle q:Q:i:I:w:t:m:n:d:\n\n");
printf ("faketle q:Q:i:I:w:t:m:n:d:\n\n");
printf("-q Perigee altitude (km)\n");
printf("-Q Apogee altitude (km)\n");
printf("-I Orbital inclination (deg)\n");
printf("-n RA of the ascending node (deg)\n");
printf("-w Argument of perigee (deg)\n");
printf("-m Mean anomaly (deg)\n");
printf("-t Epoch (YYYY-mm-ddThh:mm:ss)\n");
printf("-i Satellite number\n");
printf("-d Time offset from epoch (s)\n");
printf ("-q Perigee altitude (km)\n");
printf ("-Q Apogee altitude (km)\n");
printf ("-I Orbital inclination (deg)\n");
printf ("-n RA of the ascending node (deg)\n");
printf ("-w Argument of perigee (deg)\n");
printf ("-m Mean anomaly (deg)\n");
printf ("-t Epoch (YYYY-mm-ddThh:mm:ss)\n");
printf ("-i Satellite number\n");
printf ("-d Time offset from epoch (s)\n");
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
orbit_t orb;
float aodp,perigee,apogee,period,dt=0.0;
char line1[70],line2[70];
int arg=0;
double mjd,dh;
float aodp, perigee, apogee, period, dt = 0.0;
char line1[70], line2[70];
int arg = 0;
double mjd, dh;
// Initialize
orb.satno=99999;
orb.eqinc=0.0;
orb.ascn=0.0;
orb.argp=0.0;
orb.mnan=0.0;
orb.bstar=0.5e-4;
orb.ep_day=1.000;
orb.ep_year=2013;
orb.satno = 99999;
orb.eqinc = 0.0;
orb.ascn = 0.0;
orb.argp = 0.0;
orb.mnan = 0.0;
orb.bstar = 0.5e-4;
orb.ep_day = 1.000;
orb.ep_year = 2013;
// Decode options
while ((arg=getopt(argc,argv,"q:Q:i:I:w:t:m:n:hd:"))!=-1) {
switch(arg) {
while ((arg = getopt (argc, argv, "q:Q:i:I:w:t:m:n:hd:")) != -1)
{
switch (arg)
{
case 'q':
perigee=atof(optarg);
perigee = atof (optarg);
break;
case 'Q':
apogee=atof(optarg);
apogee = atof (optarg);
break;
case 'I':
orb.eqinc=atof(optarg)*D2R;
orb.eqinc = atof (optarg) * D2R;
break;
case 'n':
orb.ascn=atof(optarg)*D2R;
orb.ascn = atof (optarg) * D2R;
break;
case 'i':
orb.satno=atoi(optarg);
orb.satno = atoi (optarg);
break;
case 'w':
orb.argp=atof(optarg)*D2R;
orb.argp = atof (optarg) * D2R;
break;
case 'm':
orb.mnan=atof(optarg)*D2R;
orb.mnan = atof (optarg) * D2R;
break;
case 't':
mjd=nfd2mjd(optarg);
mjd = nfd2mjd (optarg);
break;
case 'd':
dt=atof(optarg);
dt = atof (optarg);
break;
case 'h':
usage();
usage ();
return 0;
default:
usage();
usage ();
return 0;
}
}
orb.ep_day=mjd2doy(mjd+dt/86400.0,&orb.ep_year);
orb.ep_day = mjd2doy (mjd + dt / 86400.0, &orb.ep_year);
perigee+=XKMPER;
apogee+=XKMPER;
aodp=0.5*(perigee+apogee)/XKMPER;
orb.ecc=0.5*(apogee-perigee)/(aodp*XKMPER);
orb.rev=XKE*pow(aodp,-1.5)*XMNPDA/(2.0*M_PI);
if (orb.rev<10)
orb.bstar=0.0;
orbit(orb,&aodp,&perigee,&apogee,&period);
perigee += XKMPER;
apogee += XKMPER;
aodp = 0.5 * (perigee + apogee) / XKMPER;
orb.ecc = 0.5 * (apogee - perigee) / (aodp * XKMPER);
orb.rev = XKE * pow (aodp, -1.5) * XMNPDA / (2.0 * M_PI);
if (orb.rev < 10)
orb.bstar = 0.0;
orbit (orb, &aodp, &perigee, &apogee, &period);
format_tle(orb,line1,line2);
printf("%s\n%s\n",line1,line2);
format_tle (orb, line1, line2);
printf ("%s\n%s\n", line1, line2);
return 0;
}
void orbit(orbit_t orb,float *aodp,float *perigee,float *apogee,float *period)
void
orbit (orbit_t orb, float *aodp, float *perigee, float *apogee, float *period)
{
float xno,eo,xincl;
float a1,betao2,betao,temp0,del1,a0,del0,xnodp;
float xno, eo, xincl;
float a1, betao2, betao, temp0, del1, a0, del0, xnodp;
xno=orb.rev*2.0*M_PI/XMNPDA;
eo=orb.ecc;
xincl=orb.eqinc;
xno = orb.rev * 2.0 * M_PI / XMNPDA;
eo = orb.ecc;
xincl = orb.eqinc;
a1 = pow(XKE / xno, 2.0/3.0);
a1 = pow (XKE / xno, 2.0 / 3.0);
betao2 = 1.0 - eo * eo;
betao = sqrt(betao2);
temp0 = (1.5 * CK2) * cos(xincl)*cos(xincl) / (betao * betao2);
betao = sqrt (betao2);
temp0 = (1.5 * CK2) * cos (xincl) * cos (xincl) / (betao * betao2);
del1 = temp0 / (a1 * a1);
a0 = a1 * (1.0 - del1 * (1.0/3.0 + del1 * (1.0 + del1 * 134.0/81.0)));
a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0)));
del0 = temp0 / (a0 * a0);
xnodp = xno / (1.0 + del0);
*aodp = (a0 / (1.0 - del0));
*perigee = (*aodp * (1.0 - eo) - 1) * XKMPER;
*apogee = (*aodp * (1.0 + eo) - 1) * XKMPER;
*period = (TWOPI * 1440.0 / XMNPDA) / xnodp;
*aodp=(*aodp-1)*XKMPER;
*aodp = (*aodp - 1) * XKMPER;
return;
}
// Format TLE
void format_tle(orbit_t orb,char *line1,char *line2)
void
format_tle (orbit_t orb, char *line1, char *line2)
{
int i,csum;
char sbstar[]=" 00000-0",bstar[13];
int i, csum;
char sbstar[] = " 00000-0", bstar[13];
// Format Bstar term
if (fabs(orb.bstar)>1e-9) {
sprintf(bstar,"%11.4e",10*orb.bstar);
sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4];
sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0';
if (fabs (orb.bstar) > 1e-9)
{
sprintf (bstar, "%11.4e", 10 * orb.bstar);
sbstar[0] = bstar[0];
sbstar[1] = bstar[1];
sbstar[2] = bstar[3];
sbstar[3] = bstar[4];
sbstar[4] = bstar[5];
sbstar[5] = bstar[6];
sbstar[6] = bstar[8];
sbstar[7] = bstar[10];
sbstar[8] = '\0';
}
// Print lines
sprintf(line1,"1 %05dU %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.ep_year-2000,orb.ep_day,sbstar);
sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev);
sprintf (line1,
"1 %05dU %2d%012.8f .00000000 00000-0 %8s 0 0",
orb.satno, orb.ep_year - 2000, orb.ep_day, sbstar);
sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",
orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc,
DEG (orb.argp), DEG (orb.mnan), orb.rev);
// Compute checksums
for (i=0,csum=0;i<strlen(line1);i++) {
if (isdigit(line1[i]))
csum+=line1[i]-'0';
else if (line1[i]=='-')
for (i = 0, csum = 0; i < strlen (line1); i++)
{
if (isdigit (line1[i]))
csum += line1[i] - '0';
else if (line1[i] == '-')
csum++;
}
sprintf(line1,"%s%d",line1,csum%10);
for (i=0,csum=0;i<strlen(line2);i++) {
if (isdigit(line2[i]))
csum+=line2[i]-'0';
else if (line2[i]=='-')
sprintf (line1, "%s%d", line1, csum % 10);
for (i = 0, csum = 0; i < strlen (line2); i++)
{
if (isdigit (line2[i]))
csum += line2[i] - '0';
else if (line2[i] == '-')
csum++;
}
sprintf(line2,"%s%d",line2,csum%10);
sprintf (line2, "%s%d", line2, csum % 10);
return;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// MJD to DOY
double mjd2doy(double mjd,int *yr)
double
mjd2doy (double mjd, int *yr)
{
int year,month,k=2;
double day,doy;
int year, month, k = 2;
double day, doy;
mjd2date(mjd,&year,&month,&day);
mjd2date (mjd, &year, &month, &day);
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30;
doy =
floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30;
*yr=year;
*yr = year;
return doy;
}
// Compute Date from Julian Day
void mjd2date(double mjd,int *year,int *month,double *day)
void
mjd2date (double mjd, int *year, int *month, double *day)
{
double f,jd;
int z,alpha,a,b,c,d,e;
double f, jd;
int z, alpha, a, b, c, d, e;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
*day=b-d-floor(30.6001*e)+f;
if (e<14)
*month=e-1;
*day = b - d - floor (30.6001 * e) + f;
if (e < 14)
*month = e - 1;
else
*month=e-13;
*month = e - 13;
if (*month>2)
*year=c-4716;
if (*month > 2)
*year = c - 4716;
else
*year=c-4715;
*year = c - 4715;
return;
}
// Greenwich Mean Sidereal Time
double gmst(double mjd)
double
gmst (double mjd)
{
double t,gmst;
double t, gmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0);
gmst =
modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) +
t * t * (0.000387933 - t / 38710000), 360.0);
return gmst;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}

View File

@ -7,17 +7,18 @@
#include <stdarg.h>
void fatal_error(const char *format, ...)
void
fatal_error (const char *format, ...)
{
va_list arg_ptr;
va_list arg_ptr;
fflush(stdout);
fflush (stdout);
fprintf(stderr, "\nFatal run-time error:\n");
fprintf (stderr, "\nFatal run-time error:\n");
va_start(arg_ptr, format);
vfprintf(stderr, format, arg_ptr);
va_end(arg_ptr);
va_start (arg_ptr, format);
vfprintf (stderr, format, arg_ptr);
va_end (arg_ptr);
//fprintf(stderr, "\nNow terminating the program...\n");
// fflush(stderr);

View File

@ -5,43 +5,48 @@
#define LIM 81
int fgetline(FILE *,char *,int);
void rtrim(char *);
int fgetline (FILE *, char *, int);
void rtrim (char *);
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
char line[LIM];
FILE *fitsfile;
// Usage
if (argc<2) {
printf("Usage: %s <fitsfile>\n",argv[0]);
printf("\n\nOutputs the header of <fitsfile>\n");
if (argc < 2)
{
printf ("Usage: %s <fitsfile>\n", argv[0]);
printf ("\n\nOutputs the header of <fitsfile>\n");
return 1;
}
// Open file
fitsfile=fopen(argv[1],"r");
fitsfile = fopen (argv[1], "r");
// Loop over file and output
while (fgetline(fitsfile,line,LIM)>0) {
rtrim(line);
printf("%s\n",line);
if (strcmp(line,"END")==0) break;
while (fgetline (fitsfile, line, LIM) > 0)
{
rtrim (line);
printf ("%s\n", line);
if (strcmp (line, "END") == 0)
break;
}
// Close file
fclose(fitsfile);
fclose (fitsfile);
return 0;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
@ -50,15 +55,17 @@ int fgetline(FILE *file,char *s,int lim)
}
// Removes trailing blanks from string s
void rtrim(char *s)
void
rtrim (char *s)
{
int i,j=0,n;
int i, j = 0, n;
n=strlen(s);
for (i=n;i>=0;i--)
if (s[i]!='\0' && s[i]!='\n')
if (!isspace(s[i]) && j==0) j=i;
s[++j]='\0';
n = strlen (s);
for (i = n; i >= 0; i--)
if (s[i] != '\0' && s[i] != '\n')
if (!isspace (s[i]) && j == 0)
j = i;
s[++j] = '\0';
return;
}

View File

@ -4,34 +4,40 @@
#include <ctype.h>
#include "qfits.h"
int main(int argc, char * argv[])
int
main (int argc, char *argv[])
{
int i;
char keyword[FITS_LINESZ+1];
char keyword[FITS_LINESZ + 1];
char *value;
// Usage
if (argc<3) {
printf("Usage: %s <filename> [ext] <key1> <key2> etc.\n", argv[0]);
return 1 ;
if (argc < 3)
{
printf ("Usage: %s <filename> [ext] <key1> <key2> etc.\n", argv[0]);
return 1;
}
// Check this is indeed a FITS file
if (is_fits_file(argv[1])!=1) {
printf("%s is not a FITS file\n", argv[1]);
return -1 ;
if (is_fits_file (argv[1]) != 1)
{
printf ("%s is not a FITS file\n", argv[1]);
return -1;
}
// Extension header?
if (atoi(argv[2])==0) {
for (i=2;i<argc;i++)
printf("%s ",qfits_query_hdr(argv[1], argv[i]));
} else {
for (i=3;i<argc;i++)
printf("%s ",qfits_query_ext(argv[1], argv[i],atoi(argv[2])));
if (atoi (argv[2]) == 0)
{
for (i = 2; i < argc; i++)
printf ("%s ", qfits_query_hdr (argv[1], argv[i]));
}
printf("\n");
else
{
for (i = 3; i < argc; i++)
printf ("%s ", qfits_query_ext (argv[1], argv[i], atoi (argv[2])));
}
printf ("\n");
return 0 ;
return 0;
}

View File

@ -4,29 +4,31 @@
#include <wcslib/cel.h>
// Get a x and y from a RA and Decl
void forward(double ra0,double de0,double ra,double de,double *x,double *y)
void
forward (double ra0, double de0, double ra, double de, double *x, double *y)
{
int i,status;
double phi,theta;
int i, status;
double phi, theta;
struct celprm cel;
// Initialize Reference Angles
celini(&cel);
cel.ref[0]=ra0;
cel.ref[1]=de0;
cel.ref[2]=999.;
cel.ref[3]=999.;
cel.flag=0.;
strcpy(cel.prj.code,"STG");
celini (&cel);
cel.ref[0] = ra0;
cel.ref[1] = de0;
cel.ref[2] = 999.;
cel.ref[3] = 999.;
cel.flag = 0.;
strcpy (cel.prj.code, "STG");
if (celset(&cel)) {
printf("Error in Projection (celset)\n");
if (celset (&cel))
{
printf ("Error in Projection (celset)\n");
return;
}
cels2x(&cel,1,0,1,1,&ra,&de,&phi,&theta,x,y,&status);
cels2x (&cel, 1, 0, 1, 1, &ra, &de, &phi, &theta, x, y, &status);
*x *=3600.;
*y *=3600.;
*x *= 3600.;
*y *= 3600.;
return;
}

View File

@ -11,194 +11,225 @@
#define R2D 180.0/M_PI
#define XKMPER 6378.135 // Earth radius in km
long Isat=0;
long Isatsel=0;
long Isat = 0;
long Isatsel = 0;
extern double SGDP4_jd0;
struct map {
struct map
{
long satno;
double mjd;
char nfd[LIM],tlefile[LIM],observer[32];
char datadir[LIM],tledir[LIM];
char nfd[LIM], tlefile[LIM], observer[32];
char datadir[LIM], tledir[LIM];
} m;
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
void usage()
void
usage ()
{
printf("Usage goes here.\n");
printf ("Usage goes here.\n");
return;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Greenwich Mean Sidereal Time
double gmst(double mjd)
double
gmst (double mjd)
{
double t,gmst;
double t, gmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0);
gmst =
modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) +
t * t * (0.000387933 - t / 38710000), 360.0);
return gmst;
}
// Present nfd
void nfd_now(char *s)
void
nfd_now (char *s)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
time(&rawtime);
ptm=gmtime(&rawtime);
time (&rawtime);
ptm = gmtime (&rawtime);
sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900,
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
ptm->tm_sec);
return;
}
// Compute longitude
void compute_longitude(char *tlefile,long satno,double mjd)
void
compute_longitude (char *tlefile, long satno, double mjd)
{
FILE *fp=NULL;
FILE *fp = NULL;
orbit_t orb;
xyz_t satpos,satvel;
double jd,h,l,b,r;
xyz_t satpos, satvel;
double jd, h, l, b, r;
long imode;
// Open TLE file
fp = fopen(tlefile, "rb");
if(fp == NULL)
fatal_error("File open failed for reading \"%s\"", tlefile);
fp = fopen (tlefile, "rb");
if (fp == NULL)
fatal_error ("File open failed for reading \"%s\"", tlefile);
// Loop over elements
while(read_twoline(fp, satno, &orb) == 0) {
while (read_twoline (fp, satno, &orb) == 0)
{
Isat = orb.satno;
imode = init_sgdp4(&orb);
if(imode == SGDP4_ERROR) continue;
imode = init_sgdp4 (&orb);
if (imode == SGDP4_ERROR)
continue;
// Skip objects with mean motions outside of 0.8 to 1.2 revs/day
if (orb.rev<0.8 || orb.rev>1.2)
if (orb.rev < 0.8 || orb.rev > 1.2)
continue;
// Get Julian Date
jd=mjd+2400000.5;
jd = mjd + 2400000.5;
// Get positions
satpos_xyz(jd,&satpos,&satvel);
satpos_xyz (jd, &satpos, &satvel);
// Greenwich Mean Sidereal time
h=gmst(mjd);
h = gmst (mjd);
// Celestial position
r=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z);
l=atan2(satpos.y,satpos.x)*R2D;
l=modulo(l-h,360.0);
b=asin(satpos.z/r)*R2D;
if (l>180.0)
l-=360.0;
if (l<-180.0)
l+=360.0;
r =
sqrt (satpos.x * satpos.x + satpos.y * satpos.y +
satpos.z * satpos.z);
l = atan2 (satpos.y, satpos.x) * R2D;
l = modulo (l - h, 360.0);
b = asin (satpos.z / r) * R2D;
if (l > 180.0)
l -= 360.0;
if (l < -180.0)
l += 360.0;
printf("%05d %10s %8.3lf %8.3lf %6.0lf\n",orb.satno,orb.desig,l,b,r-XKMPER);
printf ("%05d %10s %8.3lf %8.3lf %6.0lf\n", orb.satno, orb.desig, l, b,
r - XKMPER);
}
fclose(fp);
fclose (fp);
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int arg=0;
long satno=0;
int arg = 0;
long satno = 0;
double mjd;
char nfd[LIM],tlefile[LIM];
char nfd[LIM], tlefile[LIM];
nfd_now(nfd);
mjd=nfd2mjd(nfd);
nfd_now (nfd);
mjd = nfd2mjd (nfd);
// Decode options
if (argc>1) {
while ((arg=getopt(argc,argv,"t:c:i:h"))!=-1) {
switch (arg) {
if (argc > 1)
{
while ((arg = getopt (argc, argv, "t:c:i:h")) != -1)
{
switch (arg)
{
case 't':
strcpy(nfd,optarg);
mjd=nfd2mjd(nfd);
strcpy (nfd, optarg);
mjd = nfd2mjd (nfd);
break;
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
} else {
usage();
}
else
{
usage ();
return 0;
}
// Compute longitudes of satellites
compute_longitude(tlefile,satno,mjd);
compute_longitude (tlefile, satno, mjd);
return 0;
}

View File

@ -8,266 +8,294 @@
#define D2R M_PI/180.0
#define R2D 180.0/M_PI
struct image {
struct image
{
char filename[64];
int naxis1,naxis2;
int naxis1, naxis2;
float *zavg;
double ra0,de0;
float x0,y0;
float a[3],b[3],xrms,yrms;
double ra0, de0;
float x0, y0;
float a[3], b[3], xrms, yrms;
double mjd;
float exptime;
char nfd[32];
int cospar;
};
struct map {
char datadir[LIM],observer[32];
double lng,lat;
struct map
{
char datadir[LIM], observer[32];
double lng, lat;
float alt;
int site_id;
} m;
struct image read_fits(char *filename);
struct image read_fits (char *filename);
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Greenwich Mean Sidereal Time
double gmst(double mjd)
double
gmst (double mjd)
{
double t,gmst;
double t, gmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0);
gmst =
modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) +
t * t * (0.000387933 - t / 38710000), 360.0);
return gmst;
}
// Precess a celestial position
void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de)
void
precess (double mjd0, double ra0, double de0, double mjd, double *ra,
double *de)
{
double t0,t;
double zeta,z,theta;
double a,b,c;
double t0, t;
double zeta, z, theta;
double a, b, c;
// Angles in radians
ra0*=D2R;
de0*=D2R;
ra0 *= D2R;
de0 *= D2R;
// Time in centuries
t0=(mjd0-51544.5)/36525.0;
t=(mjd-mjd0)/36525.0;
t0 = (mjd0 - 51544.5) / 36525.0;
t = (mjd - mjd0) / 36525.0;
// Precession angles
zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t;
zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t;
zeta*=D2R/3600.0;
z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t;
z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t;
z*=D2R/3600.0;
theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t;
theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t;
theta*=D2R/3600.0;
zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t;
zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t;
zeta *= D2R / 3600.0;
z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t;
z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t;
z *= D2R / 3600.0;
theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t;
theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t;
theta *= D2R / 3600.0;
a=cos(de0)*sin(ra0+zeta);
b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0);
c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0);
a = cos (de0) * sin (ra0 + zeta);
b = cos (theta) * cos (de0) * cos (ra0 + zeta) - sin (theta) * sin (de0);
c = sin (theta) * cos (de0) * cos (ra0 + zeta) + cos (theta) * sin (de0);
*ra=(atan2(a,b)+z)*R2D;
*de=asin(c)*R2D;
*ra = (atan2 (a, b) + z) * R2D;
*de = asin (c) * R2D;
if (*ra<360.0)
*ra+=360.0;
if (*ra>360.0)
*ra-=360.0;
if (*ra < 360.0)
*ra += 360.0;
if (*ra > 360.0)
*ra -= 360.0;
return;
}
// Get observing site
void get_site(int site_id)
void
get_site (int site_id)
{
int i=0;
int i = 0;
char line[LIM];
FILE *file;
int id;
double lat,lng;
double lat, lng;
float alt;
char abbrev[3],observer[64],filename[LIM];
char abbrev[3], observer[64], filename[LIM];
sprintf(filename,"%s/data/sites.txt",m.datadir);
file=fopen(filename,"r");
if (file==NULL) {
printf("File with site information not found!\n");
sprintf (filename, "%s/data/sites.txt", m.datadir);
file = fopen (filename, "r");
if (file == NULL)
{
printf ("File with site information not found!\n");
return;
}
while (fgets(line,LIM,file)!=NULL) {
while (fgets (line, LIM, file) != NULL)
{
// Skip
if (strstr(line,"#")!=NULL)
if (strstr (line, "#") != NULL)
continue;
// Strip newline
line[strlen(line)-1]='\0';
line[strlen (line) - 1] = '\0';
// Read data
sscanf(line,"%4d %2s %lf %lf %f",
&id,abbrev,&lat,&lng,&alt);
strcpy(observer,line+38);
sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt);
strcpy (observer, line + 38);
// Change to km
alt/=1000.0;
alt /= 1000.0;
if (id==site_id) {
m.lat=lat;
m.lng=lng;
m.alt=alt;
m.site_id=id;
strcpy(m.observer,observer);
if (id == site_id)
{
m.lat = lat;
m.lng = lng;
m.alt = alt;
m.site_id = id;
strcpy (m.observer, observer);
}
}
fclose(file);
fclose (file);
return;
}
// Convert equatorial into horizontal coordinates
void equatorial2horizontal(double mjd,double ra,double de,double *azi,double *alt)
void
equatorial2horizontal (double mjd, double ra, double de, double *azi,
double *alt)
{
double h;
h=gmst(mjd)+m.lng-ra;
h = gmst (mjd) + m.lng - ra;
*azi=modulo(atan2(sin(h*D2R),cos(h*D2R)*sin(m.lat*D2R)-tan(de*D2R)*cos(m.lat*D2R))*R2D,360.0);
*alt=asin(sin(m.lat*D2R)*sin(de*D2R)+cos(m.lat*D2R)*cos(de*D2R)*cos(h*D2R))*R2D;
*azi =
modulo (atan2
(sin (h * D2R),
cos (h * D2R) * sin (m.lat * D2R) -
tan (de * D2R) * cos (m.lat * D2R)) * R2D, 360.0);
*alt =
asin (sin (m.lat * D2R) * sin (de * D2R) +
cos (m.lat * D2R) * cos (de * D2R) * cos (h * D2R)) * R2D;
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int i;
struct image img;
float zavg,zstd,sx,sy,wx,wy;
double ra,de,alt,azi,mjd0=51544.5;
float zavg, zstd, sx, sy, wx, wy;
double ra, de, alt, azi, mjd0 = 51544.5;
char *env;
// Get environment variables
env=getenv("ST_DATADIR");
if (env!=NULL) {
strcpy(m.datadir,env);
} else {
printf("ST_DATADIR environment variable not found.\n");
env = getenv ("ST_DATADIR");
if (env != NULL)
{
strcpy (m.datadir, env);
}
else
{
printf ("ST_DATADIR environment variable not found.\n");
}
// Read image
img=read_fits(argv[1]);
img = read_fits (argv[1]);
// Get site
get_site(img.cospar);
get_site (img.cospar);
// Compute statistics
for (i=0,zavg=0.0;i<img.naxis1*img.naxis2;i++)
zavg+=img.zavg[i];
zavg/=(float) img.naxis1*img.naxis2;
for (i=0,zstd=0.0;i<img.naxis1*img.naxis2;i++)
zstd+=pow(img.zavg[i]-zavg,2);
zstd=sqrt(zstd/(float) (img.naxis1*img.naxis2));
for (i = 0, zavg = 0.0; i < img.naxis1 * img.naxis2; i++)
zavg += img.zavg[i];
zavg /= (float) img.naxis1 * img.naxis2;
for (i = 0, zstd = 0.0; i < img.naxis1 * img.naxis2; i++)
zstd += pow (img.zavg[i] - zavg, 2);
zstd = sqrt (zstd / (float) (img.naxis1 * img.naxis2));
// Image scale
sx=sqrt(img.a[1]*img.a[1]+img.b[1]*img.b[1]);
sy=sqrt(img.a[2]*img.a[2]+img.b[2]*img.b[2]);
wx=img.naxis1*sx/3600.0;
wy=img.naxis2*sy/3600.0;
sx = sqrt (img.a[1] * img.a[1] + img.b[1] * img.b[1]);
sy = sqrt (img.a[2] * img.a[2] + img.b[2] * img.b[2]);
wx = img.naxis1 * sx / 3600.0;
wy = img.naxis2 * sy / 3600.0;
// Precess to epoch of date
precess(mjd0,img.ra0,img.de0,img.mjd,&ra,&de);
precess (mjd0, img.ra0, img.de0, img.mjd, &ra, &de);
// Get horizontal coordinates
equatorial2horizontal(img.mjd,ra,de,&azi,&alt);
azi=modulo(azi+180,360);
printf("%s %14.8lf %10.6f %10.6f %10.6f %10.6f %.2f %.2f %.1f %.1f\n",argv[1],img.mjd,img.ra0,img.de0,azi,alt,img.xrms,img.yrms,zavg,zstd);
equatorial2horizontal (img.mjd, ra, de, &azi, &alt);
azi = modulo (azi + 180, 360);
printf ("%s %14.8lf %10.6f %10.6f %10.6f %10.6f %.2f %.2f %.1f %.1f\n",
argv[1], img.mjd, img.ra0, img.de0, azi, alt, img.xrms, img.yrms,
zavg, zstd);
return 0;
}
// Read fits image
struct image read_fits(char *filename)
struct image
read_fits (char *filename)
{
int i,j,k,l,m;
int i, j, k, l, m;
qfitsloader ql;
char key[FITS_LINESZ+1];
char val[FITS_LINESZ+1];
char key[FITS_LINESZ + 1];
char val[FITS_LINESZ + 1];
struct image img;
int naxis;
// Copy filename
strcpy(img.filename,filename);
strcpy (img.filename, filename);
// Image size
naxis=atoi(qfits_query_hdr(filename,"NAXIS"));
img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1"));
img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2"));
naxis = atoi (qfits_query_hdr (filename, "NAXIS"));
img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1"));
img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2"));
// MJD
img.mjd=(double) atof(qfits_query_hdr(filename,"MJD-OBS"));
strcpy(img.nfd,qfits_query_hdr(filename,"DATE-OBS"));
img.exptime=atof(qfits_query_hdr(filename,"EXPTIME"));
img.mjd = (double) atof (qfits_query_hdr (filename, "MJD-OBS"));
strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS"));
img.exptime = atof (qfits_query_hdr (filename, "EXPTIME"));
// COSPAR ID
img.cospar=atoi(qfits_query_hdr(filename,"COSPAR"));
img.cospar = atoi (qfits_query_hdr (filename, "COSPAR"));
// Transformation
img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS"));
img.ra0=atof(qfits_query_hdr(filename,"CRVAL1"));
img.de0=atof(qfits_query_hdr(filename,"CRVAL2"));
img.x0=atof(qfits_query_hdr(filename,"CRPIX1"));
img.y0=atof(qfits_query_hdr(filename,"CRPIX2"));
img.a[0]=0.0;
img.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1"));
img.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2"));
img.b[0]=0.0;
img.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1"));
img.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2"));
img.xrms=3600.0*atof(qfits_query_hdr(filename,"CRRES1"));
img.yrms=3600.0*atof(qfits_query_hdr(filename,"CRRES2"));
img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS"));
img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1"));
img.de0 = atof (qfits_query_hdr (filename, "CRVAL2"));
img.x0 = atof (qfits_query_hdr (filename, "CRPIX1"));
img.y0 = atof (qfits_query_hdr (filename, "CRPIX2"));
img.a[0] = 0.0;
img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1"));
img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2"));
img.b[0] = 0.0;
img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1"));
img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2"));
img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1"));
img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2"));
// Allocate image memory
img.zavg=(float *) malloc(sizeof(float)*img.naxis1*img.naxis2);
img.zavg = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
// Set parameters
ql.xtnum=0;
ql.ptype=PTYPE_FLOAT;
ql.filename=filename;
ql.xtnum = 0;
ql.ptype = PTYPE_FLOAT;
ql.filename = filename;
// Loop over planes
if (naxis==3)
ql.pnum=2;
if (naxis == 3)
ql.pnum = 2;
else
ql.pnum=0;
ql.pnum = 0;
// Initialize load
if (qfitsloader_init(&ql) != 0)
printf("Error initializing data loading\n");
if (qfitsloader_init (&ql) != 0)
printf ("Error initializing data loading\n");
// Test load
if (qfits_loadpix(&ql) != 0)
printf("Error loading actual data\n");
if (qfits_loadpix (&ql) != 0)
printf ("Error loading actual data\n");
// Fill z array
for (i=0,l=0;i<img.naxis1;i++) {
for (j=0;j<img.naxis2;j++) {
img.zavg[l]=ql.fbuf[l];
for (i = 0, l = 0; i < img.naxis1; i++)
{
for (j = 0; j < img.naxis2; j++)
{
img.zavg[l] = ql.fbuf[l];
l++;
}
}
return img;
}

View File

@ -7,28 +7,30 @@
#include <libexif/exif-data.h>
#include <getopt.h>
struct image {
int nx,ny,nz;
struct image
{
int nx, ny, nz;
float *z;
double mjd;
char nfd[32],observer[32];
int cospar,tracked;
char nfd[32], observer[32];
int cospar, tracked;
float exptime;
};
struct image read_jpg(char *filename);
void write_fits(struct image img,char *filename);
double date2mjd(int year,int month,double day);
double nfd2mjd(char *date);
void mjd2nfd(double mjd,char *nfd);
struct image read_jpg (char *filename);
void write_fits (struct image img, char *filename);
double date2mjd (int year, int month, double day);
double nfd2mjd (char *date);
void mjd2nfd (double mjd, char *nfd);
// Read fits image
struct image read_fits(char *filename)
struct image
read_fits (char *filename)
{
int i,j,k,l,m;
int i, j, k, l, m;
qfitsloader ql;
char key[FITS_LINESZ+1] ;
char key[FITS_LINESZ + 1];
struct image img;
float s1,s2,avg,std;
float s1, s2, avg, std;
// Set plane
ql.xtnum = 0;
@ -38,28 +40,30 @@ struct image read_fits(char *filename)
ql.ptype = PTYPE_FLOAT;
// Set filename
ql.filename=filename;
ql.filename = filename;
// Image size
img.nx=atoi(qfits_query_hdr(filename,"NAXIS1"));
img.ny=atoi(qfits_query_hdr(filename,"NAXIS2"));
img.nz=1;
img.nx = atoi (qfits_query_hdr (filename, "NAXIS1"));
img.ny = atoi (qfits_query_hdr (filename, "NAXIS2"));
img.nz = 1;
// Initialize load
if (qfitsloader_init(&ql) != 0)
printf("Error initializing data loading\n");
if (qfitsloader_init (&ql) != 0)
printf ("Error initializing data loading\n");
// Test load
if (qfits_loadpix(&ql) != 0)
printf("Error loading actual data\n");
if (qfits_loadpix (&ql) != 0)
printf ("Error loading actual data\n");
// Allocate image memory
img.z=(float *) malloc(sizeof(float) * img.nx*img.ny*img.nz);
img.z = (float *) malloc (sizeof (float) * img.nx * img.ny * img.nz);
// Fill z array
for (i=0,l=0,m=0;i<img.nx;i++) {
for (j=0;j<img.ny;j++) {
img.z[l]=ql.fbuf[l];
for (i = 0, l = 0, m = 0; i < img.nx; i++)
{
for (j = 0; j < img.ny; j++)
{
img.z[l] = ql.fbuf[l];
l++;
}
}
@ -68,249 +72,274 @@ struct image read_fits(char *filename)
}
struct image rebin(struct image raw,int nbin)
struct image
rebin (struct image raw, int nbin)
{
int i,j,k;
int ii,jj,kk;
int i, j, k;
int ii, jj, kk;
struct image img;
img.nx=raw.nx/nbin;
img.ny=raw.ny/nbin;
img.nz=1;
img.z=(float *) malloc(sizeof(float)*img.nx*img.ny*img.nz);
img.nx = raw.nx / nbin;
img.ny = raw.ny / nbin;
img.nz = 1;
img.z = (float *) malloc (sizeof (float) * img.nx * img.ny * img.nz);
for (i=0;i<img.nx;i++) {
for (j=0;j<img.ny;j++) {
k=i+img.nx*j;
img.z[k]=0.0;
for (ii=0;ii<nbin;ii++) {
for (jj=0;jj<nbin;jj++) {
kk=ii+nbin*i+raw.nx*(jj+nbin*j);
img.z[k]+=raw.z[kk];
for (i = 0; i < img.nx; i++)
{
for (j = 0; j < img.ny; j++)
{
k = i + img.nx * j;
img.z[k] = 0.0;
for (ii = 0; ii < nbin; ii++)
{
for (jj = 0; jj < nbin; jj++)
{
kk = ii + nbin * i + raw.nx * (jj + nbin * j);
img.z[k] += raw.z[kk];
}
}
}
}
img.mjd=raw.mjd;
img.cospar=raw.cospar;
img.exptime=raw.exptime;
strcpy(img.nfd,raw.nfd);
strcpy(img.observer,raw.observer);
img.mjd = raw.mjd;
img.cospar = raw.cospar;
img.exptime = raw.exptime;
strcpy (img.nfd, raw.nfd);
strcpy (img.observer, raw.observer);
return img;
}
void usage(void)
void
usage (void)
{
printf("jpg2fits i:t:o:d:Z:c:T:O:b:hF\n\n");
printf("-i input JPG file\n");
printf("-o output FITS file\n");
printf("-t start time (YYYY-MM-DDTHH:MM:SS.sss)\n");
printf("-d delay (in seconds)\n");
printf("-Z timezone offset (in seconds)\n");
printf("-T exposure time (in seconds)\n");
printf("-c COSPAR site number\n");
printf("-O observer name\n");
printf("-b binning factor\n");
printf("-F FITS input\n");
printf("-h this help\n");
printf ("jpg2fits i:t:o:d:Z:c:T:O:b:hF\n\n");
printf ("-i input JPG file\n");
printf ("-o output FITS file\n");
printf ("-t start time (YYYY-MM-DDTHH:MM:SS.sss)\n");
printf ("-d delay (in seconds)\n");
printf ("-Z timezone offset (in seconds)\n");
printf ("-T exposure time (in seconds)\n");
printf ("-c COSPAR site number\n");
printf ("-O observer name\n");
printf ("-b binning factor\n");
printf ("-F FITS input\n");
printf ("-h this help\n");
exit(0);
exit (0);
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int arg;
struct image img,raw;
char infile[64],outfile[64]="",nfd[32]="2000-01-01T00:00:00";
double mjd=51544.0,delay=0.0,tz=0.0;
int cospar=0;
char observer[32]="Cees Bassa";
float exptime=10.06;
int flag=0,nbin=1,readfits=0,tracked=0;
struct image img, raw;
char infile[64], outfile[64] = "", nfd[32] = "2000-01-01T00:00:00";
double mjd = 51544.0, delay = 0.0, tz = 0.0;
int cospar = 0;
char observer[32] = "Cees Bassa";
float exptime = 10.06;
int flag = 0, nbin = 1, readfits = 0, tracked = 0;
// Decode options
if (argc>1) {
while ((arg=getopt(argc,argv,"i:t:o:d:Z:c:T:O:b:hFs"))!=-1) {
switch(arg) {
if (argc > 1)
{
while ((arg = getopt (argc, argv, "i:t:o:d:Z:c:T:O:b:hFs")) != -1)
{
switch (arg)
{
case 's':
tracked=1;
tracked = 1;
break;
case 'i':
strcpy(infile,optarg);
strcpy (infile, optarg);
break;
case 'd':
delay=(double) atof(optarg);
delay = (double) atof (optarg);
break;
case 'b':
nbin=atoi(optarg);
nbin = atoi (optarg);
break;
case 'Z':
tz=(double) atof(optarg);
tz = (double) atof (optarg);
break;
case 'o':
strcpy(outfile,optarg);
flag=1;
strcpy (outfile, optarg);
flag = 1;
break;
case 'F':
readfits=1;
readfits = 1;
break;
case 't':
strcpy(nfd,optarg);
strcpy (nfd, optarg);
break;
case 'c':
cospar=atoi(optarg);
cospar = atoi (optarg);
break;
case 'T':
exptime=atof(optarg);
exptime = atof (optarg);
break;
case 'O':
strcpy(observer,optarg);
strcpy (observer, optarg);
break;
case 'h':
usage();
usage ();
break;
default:
usage();
usage ();
return 0;
}
}
} else {
usage();
}
else
{
usage ();
}
if (infile!=NULL) {
if (nbin==1) {
if (readfits==0)
img=read_jpg(infile);
if (infile != NULL)
{
if (nbin == 1)
{
if (readfits == 0)
img = read_jpg (infile);
else
img=read_fits(infile);
} else {
if (readfits==0)
raw=read_jpg(infile);
img = read_fits (infile);
}
else
raw=read_fits(infile);
img=rebin(raw,nbin);
{
if (readfits == 0)
raw = read_jpg (infile);
else
raw = read_fits (infile);
img = rebin (raw, nbin);
}
}
// Set tracked flag
if (tracked==1)
img.tracked=1;
if (tracked == 1)
img.tracked = 1;
else
img.tracked=0;
img.tracked = 0;
if (nfd!=NULL) {
if (nfd != NULL)
{
// Compute time
mjd=nfd2mjd(nfd);
mjd+=(delay+tz)/86400.0;
mjd2nfd(mjd,nfd);
mjd = nfd2mjd (nfd);
mjd += (delay + tz) / 86400.0;
mjd2nfd (mjd, nfd);
// Into file
strcpy(img.nfd,nfd);
img.mjd=mjd;
strcpy (img.nfd, nfd);
img.mjd = mjd;
}
if (flag==0)
sprintf(outfile,"%s.fits",img.nfd);
if (flag == 0)
sprintf (outfile, "%s.fits", img.nfd);
// Set properties
img.cospar=cospar;
img.exptime=exptime;
strcpy(img.observer,observer);
img.cospar = cospar;
img.exptime = exptime;
strcpy (img.observer, observer);
if (outfile!=NULL)
write_fits(img,outfile);
if (outfile != NULL)
write_fits (img, outfile);
// Free
free(img.z);
if (nbin!=1)
free(raw.z);
free (img.z);
if (nbin != 1)
free (raw.z);
return 0;
}
struct image read_jpg(char *filename)
struct image
read_jpg (char *filename)
{
int i=0,j,k,l,m;
unsigned long location=0;
int i = 0, j, k, l, m;
unsigned long location = 0;
struct image img;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
unsigned char *raw_image=NULL;
unsigned char *raw_image = NULL;
FILE *file;
ExifData *ed;
ExifEntry *entry;
// Open file
file=fopen(filename,"rb");
file = fopen (filename, "rb");
if (!file)
perror("Error opening file");
perror ("Error opening file");
// Get header info, decompress
cinfo.err=jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo,file);
jpeg_read_header(&cinfo,TRUE);
jpeg_start_decompress(&cinfo);
cinfo.err = jpeg_std_error (&jerr);
jpeg_create_decompress (&cinfo);
jpeg_stdio_src (&cinfo, file);
jpeg_read_header (&cinfo, TRUE);
jpeg_start_decompress (&cinfo);
// Allocate memory
raw_image=(unsigned char *) malloc(cinfo.output_width*cinfo.output_height*cinfo.num_components);
raw_image =
(unsigned char *) malloc (cinfo.output_width * cinfo.output_height *
cinfo.num_components);
// Read image, one scan at a time
row_pointer[0]=(unsigned char *) malloc(cinfo.output_width*cinfo.num_components);
while(cinfo.output_scanline<cinfo.image_height) {
jpeg_read_scanlines(&cinfo,row_pointer,1);
for(i=0;i<cinfo.image_width*cinfo.num_components;i++)
raw_image[location++]=row_pointer[0][i];
row_pointer[0] =
(unsigned char *) malloc (cinfo.output_width * cinfo.num_components);
while (cinfo.output_scanline < cinfo.image_height)
{
jpeg_read_scanlines (&cinfo, row_pointer, 1);
for (i = 0; i < cinfo.image_width * cinfo.num_components; i++)
raw_image[location++] = row_pointer[0][i];
}
// wrap up decompression, destroy objects, free pointers and close open files
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
jpeg_finish_decompress (&cinfo);
jpeg_destroy_decompress (&cinfo);
// Copy image to image struct
img.nx=cinfo.image_width;
img.ny=cinfo.image_height;
img.nz=cinfo.num_components;
img.z=(float *) malloc(sizeof(float)*img.nx*img.ny*img.nz);
img.nx = cinfo.image_width;
img.ny = cinfo.image_height;
img.nz = cinfo.num_components;
img.z = (float *) malloc (sizeof (float) * img.nx * img.ny * img.nz);
// Fill image
for (i=0;i<img.nx;i++) {
for (j=0;j<img.ny;j++) {
k=i+(img.ny-j-1)*img.nx;
img.z[k]=0.0;
for (l=0;l<img.nz;l++) {
m=img.nz*(i+img.nx*j)+l;
img.z[k]+=(float) raw_image[m];
for (i = 0; i < img.nx; i++)
{
for (j = 0; j < img.ny; j++)
{
k = i + (img.ny - j - 1) * img.nx;
img.z[k] = 0.0;
for (l = 0; l < img.nz; l++)
{
m = img.nz * (i + img.nx * j) + l;
img.z[k] += (float) raw_image[m];
}
img.z[k]/=3.0;
img.z[k] /= 3.0;
}
}
// Free allocated memory
free(row_pointer[0]);
free(raw_image);
free (row_pointer[0]);
free (raw_image);
// Close file
fclose(file);
fclose (file);
/*
// Get exif info
@ -331,185 +360,200 @@ struct image read_jpg(char *filename)
}
// Write fits file
void write_fits(struct image img,char *filename)
void
write_fits (struct image img, char *filename)
{
int i,j,k,l;
int i, j, k, l;
int *ibuf;
qfitsdumper qd;
qfits_header *qh;
char key[FITS_LINESZ+1] ;
char val[FITS_LINESZ+1] ;
char com[FITS_LINESZ+1] ;
char lin[FITS_LINESZ+1] ;
char key[FITS_LINESZ + 1];
char val[FITS_LINESZ + 1];
char com[FITS_LINESZ + 1];
char lin[FITS_LINESZ + 1];
FILE *file;
// Create FITS header
qh=qfits_header_default();
qh = qfits_header_default ();
// Add stuff
qfits_header_add(qh,"BITPIX","16"," ",NULL);
qfits_header_add(qh,"NAXIS","2"," ",NULL);
sprintf(val,"%i",img.nx);
qfits_header_add(qh,"NAXIS1",val," ",NULL);
sprintf(val,"%i",img.ny);
qfits_header_add(qh,"NAXIS2",val," ",NULL);
qfits_header_add(qh,"BSCALE","1.0"," ",NULL);
qfits_header_add(qh,"BZERO","0.0"," ",NULL);
qfits_header_add(qh,"DATAMAX","255.0"," ",NULL);
qfits_header_add(qh,"DATAMIN","0.0"," ",NULL);
qfits_header_add (qh, "BITPIX", "16", " ", NULL);
qfits_header_add (qh, "NAXIS", "2", " ", NULL);
sprintf (val, "%i", img.nx);
qfits_header_add (qh, "NAXIS1", val, " ", NULL);
sprintf (val, "%i", img.ny);
qfits_header_add (qh, "NAXIS2", val, " ", NULL);
qfits_header_add (qh, "BSCALE", "1.0", " ", NULL);
qfits_header_add (qh, "BZERO", "0.0", " ", NULL);
qfits_header_add (qh, "DATAMAX", "255.0", " ", NULL);
qfits_header_add (qh, "DATAMIN", "0.0", " ", NULL);
// Astrometry keywors
sprintf(val,"%f",img.nx/2.0);
qfits_header_add(qh,"CRPIX1",val," ",NULL);
sprintf(val,"%f",img.ny/2.0);
qfits_header_add(qh,"CRPIX2",val," ",NULL);
qfits_header_add(qh,"CRVAL1","0.0"," ",NULL);
qfits_header_add(qh,"CRVAL2","0.0"," ",NULL);
qfits_header_add(qh,"CD1_1","0.0"," ",NULL);
qfits_header_add(qh,"CD1_2","0.0"," ",NULL);
qfits_header_add(qh,"CD2_1","0.0"," ",NULL);
qfits_header_add(qh,"CD2_2","0.0"," ",NULL);
qfits_header_add(qh,"CTYPE1","'RA---TAN'"," ",NULL);
qfits_header_add(qh,"CTYPE2","'DEC--TAN'"," ",NULL);
qfits_header_add(qh,"CUNIT1","'deg'"," ",NULL);
qfits_header_add(qh,"CUNIT2","'deg'"," ",NULL);
qfits_header_add(qh,"CRRES1","0.0"," ",NULL);
qfits_header_add(qh,"CRRES2","0.0"," ",NULL);
qfits_header_add(qh,"EQUINOX","2000.0"," ",NULL);
qfits_header_add(qh,"RADECSYS","ICRS"," ",NULL);
sprintf(val,"%s",img.nfd);
qfits_header_add(qh,"DATE-OBS",val," ",NULL);
sprintf(val,"%lf",img.mjd);
qfits_header_add(qh,"MJD-OBS",val," ",NULL);
sprintf(val,"%d",img.cospar);
qfits_header_add(qh,"COSPAR",val," ",NULL);
sprintf(val,"%f",img.exptime);
qfits_header_add(qh,"EXPTIME",val," ",NULL);
sprintf(val,"%s",img.observer);
qfits_header_add(qh,"OBSERVER",val," ",NULL);
sprintf(val,"%d",img.tracked);
qfits_header_add(qh,"TRACKED",val," ",NULL);
sprintf (val, "%f", img.nx / 2.0);
qfits_header_add (qh, "CRPIX1", val, " ", NULL);
sprintf (val, "%f", img.ny / 2.0);
qfits_header_add (qh, "CRPIX2", val, " ", NULL);
qfits_header_add (qh, "CRVAL1", "0.0", " ", NULL);
qfits_header_add (qh, "CRVAL2", "0.0", " ", NULL);
qfits_header_add (qh, "CD1_1", "0.0", " ", NULL);
qfits_header_add (qh, "CD1_2", "0.0", " ", NULL);
qfits_header_add (qh, "CD2_1", "0.0", " ", NULL);
qfits_header_add (qh, "CD2_2", "0.0", " ", NULL);
qfits_header_add (qh, "CTYPE1", "'RA---TAN'", " ", NULL);
qfits_header_add (qh, "CTYPE2", "'DEC--TAN'", " ", NULL);
qfits_header_add (qh, "CUNIT1", "'deg'", " ", NULL);
qfits_header_add (qh, "CUNIT2", "'deg'", " ", NULL);
qfits_header_add (qh, "CRRES1", "0.0", " ", NULL);
qfits_header_add (qh, "CRRES2", "0.0", " ", NULL);
qfits_header_add (qh, "EQUINOX", "2000.0", " ", NULL);
qfits_header_add (qh, "RADECSYS", "ICRS", " ", NULL);
sprintf (val, "%s", img.nfd);
qfits_header_add (qh, "DATE-OBS", val, " ", NULL);
sprintf (val, "%lf", img.mjd);
qfits_header_add (qh, "MJD-OBS", val, " ", NULL);
sprintf (val, "%d", img.cospar);
qfits_header_add (qh, "COSPAR", val, " ", NULL);
sprintf (val, "%f", img.exptime);
qfits_header_add (qh, "EXPTIME", val, " ", NULL);
sprintf (val, "%s", img.observer);
qfits_header_add (qh, "OBSERVER", val, " ", NULL);
sprintf (val, "%d", img.tracked);
qfits_header_add (qh, "TRACKED", val, " ", NULL);
// Dump fitsheader
// qfits_header_dump(qh,stdout);
// Dump to file
file=fopen(filename,"w");
qfits_header_dump(qh,file);
fclose(file);
file = fopen (filename, "w");
qfits_header_dump (qh, file);
fclose (file);
// Fill buffer
ibuf=malloc(img.nx*img.ny*sizeof(int));
for (i=0,l=0;i<img.nx;i++) {
for (j=img.ny-1;j>=0;j--) {
ibuf[l]=(int) img.z[l];
ibuf = malloc (img.nx * img.ny * sizeof (int));
for (i = 0, l = 0; i < img.nx; i++)
{
for (j = img.ny - 1; j >= 0; j--)
{
ibuf[l] = (int) img.z[l];
l++;
}
}
// Set parameters
qd.filename=filename;
qd.npix=img.nx*img.ny;
qd.ptype=PTYPE_INT;
qd.ibuf=ibuf;
qd.out_ptype=BPP_16_SIGNED;
qd.filename = filename;
qd.npix = img.nx * img.ny;
qd.ptype = PTYPE_INT;
qd.ibuf = ibuf;
qd.out_ptype = BPP_16_SIGNED;
// Dump
qfits_pixdump(&qd);
qfits_pixdump (&qd);
free(ibuf);
free (ibuf);
return;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min;
int year, month, day, hour, min;
float sec;
double mjd,dday;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%f",&year,&month,&day,&hour,&min,&sec);
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%f", &year, &month, &day, &hour,
&min, &sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
mjd=date2mjd(year,month,dday);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd = date2mjd (year, month, dday);
return mjd;
}
// Compute Date from Julian Day
void mjd2nfd(double mjd,char *nfd)
void
mjd2nfd (double mjd, char *nfd)
{
double f,jd,dday;
int z,alpha,a,b,c,d,e;
int year,month,day,hour,min;
float sec,x;
double f, jd, dday;
int z, alpha, a, b, c, d, e;
int year, month, day, hour, min;
float sec, x;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
dday=b-d-floor(30.6001*e)+f;
if (e<14)
month=e-1;
dday = b - d - floor (30.6001 * e) + f;
if (e < 14)
month = e - 1;
else
month=e-13;
month = e - 13;
if (month>2)
year=c-4716;
if (month > 2)
year = c - 4716;
else
year=c-4715;
year = c - 4715;
day=(int) floor(dday);
x=24.0*(dday-day);
x=3600.*fabs(x);
sec=fmod(x,60.);
x=(x-sec)/60.;
min=fmod(x,60.);
x=(x-min)/60.;
hour=x;
sec=floor(1000.0*sec)/1000.0;
day = (int) floor (dday);
x = 24.0 * (dday - day);
x = 3600. * fabs (x);
sec = fmod (x, 60.);
x = (x - sec) / 60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
hour = x;
sec = floor (1000.0 * sec) / 1000.0;
sprintf(nfd,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec);
sprintf (nfd, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour,
min, sec);
return;
}

View File

@ -6,175 +6,198 @@
#define NMAX 1024
struct image {
int nx,ny,nz;
struct image
{
int nx, ny, nz;
float *z;
};
struct image read_jpg(char *filename);
void write_jpg(char *filename,struct image img);
struct image read_jpg (char *filename);
void write_jpg (char *filename, struct image img);
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int i,j,flag,n;
struct image avg,max,raw;
int i, j, flag, n;
struct image avg, max, raw;
for (flag=0,i=1,n=0;i<argc;i++,n++) {
printf("%d %s\n",i,argv[i]);
for (flag = 0, i = 1, n = 0; i < argc; i++, n++)
{
printf ("%d %s\n", i, argv[i]);
// Read image
raw=read_jpg(argv[i]);
raw = read_jpg (argv[i]);
// If first image, initialize
if (flag==0) {
avg.nx=raw.nx;
avg.ny=raw.ny;
avg.nz=raw.nz;
avg.z=(float *) malloc(sizeof(float)*avg.nx*avg.ny*avg.nz);
for (j=0;j<avg.nx*avg.ny*avg.nz;j++)
avg.z[j]=0.0;
if (flag == 0)
{
avg.nx = raw.nx;
avg.ny = raw.ny;
avg.nz = raw.nz;
avg.z =
(float *) malloc (sizeof (float) * avg.nx * avg.ny * avg.nz);
for (j = 0; j < avg.nx * avg.ny * avg.nz; j++)
avg.z[j] = 0.0;
max.nx=raw.nx;
max.ny=raw.ny;
max.nz=raw.nz;
max.z=(float *) malloc(sizeof(float)*max.nx*max.ny*max.nz);
for (j=0;j<max.nx*max.ny*max.nz;j++)
max.z[j]=0.0;
max.nx = raw.nx;
max.ny = raw.ny;
max.nz = raw.nz;
max.z =
(float *) malloc (sizeof (float) * max.nx * max.ny * max.nz);
for (j = 0; j < max.nx * max.ny * max.nz; j++)
max.z[j] = 0.0;
flag=1;
flag = 1;
}
// Add values
for (j=0;j<avg.nx*avg.ny*avg.nz;j++)
avg.z[j]+=raw.z[j];
for (j = 0; j < avg.nx * avg.ny * avg.nz; j++)
avg.z[j] += raw.z[j];
// Add values
for (j=0;j<avg.nx*avg.ny*avg.nz;j++)
if (raw.z[j]>max.z[j])
max.z[j]=raw.z[j];
for (j = 0; j < avg.nx * avg.ny * avg.nz; j++)
if (raw.z[j] > max.z[j])
max.z[j] = raw.z[j];
// Free
free(raw.z);
free (raw.z);
}
// Average;
for (j=0;j<avg.nx*avg.ny*avg.nz;j++)
avg.z[j]/=(float) n;
for (j = 0; j < avg.nx * avg.ny * avg.nz; j++)
avg.z[j] /= (float) n;
// Write
write_jpg("average.jpg",avg);
write_jpg("maximum.jpg",max);
write_jpg ("average.jpg", avg);
write_jpg ("maximum.jpg", max);
// Free
free(avg.z);
free(max.z);
free (avg.z);
free (max.z);
return 0;
}
struct image read_jpg(char *filename)
struct image
read_jpg (char *filename)
{
int i=0,j,k,l,m;
unsigned long location=0;
int i = 0, j, k, l, m;
unsigned long location = 0;
struct image img;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
unsigned char *raw_image=NULL;
unsigned char *raw_image = NULL;
FILE *file;
// Open file
file=fopen(filename,"rb");
file = fopen (filename, "rb");
if (!file)
perror("Error opening file");
perror ("Error opening file");
// Get header info, decompress
cinfo.err=jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo,file);
jpeg_read_header(&cinfo,TRUE);
jpeg_start_decompress(&cinfo);
cinfo.err = jpeg_std_error (&jerr);
jpeg_create_decompress (&cinfo);
jpeg_stdio_src (&cinfo, file);
jpeg_read_header (&cinfo, TRUE);
jpeg_start_decompress (&cinfo);
// Allocate memory
raw_image=(unsigned char *) malloc(cinfo.output_width*cinfo.output_height*cinfo.num_components);
raw_image =
(unsigned char *) malloc (cinfo.output_width * cinfo.output_height *
cinfo.num_components);
// Read image, one scan at a time
row_pointer[0]=(unsigned char *) malloc(cinfo.output_width*cinfo.num_components);
while(cinfo.output_scanline<cinfo.image_height) {
jpeg_read_scanlines(&cinfo,row_pointer,1);
for(i=0;i<cinfo.image_width*cinfo.num_components;i++)
raw_image[location++]=row_pointer[0][i];
row_pointer[0] =
(unsigned char *) malloc (cinfo.output_width * cinfo.num_components);
while (cinfo.output_scanline < cinfo.image_height)
{
jpeg_read_scanlines (&cinfo, row_pointer, 1);
for (i = 0; i < cinfo.image_width * cinfo.num_components; i++)
raw_image[location++] = row_pointer[0][i];
}
// wrap up decompression, destroy objects, free pointers and close open files
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
jpeg_finish_decompress (&cinfo);
jpeg_destroy_decompress (&cinfo);
// Copy image to image struct
img.nx=cinfo.image_width;
img.ny=cinfo.image_height;
img.nz=cinfo.num_components;
img.z=(float *) malloc(sizeof(float)*img.nx*img.ny*img.nz);
img.nx = cinfo.image_width;
img.ny = cinfo.image_height;
img.nz = cinfo.num_components;
img.z = (float *) malloc (sizeof (float) * img.nx * img.ny * img.nz);
// Fill image
for (i=0;i<img.nx;i++) {
for (j=0;j<img.ny;j++) {
for (k=0;k<img.nz;k++) {
l=img.nz*(i+img.nx*j)+k;
img.z[l]=(float) raw_image[l];
for (i = 0; i < img.nx; i++)
{
for (j = 0; j < img.ny; j++)
{
for (k = 0; k < img.nz; k++)
{
l = img.nz * (i + img.nx * j) + k;
img.z[l] = (float) raw_image[l];
}
}
}
// Free allocated memory
free(row_pointer[0]);
free(raw_image);
free (row_pointer[0]);
free (raw_image);
// Close file
fclose(file);
fclose (file);
return img;
}
// Write jpg
void write_jpg(char *filename,struct image img)
void
write_jpg (char *filename, struct image img)
{
int i,j,k,l,m;
int i, j, k, l, m;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
FILE *outfile;
unsigned char *raw_image=NULL;
unsigned char *raw_image = NULL;
outfile=fopen(filename,"wb");
cinfo.err=jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo,outfile);
cinfo.image_width=img.nx;
cinfo.image_height=img.ny;
cinfo.input_components=3;
cinfo.in_color_space=JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_start_compress(&cinfo,TRUE);
outfile = fopen (filename, "wb");
cinfo.err = jpeg_std_error (&jerr);
jpeg_create_compress (&cinfo);
jpeg_stdio_dest (&cinfo, outfile);
cinfo.image_width = img.nx;
cinfo.image_height = img.ny;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults (&cinfo);
jpeg_start_compress (&cinfo, TRUE);
// Allocate memory
raw_image=(unsigned char *) malloc(cinfo.image_width*cinfo.image_height*cinfo.input_components);
raw_image =
(unsigned char *) malloc (cinfo.image_width * cinfo.image_height *
cinfo.input_components);
// Fill image
for (i=0;i<img.nx;i++) {
for (j=0;j<img.ny;j++) {
for (k=0;k<img.nz;k++) {
l=img.nz*(i+img.nx*j)+k;
raw_image[l]=(unsigned char) img.z[l];
for (i = 0; i < img.nx; i++)
{
for (j = 0; j < img.ny; j++)
{
for (k = 0; k < img.nz; k++)
{
l = img.nz * (i + img.nx * j) + k;
raw_image[l] = (unsigned char) img.z[l];
}
}
}
while(cinfo.next_scanline<cinfo.image_height) {
row_pointer[0]=&raw_image[cinfo.next_scanline*cinfo.image_width*cinfo.input_components];
jpeg_write_scanlines(&cinfo,row_pointer,1);
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] =
&raw_image[cinfo.next_scanline * cinfo.image_width *
cinfo.input_components];
jpeg_write_scanlines (&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
fclose(outfile);
jpeg_finish_compress (&cinfo);
jpeg_destroy_compress (&cinfo);
fclose (outfile);
return;
}

View File

@ -16,264 +16,304 @@
extern double SGDP4_jd0;
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// DOY to MJD
double doy2mjd(int year,double doy)
double
doy2mjd (int year, double doy)
{
int month,k=2;
int month, k = 2;
double day;
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
month=floor(9.0*(k+doy)/275.0+0.98);
month = floor (9.0 * (k + doy) / 275.0 + 0.98);
if (doy<32.0)
month=1;
if (doy < 32.0)
month = 1;
day=doy-floor(275.0*month/9.0)+k*floor((month+9.0)/12.0)+30.0;
day =
doy - floor (275.0 * month / 9.0) + k * floor ((month + 9.0) / 12.0) +
30.0;
return date2mjd(year,month,day);
return date2mjd (year, month, day);
}
// Greenwich Mean Sidereal Time
double gmst(double mjd)
double
gmst (double mjd)
{
double t,gmst;
double t, gmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0);
gmst =
modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) +
t * t * (0.000387933 - t / 38710000), 360.0);
return gmst;
}
// Compute Date from Julian Day
void mjd2date(double mjd,int *year,int *month,double *day)
void
mjd2date (double mjd, int *year, int *month, double *day)
{
double f,jd;
int z,alpha,a,b,c,d,e;
double f, jd;
int z, alpha, a, b, c, d, e;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
*day=b-d-floor(30.6001*e)+f;
if (e<14)
*month=e-1;
*day = b - d - floor (30.6001 * e) + f;
if (e < 14)
*month = e - 1;
else
*month=e-13;
*month = e - 13;
if (*month>2)
*year=c-4716;
if (*month > 2)
*year = c - 4716;
else
*year=c-4715;
*year = c - 4715;
return;
}
// MJD to DOY
double mjd2doy(double mjd,int *yr)
double
mjd2doy (double mjd, int *yr)
{
int year,month,k=2;
double day,doy;
int year, month, k = 2;
double day, doy;
mjd2date(mjd,&year,&month,&day);
mjd2date (mjd, &year, &month, &day);
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30;
doy =
floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30;
*yr=year;
*yr = year;
return doy;
}
// Format TLE
void format_tle(orbit_t orb,char *line1,char *line2)
void
format_tle (orbit_t orb, char *line1, char *line2)
{
int i,csum;
char sbstar[]=" 00000-0",bstar[13];
int i, csum;
char sbstar[] = " 00000-0", bstar[13];
// Format Bstar term
if (fabs(orb.bstar)>1e-9) {
sprintf(bstar,"%11.4e",10*orb.bstar);
sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4];
sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0';
if (fabs (orb.bstar) > 1e-9)
{
sprintf (bstar, "%11.4e", 10 * orb.bstar);
sbstar[0] = bstar[0];
sbstar[1] = bstar[1];
sbstar[2] = bstar[3];
sbstar[3] = bstar[4];
sbstar[4] = bstar[5];
sbstar[5] = bstar[6];
sbstar[6] = bstar[8];
sbstar[7] = bstar[10];
sbstar[8] = '\0';
}
// Print lines
sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar);
sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev);
sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",
orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar);
sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",
orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc,
DEG (orb.argp), DEG (orb.mnan), orb.rev);
// Compute checksums
for (i=0,csum=0;i<strlen(line1);i++) {
if (isdigit(line1[i]))
csum+=line1[i]-'0';
else if (line1[i]=='-')
for (i = 0, csum = 0; i < strlen (line1); i++)
{
if (isdigit (line1[i]))
csum += line1[i] - '0';
else if (line1[i] == '-')
csum++;
}
sprintf(line1,"%s%d",line1,csum%10);
for (i=0,csum=0;i<strlen(line2);i++) {
if (isdigit(line2[i]))
csum+=line2[i]-'0';
else if (line2[i]=='-')
sprintf (line1, "%s%d", line1, csum % 10);
for (i = 0, csum = 0; i < strlen (line2); i++)
{
if (isdigit (line2[i]))
csum += line2[i] - '0';
else if (line2[i] == '-')
csum++;
}
sprintf(line2,"%s%d",line2,csum%10);
sprintf (line2, "%s%d", line2, csum % 10);
return;
}
void usage(void)
void
usage (void)
{
printf("launch tle c:i:t:T:I:d:\n\n");
printf("-c reference tle\n-i reference satno\n-t reference launch time\n-T launch time\n-I output satno\n-d output desig\n");
printf ("launch tle c:i:t:T:I:d:\n\n");
printf
("-c reference tle\n-i reference satno\n-t reference launch time\n-T launch time\n-I output satno\n-d output desig\n");
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int arg=0,satno=0,satno1=84001;
int arg = 0, satno = 0, satno1 = 84001;
char tlefile[LIM];
char nfd0[32],nfd1[32];
char line1[70],line2[70];
char nfd0[32], nfd1[32];
char line1[70], line2[70];
FILE *file;
orbit_t orb;
double mjd0,mjd1,h0,h1,dmjd,dh;
double mjd0, mjd1, h0, h1, dmjd, dh;
char *env;
char desig[]="14900A";
char desig[] = "14900A";
env=getenv("ST_TLEDIR");
sprintf(tlefile,"%s/classfd.tle",env);
env = getenv ("ST_TLEDIR");
sprintf (tlefile, "%s/classfd.tle", env);
// Decode options
while ((arg=getopt(argc,argv,"c:i:t:T:I:d:"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "c:i:t:T:I:d:")) != -1)
{
switch (arg)
{
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 't':
strcpy(nfd0,optarg);
mjd0=nfd2mjd(nfd0);
strcpy (nfd0, optarg);
mjd0 = nfd2mjd (nfd0);
break;
case 'T':
strcpy(nfd1,optarg);
mjd1=nfd2mjd(nfd1);
strcpy (nfd1, optarg);
mjd1 = nfd2mjd (nfd1);
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'I':
satno1=atoi(optarg);
satno1 = atoi (optarg);
break;
case 'd':
strcpy(desig,optarg);
strcpy (desig, optarg);
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
// Open file
file=fopen(tlefile,"rb");
if (file==NULL)
fatal_error("File open failed for reading \"%s\"",tlefile);
file = fopen (tlefile, "rb");
if (file == NULL)
fatal_error ("File open failed for reading \"%s\"", tlefile);
// Find elements
read_twoline(file,satno,&orb);
fclose(file);
read_twoline (file, satno, &orb);
fclose (file);
// Difference between epoch and launch time
dmjd=doy2mjd(orb.ep_year,orb.ep_day)-mjd0;
dmjd = doy2mjd (orb.ep_year, orb.ep_day) - mjd0;
// Difference in RAAN
orb.ascn=RAD(modulo(gmst(mjd1)-gmst(mjd0)+DEG(orb.ascn),360.0));
orb.ascn = RAD (modulo (gmst (mjd1) - gmst (mjd0) + DEG (orb.ascn), 360.0));
// New epoch
mjd0=mjd1+dmjd;
mjd0 = mjd1 + dmjd;
// Format epoch
orb.ep_day=mjd2doy(mjd0,&orb.ep_year);
orb.ep_day = mjd2doy (mjd0, &orb.ep_year);
// Update desig
strcpy(orb.desig,desig);
orb.satno=satno1;
strcpy (orb.desig, desig);
orb.satno = satno1;
// Print output
format_tle(orb,line1,line2);
printf("%s\n%s\n",line1,line2);
format_tle (orb, line1, line2);
printf ("%s\n%s\n", line1, line2);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -8,11 +8,12 @@
#include "satutl.h"
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
// if (c == '\n')
// s[i++] = c;
@ -21,94 +22,114 @@ int fgetline(FILE *file,char *s,int lim)
}
// Format TLE
void format_tle(orbit_t orb,char *line1,char *line2)
void
format_tle (orbit_t orb, char *line1, char *line2)
{
int i,csum;
char sbstar[]=" 00000-0",bstar[13];
int i, csum;
char sbstar[] = " 00000-0", bstar[13];
// Format Bstar term
if (fabs(orb.bstar)>1e-9) {
sprintf(bstar,"%11.4e",10*orb.bstar);
sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4];
sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0';
if (fabs (orb.bstar) > 1e-9)
{
sprintf (bstar, "%11.4e", 10 * orb.bstar);
sbstar[0] = bstar[0];
sbstar[1] = bstar[1];
sbstar[2] = bstar[3];
sbstar[3] = bstar[4];
sbstar[4] = bstar[5];
sbstar[5] = bstar[6];
sbstar[6] = bstar[8];
sbstar[7] = bstar[10];
sbstar[8] = '\0';
}
// Print lines
sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar);
sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f%5ld",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev,orb.norb);
sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",
orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar);
sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f%5ld",
orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc,
DEG (orb.argp), DEG (orb.mnan), orb.rev, orb.norb);
// Compute checksums
for (i=0,csum=0;i<strlen(line1);i++) {
if (isdigit(line1[i]))
csum+=line1[i]-'0';
else if (line1[i]=='-')
for (i = 0, csum = 0; i < strlen (line1); i++)
{
if (isdigit (line1[i]))
csum += line1[i] - '0';
else if (line1[i] == '-')
csum++;
}
sprintf(line1,"%s%d",line1,csum%10);
for (i=0,csum=0;i<strlen(line2);i++) {
if (isdigit(line2[i]))
csum+=line2[i]-'0';
else if (line2[i]=='-')
sprintf (line1, "%s%d", line1, csum % 10);
for (i = 0, csum = 0; i < strlen (line2); i++)
{
if (isdigit (line2[i]))
csum += line2[i] - '0';
else if (line2[i] == '-')
csum++;
}
sprintf(line2,"%s%d",line2,csum%10);
sprintf (line2, "%s%d", line2, csum % 10);
return;
}
void usage(void)
void
usage (void)
{
// while ((arg=getopt(argc,argv,"c:i:I:D:N:h"))!=-1) {
printf("Usage: mvtle -i OLD_NORAD_ID -I NEW_NORAD_ID -d COSPAR_ID [-N SATELLITE_NAME] [-h]\n\n");
printf("Arguments:\n");
printf("-i OLD_NORAD_ID Old Satellite Catalog Number (NORAD ID)\n");
printf("-i NEW_NORAD_ID New Satellite Catalog Number (NORAD ID)\n");
printf("-d COSPAR_ID International Designator (COSPAR ID)\n");
printf("-N SATELLITE_NAME (New) Satellite Name / TLE Line 0, default: ''\n");
printf("-h This help\n");
printf
("Usage: mvtle -i OLD_NORAD_ID -I NEW_NORAD_ID -d COSPAR_ID [-N SATELLITE_NAME] [-h]\n\n");
printf ("Arguments:\n");
printf ("-i OLD_NORAD_ID Old Satellite Catalog Number (NORAD ID)\n");
printf ("-i NEW_NORAD_ID New Satellite Catalog Number (NORAD ID)\n");
printf ("-d COSPAR_ID International Designator (COSPAR ID)\n");
printf
("-N SATELLITE_NAME (New) Satellite Name / TLE Line 0, default: ''\n");
printf ("-h This help\n");
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int arg=0;
int arg = 0;
char *tlefile;
int satno=0,satno_new=0;
char line0[70]="",line1[70],line2[70],desig[10]="";
int satno = 0, satno_new = 0;
char line0[70] = "", line1[70], line2[70], desig[10] = "";
orbit_t orb;
FILE *file;
// Decode options
while ((arg=getopt(argc,argv,"c:i:I:D:N:h"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "c:i:I:D:N:h")) != -1)
{
switch (arg)
{
case 'c':
tlefile=optarg;
tlefile = optarg;
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'I':
satno_new=atoi(optarg);
satno_new = atoi (optarg);
break;
case 'D':
strcpy(desig,optarg);
strcpy (desig, optarg);
break;
case 'N':
strcpy(line0,optarg);
strcpy (line0, optarg);
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
@ -116,22 +137,23 @@ int main(int argc,char *argv[])
// Open file
file=fopen(tlefile,"rb");
if (file==NULL)
fatal_error("File open failed for reading \"%s\"",tlefile);
file = fopen (tlefile, "rb");
if (file == NULL)
fatal_error ("File open failed for reading \"%s\"", tlefile);
// Loop over file
while (read_twoline(file,satno,&orb)==0) {
while (read_twoline (file, satno, &orb) == 0)
{
// Adjust changes
if (satno_new!=0)
orb.satno=satno_new;
if (strcmp(desig,"")!=0)
strcpy(orb.desig,desig);
if (satno_new != 0)
orb.satno = satno_new;
if (strcmp (desig, "") != 0)
strcpy (orb.desig, desig);
// Format
format_tle(orb,line1,line2);
printf("%s\n%s\n%s\n",line0,line1,line2);
format_tle (orb, line1, line2);
printf ("%s\n%s\n%s\n", line0, line1, line2);
}
fclose(file);
fclose (file);
return 0;
}

View File

@ -19,441 +19,491 @@
extern double SGDP4_jd0;
// Dot product
float dot(xyz_t a,xyz_t b)
float
dot (xyz_t a, xyz_t b)
{
return a.x*b.x+a.y*b.y+a.z*b.z;
return a.x * b.x + a.y * b.y + a.z * b.z;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Magnitude
double magnitude(xyz_t a)
double
magnitude (xyz_t a)
{
return sqrt(dot(a,a));
return sqrt (dot (a, a));
}
// Cross product
xyz_t cross(xyz_t a,xyz_t b)
xyz_t
cross (xyz_t a, xyz_t b)
{
xyz_t c;
c.x=a.y*b.z-a.z*b.y;
c.y=a.z*b.x-a.x*b.z;
c.z=a.x*b.y-a.y*b.x;
c.x = a.y * b.z - a.z * b.y;
c.y = a.z * b.x - a.x * b.z;
c.z = a.x * b.y - a.y * b.x;
return c;
}
// Compute Date from Julian Day
void mjd2date(double mjd,int *year,int *month,double *day)
void
mjd2date (double mjd, int *year, int *month, double *day)
{
double f,jd;
int z,alpha,a,b,c,d,e;
double f, jd;
int z, alpha, a, b, c, d, e;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
*day=b-d-floor(30.6001*e)+f;
if (e<14)
*month=e-1;
*day = b - d - floor (30.6001 * e) + f;
if (e < 14)
*month = e - 1;
else
*month=e-13;
*month = e - 13;
if (*month>2)
*year=c-4716;
if (*month > 2)
*year = c - 4716;
else
*year=c-4715;
*year = c - 4715;
return;
}
// MJD to DOY
double mjd2doy(double mjd,int *yr)
double
mjd2doy (double mjd, int *yr)
{
int year,month,k=2;
double day,doy;
int year, month, k = 2;
double day, doy;
mjd2date(mjd,&year,&month,&day);
mjd2date (mjd, &year, &month, &day);
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30;
doy =
floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30;
*yr=year;
*yr = year;
return doy;
}
// Clasical elements
orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v)
orbit_t
classel (int ep_year, double ep_day, xyz_t r, xyz_t v)
{
int i;
double rm,vm,vm2,rvm,mu=1.0;;
double chi,xp,yp,sx,cx,b,ee;
double a,ecc,incl,node,peri,mm,n;
xyz_t h,e,kk,nn;
double rm, vm, vm2, rvm, mu = 1.0;;
double chi, xp, yp, sx, cx, b, ee;
double a, ecc, incl, node, peri, mm, n;
xyz_t h, e, kk, nn;
orbit_t orb;
r.x/=XKMPER;
r.y/=XKMPER;
r.z/=XKMPER;
v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0);
v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0);
v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0);
r.x /= XKMPER;
r.y /= XKMPER;
r.z /= XKMPER;
v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
rm=magnitude(r);
vm2=dot(v,v);
rvm=dot(r,v);
h=cross(r,v);
chi=dot(h,h)/mu;
rm = magnitude (r);
vm2 = dot (v, v);
rvm = dot (r, v);
h = cross (r, v);
chi = dot (h, h) / mu;
e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x;
e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y;
e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z;
e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x;
e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y;
e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z;
a=pow(2.0/rm-vm2/mu,-1);
ecc=magnitude(e);
incl=acos(h.z/magnitude(h))*R2D;
a = pow (2.0 / rm - vm2 / mu, -1);
ecc = magnitude (e);
incl = acos (h.z / magnitude (h)) * R2D;
kk.x=0.0;
kk.y=0.0;
kk.z=1.0;
nn=cross(kk,h);
if (nn.x==0.0 && nn.y==0.0)
nn.x=1.0;
node=atan2(nn.y,nn.x)*R2D;
if (node<0.0)
node+=360.0;
kk.x = 0.0;
kk.y = 0.0;
kk.z = 1.0;
nn = cross (kk, h);
if (nn.x == 0.0 && nn.y == 0.0)
nn.x = 1.0;
node = atan2 (nn.y, nn.x) * R2D;
if (node < 0.0)
node += 360.0;
peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D;
if (e.z<0.0)
peri=360.0-peri;
if (peri<0.0)
peri+=360.0;
peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D;
if (e.z < 0.0)
peri = 360.0 - peri;
if (peri < 0.0)
peri += 360.0;
// Elliptic motion
if (ecc<1.0) {
xp=(chi-rm)/ecc;
yp=rvm/ecc*sqrt(chi/mu);
b=a*sqrt(1.0-ecc*ecc);
cx=xp/a+ecc;
sx=yp/b;
ee=atan2(sx,cx);
n=XKE*sqrt(mu/(a*a*a));
mm=(ee-ecc*sx)*R2D;
if (ecc < 1.0)
{
xp = (chi - rm) / ecc;
yp = rvm / ecc * sqrt (chi / mu);
b = a * sqrt (1.0 - ecc * ecc);
cx = xp / a + ecc;
sx = yp / b;
ee = atan2 (sx, cx);
n = XKE * sqrt (mu / (a * a * a));
mm = (ee - ecc * sx) * R2D;
}
if (mm<0.0)
mm+=360.0;
if (mm < 0.0)
mm += 360.0;
// Fill
orb.satno=0;
orb.eqinc=incl*D2R;
orb.ascn=node*D2R;
orb.argp=peri*D2R;
orb.mnan=mm*D2R;
orb.ecc=ecc;
orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI);
orb.bstar=0.0;
orb.ep_year=ep_year;
orb.ep_day=ep_day;
orb.norb=0;
orb.satno = 0;
orb.eqinc = incl * D2R;
orb.ascn = node * D2R;
orb.argp = peri * D2R;
orb.mnan = mm * D2R;
orb.ecc = ecc;
orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI);
orb.bstar = 0.0;
orb.ep_year = ep_year;
orb.ep_day = ep_day;
orb.norb = 0;
return orb;
}
orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0)
orbit_t
rv2el (int satno, double mjd, xyz_t r0, xyz_t v0)
{
int i,imode;
orbit_t orb[5],orb1[5];
xyz_t r,v;
int i, imode;
orbit_t orb[5], orb1[5];
xyz_t r, v;
kep_t kep;
char line1[70],line2[70];
char line1[70], line2[70];
int ep_year;
double ep_day;
// Epoch
ep_day=mjd2doy(mjd,&ep_year);
ep_day = mjd2doy (mjd, &ep_year);
// Initial guess
orb[0]=classel(ep_year,ep_day,r0,v0);
orb[0].satno=satno;
orb[0] = classel (ep_year, ep_day, r0, v0);
orb[0].satno = satno;
for (i=0;i<4;i++) {
for (i = 0; i < 4; i++)
{
// Propagate
imode=init_sgdp4(&orb[i]);
imode=satpos_xyz(mjd+2400000.5,&r,&v);
imode = init_sgdp4 (&orb[i]);
imode = satpos_xyz (mjd + 2400000.5, &r, &v);
// Compute initial orbital elements
orb1[i]=classel(ep_year,ep_day,r,v);
orb1[i] = classel (ep_year, ep_day, r, v);
// Adjust
orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev;
orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn;
orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp;
orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan;
orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc;
orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc;
orb[i+1].ep_year=orb[i].ep_year;
orb[i+1].ep_day=orb[i].ep_day;
orb[i+1].satno=orb[i].satno;
orb[i+1].norb=orb[i].norb;
orb[i+1].bstar=orb[i].bstar;
orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev;
orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn;
orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp;
orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan;
orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc;
orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc;
orb[i + 1].ep_year = orb[i].ep_year;
orb[i + 1].ep_day = orb[i].ep_day;
orb[i + 1].satno = orb[i].satno;
orb[i + 1].norb = orb[i].norb;
orb[i + 1].bstar = orb[i].bstar;
// Keep in range
if (orb[i+1].ecc<0.0)
orb[i+1].ecc=0.0;
if (orb[i+1].eqinc<0.0)
orb[i+1].eqinc=0.0;
if (orb[i + 1].ecc < 0.0)
orb[i + 1].ecc = 0.0;
if (orb[i + 1].eqinc < 0.0)
orb[i + 1].eqinc = 0.0;
}
orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI);
orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI);
orb[i].argp=modulo(orb[i].argp,2.0*M_PI);
orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI);
orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI);
orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI);
return orb[i];
}
// Format TLE
void format_tle(orbit_t orb,char *line1,char *line2)
void
format_tle (orbit_t orb, char *line1, char *line2)
{
int i,csum;
char sbstar[]=" 00000-0",bstar[13];
int i, csum;
char sbstar[] = " 00000-0", bstar[13];
// Format Bstar term
if (fabs(orb.bstar)>1e-9) {
sprintf(bstar,"%11.4e",10*orb.bstar);
sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4];
sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0';
if (fabs (orb.bstar) > 1e-9)
{
sprintf (bstar, "%11.4e", 10 * orb.bstar);
sbstar[0] = bstar[0];
sbstar[1] = bstar[1];
sbstar[2] = bstar[3];
sbstar[3] = bstar[4];
sbstar[4] = bstar[5];
sbstar[5] = bstar[6];
sbstar[6] = bstar[8];
sbstar[7] = bstar[10];
sbstar[8] = '\0';
}
// Print lines
sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar);
sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev);
sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",
orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar);
sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",
orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc,
DEG (orb.argp), DEG (orb.mnan), orb.rev);
// Compute checksums
for (i=0,csum=0;i<strlen(line1);i++) {
if (isdigit(line1[i]))
csum+=line1[i]-'0';
else if (line1[i]=='-')
for (i = 0, csum = 0; i < strlen (line1); i++)
{
if (isdigit (line1[i]))
csum += line1[i] - '0';
else if (line1[i] == '-')
csum++;
}
sprintf(line1,"%s%d",line1,csum%10);
for (i=0,csum=0;i<strlen(line2);i++) {
if (isdigit(line2[i]))
csum+=line2[i]-'0';
else if (line2[i]=='-')
sprintf (line1, "%s%d", line1, csum % 10);
for (i = 0, csum = 0; i < strlen (line2); i++)
{
if (isdigit (line2[i]))
csum += line2[i] - '0';
else if (line2[i] == '-')
csum++;
}
sprintf(line2,"%s%d",line2,csum%10);
sprintf (line2, "%s%d", line2, csum % 10);
return;
}
// Present nfd
void nfd_now(char *s)
void
nfd_now (char *s)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
time(&rawtime);
ptm=gmtime(&rawtime);
time (&rawtime);
ptm = gmtime (&rawtime);
sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900,
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
ptm->tm_sec);
return;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
void usage(void)
void
usage (void)
{
printf("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n");
printf
("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n");
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int imode,satno=0,arg,usecatalog=0,satnomin,flag=0;
int imode, satno = 0, arg, usecatalog = 0, satnomin, flag = 0;
FILE *file;
orbit_t orb;
xyz_t r,v,n,m,nm,r0,v0,mr,mv;
char tlefile[LIM],catalog[LIM],nfd[32];
char line1[80],line2[80],desig[20];
double mjd,ra,de,dr,drmin,dmr,dmv;
xyz_t r, v, n, m, nm, r0, v0, mr, mv;
char tlefile[LIM], catalog[LIM], nfd[32];
char line1[80], line2[80], desig[20];
double mjd, ra, de, dr, drmin, dmr, dmv;
char *env;
int at_epoch=0;
int at_epoch = 0;
// Get environment variable
env=getenv("ST_TLEDIR");
sprintf(tlefile,"%s/classfd.tle",env);
env = getenv ("ST_TLEDIR");
sprintf (tlefile, "%s/classfd.tle", env);
// Set date
nfd_now(nfd);
mjd=nfd2mjd(nfd);
nfd_now (nfd);
mjd = nfd2mjd (nfd);
// Decode options
while ((arg=getopt(argc,argv,"C:c:i:t:m:he"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "C:c:i:t:m:he")) != -1)
{
switch (arg)
{
case 't':
strcpy(nfd,optarg);
mjd=nfd2mjd(nfd);
strcpy (nfd, optarg);
mjd = nfd2mjd (nfd);
break;
case 'm':
mjd=(double) atof(optarg);
mjd = (double) atof (optarg);
break;
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 'C':
strcpy(catalog,optarg);
usecatalog=1;
strcpy (catalog, optarg);
usecatalog = 1;
break;
case 'e':
at_epoch=1;
at_epoch = 1;
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
// Reloop stderr
freopen("/tmp/stderr.txt","w",stderr);
freopen ("/tmp/stderr.txt", "w", stderr);
// Open file
file=fopen(tlefile,"r");
while (read_twoline(file,satno,&orb)==0) {
format_tle(orb,line1,line2);
file = fopen (tlefile, "r");
while (read_twoline (file, satno, &orb) == 0)
{
format_tle (orb, line1, line2);
// Propagate
imode=init_sgdp4(&orb);
if (at_epoch==1)
mjd=SGDP4_jd0-2400000.5;
imode=satpos_xyz(mjd+2400000.5,&r0,&v0);
imode = init_sgdp4 (&orb);
if (at_epoch == 1)
mjd = SGDP4_jd0 - 2400000.5;
imode = satpos_xyz (mjd + 2400000.5, &r0, &v0);
// Compute normal
n=cross(r0,v0);
ra=modulo(atan2(n.y,n.x)*R2D,360.0);
de=asin(n.z/magnitude(n))*R2D;
n = cross (r0, v0);
ra = modulo (atan2 (n.y, n.x) * R2D, 360.0);
de = asin (n.z / magnitude (n)) * R2D;
if (usecatalog==0)
printf("%05d %14.8lf %10.6f %10.6f %10.2f %10.2f %10.2f %10.2f\n",orb.satno,mjd,ra,de,magnitude(n),n.x,n.y,n.z);
if (usecatalog == 0)
printf ("%05d %14.8lf %10.6f %10.6f %10.2f %10.2f %10.2f %10.2f\n",
orb.satno, mjd, ra, de, magnitude (n), n.x, n.y, n.z);
}
fclose(file);
fclose (file);
// Match against a catalog
if (usecatalog==1) {
if (usecatalog == 1)
{
// Open file
file=fopen(catalog,"r");
while (read_twoline(file,0,&orb)==0) {
format_tle(orb,line1,line2);
file = fopen (catalog, "r");
while (read_twoline (file, 0, &orb) == 0)
{
format_tle (orb, line1, line2);
// Propagate
imode=init_sgdp4(&orb);
imode=satpos_xyz(mjd+2400000.5,&r,&v);
imode = init_sgdp4 (&orb);
imode = satpos_xyz (mjd + 2400000.5, &r, &v);
// Compute normal
m=cross(r,v);
m = cross (r, v);
// Normal difference
nm.x=n.x-m.x;
nm.y=n.y-m.y;
nm.z=n.z-m.z;
dr=magnitude(nm);
nm.x = n.x - m.x;
nm.y = n.y - m.y;
nm.z = n.z - m.z;
dr = magnitude (nm);
// Position/velocity difference
mr.x=r0.x-r.x;
mr.y=r0.y-r.y;
mr.z=r0.z-r.z;
mv.x=v0.x-v.x;
mv.y=v0.y-v.y;
mv.z=v0.z-v.z;
mr.x = r0.x - r.x;
mr.y = r0.y - r.y;
mr.z = r0.z - r.z;
mv.x = v0.x - v.x;
mv.y = v0.y - v.y;
mv.z = v0.z - v.z;
if (flag==0 || dr<drmin) {
drmin=dr;
dmr=magnitude(mr);
dmv=magnitude(mv);
satnomin=orb.satno;
flag=1;
if (flag == 0 || dr < drmin)
{
drmin = dr;
dmr = magnitude (mr);
dmv = magnitude (mv);
satnomin = orb.satno;
flag = 1;
}
}
printf("%05d %05d %8.2f km %8.2f km %10.6f km/s\n",satno,satnomin,drmin,dmr,dmv);
printf ("%05d %05d %8.2f km %8.2f km %10.6f km/s\n", satno, satnomin,
drmin, dmr, dmv);
}
return 0;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -9,26 +9,28 @@
#define LIM 80
// Cross product
xyz_t cross(xyz_t a,xyz_t b)
xyz_t
cross (xyz_t a, xyz_t b)
{
xyz_t c;
c.x=a.y*b.z-a.z*b.y;
c.y=a.z*b.x-a.x*b.z;
c.z=a.x*b.y-a.y*b.x;
c.x = a.y * b.z - a.z * b.y;
c.y = a.z * b.x - a.x * b.z;
c.z = a.x * b.y - a.y * b.x;
return c;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\t')
c=' ';
c = ' ';
if (c == '\n')
s[i++] = c;
s[i] = '\0';
@ -36,140 +38,160 @@ int fgetline(FILE *file,char *s,int lim)
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// DOY to MJD
double doy2mjd(int year,double doy)
double
doy2mjd (int year, double doy)
{
int month,k=2;
int month, k = 2;
double day;
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
month=floor(9.0*(k+doy)/275.0+0.98);
month = floor (9.0 * (k + doy) / 275.0 + 0.98);
if (doy<32)
month=1;
if (doy < 32)
month = 1;
day=doy-floor(275.0*month/9.0)+k*floor((month+9.0)/12.0)+30.0;
day =
doy - floor (275.0 * month / 9.0) + k * floor ((month + 9.0) / 12.0) +
30.0;
return date2mjd(year,month,day);
return date2mjd (year, month, day);
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int i,arg=0,imode,n=100,satno,satname,satno2,imin,flag,status;
char catalog1[]="20180121_173045_catalog.txt",catalog2[]="jsc_20180122.txt";
FILE *file1,*file2;
orbit_t orb1,orb2;
double mjd0=58140.0,mjd;
xyz_t *r,*v,r0,v0,d,n1,n2;
double dr,dv,dn,drmin,dvmin,mjdmin;
char line0[LIM],line1[LIM],line2[LIM];
int i, arg = 0, imode, n = 100, satno, satname, satno2, imin, flag, status;
char catalog1[] = "20180121_173045_catalog.txt", catalog2[] =
"jsc_20180122.txt";
FILE *file1, *file2;
orbit_t orb1, orb2;
double mjd0 = 58140.0, mjd;
xyz_t *r, *v, r0, v0, d, n1, n2;
double dr, dv, dn, drmin, dvmin, mjdmin;
char line0[LIM], line1[LIM], line2[LIM];
// Reroute stderr
freopen("/tmp/stderr.txt","w",stderr);
freopen ("/tmp/stderr.txt", "w", stderr);
// Allocate
r=(xyz_t *) malloc(sizeof(xyz_t)*n);
v=(xyz_t *) malloc(sizeof(xyz_t)*n);
r = (xyz_t *) malloc (sizeof (xyz_t) * n);
v = (xyz_t *) malloc (sizeof (xyz_t) * n);
// Open file
file1=fopen(catalog1,"r");
file2=fopen(catalog2,"r");
file1 = fopen (catalog1, "r");
file2 = fopen (catalog2, "r");
// Loop over classfd catalog
while (read_twoline(file1,0,&orb1)==0) {
while (read_twoline (file1, 0, &orb1) == 0)
{
// Compute positions
imode=init_sgdp4(&orb1);
for (i=0;i<n;i++)
satpos_xyz(mjd0+2400000.5+(double) i/86400.0,&r[i],&v[i]);
imode = init_sgdp4 (&orb1);
for (i = 0; i < n; i++)
satpos_xyz (mjd0 + 2400000.5 + (double) i / 86400.0, &r[i], &v[i]);
// Loop over ISON catalog
flag=0;
rewind(file2);
while (read_twoline(file2,0,&orb2)==0) {
mjd=doy2mjd(orb2.ep_year,orb2.ep_day);
flag = 0;
rewind (file2);
while (read_twoline (file2, 0, &orb2) == 0)
{
mjd = doy2mjd (orb2.ep_year, orb2.ep_day);
imode=init_sgdp4(&orb2);
satpos_xyz(mjd+2400000.5,&r0,&v0);
imode = init_sgdp4 (&orb2);
satpos_xyz (mjd + 2400000.5, &r0, &v0);
// Find nearest offset
for (i=0;i<n;i++) {
d.x=r[i].x-r0.x;
d.y=r[i].y-r0.y;
d.z=r[i].z-r0.z;
dr=sqrt(d.x*d.x+d.y*d.y+d.z*d.z);
d.x=v[i].x-v0.x;
d.y=v[i].y-v0.y;
d.z=v[i].z-v0.z;
dv=sqrt(d.x*d.x+d.y*d.y+d.z*d.z);
for (i = 0; i < n; i++)
{
d.x = r[i].x - r0.x;
d.y = r[i].y - r0.y;
d.z = r[i].z - r0.z;
dr = sqrt (d.x * d.x + d.y * d.y + d.z * d.z);
d.x = v[i].x - v0.x;
d.y = v[i].y - v0.y;
d.z = v[i].z - v0.z;
dv = sqrt (d.x * d.x + d.y * d.y + d.z * d.z);
if (flag==0 || dr<drmin) {
drmin=dr;
dvmin=dv;
satno=orb2.satno;
imin=i;
mjdmin=mjd;
flag=1;
if (flag == 0 || dr < drmin)
{
drmin = dr;
dvmin = dv;
satno = orb2.satno;
imin = i;
mjdmin = mjd;
flag = 1;
}
}
}
// Compute normals
rewind(file2);
read_twoline(file2,satno,&orb2);
mjd=doy2mjd(orb2.ep_year,orb2.ep_day);
imode=init_sgdp4(&orb2);
satpos_xyz(mjd+2400000.5,&r0,&v0);
n1=cross(r[0],v[0]);
n2=cross(r0,v0);
d.x=n1.x-n2.x;
d.y=n1.y-n2.y;
d.z=n1.z-n2.z;
dn=sqrt(d.x*d.x+d.y*d.y+d.z*d.z);
rewind (file2);
read_twoline (file2, satno, &orb2);
mjd = doy2mjd (orb2.ep_year, orb2.ep_day);
imode = init_sgdp4 (&orb2);
satpos_xyz (mjd + 2400000.5, &r0, &v0);
n1 = cross (r[0], v[0]);
n2 = cross (r0, v0);
d.x = n1.x - n2.x;
d.y = n1.y - n2.y;
d.z = n1.z - n2.z;
dn = sqrt (d.x * d.x + d.y * d.y + d.z * d.z);
// Find object name
rewind(file2);
while (fgetline(file2,line0,LIM)>0) {
fgetline(file2,line1,LIM);
fgetline(file2,line2,LIM);
sscanf(line1,"1 %d",&satno2);
if (satno==satno2) {
sscanf(line0,"SO %d",&satname);
rewind (file2);
while (fgetline (file2, line0, LIM) > 0)
{
fgetline (file2, line1, LIM);
fgetline (file2, line2, LIM);
sscanf (line1, "1 %d", &satno2);
if (satno == satno2)
{
sscanf (line0, "SO %d", &satname);
}
}
// printf("%05d %05d %8.2f km %9.5f km/s %6.0lf s %8.0f km\n",orb1.satno,satno,drmin,dvmin,(mjd0+(double) imin/86400.0-mjd)*86400,dn);
printf("%6d %05d %s | %5d %8.2f km %9.5f km/s %6.0lf s %8.0f km\n",satname,orb1.satno,orb1.desig,satno,drmin,dvmin,(mjd0+(double) imin/86400.0-mjd)*86400,dn);
printf ("%6d %05d %s | %5d %8.2f km %9.5f km/s %6.0lf s %8.0f km\n",
satname, orb1.satno, orb1.desig, satno, drmin, dvmin,
(mjd0 + (double) imin / 86400.0 - mjd) * 86400, dn);
}
fclose(file1);
fclose(file2);
fclose (file1);
fclose (file2);
// Free
free(r);
free(v);
free (r);
free (v);
return 0;
}

View File

@ -19,191 +19,214 @@ extern double SGDP4_jd0;
// Compute Date from Julian Day
void mjd2date(double mjd,int *year,int *month,double *day)
void
mjd2date (double mjd, int *year, int *month, double *day)
{
double f,jd;
int z,alpha,a,b,c,d,e;
double f, jd;
int z, alpha, a, b, c, d, e;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
*day=b-d-floor(30.6001*e)+f;
if (e<14)
*month=e-1;
*day = b - d - floor (30.6001 * e) + f;
if (e < 14)
*month = e - 1;
else
*month=e-13;
*month = e - 13;
if (*month>2)
*year=c-4716;
if (*month > 2)
*year = c - 4716;
else
*year=c-4715;
*year = c - 4715;
return;
}
// MJD to DOY
double mjd2doy(double mjd,int *yr)
double
mjd2doy (double mjd, int *yr)
{
int year,month,k=2;
double day,doy;
int year, month, k = 2;
double day, doy;
mjd2date(mjd,&year,&month,&day);
mjd2date (mjd, &year, &month, &day);
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30;
doy =
floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30;
*yr=year;
*yr = year;
return doy;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
// Present nfd
void nfd_now(char *s)
void
nfd_now (char *s)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
time(&rawtime);
ptm=gmtime(&rawtime);
time (&rawtime);
ptm = gmtime (&rawtime);
sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900,
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
ptm->tm_sec);
return;
}
void usage(void)
void
usage (void)
{
printf("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n");
printf
("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n");
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int imode,satno=0,arg,i;
int imode, satno = 0, arg, i;
FILE *file;
orbit_t orb;
xyz_t r,v;
char tlefile[LIM],nfd[32];
xyz_t r, v;
char tlefile[LIM], nfd[32];
char *env;
double mjd;
int length=3600,dl=60;
int length = 3600, dl = 60;
// Get environment variable
env=getenv("ST_TLEDIR");
sprintf(tlefile,"%s/classfd.tle",env);
env = getenv ("ST_TLEDIR");
sprintf (tlefile, "%s/classfd.tle", env);
// Set date
nfd_now(nfd);
mjd=nfd2mjd(nfd);
nfd_now (nfd);
mjd = nfd2mjd (nfd);
// Decode options
while ((arg=getopt(argc,argv,"c:i:t:l:d:"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "c:i:t:l:d:")) != -1)
{
switch (arg)
{
case 't':
strcpy(nfd,optarg);
mjd=nfd2mjd(nfd);
strcpy (nfd, optarg);
mjd = nfd2mjd (nfd);
break;
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'l':
length=atoi(optarg);
length = atoi (optarg);
break;
case 'd':
dl=atoi(optarg);
dl = atoi (optarg);
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
// Reloop stderr
freopen("/tmp/stderr.txt","w",stderr);
freopen ("/tmp/stderr.txt", "w", stderr);
// Open file
file=fopen(tlefile,"r");
while (read_twoline(file,satno,&orb)==0) {
file = fopen (tlefile, "r");
while (read_twoline (file, satno, &orb) == 0)
{
// Propagate
imode=init_sgdp4(&orb);
imode = init_sgdp4 (&orb);
for (i=0;i<length;i+=dl) {
satpos_xyz(mjd+2400000.5+(double) i/86400.0,&r,&v);
printf("%f %f %f %f %f %f\n",r.x,r.y,r.z,v.x,v.y,v.z);
for (i = 0; i < length; i += dl)
{
satpos_xyz (mjd + 2400000.5 + (double) i / 86400.0, &r, &v);
printf ("%f %f %f %f %f %f\n", r.x, r.y, r.z, v.x, v.y, v.z);
}
}
fclose(file);
fclose (file);
return 0;
}

View File

@ -18,431 +18,479 @@
extern double SGDP4_jd0;
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Dot product
float dot(xyz_t a,xyz_t b)
float
dot (xyz_t a, xyz_t b)
{
return a.x*b.x+a.y*b.y+a.z*b.z;
return a.x * b.x + a.y * b.y + a.z * b.z;
}
// Magnitude
double magnitude(xyz_t a)
double
magnitude (xyz_t a)
{
return sqrt(dot(a,a));
return sqrt (dot (a, a));
}
// Cross product
xyz_t cross(xyz_t a,xyz_t b)
xyz_t
cross (xyz_t a, xyz_t b)
{
xyz_t c;
c.x=a.y*b.z-a.z*b.y;
c.y=a.z*b.x-a.x*b.z;
c.z=a.x*b.y-a.y*b.x;
c.x = a.y * b.z - a.z * b.y;
c.y = a.z * b.x - a.x * b.z;
c.z = a.x * b.y - a.y * b.x;
return c;
}
// Compute Date from Julian Day
void mjd2date(double mjd,int *year,int *month,double *day)
void
mjd2date (double mjd, int *year, int *month, double *day)
{
double f,jd;
int z,alpha,a,b,c,d,e;
double f, jd;
int z, alpha, a, b, c, d, e;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
*day=b-d-floor(30.6001*e)+f;
if (e<14)
*month=e-1;
*day = b - d - floor (30.6001 * e) + f;
if (e < 14)
*month = e - 1;
else
*month=e-13;
*month = e - 13;
if (*month>2)
*year=c-4716;
if (*month > 2)
*year = c - 4716;
else
*year=c-4715;
*year = c - 4715;
return;
}
// MJD to DOY
double mjd2doy(double mjd,int *yr)
double
mjd2doy (double mjd, int *yr)
{
int year,month,k=2;
double day,doy;
int year, month, k = 2;
double day, doy;
mjd2date(mjd,&year,&month,&day);
mjd2date (mjd, &year, &month, &day);
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30;
doy =
floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30;
*yr=year;
*yr = year;
return doy;
}
// Clasical elements
orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v)
orbit_t
classel (int ep_year, double ep_day, xyz_t r, xyz_t v)
{
int i;
double rm,vm,vm2,rvm,mu=1.0;;
double chi,xp,yp,sx,cx,b,ee;
double a,ecc,incl,node,peri,mm,n;
xyz_t h,e,kk,nn;
double rm, vm, vm2, rvm, mu = 1.0;;
double chi, xp, yp, sx, cx, b, ee;
double a, ecc, incl, node, peri, mm, n;
xyz_t h, e, kk, nn;
orbit_t orb;
r.x/=XKMPER;
r.y/=XKMPER;
r.z/=XKMPER;
v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0);
v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0);
v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0);
r.x /= XKMPER;
r.y /= XKMPER;
r.z /= XKMPER;
v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
rm=magnitude(r);
vm2=dot(v,v);
rvm=dot(r,v);
h=cross(r,v);
chi=dot(h,h)/mu;
rm = magnitude (r);
vm2 = dot (v, v);
rvm = dot (r, v);
h = cross (r, v);
chi = dot (h, h) / mu;
e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x;
e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y;
e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z;
e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x;
e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y;
e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z;
a=pow(2.0/rm-vm2/mu,-1);
ecc=magnitude(e);
incl=acos(h.z/magnitude(h))*R2D;
a = pow (2.0 / rm - vm2 / mu, -1);
ecc = magnitude (e);
incl = acos (h.z / magnitude (h)) * R2D;
kk.x=0.0;
kk.y=0.0;
kk.z=1.0;
nn=cross(kk,h);
if (nn.x==0.0 && nn.y==0.0)
nn.x=1.0;
node=atan2(nn.y,nn.x)*R2D;
if (node<0.0)
node+=360.0;
kk.x = 0.0;
kk.y = 0.0;
kk.z = 1.0;
nn = cross (kk, h);
if (nn.x == 0.0 && nn.y == 0.0)
nn.x = 1.0;
node = atan2 (nn.y, nn.x) * R2D;
if (node < 0.0)
node += 360.0;
peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D;
if (e.z<0.0)
peri=360.0-peri;
if (peri<0.0)
peri+=360.0;
peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D;
if (e.z < 0.0)
peri = 360.0 - peri;
if (peri < 0.0)
peri += 360.0;
// Elliptic motion
if (ecc<1.0) {
xp=(chi-rm)/ecc;
yp=rvm/ecc*sqrt(chi/mu);
b=a*sqrt(1.0-ecc*ecc);
cx=xp/a+ecc;
sx=yp/b;
ee=atan2(sx,cx);
n=XKE*sqrt(mu/(a*a*a));
mm=(ee-ecc*sx)*R2D;
if (ecc < 1.0)
{
xp = (chi - rm) / ecc;
yp = rvm / ecc * sqrt (chi / mu);
b = a * sqrt (1.0 - ecc * ecc);
cx = xp / a + ecc;
sx = yp / b;
ee = atan2 (sx, cx);
n = XKE * sqrt (mu / (a * a * a));
mm = (ee - ecc * sx) * R2D;
}
if (mm<0.0)
mm+=360.0;
if (mm < 0.0)
mm += 360.0;
// Fill
orb.satno=0;
orb.eqinc=incl*D2R;
orb.ascn=node*D2R;
orb.argp=peri*D2R;
orb.mnan=mm*D2R;
orb.ecc=ecc;
orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI);
orb.bstar=0.0;
orb.ep_year=ep_year;
orb.ep_day=ep_day;
orb.norb=0;
orb.satno = 0;
orb.eqinc = incl * D2R;
orb.ascn = node * D2R;
orb.argp = peri * D2R;
orb.mnan = mm * D2R;
orb.ecc = ecc;
orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI);
orb.bstar = 0.0;
orb.ep_year = ep_year;
orb.ep_day = ep_day;
orb.norb = 0;
return orb;
}
orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0)
orbit_t
rv2el (int satno, double mjd, xyz_t r0, xyz_t v0)
{
int i,imode;
orbit_t orb[5],orb1[5];
xyz_t r,v;
int i, imode;
orbit_t orb[5], orb1[5];
xyz_t r, v;
kep_t kep;
char line1[70],line2[70];
char line1[70], line2[70];
int ep_year;
double ep_day;
// Epoch
ep_day=mjd2doy(mjd,&ep_year);
ep_day = mjd2doy (mjd, &ep_year);
// Initial guess
orb[0]=classel(ep_year,ep_day,r0,v0);
orb[0].satno=satno;
orb[0] = classel (ep_year, ep_day, r0, v0);
orb[0].satno = satno;
for (i=0;i<4;i++) {
for (i = 0; i < 4; i++)
{
// Propagate
imode=init_sgdp4(&orb[i]);
imode=satpos_xyz(mjd+2400000.5,&r,&v);
imode = init_sgdp4 (&orb[i]);
imode = satpos_xyz (mjd + 2400000.5, &r, &v);
// Compute initial orbital elements
orb1[i]=classel(ep_year,ep_day,r,v);
orb1[i] = classel (ep_year, ep_day, r, v);
// Adjust
orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev;
orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn;
orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp;
orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan;
orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc;
orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc;
orb[i+1].ep_year=orb[i].ep_year;
orb[i+1].ep_day=orb[i].ep_day;
orb[i+1].satno=orb[i].satno;
orb[i+1].norb=orb[i].norb;
orb[i+1].bstar=orb[i].bstar;
orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev;
orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn;
orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp;
orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan;
orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc;
orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc;
orb[i + 1].ep_year = orb[i].ep_year;
orb[i + 1].ep_day = orb[i].ep_day;
orb[i + 1].satno = orb[i].satno;
orb[i + 1].norb = orb[i].norb;
orb[i + 1].bstar = orb[i].bstar;
// Keep in range
if (orb[i+1].ecc<0.0)
orb[i+1].ecc=0.0;
if (orb[i+1].eqinc<0.0)
orb[i+1].eqinc=0.0;
if (orb[i + 1].ecc < 0.0)
orb[i + 1].ecc = 0.0;
if (orb[i + 1].eqinc < 0.0)
orb[i + 1].eqinc = 0.0;
}
orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI);
orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI);
orb[i].argp=modulo(orb[i].argp,2.0*M_PI);
orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI);
orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI);
orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI);
return orb[i];
}
// Format TLE
void format_tle(orbit_t orb,char *line1,char *line2)
void
format_tle (orbit_t orb, char *line1, char *line2)
{
int i,csum;
char sbstar[]=" 00000-0",bstar[13];
int i, csum;
char sbstar[] = " 00000-0", bstar[13];
// Format Bstar term
if (fabs(orb.bstar)>1e-9) {
sprintf(bstar,"%11.4e",10*orb.bstar);
sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4];
sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0';
if (fabs (orb.bstar) > 1e-9)
{
sprintf (bstar, "%11.4e", 10 * orb.bstar);
sbstar[0] = bstar[0];
sbstar[1] = bstar[1];
sbstar[2] = bstar[3];
sbstar[3] = bstar[4];
sbstar[4] = bstar[5];
sbstar[5] = bstar[6];
sbstar[6] = bstar[8];
sbstar[7] = bstar[10];
sbstar[8] = '\0';
}
// Print lines
sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar);
sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev);
sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",
orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar);
sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",
orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc,
DEG (orb.argp), DEG (orb.mnan), orb.rev);
// Compute checksums
for (i=0,csum=0;i<strlen(line1);i++) {
if (isdigit(line1[i]))
csum+=line1[i]-'0';
else if (line1[i]=='-')
for (i = 0, csum = 0; i < strlen (line1); i++)
{
if (isdigit (line1[i]))
csum += line1[i] - '0';
else if (line1[i] == '-')
csum++;
}
sprintf(line1,"%s%d",line1,csum%10);
for (i=0,csum=0;i<strlen(line2);i++) {
if (isdigit(line2[i]))
csum+=line2[i]-'0';
else if (line2[i]=='-')
sprintf (line1, "%s%d", line1, csum % 10);
for (i = 0, csum = 0; i < strlen (line2); i++)
{
if (isdigit (line2[i]))
csum += line2[i] - '0';
else if (line2[i] == '-')
csum++;
}
sprintf(line2,"%s%d",line2,csum%10);
sprintf (line2, "%s%d", line2, csum % 10);
return;
}
// Present nfd
void nfd_now(char *s)
void
nfd_now (char *s)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
time(&rawtime);
ptm=gmtime(&rawtime);
time (&rawtime);
ptm = gmtime (&rawtime);
sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900,
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
ptm->tm_sec);
return;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// DOY to MJD
double doy2mjd(int year,double doy)
double
doy2mjd (int year, double doy)
{
int month,k=2;
int month, k = 2;
double day;
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
month=floor(9.0*(k+doy)/275.0+0.98);
month = floor (9.0 * (k + doy) / 275.0 + 0.98);
if (doy<32)
month=1;
if (doy < 32)
month = 1;
day=doy-floor(275.0*month/9.0)+k*floor((month+9.0)/12.0)+30.0;
day =
doy - floor (275.0 * month / 9.0) + k * floor ((month + 9.0) / 12.0) +
30.0;
return date2mjd(year,month,day);
return date2mjd (year, month, day);
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
void usage(void)
void
usage (void)
{
printf("propagate c:i:t:m:e:d:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n-e New epoch (YYDDD.ddddddd)\n-d New COSPAR designation\n");
printf
("propagate c:i:t:m:e:d:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n-e New epoch (YYDDD.ddddddd)\n-d New COSPAR designation\n");
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int imode,satno=0,arg,desigflag=0;
int imode, satno = 0, arg, desigflag = 0;
FILE *file;
orbit_t orb;
xyz_t r,v;
char tlefile[LIM],nfd[32];
char line1[80],line2[80],desig[20];
double mjd,epoch,ep_day,bstar;
xyz_t r, v;
char tlefile[LIM], nfd[32];
char line1[80], line2[80], desig[20];
double mjd, epoch, ep_day, bstar;
char *env;
int ep_year;
// Get environment variable
env=getenv("ST_TLEDIR");
sprintf(tlefile,"%s/classfd.tle",env);
env = getenv ("ST_TLEDIR");
sprintf (tlefile, "%s/classfd.tle", env);
// Set date
nfd_now(nfd);
mjd=nfd2mjd(nfd);
nfd_now (nfd);
mjd = nfd2mjd (nfd);
// Decode options
while ((arg=getopt(argc,argv,"c:i:t:m:he:d:"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "c:i:t:m:he:d:")) != -1)
{
switch (arg)
{
case 't':
strcpy(nfd,optarg);
mjd=nfd2mjd(nfd);
strcpy (nfd, optarg);
mjd = nfd2mjd (nfd);
break;
case 'e':
epoch=(double) atof(optarg);
ep_year=(int) floor(epoch/1000.0);
ep_day=epoch-1000*ep_year;
printf("%d %f\n",ep_year,ep_day);
if (ep_year<50)
ep_year+=2000;
epoch = (double) atof (optarg);
ep_year = (int) floor (epoch / 1000.0);
ep_day = epoch - 1000 * ep_year;
printf ("%d %f\n", ep_year, ep_day);
if (ep_year < 50)
ep_year += 2000;
else
ep_year+=1900;
ep_year += 1900;
mjd=doy2mjd(ep_year,ep_day);
mjd = doy2mjd (ep_year, ep_day);
break;
case 'd':
strcpy(desig,optarg);
desigflag=1;
strcpy (desig, optarg);
desigflag = 1;
break;
case 'm':
mjd=(double) atof(optarg);
mjd = (double) atof (optarg);
break;
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
// Open file
file=fopen(tlefile,"r");
while (read_twoline(file,satno,&orb)==0) {
format_tle(orb,line1,line2);
file = fopen (tlefile, "r");
while (read_twoline (file, satno, &orb) == 0)
{
format_tle (orb, line1, line2);
// printf("Input:\n%s\n%s\n",line1,line2);
if (desigflag==0)
strcpy(desig,orb.desig);
bstar=orb.bstar;
if (desigflag == 0)
strcpy (desig, orb.desig);
bstar = orb.bstar;
// Propagate
imode=init_sgdp4(&orb);
imode=satpos_xyz(mjd+2400000.5,&r,&v);
imode = init_sgdp4 (&orb);
imode = satpos_xyz (mjd + 2400000.5, &r, &v);
// Convert
orb=rv2el(orb.satno,mjd,r,v);
orb = rv2el (orb.satno, mjd, r, v);
// Copy back
strcpy(orb.desig,desig);
orb.bstar=bstar;
strcpy (orb.desig, desig);
orb.bstar = bstar;
format_tle(orb,line1,line2);
printf("%s\n%s\n",line1,line2);
format_tle (orb, line1, line2);
printf ("%s\n%s\n", line1, line2);
}
fclose(file);
fclose (file);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -6,147 +6,165 @@
#define LIM 128
int fgetline(FILE *file,char *s,int lim);
int find_satno(char *desig0)
int fgetline (FILE * file, char *s, int lim);
int
find_satno (char *desig0)
{
FILE *file;
int satno=99999,status;
int satno = 99999, status;
char desig[16];
char *env,filename[LIM];
char *env, filename[LIM];
env=getenv("ST_DATADIR");
sprintf(filename,"%s/data/desig.txt",env);
file=fopen(filename,"r");
if (file==NULL) {
fprintf(stderr,"Designation file not found!\n");
exit(0);
env = getenv ("ST_DATADIR");
sprintf (filename, "%s/data/desig.txt", env);
file = fopen (filename, "r");
if (file == NULL)
{
fprintf (stderr, "Designation file not found!\n");
exit (0);
}
while (!feof(file)) {
status=fscanf(file,"%d %s",&satno,desig);
if (strcmp(desig,desig0)==0)
while (!feof (file))
{
status = fscanf (file, "%d %s", &satno, desig);
if (strcmp (desig, desig0) == 0)
break;
}
fclose(file);
fclose (file);
return satno;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
FILE *file;
char line[LIM];
int intidy,intido,piece,site,year,month,day,hour,min,sec,fsec,satno;
char desig[16],pdesig[16];
int format,epoch,dummy,icsec;
float csec,cang;
int rah,ram,rafm,ded,dem,defm;
float tm,tx,am,ax;
int intidy, intido, piece, site, year, month, day, hour, min, sec, fsec,
satno;
char desig[16], pdesig[16];
int format, epoch, dummy, icsec;
float csec, cang;
int rah, ram, rafm, ded, dem, defm;
float tm, tx, am, ax;
char sign;
int lineno=0;
int lineno = 0;
file=fopen(argv[1],"r");
while (fgetline(file,line,LIM)>0) {
if (strncmp(line,"2420",4)==0 && lineno==0) {
file = fopen (argv[1], "r");
while (fgetline (file, line, LIM) > 0)
{
if (strncmp (line, "2420", 4) == 0 && lineno == 0)
{
lineno++;
sscanf(line,"%04d %02d%02d",&site,&year,&month);
sscanf(line+12,"%1d%1d%1d %3d%1d",&icsec,&dummy,&format,&dummy,&epoch);
sscanf (line, "%04d %02d%02d", &site, &year, &month);
sscanf (line + 12, "%1d%1d%1d %3d%1d", &icsec, &dummy, &format,
&dummy, &epoch);
csec=0.1*icsec;
cang=dummy;
csec = 0.1 * icsec;
cang = dummy;
// Year switch
if (year>50)
year+=1900;
if (year > 50)
year += 1900;
else
year+=2000;
year += 2000;
// Time accuracy
tx=floor(log10(csec))+8;
tm=floor(csec/pow(10.0,tx-8));
tx = floor (log10 (csec)) + 8;
tm = floor (csec / pow (10.0, tx - 8));
// angle accuracy
ax=floor(log10(cang))+8;
am=floor(cang/pow(10.0,ax-8));
ax = floor (log10 (cang)) + 8;
am = floor (cang / pow (10.0, ax - 8));
if (ax>9.0) {
ax=9.0;
am=9.0;
if (ax > 9.0)
{
ax = 9.0;
am = 9.0;
}
continue;
}
if (strlen(line)<5 && lineno==1) {
sscanf(line,"%d",&day);
if (day==999)
if (strlen (line) < 5 && lineno == 1)
{
sscanf (line, "%d", &day);
if (day == 999)
break;
continue;
}
// Skip wrong lines
if (!isdigit(line[0]))
if (!isdigit (line[0]))
continue;
// Skip short lines
if (strlen(line)<31)
if (strlen (line) < 31)
continue;
// Scan line
sscanf(line,"%02d%03d%02d",&intidy,&intido,&piece);
sscanf(line+8,"%02d%02d%02d.%02d",&hour,&min,&sec,&fsec);
sscanf(line+18,"%02d%02d%d",&rah,&ram,&rafm);
sscanf(line+24,"%c%02d%02d%d",&sign,&ded,&dem,&defm);
fsec*=10.0;
sscanf (line, "%02d%03d%02d", &intidy, &intido, &piece);
sscanf (line + 8, "%02d%02d%02d.%02d", &hour, &min, &sec, &fsec);
sscanf (line + 18, "%02d%02d%d", &rah, &ram, &rafm);
sscanf (line + 24, "%c%02d%02d%d", &sign, &ded, &dem, &defm);
fsec *= 10.0;
// Format designation
if (piece<26) {
sprintf(desig,"%02d %03d%c",intidy,intido,piece+'A'-1);
sprintf(pdesig,"%02d%03d%c",intidy,intido,piece+'A'-1);
} else {
fprintf(stderr,"Failed to understand designation!\n");
fprintf(stderr,"%s\n",line);
if (piece < 26)
{
sprintf (desig, "%02d %03d%c", intidy, intido, piece + 'A' - 1);
sprintf (pdesig, "%02d%03d%c", intidy, intido, piece + 'A' - 1);
}
else
{
fprintf (stderr, "Failed to understand designation!\n");
fprintf (stderr, "%s\n", line);
continue;
}
// Test data format
if (format!=1) {
fprintf(stderr,"Angle format %d not implemented!\n",format);
fprintf(stderr,"%s\n",line);
if (format != 1)
{
fprintf (stderr, "Angle format %d not implemented!\n", format);
fprintf (stderr, "%s\n", line);
continue;
}
// Fractional RA
if (rafm<10)
rafm*=100;
else if (rafm<100)
rafm*=10;
if (rafm < 10)
rafm *= 100;
else if (rafm < 100)
rafm *= 10;
// Fractional DE
if (defm<10)
defm*=10;
else if (defm<100)
defm*=1;
if (defm < 10)
defm *= 10;
else if (defm < 100)
defm *= 1;
// Get satellite number
satno=find_satno(pdesig);
satno = find_satno (pdesig);
// Format IOD line
printf("%05d %s %04d G %04d%02d%02d%02d%02d%02d%03d %1.0f%1.0f %d%d ",satno,desig,site,year,month,day,hour,min,sec,fsec,tm,tx,format,epoch);
printf("%02d%02d%03d%c%02d%02d%02d %1.0f%1.0f\n",rah,ram,rafm,sign,ded,dem,defm,am,ax);
printf
("%05d %s %04d G %04d%02d%02d%02d%02d%02d%03d %1.0f%1.0f %d%d ",
satno, desig, site, year, month, day, hour, min, sec, fsec, tm, tx,
format, epoch);
printf ("%02d%02d%03d%c%02d%02d%02d %1.0f%1.0f\n", rah, ram, rafm, sign,
ded, dem, defm, am, ax);
}
fclose(file);
fclose (file);
return 0;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}

File diff suppressed because it is too large Load Diff

View File

@ -15,578 +15,644 @@
#define XKMPAU 149597879.691 // AU in km
#define FLAT (1.0/298.257)
long Isat=0;
long Isatsel=0;
long Isat = 0;
long Isatsel = 0;
extern double SGDP4_jd0;
struct point {
int flag,satno;
double mjd,ra,de;
float st,sr;
struct point
{
int flag, satno;
double mjd, ra, de;
float st, sr;
char iod_line[LIM];
xyz_t obspos;
};
struct site {
struct site
{
int id;
double lng,lat;
double lng, lat;
float alt;
char observer[64];
};
struct data {
struct data
{
int n;
struct point *p;
} ;
struct point decode_iod_observation(char *iod_line);
struct site get_site(int site_id);
int fgetline(FILE *file,char *s,int lim);
double modulo(double x,double y);
double gmst(double mjd);
double dgmst(double mjd);
double date2mjd(int year,int month,double day);
void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de);
void usage();
void obspos_xyz(double mjd,double lng,double lat,float alt,xyz_t *pos,xyz_t *vel);
struct data read_data(char *filename);
void forward(double ra0,double de0,double ra,double de,double *x,double *y);
};
struct point decode_iod_observation (char *iod_line);
struct site get_site (int site_id);
int fgetline (FILE * file, char *s, int lim);
double modulo (double x, double y);
double gmst (double mjd);
double dgmst (double mjd);
double date2mjd (int year, int month, double day);
void precess (double mjd0, double ra0, double de0, double mjd, double *ra,
double *de);
void usage ();
void obspos_xyz (double mjd, double lng, double lat, float alt, xyz_t * pos,
xyz_t * vel);
struct data read_data (char *filename);
void forward (double ra0, double de0, double ra, double de, double *x,
double *y);
void compute_residual(char *filename,struct point p,int satno)
void
compute_residual (char *filename, struct point p, int satno)
{
int i,imode;
int i, imode;
FILE *file;
orbit_t orb;
xyz_t satpos,satvel;
double dx,dy,dz;
double r[2],ra,de;
double rx[2],ry[2],dr,dt,drx,dry;
xyz_t satpos, satvel;
double dx, dy, dz;
double r[2], ra, de;
double rx[2], ry[2], dr, dt, drx, dry;
double jd;
double age;
// Open catalog
file=fopen(filename,"r");
if (file==NULL)
fatal_error("Failed to open %s\n",filename);
file = fopen (filename, "r");
if (file == NULL)
fatal_error ("Failed to open %s\n", filename);
// Read TLE
if (satno==0)
read_twoline(file,p.satno,&orb);
if (satno == 0)
read_twoline (file, p.satno, &orb);
else
read_twoline(file,satno,&orb);
fclose(file);
read_twoline (file, satno, &orb);
fclose (file);
// Check for match
if (orb.satno!=p.satno && satno==0) {
if (orb.satno != p.satno && satno == 0)
{
// fprintf(stderr,"object %d not found in %s\n",p.satno,filename);
return;
}
// Initialize
imode=init_sgdp4(&orb);
if (imode==SGDP4_ERROR) {
fprintf(stderr,"Error initializing SGDP4\n");
exit(0);
imode = init_sgdp4 (&orb);
if (imode == SGDP4_ERROR)
{
fprintf (stderr, "Error initializing SGDP4\n");
exit (0);
}
for (i=0;i<2;i++) {
jd=p.mjd+2400000.5+(double) i/86400;
for (i = 0; i < 2; i++)
{
jd = p.mjd + 2400000.5 + (double) i / 86400;
// Compute position
satpos_xyz(jd,&satpos,&satvel);
age=jd-SGDP4_jd0;
satpos_xyz (jd, &satpos, &satvel);
age = jd - SGDP4_jd0;
// compute difference vector
dx=satpos.x-p.obspos.x;
dy=satpos.y-p.obspos.y;
dz=satpos.z-p.obspos.z;
dx = satpos.x - p.obspos.x;
dy = satpos.y - p.obspos.y;
dz = satpos.z - p.obspos.z;
// Celestial position
r[i]=sqrt(dx*dx+dy*dy+dz*dz);
ra=modulo(atan2(dy,dx)*R2D,360.0);
de=asin(dz/r[i])*R2D;
r[i] = sqrt (dx * dx + dy * dy + dz * dz);
ra = modulo (atan2 (dy, dx) * R2D, 360.0);
de = asin (dz / r[i]) * R2D;
// Compute offset
forward(p.ra,p.de,ra,de,&rx[i],&ry[i]);
forward (p.ra, p.de, ra, de, &rx[i], &ry[i]);
}
drx=rx[1]-rx[0];
dry=ry[1]-ry[0];
dt=-(rx[0]*drx+ry[0]*dry)/(drx*drx+dry*dry);
dr=sqrt(pow(dry*rx[0]-drx*ry[0],2)/(drx*drx+dry*dry));
if ((-rx[0]*drx-ry[0]*dry)<0.0)
dr*=-1;
printf("%s | %8.5f deg %9.4f sec %7.3f day, %.1f km\n",p.iod_line,dr,dt,age,r[0]);
drx = rx[1] - rx[0];
dry = ry[1] - ry[0];
dt = -(rx[0] * drx + ry[0] * dry) / (drx * drx + dry * dry);
dr = sqrt (pow (dry * rx[0] - drx * ry[0], 2) / (drx * drx + dry * dry));
if ((-rx[0] * drx - ry[0] * dry) < 0.0)
dr *= -1;
printf ("%s | %8.5f deg %9.4f sec %7.3f day, %.1f km\n", p.iod_line, dr, dt,
age, r[0]);
//printf("%12.8lf %8.3f %8.3f\n",p.mjd,3600*rx[0],3600*ry[0]);
return;
}
void split_file(struct data d,float dtmax)
void
split_file (struct data d, float dtmax)
{
int i,j,flag=0;
int i, j, flag = 0;
FILE *file;
char filename[LIM];
double mjd0,dt;
double mjd0, dt;
for (i=0,j=0;i<d.n;i++) {
if (flag==1) {
dt=86400*(d.p[i].mjd-mjd0);
if (dt>dtmax) {
if (file!=NULL)
fclose(file);
flag=0;
for (i = 0, j = 0; i < d.n; i++)
{
if (flag == 1)
{
dt = 86400 * (d.p[i].mjd - mjd0);
if (dt > dtmax)
{
if (file != NULL)
fclose (file);
flag = 0;
j++;
}
}
if (flag==0) {
mjd0=d.p[i].mjd;
flag=1;
sprintf(filename,"split%04d.dat",j+1);
file=fopen(filename,"w");
if (flag == 0)
{
mjd0 = d.p[i].mjd;
flag = 1;
sprintf (filename, "split%04d.dat", j + 1);
file = fopen (filename, "w");
}
fprintf(file,"%s\n",d.p[i].iod_line);
fprintf (file, "%s\n", d.p[i].iod_line);
}
if (file!=NULL)
fclose(file);
if (file != NULL)
fclose (file);
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int i,arg=0,split=0;
int i, arg = 0, split = 0;
struct data d;
char *datafile,catalog[LIM];
char *datafile, catalog[LIM];
char *env;
float dt;
int verbose=0,satno=0;
int verbose = 0, satno = 0;
env=getenv("ST_TLEDIR");
sprintf(catalog,"%s/classfd.tle",env);
env = getenv ("ST_TLEDIR");
sprintf (catalog, "%s/classfd.tle", env);
// Decode options
while ((arg=getopt(argc,argv,"d:c:hs:vi:"))!=-1) {
switch(arg) {
while ((arg = getopt (argc, argv, "d:c:hs:vi:")) != -1)
{
switch (arg)
{
case 'd':
datafile=optarg;
datafile = optarg;
break;
case 'v':
verbose=1;
verbose = 1;
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'c':
strcpy(catalog,optarg);
strcpy (catalog, optarg);
break;
case 's':
dt=atof(optarg);
split=1;
dt = atof (optarg);
split = 1;
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
// Read data
d=read_data(datafile);
d = read_data (datafile);
if (verbose==1) {
for (i=0;i<d.n;i++) {
printf("%14.8lf %10.4f %10.4f %10.4f %10.6f %10.6f\n",d.p[i].mjd,d.p[i].obspos.x,d.p[i].obspos.y,d.p[i].obspos.z,d.p[i].ra,d.p[i].de);
if (verbose == 1)
{
for (i = 0; i < d.n; i++)
{
printf ("%14.8lf %10.4f %10.4f %10.4f %10.6f %10.6f\n", d.p[i].mjd,
d.p[i].obspos.x, d.p[i].obspos.y, d.p[i].obspos.z,
d.p[i].ra, d.p[i].de);
}
}
if (split==1) {
split_file(d,dt);
} else {
for (i=0;i<d.n;i++)
compute_residual(catalog,d.p[i],satno);
if (split == 1)
{
split_file (d, dt);
}
else
{
for (i = 0; i < d.n; i++)
compute_residual (catalog, d.p[i], satno);
}
return 0;
}
// Decode IOD Observations
struct point decode_iod_observation(char *iod_line)
struct point
decode_iod_observation (char *iod_line)
{
int year,month,iday,hour,min;
int format,epoch,me,xe,sign;
int year, month, iday, hour, min;
int format, epoch, me, xe, sign;
int site_id;
double sec,ra,mm,ss,de,dd,ds,day,mjd0;
char secbuf[6],sn[2],degbuf[3];
double sec, ra, mm, ss, de, dd, ds, day, mjd0;
char secbuf[6], sn[2], degbuf[3];
struct point p;
struct site s;
xyz_t vel;
// Strip newline
iod_line[strlen(iod_line)-1]='\0';
iod_line[strlen (iod_line) - 1] = '\0';
// Copy full line
strcpy(p.iod_line,iod_line);
strcpy (p.iod_line, iod_line);
// Set flag
p.flag=1;
p.flag = 1;
// Get SSN
sscanf(iod_line,"%5d",&p.satno);
sscanf (iod_line, "%5d", &p.satno);
// Get site
sscanf(iod_line+16,"%4d",&site_id);
s=get_site(site_id);
sscanf (iod_line + 16, "%4d", &site_id);
s = get_site (site_id);
// Skip if site not found
if (s.id<0) {
fprintf(stderr,"Site %d not found!\n",site_id);
p.flag=0;
if (s.id < 0)
{
fprintf (stderr, "Site %d not found!\n", site_id);
p.flag = 0;
}
// Decode date/time
sscanf(iod_line+23,"%4d%2d%2d%2d%2d%5s",&year,&month,&iday,&hour,&min,secbuf);
sec=atof(secbuf);
sec/=pow(10,strlen(secbuf)-2);
day=(double) iday+(double) hour/24.0+(double) min/1440.0+(double) sec/86400.0;
p.mjd=date2mjd(year,month,day);
sscanf (iod_line + 23, "%4d%2d%2d%2d%2d%5s", &year, &month, &iday, &hour,
&min, secbuf);
sec = atof (secbuf);
sec /= pow (10, strlen (secbuf) - 2);
day =
(double) iday + (double) hour / 24.0 + (double) min / 1440.0 +
(double) sec / 86400.0;
p.mjd = date2mjd (year, month, day);
// Get uncertainty in time
sscanf(iod_line+41,"%1d%1d",&me,&xe);
p.st=(float) me*pow(10,xe-8);
sscanf (iod_line + 41, "%1d%1d", &me, &xe);
p.st = (float) me *pow (10, xe - 8);
// Get observer position
obspos_xyz(p.mjd,s.lng,s.lat,s.alt,&p.obspos,&vel);
obspos_xyz (p.mjd, s.lng, s.lat, s.alt, &p.obspos, &vel);
// Skip empty observations
if (strlen(iod_line)<64 || (iod_line[54]!='+' && iod_line[54]!='-'))
p.flag=0;
if (strlen (iod_line) < 64 || (iod_line[54] != '+' && iod_line[54] != '-'))
p.flag = 0;
// Get format, epoch
sscanf(iod_line+44,"%1d%1d",&format,&epoch);
sscanf (iod_line + 44, "%1d%1d", &format, &epoch);
// Read position
sscanf(iod_line+47,"%2lf%2lf%3lf%1s",&ra,&mm,&ss,sn);
sscanf(iod_line+55,"%2lf%2lf%2s",&de,&dd,degbuf);
ds=atof(degbuf);
if (strlen(degbuf)==1)
ds*=10;
sign=(sn[0]=='-') ? -1 : 1;
sscanf(iod_line+62,"%1d%1d",&me,&xe);
p.sr=(float) me*pow(10,xe-8);
sscanf (iod_line + 47, "%2lf%2lf%3lf%1s", &ra, &mm, &ss, sn);
sscanf (iod_line + 55, "%2lf%2lf%2s", &de, &dd, degbuf);
ds = atof (degbuf);
if (strlen (degbuf) == 1)
ds *= 10;
sign = (sn[0] == '-') ? -1 : 1;
sscanf (iod_line + 62, "%1d%1d", &me, &xe);
p.sr = (float) me *pow (10, xe - 8);
// Decode position
switch(format)
switch (format)
{
// Format 1: RA/DEC = HHMMSSs+DDMMSS MX (MX in seconds of arc)
case 1 :
ra+=mm/60+ss/36000;
de=sign*(de+dd/60+ds/3600);
p.sr/=3600.0;
case 1:
ra += mm / 60 + ss / 36000;
de = sign * (de + dd / 60 + ds / 3600);
p.sr /= 3600.0;
break;
// Format 2: RA/DEC = HHMMmmm+DDMMmm MX (MX in minutes of arc)
case 2:
ra+=mm/60+ss/60000;
de=sign*(de+dd/60+ds/6000);
p.sr/=60.0;
ra += mm / 60 + ss / 60000;
de = sign * (de + dd / 60 + ds / 6000);
p.sr /= 60.0;
break;
// Format 3: RA/DEC = HHMMmmm+DDdddd MX (MX in degrees of arc)
case 3 :
ra+=mm/60+ss/60000;
de=sign*(de+dd/100+ds/10000);
case 3:
ra += mm / 60 + ss / 60000;
de = sign * (de + dd / 100 + ds / 10000);
break;
// Format 7: RA/DEC = HHMMSSs+DDdddd MX (MX in degrees of arc)
case 7 :
ra+=mm/60+ss/36000;
de=sign*(de+dd/100+ds/10000);
case 7:
ra += mm / 60 + ss / 36000;
de = sign * (de + dd / 100 + ds / 10000);
break;
default :
fprintf(stderr,"IOD Format not implemented\n");
p.flag=0;
default:
fprintf (stderr, "IOD Format not implemented\n");
p.flag = 0;
break;
}
// Convert to degrees
ra*=15.0;
ra *= 15.0;
// Get precession epoch
if (epoch==0) {
p.ra=ra;
p.de=de;
if (epoch == 0)
{
p.ra = ra;
p.de = de;
return p;
} else if (epoch==4) {
mjd0=33281.9235;
} else if (epoch==5) {
mjd0=51544.5;
} else {
fprintf(stderr,"Observing epoch not implemented\n");
p.flag=0;
}
else if (epoch == 4)
{
mjd0 = 33281.9235;
}
else if (epoch == 5)
{
mjd0 = 51544.5;
}
else
{
fprintf (stderr, "Observing epoch not implemented\n");
p.flag = 0;
}
// Precess position
precess(mjd0,ra,de,p.mjd,&p.ra,&p.de);
precess (mjd0, ra, de, p.mjd, &p.ra, &p.de);
return p;
}
// Get observing site
struct site get_site(int site_id)
struct site
get_site (int site_id)
{
int i=0;
int i = 0;
char line[LIM];
FILE *file;
int id;
double lat,lng;
double lat, lng;
float alt;
char abbrev[3],observer[64];
char abbrev[3], observer[64];
struct site s;
char *env,filename[LIM];
char *env, filename[LIM];
env=getenv("ST_DATADIR");
sprintf(filename,"%s/data/sites.txt",env);
file=fopen(filename,"r");
if (file==NULL) {
printf("File with site information not found!\n");
env = getenv ("ST_DATADIR");
sprintf (filename, "%s/data/sites.txt", env);
file = fopen (filename, "r");
if (file == NULL)
{
printf ("File with site information not found!\n");
return s;
}
while (fgets(line,LIM,file)!=NULL) {
while (fgets (line, LIM, file) != NULL)
{
// Skip
if (strstr(line,"#")!=NULL)
if (strstr (line, "#") != NULL)
continue;
// Strip newline
line[strlen(line)-1]='\0';
line[strlen (line) - 1] = '\0';
// Read data
sscanf(line,"%4d %2s %lf %lf %f",
&id,abbrev,&lat,&lng,&alt);
strcpy(observer,line+38);
sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt);
strcpy (observer, line + 38);
// Change to km
alt/=1000.0;
alt /= 1000.0;
// Copy site
if (id==site_id) {
s.lat=lat;
s.lng=lng;
s.alt=alt;
s.id=id;
strcpy(s.observer,observer);
if (id == site_id)
{
s.lat = lat;
s.lng = lng;
s.alt = alt;
s.id = id;
strcpy (s.observer, observer);
}
}
fclose(file);
fclose (file);
if (id!=site_id)
s.id==-1;
if (id != site_id)
s.id == -1;
return s;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Greenwich Mean Sidereal Time
double gmst(double mjd)
double
gmst (double mjd)
{
double t,gmst;
double t, gmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0);
gmst =
modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) +
t * t * (0.000387933 - t / 38710000), 360.0);
return gmst;
}
// Greenwich Mean Sidereal Time
double dgmst(double mjd)
double
dgmst (double mjd)
{
double t,dgmst;
double t, dgmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
dgmst=360.98564736629+t*(0.000387933-t/38710000);
dgmst = 360.98564736629 + t * (0.000387933 - t / 38710000);
return dgmst;
}
// Observer position
void obspos_xyz(double mjd,double lng,double lat,float alt,xyz_t *pos,xyz_t *vel)
void
obspos_xyz (double mjd, double lng, double lat, float alt, xyz_t * pos,
xyz_t * vel)
{
double ff,gc,gs,theta,s,dtheta;
double ff, gc, gs, theta, s, dtheta;
s=sin(lat*D2R);
ff=sqrt(1.0-FLAT*(2.0-FLAT)*s*s);
gc=1.0/ff+alt/XKMPER;
gs=(1.0-FLAT)*(1.0-FLAT)/ff+alt/XKMPER;
s = sin (lat * D2R);
ff = sqrt (1.0 - FLAT * (2.0 - FLAT) * s * s);
gc = 1.0 / ff + alt / XKMPER;
gs = (1.0 - FLAT) * (1.0 - FLAT) / ff + alt / XKMPER;
theta=gmst(mjd)+lng;
dtheta=dgmst(mjd)*D2R/86400;
theta = gmst (mjd) + lng;
dtheta = dgmst (mjd) * D2R / 86400;
pos->x=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER;
pos->y=gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER;
pos->z=gs*sin(lat*D2R)*XKMPER;
vel->x=-gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER*dtheta;
vel->y=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER*dtheta;
vel->z=0.0;
pos->x = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER;
pos->y = gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER;
pos->z = gs * sin (lat * D2R) * XKMPER;
vel->x = -gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER * dtheta;
vel->y = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER * dtheta;
vel->z = 0.0;
return;
}
// Precess a celestial position
void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de)
void
precess (double mjd0, double ra0, double de0, double mjd, double *ra,
double *de)
{
double t0,t;
double zeta,z,theta;
double a,b,c;
double t0, t;
double zeta, z, theta;
double a, b, c;
// Angles in radians
ra0*=D2R;
de0*=D2R;
ra0 *= D2R;
de0 *= D2R;
// Time in centuries
t0=(mjd0-51544.5)/36525.0;
t=(mjd-mjd0)/36525.0;
t0 = (mjd0 - 51544.5) / 36525.0;
t = (mjd - mjd0) / 36525.0;
// Precession angles
zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t;
zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t;
zeta*=D2R/3600.0;
z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t;
z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t;
z*=D2R/3600.0;
theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t;
theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t;
theta*=D2R/3600.0;
zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t;
zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t;
zeta *= D2R / 3600.0;
z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t;
z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t;
z *= D2R / 3600.0;
theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t;
theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t;
theta *= D2R / 3600.0;
a=cos(de0)*sin(ra0+zeta);
b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0);
c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0);
a = cos (de0) * sin (ra0 + zeta);
b = cos (theta) * cos (de0) * cos (ra0 + zeta) - sin (theta) * sin (de0);
c = sin (theta) * cos (de0) * cos (ra0 + zeta) + cos (theta) * sin (de0);
*ra=(atan2(a,b)+z)*R2D;
*de=asin(c)*R2D;
*ra = (atan2 (a, b) + z) * R2D;
*de = asin (c) * R2D;
if (*ra<360.0)
*ra+=360.0;
if (*ra>360.0)
*ra-=360.0;
if (*ra < 360.0)
*ra += 360.0;
if (*ra > 360.0)
*ra -= 360.0;
return;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\t')
c=' ';
c = ' ';
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
void usage()
void
usage ()
{
printf("bla\n");
printf ("bla\n");
return;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// Read data
struct data read_data(char *filename)
struct data
read_data (char *filename)
{
int i=0;
int i = 0;
char line[LIM];
FILE *file;
struct data d;
// Open file
file=fopen(filename,"r");
if (file==NULL) {
fprintf(stderr,"Failed to open %s\n",filename);
exit(1);
file = fopen (filename, "r");
if (file == NULL)
{
fprintf (stderr, "Failed to open %s\n", filename);
exit (1);
}
// Count lines
while (fgetline(file,line,LIM)>0)
while (fgetline (file, line, LIM) > 0)
i++;
d.n=i;
d.n = i;
// Allocate
d.p=(struct point *) malloc(sizeof(struct point)*d.n);
d.p = (struct point *) malloc (sizeof (struct point) * d.n);
// Rewind file
rewind(file);
rewind (file);
// Read data
i=0;
while (fgetline(file,line,LIM)>0) {
if (isdigit(line[0]))
d.p[i++]=decode_iod_observation(line);
i = 0;
while (fgetline (file, line, LIM) > 0)
{
if (isdigit (line[0]))
d.p[i++] = decode_iod_observation (line);
}
// Close file
fclose(file);
fclose (file);
return d;
}
// Get a x and y from a RA and Decl
void forward(double ra0,double de0,double ra,double de,double *x,double *y)
void
forward (double ra0, double de0, double ra, double de, double *x, double *y)
{
int i,status;
double phi,theta;
int i, status;
double phi, theta;
struct celprm cel;
// Initialize Reference Angles
celini(&cel);
cel.ref[0]=ra0;
cel.ref[1]=de0;
cel.ref[2]=999.;
cel.ref[3]=999.;
cel.flag=0.;
strcpy(cel.prj.code,"TAN");
celini (&cel);
cel.ref[0] = ra0;
cel.ref[1] = de0;
cel.ref[2] = 999.;
cel.ref[3] = 999.;
cel.flag = 0.;
strcpy (cel.prj.code, "TAN");
if (celset(&cel)) {
printf("Error in Projection (celset)\n");
if (celset (&cel))
{
printf ("Error in Projection (celset)\n");
return;
}
cels2x(&cel,1,0,1,1,&ra,&de,&phi,&theta,x,y,&status);
cels2x (&cel, 1, 0, 1, 1, &ra, &de, &phi, &theta, x, y, &status);
return;
}

View File

@ -4,29 +4,31 @@
#include <wcslib/cel.h>
// Get a RA and Decl from x and y
void reverse(double ra0,double de0,double x,double y,double *ra,double *de)
void
reverse (double ra0, double de0, double x, double y, double *ra, double *de)
{
int i,status;
double phi,theta;
int i, status;
double phi, theta;
struct celprm cel;
x/=3600.;
y/=3600.;
x /= 3600.;
y /= 3600.;
// Initialize Reference Angles
celini(&cel);
cel.ref[0]=ra0;
cel.ref[1]=de0;
cel.ref[2]=999.;
cel.ref[3]=999.;
cel.flag=0.;
strcpy(cel.prj.code,"STG");
celini (&cel);
cel.ref[0] = ra0;
cel.ref[1] = de0;
cel.ref[2] = 999.;
cel.ref[3] = 999.;
cel.flag = 0.;
strcpy (cel.prj.code, "STG");
if (celset(&cel)) {
printf("Error in Projection (celset)\n");
if (celset (&cel))
{
printf ("Error in Projection (celset)\n");
return;
}
celx2s(&cel,1,0,1,1,&x,&y,&phi,&theta,ra,de,&status);
celx2s (&cel, 1, 0, 1, 1, &x, &y, &phi, &theta, ra, de, &status);
return;
}

View File

@ -23,117 +23,142 @@
#define FINISHED 2
// Observation struct contains observation time, celestial coords and camera name
struct observation {
char stime[32],sra[32],sde[32],camname[15],startstop[10];
struct observation
{
char stime[32], sra[32], sde[32], camname[15], startstop[10];
time_t ptime;
float dt;
};
int fgetline(FILE *file,char *s,int lim);
void send_position(char *sra,char *sde,char *datadir,char *obsdir,char *camname);
void stop_obs(char *datadir,char *obsdir,char *camname);
time_t decode_time(char *stm);
int fgetline (FILE * file, char *s, int lim);
void send_position (char *sra, char *sde, char *datadir, char *obsdir,
char *camname);
void stop_obs (char *datadir, char *obsdir, char *camname);
time_t decode_time (char *stm);
int main(int argc, char *argv[])
int
main (int argc, char *argv[])
{
int i=0,nobs,flag=0;
time_t rawtime,aimtime;
struct tm *ptm,*rtm;
char buf[20],line[LIM],stm[20],sra[32],sde[32],pra[32],pde[32];
int i = 0, nobs, flag = 0;
time_t rawtime, aimtime;
struct tm *ptm, *rtm;
char buf[20], line[LIM], stm[20], sra[32], sde[32], pra[32], pde[32];
FILE *file;
struct observation obs[NMAX];
char *env;
char datadir[128],obsdir[128];
char datadir[128], obsdir[128];
int nextobs, dtnext;
// Get environment variables
env=getenv("ST_DATADIR");
if (env!=NULL) {
strcpy(datadir,env);
} else {
printf("ST_DATADIR environment variable not found.\n");
env = getenv ("ST_DATADIR");
if (env != NULL)
{
strcpy (datadir, env);
}
else
{
printf ("ST_DATADIR environment variable not found.\n");
}
// Get environment variables
env=getenv("ST_OBSDIR");
if (env!=NULL) {
strcpy(obsdir,env);
} else {
printf("ST_OBSDIR environment variable not found.\n");
env = getenv ("ST_OBSDIR");
if (env != NULL)
{
strcpy (obsdir, env);
}
else
{
printf ("ST_OBSDIR environment variable not found.\n");
}
// For ever loop
for (;;) {
for (;;)
{
// Read file
i=0;
file=fopen("schedule.txt","r");
while (fgetline(file,line,LIM)>0) {
sscanf(line,"%s %s %s %s %s",obs[i].stime,obs[i].sra,obs[i].sde,obs[i].camname,obs[i].startstop);
obs[i].ptime=decode_time(obs[i].stime);
i = 0;
file = fopen ("schedule.txt", "r");
while (fgetline (file, line, LIM) > 0)
{
sscanf (line, "%s %s %s %s %s", obs[i].stime, obs[i].sra,
obs[i].sde, obs[i].camname, obs[i].startstop);
obs[i].ptime = decode_time (obs[i].stime);
i++;
}
fclose(file);
nobs=i;
fclose (file);
nobs = i;
// Get local time
time(&rawtime);
time (&rawtime);
//rawtime-=3600;
// Print UTC time
ptm=gmtime(&rawtime);
strftime(buf,32,"%Y-%m-%dT%H:%M:%S",ptm);
ptm = gmtime (&rawtime);
strftime (buf, 32, "%Y-%m-%dT%H:%M:%S", ptm);
// Make raw time UTC to compare with scheduled time
rawtime=mktime(ptm);
rawtime = mktime (ptm);
// Show current raw time, just to check
// printf("%s\n",ctime(&rawtime));
// Compute time differences
for (i=0;i<nobs;i++) {
obs[i].dt=difftime(obs[i].ptime,rawtime);
for (i = 0; i < nobs; i++)
{
obs[i].dt = difftime (obs[i].ptime, rawtime);
}
nextobs=-1;
dtnext=9999999;
nextobs = -1;
dtnext = 9999999;
// Loop over observations
for (i=0;i<nobs;i++) {
if (obs[i].dt>0.0) {
if(obs[i].dt < dtnext){
nextobs=i;
dtnext=obs[i].dt;
for (i = 0; i < nobs; i++)
{
if (obs[i].dt > 0.0)
{
if (obs[i].dt < dtnext)
{
nextobs = i;
dtnext = obs[i].dt;
}
// printf("%4.0f %s %s %s %s\n",obs[i].dt,obs[i].stime,obs[i].sra,obs[i].sde,obs[i].startstop);
// break;
} else if (obs[i].dt==0) {
if(strstr(obs[i].startstop,"tart")!=NULL){
}
else if (obs[i].dt == 0)
{
if (strstr (obs[i].startstop, "tart") != NULL)
{
//printf("Slewing to %s %s\n",obs[i].sra,obs[i].sde);
send_position(obs[i].sra,obs[i].sde,datadir,obsdir,obs[i].camname);
} else if(strstr(obs[i].startstop,"top")!=NULL){
stop_obs(datadir,obsdir,obs[i].camname);
send_position (obs[i].sra, obs[i].sde, datadir, obsdir,
obs[i].camname);
}
else if (strstr (obs[i].startstop, "top") != NULL)
{
stop_obs (datadir, obsdir, obs[i].camname);
}
}
}
if(nextobs>=0){
if (nextobs >= 0)
{
// print next observation data if any found
printf("%4.0f %s %s %s %s\n",obs[nextobs].dt,obs[nextobs].stime,obs[nextobs].sra,obs[nextobs].sde,obs[nextobs].startstop);
printf ("%4.0f %s %s %s %s\n", obs[nextobs].dt, obs[nextobs].stime,
obs[nextobs].sra, obs[nextobs].sde, obs[nextobs].startstop);
}
// Sleep
sleep(1);
sleep (1);
}
return 0;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
@ -142,110 +167,127 @@ int fgetline(FILE *file,char *s,int lim)
}
// Read data/cameras.txt in search of specified camera name and return complete camera details line
int read_cameras(char *camname,char *datadir,char *camera)
int
read_cameras (char *camname, char *datadir, char *camera)
{
FILE *file;
char line[127],filename[127];
char line[127], filename[127];
sprintf(filename,"%s/data/cameras.txt",datadir);
file=fopen(filename,"r");
if (file==NULL) {
printf("File with camera information not found!\n");
sprintf (filename, "%s/data/cameras.txt", datadir);
file = fopen (filename, "r");
if (file == NULL)
{
printf ("File with camera information not found!\n");
return -1;
}
while (fgets(line,LIM,file)!=NULL) {
while (fgets (line, LIM, file) != NULL)
{
// Skip commented lines
if (strstr(line,"#")!=NULL)
if (strstr (line, "#") != NULL)
continue;
if(strstr(line, camname)!=NULL){
strcpy(camera, line);
if (strstr (line, camname) != NULL)
{
strcpy (camera, line);
return 0;
}
}
fclose(file);
fclose (file);
return -1;
}
// Send new position to telescope
void send_position(char *sra,char *sde,char *datadir,char *obsdir,char *camname)
void
send_position (char *sra, char *sde, char *datadir, char *obsdir,
char *camname)
{
int skt, port;
struct hostent *he;
struct sockaddr_in addr;
char packet[LIM];
FILE *file;
float ra,de;
char camera[128],fname[128];
float ra, de;
char camera[128], fname[128];
float f;
char s[31];
// Check if camera is fixed
// read complete line from data/cameras.txt describing the scheduled camera
read_cameras(camname,datadir,camera); // search for camera name
sscanf(camera,"%s %f %f %f %f %s", s, &f, &f, &f, &f, s);
read_cameras (camname, datadir, camera); // search for camera name
sscanf (camera, "%s %f %f %f %f %s", s, &f, &f, &f, &f, s);
// Look for "fix" string to jump over slewing routines.
if(strstr(s,"ix")==NULL){
if (strstr (s, "ix") == NULL)
{
// Old packet style
// sprintf(packet,"<newNumberVector device='iEQ' name='EQUATORIAL_EOD_COORD_REQUEST'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",sra,sde);
// New packet style (as of 2013-08-20)
sprintf(packet,"<newNumberVector device='iEQ' name='EQUATORIAL_EOD_COORD'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",sra,sde);
sprintf (packet,
"<newNumberVector device='iEQ' name='EQUATORIAL_EOD_COORD'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",
sra, sde);
printf("Slewing to %s %s\n",sra,sde);
printf ("Slewing to %s %s\n", sra, sde);
// Send TCP packet
skt=socket(AF_INET,SOCK_STREAM,0);
addr.sin_family=AF_INET;
port=PORT;
addr.sin_port=htons(port);
he=gethostbyname(IP);
bcopy(he->h_addr,(struct in_addr *) &addr.sin_addr,he->h_length);
while((connect(skt,(struct sockaddr *) &addr,sizeof(addr))<0) && (port < MAXPORT)) {
fprintf(stderr,"Connection refused by remote host on port %04d.\n",port);
skt = socket (AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
port = PORT;
addr.sin_port = htons (port);
he = gethostbyname (IP);
bcopy (he->h_addr, (struct in_addr *) &addr.sin_addr, he->h_length);
while ((connect (skt, (struct sockaddr *) &addr, sizeof (addr)) < 0)
&& (port < MAXPORT))
{
fprintf (stderr,
"Connection refused by remote host on port %04d.\n", port);
port++;
// Skip port 7265... used by some other service?
if(port==7265) port++;
fprintf(stderr,"Trying port %04d.\n",port);
if (port == 7265)
port++;
fprintf (stderr, "Trying port %04d.\n", port);
addr.sin_port=htons(port);
he=gethostbyname(IP);
bcopy(he->h_addr,(struct in_addr *) &addr.sin_addr,he->h_length);
addr.sin_port = htons (port);
he = gethostbyname (IP);
bcopy (he->h_addr, (struct in_addr *) &addr.sin_addr, he->h_length);
}
if(port>=MAXPORT) return;
if (port >= MAXPORT)
return;
printf("Connected to Indi server on port %04d.\n",port);
printf ("Connected to Indi server on port %04d.\n", port);
write(skt,packet,strlen(packet));
close(skt);
write (skt, packet, strlen (packet));
close (skt);
}
printf("Starting new observation\n");
printf ("Starting new observation\n");
// Set restart
sprintf(fname,"%s/control/state.txt",obsdir);
file=fopen(fname,"w");
if (file!=NULL) {
fprintf(file,"restart");
fclose(file);
sprintf (fname, "%s/control/state.txt", obsdir);
file = fopen (fname, "w");
if (file != NULL)
{
fprintf (file, "restart");
fclose (file);
}
// Set position
sprintf(fname,"%s/control/position.txt",obsdir);
file=fopen(fname,"w");
if (file!=NULL) {
fprintf(file,"%s %s\n",sra,sde);
fclose(file);
sprintf (fname, "%s/control/position.txt", obsdir);
file = fopen (fname, "w");
if (file != NULL)
{
fprintf (file, "%s %s\n", sra, sde);
fclose (file);
}
// Set camera
sprintf(fname,"%s/control/camera.txt",obsdir);
file=fopen(fname,"w");
if (file!=NULL) {
fprintf(file,"%s",camera);
fclose(file);
sprintf (fname, "%s/control/camera.txt", obsdir);
file = fopen (fname, "w");
if (file != NULL)
{
fprintf (file, "%s", camera);
fclose (file);
}
return;
@ -253,26 +295,28 @@ void send_position(char *sra,char *sde,char *datadir,char *obsdir,char *camname)
// Send stop observation signal
void stop_obs(char *datadir,char *obsdir,char *camname)
void
stop_obs (char *datadir, char *obsdir, char *camname)
{
FILE *file;
char camera[128],fname[128];
char camera[128], fname[128];
float f;
char s[31];
// Retrieve Camera data
// read complete line from data/cameras.txt describing the scheduled camera
read_cameras(camname,datadir,camera); // search for camera name
sscanf(camera,"%s %f %f %f %f %s", s, &f, &f, &f, &f, s);
read_cameras (camname, datadir, camera); // search for camera name
sscanf (camera, "%s %f %f %f %f %s", s, &f, &f, &f, &f, s);
printf("Stop observation\n");
printf ("Stop observation\n");
// Set stop
sprintf(fname,"%s/control/state.txt",obsdir);
file=fopen(fname,"w");
if (file!=NULL) {
fprintf(file,"stop");
fclose(file);
sprintf (fname, "%s/control/state.txt", obsdir);
file = fopen (fname, "w");
if (file != NULL)
{
fprintf (file, "stop");
fclose (file);
}
return;
@ -280,17 +324,19 @@ void stop_obs(char *datadir,char *obsdir,char *camname)
// Decode time
time_t decode_time(char *stm)
time_t
decode_time (char *stm)
{
time_t aimtime;
struct tm *rtm;
int d;
rtm=gmtime(&aimtime);
sscanf(stm,"%04d-%02d-%02dT%02d:%02d:%02d",&rtm->tm_year,&rtm->tm_mon,&rtm->tm_mday,&rtm->tm_hour,&rtm->tm_min,&rtm->tm_sec);
rtm->tm_year-=1900;
rtm = gmtime (&aimtime);
sscanf (stm, "%04d-%02d-%02dT%02d:%02d:%02d", &rtm->tm_year, &rtm->tm_mon,
&rtm->tm_mday, &rtm->tm_hour, &rtm->tm_min, &rtm->tm_sec);
rtm->tm_year -= 1900;
rtm->tm_mon--;
aimtime=mktime(rtm);
aimtime = mktime (rtm);
return aimtime;
}

View File

@ -18,330 +18,374 @@
extern double SGDP4_jd0;
// Dot product
float dot(xyz_t a,xyz_t b)
float
dot (xyz_t a, xyz_t b)
{
return a.x*b.x+a.y*b.y+a.z*b.z;
return a.x * b.x + a.y * b.y + a.z * b.z;
}
// Magnitude
double magnitude(xyz_t a)
double
magnitude (xyz_t a)
{
return sqrt(dot(a,a));
return sqrt (dot (a, a));
}
// Cross product
xyz_t cross(xyz_t a,xyz_t b)
xyz_t
cross (xyz_t a, xyz_t b)
{
xyz_t c;
c.x=a.y*b.z-a.z*b.y;
c.y=a.z*b.x-a.x*b.z;
c.z=a.x*b.y-a.y*b.x;
c.x = a.y * b.z - a.z * b.y;
c.y = a.z * b.x - a.x * b.z;
c.z = a.x * b.y - a.y * b.x;
return c;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Compute Date from Julian Day
void mjd2date(double mjd,int *year,int *month,double *day)
void
mjd2date (double mjd, int *year, int *month, double *day)
{
double f,jd;
int z,alpha,a,b,c,d,e;
double f, jd;
int z, alpha, a, b, c, d, e;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
*day=b-d-floor(30.6001*e)+f;
if (e<14)
*month=e-1;
*day = b - d - floor (30.6001 * e) + f;
if (e < 14)
*month = e - 1;
else
*month=e-13;
*month = e - 13;
if (*month>2)
*year=c-4716;
if (*month > 2)
*year = c - 4716;
else
*year=c-4715;
*year = c - 4715;
return;
}
// MJD to DOY
double mjd2doy(double mjd,int *yr)
double
mjd2doy (double mjd, int *yr)
{
int year,month,k=2;
double day,doy;
int year, month, k = 2;
double day, doy;
mjd2date(mjd,&year,&month,&day);
mjd2date (mjd, &year, &month, &day);
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30;
doy =
floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30;
*yr=year;
*yr = year;
return doy;
}
// Clasical elements
orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v)
orbit_t
classel (int ep_year, double ep_day, xyz_t r, xyz_t v)
{
int i;
double rm,vm,vm2,rvm,mu=1.0;;
double chi,xp,yp,sx,cx,b,ee;
double a,ecc,incl,node,peri,mm,n;
xyz_t h,e,kk,nn;
double rm, vm, vm2, rvm, mu = 1.0;;
double chi, xp, yp, sx, cx, b, ee;
double a, ecc, incl, node, peri, mm, n;
xyz_t h, e, kk, nn;
orbit_t orb;
r.x/=XKMPER;
r.y/=XKMPER;
r.z/=XKMPER;
v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0);
v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0);
v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0);
r.x /= XKMPER;
r.y /= XKMPER;
r.z /= XKMPER;
v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
rm=magnitude(r);
vm2=dot(v,v);
rvm=dot(r,v);
h=cross(r,v);
chi=dot(h,h)/mu;
rm = magnitude (r);
vm2 = dot (v, v);
rvm = dot (r, v);
h = cross (r, v);
chi = dot (h, h) / mu;
e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x;
e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y;
e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z;
e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x;
e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y;
e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z;
a=pow(2.0/rm-vm2/mu,-1);
ecc=magnitude(e);
incl=acos(h.z/magnitude(h))*R2D;
a = pow (2.0 / rm - vm2 / mu, -1);
ecc = magnitude (e);
incl = acos (h.z / magnitude (h)) * R2D;
kk.x=0.0;
kk.y=0.0;
kk.z=1.0;
nn=cross(kk,h);
if (nn.x==0.0 && nn.y==0.0)
nn.x=1.0;
node=atan2(nn.y,nn.x)*R2D;
if (node<0.0)
node+=360.0;
kk.x = 0.0;
kk.y = 0.0;
kk.z = 1.0;
nn = cross (kk, h);
if (nn.x == 0.0 && nn.y == 0.0)
nn.x = 1.0;
node = atan2 (nn.y, nn.x) * R2D;
if (node < 0.0)
node += 360.0;
peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D;
if (e.z<0.0)
peri=360.0-peri;
if (peri<0.0)
peri+=360.0;
peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D;
if (e.z < 0.0)
peri = 360.0 - peri;
if (peri < 0.0)
peri += 360.0;
// Elliptic motion
if (ecc<1.0) {
xp=(chi-rm)/ecc;
yp=rvm/ecc*sqrt(chi/mu);
b=a*sqrt(1.0-ecc*ecc);
cx=xp/a+ecc;
sx=yp/b;
ee=atan2(sx,cx);
n=XKE*sqrt(mu/(a*a*a));
mm=(ee-ecc*sx)*R2D;
if (ecc < 1.0)
{
xp = (chi - rm) / ecc;
yp = rvm / ecc * sqrt (chi / mu);
b = a * sqrt (1.0 - ecc * ecc);
cx = xp / a + ecc;
sx = yp / b;
ee = atan2 (sx, cx);
n = XKE * sqrt (mu / (a * a * a));
mm = (ee - ecc * sx) * R2D;
}
if (mm<0.0)
mm+=360.0;
if (mm < 0.0)
mm += 360.0;
// Fill
orb.satno=0;
orb.eqinc=incl*D2R;
orb.ascn=node*D2R;
orb.argp=peri*D2R;
orb.mnan=mm*D2R;
orb.ecc=ecc;
orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI);
orb.bstar=0.0;
orb.ep_year=ep_year;
orb.ep_day=ep_day;
orb.norb=0;
orb.satno = 0;
orb.eqinc = incl * D2R;
orb.ascn = node * D2R;
orb.argp = peri * D2R;
orb.mnan = mm * D2R;
orb.ecc = ecc;
orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI);
orb.bstar = 0.0;
orb.ep_year = ep_year;
orb.ep_day = ep_day;
orb.norb = 0;
return orb;
}
orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0)
orbit_t
rv2el (int satno, double mjd, xyz_t r0, xyz_t v0)
{
int i,imode;
orbit_t orb[5],orb1[5];
xyz_t r,v;
int i, imode;
orbit_t orb[5], orb1[5];
xyz_t r, v;
kep_t kep;
char line1[70],line2[70];
char line1[70], line2[70];
int ep_year;
double ep_day;
// Epoch
ep_day=mjd2doy(mjd,&ep_year);
ep_day = mjd2doy (mjd, &ep_year);
// Initial guess
orb[0]=classel(ep_year,ep_day,r0,v0);
orb[0].satno=satno;
orb[0] = classel (ep_year, ep_day, r0, v0);
orb[0].satno = satno;
for (i=0;i<5;i++) {
for (i = 0; i < 5; i++)
{
// Propagate
imode=init_sgdp4(&orb[i]);
imode=satpos_xyz(mjd+2400000.5,&r,&v);
imode = init_sgdp4 (&orb[i]);
imode = satpos_xyz (mjd + 2400000.5, &r, &v);
// Compute initial orbital elements
orb1[i]=classel(ep_year,ep_day,r,v);
orb1[i] = classel (ep_year, ep_day, r, v);
// Adjust
orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev;
orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn;
orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp;
orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan;
orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc;
orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc;
orb[i+1].ep_year=orb[i].ep_year;
orb[i+1].ep_day=orb[i].ep_day;
orb[i+1].satno=orb[i].satno;
orb[i+1].norb=orb[i].norb;
orb[i+1].bstar=orb[i].bstar;
orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev;
orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn;
orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp;
orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan;
orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc;
orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc;
orb[i + 1].ep_year = orb[i].ep_year;
orb[i + 1].ep_day = orb[i].ep_day;
orb[i + 1].satno = orb[i].satno;
orb[i + 1].norb = orb[i].norb;
orb[i + 1].bstar = orb[i].bstar;
// Keep in range
if (orb[i+1].ecc<0.0)
orb[i+1].ecc=0.0;
if (orb[i+1].eqinc<0.0)
orb[i+1].eqinc=0.0;
if (orb[i + 1].ecc < 0.0)
orb[i + 1].ecc = 0.0;
if (orb[i + 1].eqinc < 0.0)
orb[i + 1].eqinc = 0.0;
}
orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI);
orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI);
orb[i].argp=modulo(orb[i].argp,2.0*M_PI);
orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI);
orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI);
orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI);
return orb[i];
}
// Format TLE
void format_tle(orbit_t orb,char *line1,char *line2)
void
format_tle (orbit_t orb, char *line1, char *line2)
{
int i,csum;
char sbstar[]=" 00000-0",bstar[13];
int i, csum;
char sbstar[] = " 00000-0", bstar[13];
// Format Bstar term
if (fabs(orb.bstar)>1e-9) {
sprintf(bstar,"%11.4e",10*orb.bstar);
sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4];
sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0';
if (fabs (orb.bstar) > 1e-9)
{
sprintf (bstar, "%11.4e", 10 * orb.bstar);
sbstar[0] = bstar[0];
sbstar[1] = bstar[1];
sbstar[2] = bstar[3];
sbstar[3] = bstar[4];
sbstar[4] = bstar[5];
sbstar[5] = bstar[6];
sbstar[6] = bstar[8];
sbstar[7] = bstar[10];
sbstar[8] = '\0';
}
// Print lines
sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar);
sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev);
sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",
orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar);
sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",
orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc,
DEG (orb.argp), DEG (orb.mnan), orb.rev);
// Compute checksums
for (i=0,csum=0;i<strlen(line1);i++) {
if (isdigit(line1[i]))
csum+=line1[i]-'0';
else if (line1[i]=='-')
for (i = 0, csum = 0; i < strlen (line1); i++)
{
if (isdigit (line1[i]))
csum += line1[i] - '0';
else if (line1[i] == '-')
csum++;
}
sprintf(line1,"%s%d",line1,csum%10);
for (i=0,csum=0;i<strlen(line2);i++) {
if (isdigit(line2[i]))
csum+=line2[i]-'0';
else if (line2[i]=='-')
sprintf (line1, "%s%d", line1, csum % 10);
for (i = 0, csum = 0; i < strlen (line2); i++)
{
if (isdigit (line2[i]))
csum += line2[i] - '0';
else if (line2[i] == '-')
csum++;
}
sprintf(line2,"%s%d",line2,csum%10);
sprintf (line2, "%s%d", line2, csum % 10);
return;
}
// Present nfd
void nfd_now(char *s)
void
nfd_now (char *s)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
time(&rawtime);
ptm=gmtime(&rawtime);
time (&rawtime);
ptm = gmtime (&rawtime);
sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900,
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
ptm->tm_sec);
return;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
void usage(void)
void
usage (void)
{
printf("Usage: rv2tle -p XYZFILE [- i NORADID] [-d COSPARID] [-g] [-h]\n\n");
printf("Arguments:\n");
printf("-p XYZFILE File with cartesian position and velocity vector\n");
printf(" Format: '{mjd} {x} {y} {z} {vx} {vy} {vz}'\n");
printf(" Units: position in km, velocity in km/s\n");
printf("-i NORADID Satellite Catalog Number (NORAD ID), default: 99000\n");
printf("-d COSPARID International Designator (COSPAR ID), default: 14999A\n");
printf("-g Use non-standard / GMAT's Modified Julian Date\n");
printf("-h This help\n");
printf
("Usage: rv2tle -p XYZFILE [- i NORADID] [-d COSPARID] [-g] [-h]\n\n");
printf ("Arguments:\n");
printf ("-p XYZFILE File with cartesian position and velocity vector\n");
printf (" Format: '{mjd} {x} {y} {z} {vx} {vy} {vz}'\n");
printf (" Units: position in km, velocity in km/s\n");
printf
("-i NORADID Satellite Catalog Number (NORAD ID), default: 99000\n");
printf
("-d COSPARID International Designator (COSPAR ID), default: 14999A\n");
printf ("-g Use non-standard / GMAT's Modified Julian Date\n");
printf ("-h This help\n");
return;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
@ -349,70 +393,74 @@ int fgetline(FILE *file,char *s,int lim)
return i;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int imode,satno=99000,arg,gmat=0;
int imode, satno = 99000, arg, gmat = 0;
FILE *file;
orbit_t orb;
xyz_t r,v;
char xyzfile[LIM],nfd[32],line[LIM];
char line1[80],line2[80],desig[20]="14999A";
xyz_t r, v;
char xyzfile[LIM], nfd[32], line[LIM];
char line1[80], line2[80], desig[20] = "14999A";
double mjd;
char *env;
// Decode options
while ((arg=getopt(argc,argv,"p:i:d:gh"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "p:i:d:gh")) != -1)
{
switch (arg)
{
case 'p':
strcpy(xyzfile,optarg);
strcpy (xyzfile, optarg);
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'd':
strcpy(desig,optarg);
strcpy (desig, optarg);
break;
case 'g':
gmat=1;
gmat = 1;
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
// Open file
file=fopen(xyzfile,"r");
while (fgetline(file,line,LIM)>0) {
sscanf(line,"%lf %lf %lf %lf %lf %lf %lf",&mjd,&r.x,&r.y,&r.z,&v.x,&v.y,&v.z);
file = fopen (xyzfile, "r");
while (fgetline (file, line, LIM) > 0)
{
sscanf (line, "%lf %lf %lf %lf %lf %lf %lf", &mjd, &r.x, &r.y, &r.z,
&v.x, &v.y, &v.z);
// Convert to MJD
if (gmat==1)
mjd+=29999.5;
if (gmat == 1)
mjd += 29999.5;
// Convert
orb=rv2el(orb.satno,mjd,r,v);
orb.satno=satno;
strcpy(orb.desig,desig);
orb = rv2el (orb.satno, mjd, r, v);
orb.satno = satno;
strcpy (orb.desig, desig);
format_tle(orb,line1,line2);
printf("%s\n%s\n",line1,line2);
format_tle (orb, line1, line2);
printf ("%s\n%s\n", line1, line2);
satno++;
}
fclose(file);
fclose (file);
return 0;
}

View File

@ -5,38 +5,44 @@
#include <math.h>
// Usage: s2dec [options] hh:mm:ss.ss
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
double x;
int sign=1;
float deg,min,sec;
char t[20],c;
int sign = 1;
float deg, min, sec;
char t[20], c;
if (argc==1) {
printf("Usage: s2dec -r <hh:mm:ss.sss>\n -or- <ddd:mm:ss.sss>\nCompute sexagesimal from decimal input x.\n");
printf("Options: -r Converts hours into degrees\n");
if (argc == 1)
{
printf
("Usage: s2dec -r <hh:mm:ss.sss>\n -or- <ddd:mm:ss.sss>\nCompute sexagesimal from decimal input x.\n");
printf ("Options: -r Converts hours into degrees\n");
return -1;
}
// Get Sexagesimal string
strcpy(t,argv[--argc]);
if (t[0]=='-') sign=-1;
strcpy (t, argv[--argc]);
if (t[0] == '-')
sign = -1;
deg=fabs(atof(strtok(t," :,")));
min=fabs(atof(strtok(NULL," :,")));
sec=fabs(atof(strtok(NULL," :,")));
deg = fabs (atof (strtok (t, " :,")));
min = fabs (atof (strtok (NULL, " :,")));
sec = fabs (atof (strtok (NULL, " :,")));
x=(double) deg+(double) min/60.+(double) sec/3600.;
x = (double) deg + (double) min / 60. + (double) sec / 3600.;
// Get Options
while (--argc > 0 && (*++argv)[0] == '-') {
while (c = *++argv[0]) {
while (--argc > 0 && (*++argv)[0] == '-')
{
while (c = *++argv[0])
{
if (c == 'r')
x *= 15.;
}
}
printf("%lf\n",sign*x);
printf ("%lf\n", sign * x);
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,24 +7,25 @@
#include <ctype.h>
static char *st_start(char *buf);
static long i_read(char *str, int start, int stop);
static double d_read(char *str, int start, int stop);
static char *st_start (char *buf);
static long i_read (char *str, int start, int stop);
static double d_read (char *str, int start, int stop);
/* ====================================================================
Read a string from key board, remove CR/LF etc.
==================================================================== */
void read_kb(char *buf)
void
read_kb (char *buf)
{
int ii;
int ii;
fgets(buf, ST_SIZE-1, stdin);
fgets (buf, ST_SIZE - 1, stdin);
/* Remove the CR/LF etc. */
for(ii = 0; ii < ST_SIZE; ii++)
for (ii = 0; ii < ST_SIZE; ii++)
{
if(buf[ii] == '\r' || buf[ii] == '\n')
if (buf[ii] == '\r' || buf[ii] == '\n')
{
buf[ii] = '\0';
break;
@ -38,7 +39,8 @@ int ii;
next elements of whatever sort.
==================================================================== */
int read_twoline(FILE *fp, long search_satno, orbit_t *orb)
int
read_twoline (FILE * fp, long search_satno, orbit_t * orb)
{
static char search[ST_SIZE];
static char line1[ST_SIZE];
@ -48,71 +50,83 @@ int read_twoline(FILE *fp, long search_satno, orbit_t *orb)
double bm, bx;
// Set defaults
strcpy(orb->desig,"");
strcpy (orb->desig, "");
st1 = line1;
st2 = line2;
do {
if(fgets(line1, ST_SIZE-1, fp) == NULL)
do
{
if (fgets (line1, ST_SIZE - 1, fp) == NULL)
return -1;
st1 = st_start(line1);
} while(st1[0] != '1');
if(search_satno > 0) {
found = 0;
} else {
found = 1;
search_satno = atol(st1+2);
st1 = st_start (line1);
}
sprintf(search, "1 %05ld", search_satno);
while (st1[0] != '1');
do {
st1 = st_start(line1);
if(strncmp(st1, search, 7) == 0) {
if (search_satno > 0)
{
found = 0;
}
else
{
found = 1;
search_satno = atol (st1 + 2);
}
sprintf (search, "1 %05ld", search_satno);
do
{
st1 = st_start (line1);
if (strncmp (st1, search, 7) == 0)
{
found = 1;
break;
}
} while(fgets(line1, ST_SIZE-1, fp) != NULL);
}
while (fgets (line1, ST_SIZE - 1, fp) != NULL);
sprintf(search, "2 %05ld", search_satno);
sprintf (search, "2 %05ld", search_satno);
if(found) {
fgets(line2, ST_SIZE-1, fp);
st2 = st_start(line2);
if (found)
{
fgets (line2, ST_SIZE - 1, fp);
st2 = st_start (line2);
}
if(!found || strncmp(st2, search, 7) != 0) {
if (!found || strncmp (st2, search, 7) != 0)
{
return -1;
}
orb->ep_year = (int)i_read(st1, 19, 20);
orb->ep_year = (int) i_read (st1, 19, 20);
if(orb->ep_year < 57) orb->ep_year += 2000;
else orb->ep_year += 1900;
if (orb->ep_year < 57)
orb->ep_year += 2000;
else
orb->ep_year += 1900;
orb->ep_day = d_read(st1, 21, 32);
orb->ep_day = d_read (st1, 21, 32);
orb->ndot2 = d_read(st1, 34, 43);
bm = d_read(st1, 45, 50) * 1.0e-5;
bx = d_read(st1, 51, 52);
orb->nddot6 = bm * pow(10.0, bx);
bm = d_read(st1, 54, 59) * 1.0e-5;
bx = d_read(st1, 60, 61);
orb->bstar = bm * pow(10.0, bx);
orb->ndot2 = d_read (st1, 34, 43);
bm = d_read (st1, 45, 50) * 1.0e-5;
bx = d_read (st1, 51, 52);
orb->nddot6 = bm * pow (10.0, bx);
bm = d_read (st1, 54, 59) * 1.0e-5;
bx = d_read (st1, 60, 61);
orb->bstar = bm * pow (10.0, bx);
orb->eqinc = RAD(d_read(st2, 9, 16));
orb->ascn = RAD(d_read(st2, 18, 25));
orb->ecc = d_read(st2, 27, 33) * 1.0e-7;
orb->argp = RAD(d_read(st2, 35, 42));
orb->mnan = RAD(d_read(st2, 44, 51));
orb->rev = d_read(st2, 53, 63);
orb->norb = i_read(st2, 64, 68);
orb->eqinc = RAD (d_read (st2, 9, 16));
orb->ascn = RAD (d_read (st2, 18, 25));
orb->ecc = d_read (st2, 27, 33) * 1.0e-7;
orb->argp = RAD (d_read (st2, 35, 42));
orb->mnan = RAD (d_read (st2, 44, 51));
orb->rev = d_read (st2, 53, 63);
orb->norb = i_read (st2, 64, 68);
orb->satno = search_satno;
// sscanf(st1+9,"%s",orb->desig);
strncpy(orb->desig,st1+9,8);
orb->desig[8]='\0';
strncpy (orb->desig, st1 + 9, 8);
orb->desig[8] = '\0';
return 0;
}
@ -121,13 +135,16 @@ int read_twoline(FILE *fp, long search_satno, orbit_t *orb)
Locate the first non-white space character, return location.
================================================================== */
static char *st_start(char *buf)
static char *
st_start (char *buf)
{
if(buf == NULL) return buf;
if (buf == NULL)
return buf;
while(*buf != '\0' && isspace(*buf)) buf++;
while (*buf != '\0' && isspace (*buf))
buf++;
return buf;
return buf;
}
/* ==================================================================
@ -135,27 +152,28 @@ return buf;
characters to buffer then convert.
================================================================== */
static long i_read(char *str, int start, int stop)
static long
i_read (char *str, int start, int stop)
{
long itmp=0;
char *buf, *tmp;
int ii;
long itmp = 0;
char *buf, *tmp;
int ii;
start--; /* 'C' arrays start at 0 */
stop--;
tmp = buf = (char *)vector(stop-start+2, sizeof(char));
tmp = buf = (char *) vector (stop - start + 2, sizeof (char));
for(ii = start; ii <= stop; ii++)
for (ii = start; ii <= stop; ii++)
{
*tmp++ = str[ii]; /* Copy the characters. */
}
*tmp = '\0'; /* NUL terminate */
itmp = atol(buf); /* Convert to long integer. */
free(buf);
itmp = atol (buf); /* Convert to long integer. */
free (buf);
return itmp;
return itmp;
}
/* ==================================================================
@ -163,65 +181,69 @@ return itmp;
characters to buffer then convert.
================================================================== */
static double d_read(char *str, int start, int stop)
static double
d_read (char *str, int start, int stop)
{
double dtmp=0;
char *buf, *tmp;
int ii;
double dtmp = 0;
char *buf, *tmp;
int ii;
start--;
stop--;
tmp = buf = (char *)vector(stop-start+2, sizeof(char));
tmp = buf = (char *) vector (stop - start + 2, sizeof (char));
for(ii = start; ii <= stop; ii++)
for (ii = start; ii <= stop; ii++)
{
*tmp++ = str[ii]; /* Copy the characters. */
}
*tmp = '\0'; /* NUL terminate */
dtmp = atof(buf); /* Convert to long integer. */
free(buf);
dtmp = atof (buf); /* Convert to long integer. */
free (buf);
return dtmp;
return dtmp;
}
/* ==================================================================
Allocate and check an all-zero array of memory (storage vector).
================================================================== */
void *vector(size_t num, size_t size)
void *
vector (size_t num, size_t size)
{
void *ptr;
void *ptr;
ptr = calloc(num, size);
if(ptr == NULL)
ptr = calloc (num, size);
if (ptr == NULL)
{
fatal_error("vector: Allocation failed %u * %u", num, size);
fatal_error ("vector: Allocation failed %u * %u", num, size);
}
return ptr;
return ptr;
}
/* ==================================================================
Print out orbital parameters.
================================================================== */
void print_orb(orbit_t *orb)
void
print_orb (orbit_t * orb)
{
printf("# Satellite ID = %ld\n", (long)orb->satno);
printf("# Satellite designation = %s\n",orb->desig);
printf("# Epoch year = %d day = %.8f\n", orb->ep_year, orb->ep_day);
printf("# Eccentricity = %.7f\n", orb->ecc);
printf("# Equatorial inclination = %.4f deg\n", DEG(orb->eqinc));
printf("# Argument of perigee = %.4f deg\n", DEG(orb->argp));
printf("# Mean anomaly = %.4f deg\n", DEG(orb->mnan));
printf("# Right Ascension of Ascending Node = %.4f deg\n", DEG(orb->ascn));
printf("# Mean Motion (number of rev/day) = %.8f\n", orb->rev);
printf("# First derivative of mean motion = %e\n",orb->ndot2);
printf("# Second derivative of mean motion = %e\n",orb->nddot6);
printf("# BSTAR drag = %.4e\n", orb->bstar);
printf("# Orbit number = %ld\n", orb->norb);
printf ("# Satellite ID = %ld\n", (long) orb->satno);
printf ("# Satellite designation = %s\n", orb->desig);
printf ("# Epoch year = %d day = %.8f\n", orb->ep_year, orb->ep_day);
printf ("# Eccentricity = %.7f\n", orb->ecc);
printf ("# Equatorial inclination = %.4f deg\n", DEG (orb->eqinc));
printf ("# Argument of perigee = %.4f deg\n", DEG (orb->argp));
printf ("# Mean anomaly = %.4f deg\n", DEG (orb->mnan));
printf ("# Right Ascension of Ascending Node = %.4f deg\n",
DEG (orb->ascn));
printf ("# Mean Motion (number of rev/day) = %.8f\n", orb->rev);
printf ("# First derivative of mean motion = %e\n", orb->ndot2);
printf ("# Second derivative of mean motion = %e\n", orb->nddot6);
printf ("# BSTAR drag = %.4e\n", orb->bstar);
printf ("# Orbit number = %ld\n", orb->norb);
}
/* ====================================================================== */

View File

@ -8,20 +8,21 @@
#define ST_SIZE 256
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/** satutl.c **/
void read_kb(char *buf);
int read_twoline(FILE *fp, long satno, orbit_t *orb);
void *vector(size_t num, size_t size);
void print_orb(orbit_t *orb);
void read_kb (char *buf);
int read_twoline (FILE * fp, long satno, orbit_t * orb);
void *vector (size_t num, size_t size);
void print_orb (orbit_t * orb);
/** aries.c **/
double gha_aries(double jd);
double gha_aries (double jd);
/** ferror.c **/
void fatal_error(const char *format, ...);
void fatal_error (const char *format, ...);
#ifdef __cplusplus
}

View File

@ -63,7 +63,8 @@
*
*/
static const char SCCSid[] = "@(#)sgdp4.c 3.04 (C) 1995 psc SatLib: Orbital Model";
static const char SCCSid[] =
"@(#)sgdp4.c 3.04 (C) 1995 psc SatLib: Orbital Model";
#include <math.h>
#include <stdio.h>
@ -113,7 +114,7 @@ static const char SCCSid[] = "@(#)sgdp4.c 3.04 (C) 1995 psc SatLib: Orbita
#define QOMS2T ((real)1.880279159015270643865e-9) /* (pow((Q0 - S0)*AE/XKMPER, 4.0)) */
#define KS ((real)(AE * (1.0 + S0/XKMPER)))
#endif
static const real a3ovk2 = (real)(-XJ3 / CK2 * (AE * AE * AE));
static const real a3ovk2 = (real) (-XJ3 / CK2 * (AE * AE * AE));
/* ================= Copy of the orbital elements ==================== */
@ -163,21 +164,22 @@ int Set_LS_zero = 0; /* Set to 1 to zero Lunar-Solar terms at epoch. */
The return value indicates the orbital model used.
======================================================================= */
sgdp4_mode_t init_sgdp4(orbit_t *orb)
sgdp4_mode_t
init_sgdp4 (orbit_t * orb)
{
LOCAL_REAL theta2, theta4, xhdot1, x1m5th;
LOCAL_REAL s4, del1, del0;
LOCAL_REAL betao, betao2, coef, coef1;
LOCAL_REAL etasq, eeta, qoms24;
LOCAL_REAL pinvsq, tsi, psisq, c1sq;
LOCAL_DOUBLE a0, a1, epoch;
real temp0, temp1, temp2, temp3;
long iday, iyear;
LOCAL_REAL theta2, theta4, xhdot1, x1m5th;
LOCAL_REAL s4, del1, del0;
LOCAL_REAL betao, betao2, coef, coef1;
LOCAL_REAL etasq, eeta, qoms24;
LOCAL_REAL pinvsq, tsi, psisq, c1sq;
LOCAL_DOUBLE a0, a1, epoch;
real temp0, temp1, temp2, temp3;
long iday, iyear;
/* Copy over elements. */
/* Convert year to Gregorian with century as 1994 or 94 type ? */
iyear = (long)orb->ep_year;
iyear = (long) orb->ep_year;
if (iyear < 1960)
{
@ -187,7 +189,7 @@ long iday, iyear;
if (iyear < 1901 || iyear > 2099)
{
fatal_error("init_sgdp4: Satellite ep_year error %ld", iyear);
fatal_error ("init_sgdp4: Satellite ep_year error %ld", iyear);
imode = SGDP4_ERROR;
return imode;
}
@ -196,43 +198,47 @@ long iday, iyear;
/* Compute days from 1st Jan 1900 (works 1901 to 2099 only). */
iday = ((iyear - 1901)*1461L)/4L + 364L + 1L;
iday = ((iyear - 1901) * 1461L) / 4L + 364L + 1L;
SGDP4_jd0 = JD1900 + iday + (orb->ep_day - 1.0); /* Julian day number. */
epoch = (iyear - 1900) * 1.0e3 + orb->ep_day; /* YYDDD.DDDD as from 2-line. */
#ifdef DEBUG
fprintf(stderr, "Epoch = %f SGDP4_jd0 = %f\n", epoch, SGDP4_jd0);
fprintf (stderr, "Epoch = %f SGDP4_jd0 = %f\n", epoch, SGDP4_jd0);
#endif
eo = (real)orb->ecc;
xno = (double)orb->rev * TWOPI/XMNPDA; /* Radian / unit time. */
xincl = (real)orb->eqinc;
xnodeo = (real)orb->ascn;
omegao = (real)orb->argp;
xmo = (real)orb->mnan;
bstar = (real)orb->bstar;
eo = (real) orb->ecc;
xno = (double) orb->rev * TWOPI / XMNPDA; /* Radian / unit time. */
xincl = (real) orb->eqinc;
xnodeo = (real) orb->ascn;
omegao = (real) orb->argp;
xmo = (real) orb->mnan;
bstar = (real) orb->bstar;
/* A few simple error checks here. */
if (eo < (real)0.0 || eo > ECC_LIMIT_HIGH)
if (eo < (real) 0.0 || eo > ECC_LIMIT_HIGH)
{
fatal_error("init_sgdp4: Eccentricity out of range for %ld (%le)", Isat, (double)eo);
fatal_error ("init_sgdp4: Eccentricity out of range for %ld (%le)",
Isat, (double) eo);
imode = SGDP4_ERROR;
return imode;
}
if (xno < 0.035*TWOPI/XMNPDA || xno > 18.0*TWOPI/XMNPDA)
if (xno < 0.035 * TWOPI / XMNPDA || xno > 18.0 * TWOPI / XMNPDA)
{
fatal_error("init_sgdp4: Mean motion out of range %ld (%le)", Isat, xno);
fatal_error ("init_sgdp4: Mean motion out of range %ld (%le)", Isat,
xno);
imode = SGDP4_ERROR;
return imode;
}
if (xincl < (real)0.0 || xincl > (real)PI)
if (xincl < (real) 0.0 || xincl > (real) PI)
{
fatal_error("init_sgdp4: Equatorial inclination out of range %ld (%le)", Isat, DEG(xincl));
fatal_error
("init_sgdp4: Equatorial inclination out of range %ld (%le)", Isat,
DEG (xincl));
imode = SGDP4_ERROR;
return imode;
}
@ -249,23 +255,23 @@ long iday, iyear;
from input elements.
*/
SINCOS(xincl, &sinIO, &cosIO);
SINCOS (xincl, &sinIO, &cosIO);
theta2 = cosIO * cosIO;
theta4 = theta2 * theta2;
x3thm1 = (real)3.0 * theta2 - (real)1.0;
x1mth2 = (real)1.0 - theta2;
x7thm1 = (real)7.0 * theta2 - (real)1.0;
x3thm1 = (real) 3.0 *theta2 - (real) 1.0;
x1mth2 = (real) 1.0 - theta2;
x7thm1 = (real) 7.0 *theta2 - (real) 1.0;
a1 = pow(XKE / xno, TOTHRD);
betao2 = (real)1.0 - eo * eo;
betao = SQRT(betao2);
temp0 = (real)(1.5 * CK2) * x3thm1 / (betao * betao2);
a1 = pow (XKE / xno, TOTHRD);
betao2 = (real) 1.0 - eo * eo;
betao = SQRT (betao2);
temp0 = (real) (1.5 * CK2) * x3thm1 / (betao * betao2);
del1 = temp0 / (a1 * a1);
a0 = a1 * (1.0 - del1 * (1.0/3.0 + del1 * (1.0 + del1 * 134.0/81.0)));
a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0)));
del0 = temp0 / (a0 * a0);
xnodp = xno / (1.0 + del0);
aodp = (real)(a0 / (1.0 - del0));
aodp = (real) (a0 / (1.0 - del0));
perigee = (aodp * (1.0 - eo) - AE) * XKMPER;
apogee = (aodp * (1.0 + eo) - AE) * XKMPER;
period = (TWOPI * 1440.0 / XMNPDA) / xnodp;
@ -276,10 +282,13 @@ long iday, iyear;
*/
if (perigee <= 0.0)
{
fprintf(stderr, "# Satellite %ld sub-orbital (apogee = %.1f km, perigee = %.1f km)\n", Isat, apogee, perigee);
fprintf (stderr,
"# Satellite %ld sub-orbital (apogee = %.1f km, perigee = %.1f km)\n",
Isat, apogee, perigee);
}
if (imode == SGDP4_ZERO_ECC) return imode;
if (imode == SGDP4_ZERO_ECC)
return imode;
if (period >= 225.0 && Set_LS_zero < 2)
{
@ -304,20 +313,24 @@ long iday, iyear;
if (perigee < 156.0)
{
s4 = (real)(perigee - 78.0);
s4 = (real) (perigee - 78.0);
if(s4 < (real)20.0)
if (s4 < (real) 20.0)
{
fprintf(stderr, "# Very low s4 constant for sat %ld (perigee = %.2f)\n", Isat, perigee);
s4 = (real)20.0;
fprintf (stderr,
"# Very low s4 constant for sat %ld (perigee = %.2f)\n",
Isat, perigee);
s4 = (real) 20.0;
}
else
{
fprintf(stderr, "# Changing s4 constant for sat %ld (perigee = %.2f)\n", Isat, perigee);
fprintf (stderr,
"# Changing s4 constant for sat %ld (perigee = %.2f)\n",
Isat, perigee);
}
qoms24 = POW4((real)((120.0 - s4) * (AE / XKMPER)));
s4 = (real)(s4 / XKMPER + AE);
qoms24 = POW4 ((real) ((120.0 - s4) * (AE / XKMPER)));
s4 = (real) (s4 / XKMPER + AE);
}
else
{
@ -325,112 +338,139 @@ long iday, iyear;
qoms24 = QOMS2T;
}
pinvsq = (real)1.0 / (aodp * aodp * betao2 * betao2);
tsi = (real)1.0 / (aodp - s4);
pinvsq = (real) 1.0 / (aodp * aodp * betao2 * betao2);
tsi = (real) 1.0 / (aodp - s4);
eta = aodp * eo * tsi;
etasq = eta * eta;
eeta = eo * eta;
psisq = FABS((real)1.0 - etasq);
coef = qoms24 * POW4(tsi);
coef1 = coef / POW(psisq, 3.5);
psisq = FABS ((real) 1.0 - etasq);
coef = qoms24 * POW4 (tsi);
coef1 = coef / POW (psisq, 3.5);
c2 = coef1 * (real)xnodp * (aodp *
((real)1.0 + (real)1.5 * etasq + eeta * ((real)4.0 + etasq)) +
(real)(0.75 * CK2) * tsi / psisq * x3thm1 *
((real)8.0 + (real)3.0 * etasq * ((real)8.0 + etasq)));
c2 = coef1 * (real) xnodp *(aodp *
((real) 1.0 + (real) 1.5 * etasq +
eeta * ((real) 4.0 + etasq)) +
(real) (0.75 * CK2) * tsi / psisq * x3thm1 *
((real) 8.0 +
(real) 3.0 * etasq * ((real) 8.0 + etasq)));
c1 = bstar * c2;
c4 = (real)2.0 * (real)xnodp * coef1 * aodp * betao2 * (eta *
((real)2.0 + (real)0.5 * etasq) + eo * ((real)0.5 + (real)2.0 *
etasq) - (real)(2.0 * CK2) * tsi / (aodp * psisq) * ((real)-3.0 *
x3thm1 * ((real)1.0 - (real)2.0 * eeta + etasq *
((real)1.5 - (real)0.5 * eeta)) + (real)0.75 * x1mth2 * ((real)2.0 *
etasq - eeta * ((real)1.0 + etasq)) * COS((real)2.0 * omegao)));
c4 = (real) 2.0 *(real) xnodp *coef1 * aodp * betao2 * (eta *
((real) 2.0 +
(real) 0.5 *
etasq) +
eo * ((real) 0.5 +
(real) 2.0 *
etasq) -
(real) (2.0 * CK2) *
tsi / (aodp *
psisq) *
((real) -
3.0 * x3thm1 *
((real) 1.0 -
(real) 2.0 *
eeta +
etasq *
((real) 1.5 -
(real) 0.5 *
eeta)) +
(real) 0.75 *
x1mth2 *
((real) 2.0 *
etasq -
eeta *
((real) 1.0 +
etasq)) *
COS ((real) 2.0 *
omegao)));
c5 = c3 = omgcof = (real)0.0;
c5 = c3 = omgcof = (real) 0.0;
if (imode == SGDP4_NEAR_NORM)
{
/* BSTAR drag terms for normal near-space 'normal' model only. */
c5 = (real)2.0 * coef1 * aodp * betao2 *
((real)1.0 + (real)2.75 * (etasq + eeta) + eeta * etasq);
c5 = (real) 2.0 *coef1 * aodp * betao2 *
((real) 1.0 + (real) 2.75 * (etasq + eeta) + eeta * etasq);
if(eo > ECC_ALL)
if (eo > ECC_ALL)
{
c3 = coef * tsi * a3ovk2 * (real)xnodp * (real)AE * sinIO / eo;
c3 = coef * tsi * a3ovk2 * (real) xnodp *(real) AE *sinIO / eo;
}
omgcof = bstar * c3 * COS(omegao);
omgcof = bstar * c3 * COS (omegao);
}
temp1 = (real)(3.0 * CK2) * pinvsq * (real)xnodp;
temp1 = (real) (3.0 * CK2) * pinvsq * (real) xnodp;
temp2 = temp1 * CK2 * pinvsq;
temp3 = (real)(1.25 * CK4) * pinvsq * pinvsq * (real)xnodp;
temp3 = (real) (1.25 * CK4) * pinvsq * pinvsq * (real) xnodp;
xmdot = xnodp + ((real)0.5 * temp1 * betao * x3thm1 + (real)0.0625 *
temp2 * betao * ((real)13.0 - (real)78.0 * theta2 +
(real)137.0 * theta4));
xmdot = xnodp + ((real) 0.5 * temp1 * betao * x3thm1 + (real) 0.0625 *
temp2 * betao * ((real) 13.0 - (real) 78.0 * theta2 +
(real) 137.0 * theta4));
x1m5th = (real)1.0 - (real)5.0 * theta2;
x1m5th = (real) 1.0 - (real) 5.0 *theta2;
omgdot = (real)-0.5 * temp1 * x1m5th + (real)0.0625 * temp2 *
((real)7.0 - (real)114.0 * theta2 + (real)395.0 * theta4) +
temp3 * ((real)3.0 - (real)36.0 * theta2 + (real)49.0 * theta4);
omgdot = (real) - 0.5 * temp1 * x1m5th + (real) 0.0625 *temp2 *
((real) 7.0 - (real) 114.0 * theta2 + (real) 395.0 * theta4) +
temp3 * ((real) 3.0 - (real) 36.0 * theta2 + (real) 49.0 * theta4);
xhdot1 = -temp1 * cosIO;
xnodot = xhdot1 + ((real)0.5 * temp2 * ((real)4.0 - (real)19.0 * theta2) +
(real)2.0 * temp3 * ((real)3.0 - (real)7.0 * theta2)) * cosIO;
xnodot =
xhdot1 + ((real) 0.5 * temp2 * ((real) 4.0 - (real) 19.0 * theta2) +
(real) 2.0 * temp3 * ((real) 3.0 -
(real) 7.0 * theta2)) * cosIO;
xmcof = (real)0.0;
if(eo > ECC_ALL)
xmcof = (real) 0.0;
if (eo > ECC_ALL)
{
xmcof = (real)(-TOTHRD * AE) * coef * bstar / eeta;
xmcof = (real) (-TOTHRD * AE) * coef * bstar / eeta;
}
xnodcf = (real)3.5 * betao2 * xhdot1 * c1;
t2cof = (real)1.5 * c1;
xnodcf = (real) 3.5 *betao2 * xhdot1 * c1;
t2cof = (real) 1.5 *c1;
/* Check for possible divide-by-zero for X/(1+cosIO) when calculating xlcof */
temp0 = (real)1.0 + cosIO;
temp0 = (real) 1.0 + cosIO;
if(fabs(temp0) < EPS_COSIO) temp0 = (real)SIGN(EPS_COSIO, temp0);
if (fabs (temp0) < EPS_COSIO)
temp0 = (real) SIGN (EPS_COSIO, temp0);
xlcof = (real)0.125 * a3ovk2 * sinIO *
((real)3.0 + (real)5.0 * cosIO) / temp0;
xlcof = (real) 0.125 *a3ovk2 * sinIO *
((real) 3.0 + (real) 5.0 * cosIO) / temp0;
aycof = (real)0.25 * a3ovk2 * sinIO;
aycof = (real) 0.25 *a3ovk2 * sinIO;
SINCOS(xmo, &sinXMO, &cosXMO);
delmo = CUBE((real)1.0 + eta * cosXMO);
SINCOS (xmo, &sinXMO, &cosXMO);
delmo = CUBE ((real) 1.0 + eta * cosXMO);
if (imode == SGDP4_NEAR_NORM)
{
c1sq = c1 * c1;
d2 = (real)4.0 * aodp * tsi * c1sq;
temp0 = d2 * tsi * c1 / (real)3.0;
d3 = ((real)17.0 * aodp + s4) * temp0;
d4 = (real)0.5 * temp0 * aodp * tsi * ((real)221.0 * aodp +
(real)31.0 * s4) * c1;
t3cof = d2 + (real)2.0 * c1sq;
t4cof = (real)0.25 * ((real)3.0 * d3 + c1 * ((real)12.0 * d2 +
(real)10.0 * c1sq));
t5cof = (real)0.2 * ((real)3.0 * d4 + (real)12.0 * c1 * d3 +
(real)6.0 * d2 * d2 + (real)15.0 * c1sq * ((real)2.0 *
d2 + c1sq));
d2 = (real) 4.0 *aodp * tsi * c1sq;
temp0 = d2 * tsi * c1 / (real) 3.0;
d3 = ((real) 17.0 * aodp + s4) * temp0;
d4 = (real) 0.5 *temp0 * aodp * tsi * ((real) 221.0 * aodp +
(real) 31.0 * s4) * c1;
t3cof = d2 + (real) 2.0 *c1sq;
t4cof = (real) 0.25 *((real) 3.0 * d3 + c1 * ((real) 12.0 * d2 +
(real) 10.0 * c1sq));
t5cof = (real) 0.2 *((real) 3.0 * d4 + (real) 12.0 * c1 * d3 +
(real) 6.0 * d2 * d2 +
(real) 15.0 * c1sq * ((real) 2.0 * d2 + c1sq));
}
else if (imode == SGDP4_DEEP_NORM)
{
#ifdef NO_DEEP_SPACE
fprintf(stderr, "init_sgdp4: Deep space equations not supported\n");
fprintf (stderr, "init_sgdp4: Deep space equations not supported\n");
imode = SGDP4_NEAR_NORM; /* Force operations even if wrong model? */
#else
imode = SGDP4_dpinit(epoch, omegao, xnodeo, xmo, eo, xincl,
imode = SGDP4_dpinit (epoch, omegao, xnodeo, xmo, eo, xincl,
aodp, xmdot, omgdot, xnodot, xnodp);
#endif /* !NO_DEEP_SPACE */
}
return imode;
return imode;
}
/* =======================================================================
@ -455,28 +495,29 @@ return imode;
======================================================================= */
sgdp4_mode_t sgdp4(double tsince, int withvel, kep_t *kep)
sgdp4_mode_t
sgdp4 (double tsince, int withvel, kep_t * kep)
{
LOCAL_REAL rk, uk, xnodek, xinck, em, xinc;
LOCAL_REAL xnode, delm, axn, ayn, omega;
LOCAL_REAL capu, epw, elsq, invR, beta2, betal;
LOCAL_REAL sinu, sin2u, cosu, cos2u;
LOCAL_REAL a, e, r, u, pl;
LOCAL_REAL sinEPW, cosEPW, sinOMG, cosOMG;
LOCAL_DOUBLE xmp, xl, xlt;
const int MAXI = 10;
LOCAL_REAL rk, uk, xnodek, xinck, em, xinc;
LOCAL_REAL xnode, delm, axn, ayn, omega;
LOCAL_REAL capu, epw, elsq, invR, beta2, betal;
LOCAL_REAL sinu, sin2u, cosu, cos2u;
LOCAL_REAL a, e, r, u, pl;
LOCAL_REAL sinEPW, cosEPW, sinOMG, cosOMG;
LOCAL_DOUBLE xmp, xl, xlt;
const int MAXI = 10;
#ifndef NO_DEEP_SPACE
LOCAL_DOUBLE xn, xmam;
LOCAL_DOUBLE xn, xmam;
#endif /* !NO_DEEP_SPACE */
real esinE, ecosE, maxnr;
real temp0, temp1, temp2, temp3;
real tempa, tempe, templ;
int ii;
real esinE, ecosE, maxnr;
real temp0, temp1, temp2, temp3;
real tempa, tempe, templ;
int ii;
#ifdef SGDP4_SNGL
real ts = (real)tsince;
real ts = (real) tsince;
#else
#define ts tsince
#endif /* ! SGDP4_SNGL */
@ -486,32 +527,32 @@ real ts = (real)tsince;
em = eo;
xinc = xincl;
xmp = (double)xmo + xmdot * tsince;
xmp = (double) xmo + xmdot * tsince;
xnode = xnodeo + ts * (xnodot + ts * xnodcf);
omega = omegao + omgdot * ts;
switch(imode)
switch (imode)
{
case SGDP4_ZERO_ECC:
/* Not a "real" orbit but OK for fast computation searches. */
kep->smjaxs = kep->radius = (double)aodp * XKMPER/AE;
kep->theta = fmod(PI + xnodp * tsince, TWOPI) - PI;
kep->eqinc = (double)xincl;
kep->smjaxs = kep->radius = (double) aodp *XKMPER / AE;
kep->theta = fmod (PI + xnodp * tsince, TWOPI) - PI;
kep->eqinc = (double) xincl;
kep->ascn = xnodeo;
kep->argp = 0;
kep->ecc = 0;
kep->rfdotk = 0;
if(withvel)
kep->rfdotk = aodp * xnodp * (XKMPER/AE*XMNPDA/86400.0); /* For km/sec */
if (withvel)
kep->rfdotk = aodp * xnodp * (XKMPER / AE * XMNPDA / 86400.0); /* For km/sec */
else
kep->rfdotk = 0;
return imode;
case SGDP4_NEAR_SIMP:
tempa = (real)1.0 - ts * c1;
tempa = (real) 1.0 - ts * c1;
tempe = bstar * ts * c4;
templ = ts * ts * t2cof;
a = aodp * tempa * tempa;
@ -520,12 +561,12 @@ real ts = (real)tsince;
break;
case SGDP4_NEAR_NORM:
delm = xmcof * (CUBE((real)1.0 + eta * COS(xmp)) - delmo);
delm = xmcof * (CUBE ((real) 1.0 + eta * COS (xmp)) - delmo);
temp0 = ts * omgcof + delm;
xmp += (double)temp0;
xmp += (double) temp0;
omega -= temp0;
tempa = (real)1.0 - (ts * (c1 + ts * (d2 + ts * (d3 + ts * d4))));
tempe = bstar * (c4 * ts + c5 * (SIN(xmp) - sinXMO));
tempa = (real) 1.0 - (ts * (c1 + ts * (d2 + ts * (d3 + ts * d4))));
tempe = bstar * (c4 * ts + c5 * (SIN (xmp) - sinXMO));
templ = ts * ts * (t2cof + ts * (t3cof + ts * (t4cof + ts * t5cof)));
//xmp += (double)temp0;
a = aodp * tempa * tempa;
@ -537,99 +578,106 @@ real ts = (real)tsince;
case SGDP4_DEEP_NORM:
case SGDP4_DEEP_RESN:
case SGDP4_DEEP_SYNC:
tempa = (real)1.0 - ts * c1;
tempa = (real) 1.0 - ts * c1;
tempe = bstar * ts * c4;
templ = ts * ts * t2cof;
xn = xnodp;
SGDP4_dpsec(&xmp, &omega, &xnode, &em, &xinc, &xn, tsince);
SGDP4_dpsec (&xmp, &omega, &xnode, &em, &xinc, &xn, tsince);
a = POW(XKE / xn, TOTHRD) * tempa * tempa;
a = POW (XKE / xn, TOTHRD) * tempa * tempa;
e = em - tempe;
xmam = xmp + xnodp * templ;
SGDP4_dpper(&e, &xinc, &omega, &xnode, &xmam, tsince);
SGDP4_dpper (&e, &xinc, &omega, &xnode, &xmam, tsince);
if (xinc < (real)0.0)
if (xinc < (real) 0.0)
{
xinc = (-xinc);
xnode += (real)PI;
omega -= (real)PI;
xnode += (real) PI;
omega -= (real) PI;
}
xl = xmam + omega + xnode;
/* Re-compute the perturbed values. */
SINCOS(xinc, &sinIO, &cosIO);
SINCOS (xinc, &sinIO, &cosIO);
{
real theta2 = cosIO * cosIO;
x3thm1 = (real)3.0 * theta2 - (real)1.0;
x1mth2 = (real)1.0 - theta2;
x7thm1 = (real)7.0 * theta2 - (real)1.0;
x3thm1 = (real) 3.0 *theta2 - (real) 1.0;
x1mth2 = (real) 1.0 - theta2;
x7thm1 = (real) 7.0 *theta2 - (real) 1.0;
/* Check for possible divide-by-zero for X/(1+cosIO) when calculating xlcof */
temp0 = (real)1.0 + cosIO;
temp0 = (real) 1.0 + cosIO;
if(fabs(temp0) < EPS_COSIO) temp0 = (real)SIGN(EPS_COSIO, temp0);
if (fabs (temp0) < EPS_COSIO)
temp0 = (real) SIGN (EPS_COSIO, temp0);
xlcof = (real)0.125 * a3ovk2 * sinIO *
((real)3.0 + (real)5.0 * cosIO) / temp0;
xlcof = (real) 0.125 *a3ovk2 * sinIO *
((real) 3.0 + (real) 5.0 * cosIO) / temp0;
aycof = (real)0.25 * a3ovk2 * sinIO;
aycof = (real) 0.25 *a3ovk2 * sinIO;
}
break;
#endif /* ! NO_DEEP_SPACE */
default:
fatal_error("sgdp4: Orbit not initialised");
fatal_error ("sgdp4: Orbit not initialised");
return SGDP4_ERROR;
}
if(a < (real)1.0)
if (a < (real) 1.0)
{
fprintf(stderr, "sgdp4: Satellite %05ld crashed at %.3f (a = %.3f Earth radii)\n", Isat, ts, a);
fprintf (stderr,
"sgdp4: Satellite %05ld crashed at %.3f (a = %.3f Earth radii)\n",
Isat, ts, a);
return SGDP4_ERROR;
}
if(e < ECC_LIMIT_LOW)
if (e < ECC_LIMIT_LOW)
{
fprintf(stderr, "sgdp4: Satellite %05ld modified eccentricity too low (ts = %.3f, e = %e < %e)\n", Isat, ts, e, ECC_LIMIT_LOW);
fprintf (stderr,
"sgdp4: Satellite %05ld modified eccentricity too low (ts = %.3f, e = %e < %e)\n",
Isat, ts, e, ECC_LIMIT_LOW);
return SGDP4_ERROR;
}
if(e < ECC_EPS)
if (e < ECC_EPS)
{
/*fprintf(stderr, "# ecc %f at %.3f for for %05ld\n", e, ts, Isat);*/
/*fprintf(stderr, "# ecc %f at %.3f for for %05ld\n", e, ts, Isat); */
e = ECC_EPS;
}
else if(e > ECC_LIMIT_HIGH)
else if (e > ECC_LIMIT_HIGH)
{
/*fprintf(stderr, "# ecc %f at %.3f for for %05ld\n", e, ts, Isat);*/
/*fprintf(stderr, "# ecc %f at %.3f for for %05ld\n", e, ts, Isat); */
e = ECC_LIMIT_HIGH;
}
beta2 = (real)1.0 - e * e;
beta2 = (real) 1.0 - e * e;
/* Long period periodics */
SINCOS(omega, &sinOMG, &cosOMG);
SINCOS (omega, &sinOMG, &cosOMG);
temp0 = (real)1.0 / (a * beta2);
temp0 = (real) 1.0 / (a * beta2);
axn = e * cosOMG;
ayn = e * sinOMG + temp0 * aycof;
xlt = xl + temp0 * xlcof * axn;
elsq = axn * axn + ayn * ayn;
if (elsq >= (real)1.0)
if (elsq >= (real) 1.0)
{
fprintf(stderr, "sgdp4: SQR(e) >= 1 (%.3f at tsince = %.3f for sat %05ld)\n", elsq, tsince, Isat);
fprintf (stderr,
"sgdp4: SQR(e) >= 1 (%.3f at tsince = %.3f for sat %05ld)\n",
elsq, tsince, Isat);
return SGDP4_ERROR;
}
/* Sensibility check for N-R correction. */
kep->ecc = sqrt(elsq);
kep->ecc = sqrt (elsq);
/*
* Solve Kepler's equation using Newton-Raphson root solving. Here 'capu' is
@ -641,91 +689,94 @@ real ts = (real)tsince;
* for only a couple of arithmetic operations.
*/
epw = capu = fmod(xlt - xnode, TWOPI);
epw = capu = fmod (xlt - xnode, TWOPI);
maxnr = kep->ecc;
for(ii = 0; ii < MAXI; ii++)
for (ii = 0; ii < MAXI; ii++)
{
real nr, f, df;
SINCOS(epw, &sinEPW, &cosEPW);
SINCOS (epw, &sinEPW, &cosEPW);
ecosE = axn * cosEPW + ayn * sinEPW;
esinE = axn * sinEPW - ayn * cosEPW;
f = capu - epw + esinE;
if (fabs(f) < NR_EPS) break;
if (fabs (f) < NR_EPS)
break;
df = (real)1.0 - ecosE;
df = (real) 1.0 - ecosE;
/* 1st order Newton-Raphson correction. */
nr = f / df;
/*Sanity check for high eccentricity failure case. */
if (ii == 0 && FABS(nr) > (real)1.25 * maxnr)
nr = SIGN(maxnr, nr);
if (ii == 0 && FABS (nr) > (real) 1.25 * maxnr)
nr = SIGN (maxnr, nr);
#if 1
/* 2nd order Newton-Raphson correction. */
else
nr = f / (df + (real)0.5 * esinE*nr); /* f/(df - 0.5*d2f*f/df) */
nr = f / (df + (real) 0.5 * esinE * nr); /* f/(df - 0.5*d2f*f/df) */
#endif
epw += nr; /* Newton-Raphson correction of -F/DF. */
}
/* Short period preliminary quantities */
temp0 = (real)1.0 - elsq;
betal = SQRT(temp0);
temp0 = (real) 1.0 - elsq;
betal = SQRT (temp0);
pl = a * temp0;
r = a * ((real)1.0 - ecosE);
invR = (real)1.0 / r;
r = a * ((real) 1.0 - ecosE);
invR = (real) 1.0 / r;
temp2 = a * invR;
temp3 = (real)1.0 / ((real)1.0 + betal);
temp3 = (real) 1.0 / ((real) 1.0 + betal);
cosu = temp2 * (cosEPW - axn + ayn * esinE * temp3);
sinu = temp2 * (sinEPW - ayn - axn * esinE * temp3);
u = ATAN2(sinu, cosu);
sin2u = (real)2.0 * sinu * cosu;
cos2u = (real)2.0 * cosu * cosu - (real)1.0;
temp0 = (real)1.0 / pl;
u = ATAN2 (sinu, cosu);
sin2u = (real) 2.0 *sinu * cosu;
cos2u = (real) 2.0 *cosu * cosu - (real) 1.0;
temp0 = (real) 1.0 / pl;
temp1 = CK2 * temp0;
temp2 = temp1 * temp0;
/* Update for short term periodics to position terms. */
rk = r * ((real)1.0 - (real)1.5 * temp2 * betal * x3thm1) + (real)0.5 * temp1 * x1mth2 * cos2u;
uk = u - (real)0.25 * temp2 * x7thm1 * sin2u;
xnodek = xnode + (real)1.5 * temp2 * cosIO * sin2u;
xinck = xinc + (real)1.5 * temp2 * cosIO * sinIO * cos2u;
rk =
r * ((real) 1.0 - (real) 1.5 * temp2 * betal * x3thm1) +
(real) 0.5 *temp1 * x1mth2 * cos2u;
uk = u - (real) 0.25 *temp2 * x7thm1 * sin2u;
xnodek = xnode + (real) 1.5 *temp2 * cosIO * sin2u;
xinck = xinc + (real) 1.5 *temp2 * cosIO * sinIO * cos2u;
if(rk < (real)1.0)
if (rk < (real) 1.0)
{
#if 1
fprintf(stderr, "sgdp4: Satellite %05ld crashed at %.3f (rk = %.3f Earth radii)\n", Isat, ts, rk);
fprintf (stderr,
"sgdp4: Satellite %05ld crashed at %.3f (rk = %.3f Earth radii)\n",
Isat, ts, rk);
#endif
return SGDP4_ERROR;
}
kep->radius = rk * XKMPER/AE; /* Into km */
kep->radius = rk * XKMPER / AE; /* Into km */
kep->theta = uk;
kep->eqinc = xinck;
kep->ascn = xnodek;
kep->argp = omega;
kep->smjaxs = a * XKMPER/AE;
kep->smjaxs = a * XKMPER / AE;
/* Short period velocity terms ?. */
if (withvel)
{
/* xn = XKE / pow(a, 1.5); */
temp0 = SQRT(a);
temp2 = (real)XKE / (a * temp0);
temp0 = SQRT (a);
temp2 = (real) XKE / (a * temp0);
kep->rdotk = ((real)XKE * temp0 * esinE * invR -
temp2 * temp1 * x1mth2 * sin2u) *
(XKMPER/AE*XMNPDA/86400.0); /* Into km/sec */
kep->rdotk = ((real) XKE * temp0 * esinE * invR - temp2 * temp1 * x1mth2 * sin2u) * (XKMPER / AE * XMNPDA / 86400.0); /* Into km/sec */
kep->rfdotk = ((real)XKE * SQRT(pl) * invR + temp2 * temp1 *
(x1mth2 * cos2u + (real)1.5 * x3thm1)) *
(XKMPER/AE*XMNPDA/86400.0);
kep->rfdotk = ((real) XKE * SQRT (pl) * invR + temp2 * temp1 *
(x1mth2 * cos2u + (real) 1.5 * x3thm1)) *
(XKMPER / AE * XMNPDA / 86400.0);
}
else
{
@ -736,7 +787,7 @@ real ts = (real)tsince;
#undef ts
#endif
return imode;
return imode;
}
/* ====================================================================
@ -752,17 +803,18 @@ return imode;
==================================================================== */
void kep2xyz(kep_t *K, xyz_t *pos, xyz_t *vel)
void
kep2xyz (kep_t * K, xyz_t * pos, xyz_t * vel)
{
real xmx, xmy;
real ux, uy, uz, vx, vy, vz;
real sinT, cosT, sinI, cosI, sinS, cosS;
real xmx, xmy;
real ux, uy, uz, vx, vy, vz;
real sinT, cosT, sinI, cosI, sinS, cosS;
/* Orientation vectors for X-Y-Z format. */
SINCOS((real)K->theta, &sinT, &cosT);
SINCOS((real)K->eqinc, &sinI, &cosI);
SINCOS((real)K->ascn, &sinS, &cosS);
SINCOS ((real) K->theta, &sinT, &cosT);
SINCOS ((real) K->eqinc, &sinI, &cosI);
SINCOS ((real) K->ascn, &sinS, &cosS);
xmx = -sinS * cosI;
xmy = cosS * cosI;
@ -773,14 +825,14 @@ real sinT, cosT, sinI, cosI, sinS, cosS;
/* Position and velocity */
if(pos != NULL)
if (pos != NULL)
{
pos->x = K->radius * ux;
pos->y = K->radius * uy;
pos->z = K->radius * uz;
}
if(vel != NULL)
if (vel != NULL)
{
vx = xmx * cosT - cosS * sinT;
vy = xmy * cosT - sinS * sinT;
@ -806,29 +858,30 @@ real sinT, cosT, sinI, cosI, sinS, cosS;
====================================================================== */
sgdp4_mode_t satpos_xyz(double jd, xyz_t *pos, xyz_t *vel)
sgdp4_mode_t
satpos_xyz (double jd, xyz_t * pos, xyz_t * vel)
{
kep_t K;
int withvel;
sgdp4_mode_t rv;
double tsince;
kep_t K;
int withvel;
sgdp4_mode_t rv;
double tsince;
tsince = (jd - SGDP4_jd0) * XMNPDA;
#if defined( DEBUG ) && 0
fprintf(stderr, "Tsince = %f\n", tsince);
fprintf (stderr, "Tsince = %f\n", tsince);
#endif
if(vel != NULL)
if (vel != NULL)
withvel = 1;
else
withvel = 0;
rv = sgdp4(tsince, withvel, &K);
rv = sgdp4 (tsince, withvel, &K);
kep2xyz(&K, pos, vel);
kep2xyz (&K, pos, vel);
return rv;
return rv;
}
/* ==================== End of file sgdp4.c ========================== */

View File

@ -27,14 +27,14 @@
*/
#if defined( unix )
# define UNIX
# if defined( linux ) && !defined( LINUX )
# define LINUX
# endif
#define UNIX
#if defined( linux ) && !defined( LINUX )
#define LINUX
#endif
#elif defined( __riscos ) && !defined( RISCOS )
# define RISCOS
#define RISCOS
#elif !defined( MSDOS ) && !defined( WIN32 ) && !defined( __CYGWIN__ )
# define MSDOS
#define MSDOS
#endif
/*
@ -62,7 +62,7 @@
#ifdef linux
#include <stdint.h>
void sincos(double x, double *s, double *c); /* declared where? */
void sincos (double x, double *s, double *c); /* declared where? */
#endif
/*
@ -133,31 +133,142 @@ void sincos(double x, double *s, double *c); /* declared where? */
* All other compilers can have static inline functions.
* (SQR is used badly here: do_cal.c, glat2lat.c, satpos.c, vmath.h).
*/
static INLINE int NINT(double a) { return (int)(a > 0 ? a+0.5 : a-0.5); }
static INLINE long NLONG(double a) { return (long)(a > 0 ? a+0.5 : a-0.5); }
static INLINE int
NINT (double a)
{
return (int) (a > 0 ? a + 0.5 : a - 0.5);
}
static INLINE double DSQR(double a) { return(a*a); }
static INLINE float FSQR(float a) { return(a*a); }
static INLINE int ISQR(int a) { return(a*a); }
static INLINE long
NLONG (double a)
{
return (long) (a > 0 ? a + 0.5 : a - 0.5);
}
static INLINE double DCUBE(double a) { return(a*a*a); }
static INLINE float FCUBE(float a) { return(a*a*a); }
static INLINE int ICUBE(int a) { return(a*a*a); }
static INLINE double
DSQR (double a)
{
return (a * a);
}
static INLINE double DPOW4(double a) { a*=a; return(a*a); }
static INLINE float FPOW4(float a) { a*=a; return(a*a); }
static INLINE int IPOW4(int a) { a*=a; return(a*a); }
static INLINE float
FSQR (float a)
{
return (a * a);
}
static INLINE double DMAX(double a,double b) { if (a>b) return a; else return b; }
static INLINE float FMAX(float a, float b) { if (a>b) return a; else return b; }
static INLINE int IMAX(int a, int b) { if (a>b) return a; else return b; }
static INLINE int
ISQR (int a)
{
return (a * a);
}
static INLINE double DMIN(double a,double b) { if (a<b) return a; else return b; }
static INLINE float FMIN(float a, float b) { if (a<b) return a; else return b; }
static INLINE int IMIN(int a, int b) { if (a<b) return a; else return b; }
static INLINE double
DCUBE (double a)
{
return (a * a * a);
}
static INLINE double MOD2PI(double a) { a=fmod(a, TWOPI); return a < 0.0 ? a+TWOPI : a; }
static INLINE double MOD360(double a) { a=fmod(a, 360.0); return a < 0.0 ? a+360.0 : a; }
static INLINE float
FCUBE (float a)
{
return (a * a * a);
}
static INLINE int
ICUBE (int a)
{
return (a * a * a);
}
static INLINE double
DPOW4 (double a)
{
a *= a;
return (a * a);
}
static INLINE float
FPOW4 (float a)
{
a *= a;
return (a * a);
}
static INLINE int
IPOW4 (int a)
{
a *= a;
return (a * a);
}
static INLINE double
DMAX (double a, double b)
{
if (a > b)
return a;
else
return b;
}
static INLINE float
FMAX (float a, float b)
{
if (a > b)
return a;
else
return b;
}
static INLINE int
IMAX (int a, int b)
{
if (a > b)
return a;
else
return b;
}
static INLINE double
DMIN (double a, double b)
{
if (a < b)
return a;
else
return b;
}
static INLINE float
FMIN (float a, float b)
{
if (a < b)
return a;
else
return b;
}
static INLINE int
IMIN (int a, int b)
{
if (a < b)
return a;
else
return b;
}
static INLINE double
MOD2PI (double a)
{
a = fmod (a, TWOPI);
return a < 0.0 ? a + TWOPI : a;
}
static INLINE double
MOD360 (double a)
{
a = fmod (a, 360.0);
return a < 0.0 ? a + 360.0 : a;
}
/*
* Unless you have higher than default optimisation the Sun compiler
@ -175,17 +286,17 @@ typedef struct orbit_s
{
/* Add the epoch time if required. */
int ep_year;/* Year of epoch, e.g. 94 for 1994, 100 for 2000AD */
int ep_year; /* Year of epoch, e.g. 94 for 1994, 100 for 2000AD */
double ep_day; /* Day of epoch from 00:00 Jan 1st ( = 1.0 ) */
double rev; /* Mean motion, revolutions per day */
double bstar; /* Drag term .*/
double bstar; /* Drag term . */
double eqinc; /* Equatorial inclination, radians */
double ecc; /* Eccentricity */
double mnan; /* Mean anomaly at epoch from elements, radians */
double argp; /* Argument of perigee, radians */
double ascn; /* Right ascension (ascending node), radians */
double smjaxs; /* Semi-major axis, km */
double ndot2,nddot6; /* Mean motion derivatives */
double ndot2, nddot6; /* Mean motion derivatives */
char desig[10]; /* International designation */
long norb; /* Orbit number, for elements */
int satno; /* Satellite number. */
@ -276,8 +387,8 @@ version of these functions.
#define SINCOS sincos
#endif /* ! SGDP4_SNGL */
void sincos(double, double *, double *);
void sincosf(float, float *, float *);
void sincos (double, double *, double *);
void sincosf (float, float *, float *);
#else
/* Sun 'C' compiler. */
@ -307,23 +418,23 @@ void sincosf(float, float *, float *);
/* ======== Macro fixes for float/double in math.h type functions. ===== */
#if defined( SGDP4_SNGL )
#define SIN(x) sinf(x)
#define COS(x) cosf(x)
#define SQRT(x) sqrtf(x)
#define FABS(x) fabsf(x)
#define POW(x,y) powf(x, y)
#define FMOD(x,y) fmodf(x, y)
#define ATAN2(x,y) atan2f(x, y)
#define SIN(x) sinf(x)
#define COS(x) cosf(x)
#define SQRT(x) sqrtf(x)
#define FABS(x) fabsf(x)
#define POW(x,y) powf(x, y)
#define FMOD(x,y) fmodf(x, y)
#define ATAN2(x,y) atan2f(x, y)
#elif defined( SGDP4_DBLE )
#define SIN(x) sin(x)
#define COS(x) cos(x)
#define SQRT(x) sqrt(x)
#define FABS(x) fabs(x)
#define POW(x,y) pow(x, y)
#define FMOD(x,y) fmod(x, y)
#define ATAN2(x,y) atan2(x, y)
#define SIN(x) sin(x)
#define COS(x) cos(x)
#define SQRT(x) sqrt(x)
#define FABS(x) fabs(x)
#define POW(x,y) pow(x, y)
#define FMOD(x,y) fmod(x, y)
#define ATAN2(x,y) atan2(x, y)
#else
#error "Incompatible choices for SGDP4_SNGL / SGDP4_DBLE"
#error "Incompatible choices for SGDP4_SNGL / SGDP4_DBLE"
#endif
#ifdef SGDP4_SNGL
@ -336,7 +447,8 @@ void sincosf(float, float *, float *);
/* SGDP4 function return values. */
typedef enum {
typedef enum
{
SGDP4_ERROR = (-1),
SGDP4_NOT_INIT = 0,
SGDP4_ZERO_ECC = 1,
@ -352,27 +464,29 @@ typedef enum {
/* ======================= Function prototypes ====================== */
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/** deep.c **/
sgdp4_mode_t SGDP4_dpinit(double epoch, real omegao, real xnodeo, real xmo,
real orb_eo, real orb_xincl, real aodp, double xlldot,
real omgdot, real xnodot, double xnodp);
sgdp4_mode_t SGDP4_dpinit (double epoch, real omegao, real xnodeo, real xmo,
real orb_eo, real orb_xincl, real aodp,
double xlldot, real omgdot, real xnodot,
double xnodp);
int SGDP4_dpsec(double *xll, real *omgasm, real *xnodes, real *em,
real *xinc, double *xn, double tsince);
int SGDP4_dpsec (double *xll, real * omgasm, real * xnodes, real * em,
real * xinc, double *xn, double tsince);
int SGDP4_dpper(real *em, real *xinc, real *omgasm, real *xnodes,
int SGDP4_dpper (real * em, real * xinc, real * omgasm, real * xnodes,
double *xll, double tsince);
/** sgdp4.c **/
sgdp4_mode_t init_sgdp4(orbit_t *orb);
sgdp4_mode_t sgdp4(double tsince, int withvel, kep_t *kep);
void kep2xyz(kep_t *K, xyz_t *pos, xyz_t *vel);
sgdp4_mode_t satpos_xyz(double jd, xyz_t *pos, xyz_t *vel);
sgdp4_mode_t init_sgdp4 (orbit_t * orb);
sgdp4_mode_t sgdp4 (double tsince, int withvel, kep_t * kep);
void kep2xyz (kep_t * K, xyz_t * pos, xyz_t * vel);
sgdp4_mode_t satpos_xyz (double jd, xyz_t * pos, xyz_t * vel);
#ifdef __cplusplus
}

View File

@ -2,27 +2,32 @@
#include <stdio.h>
#include <stdlib.h>
double **simplex(int n,double *a,double *da)
double **
simplex (int n, double *a, double *da)
{
int i,j;
int i, j;
double **p;
// Allocate pointers to rows
p=(double **) malloc(sizeof(double *) * (n+1));
p = (double **) malloc (sizeof (double *) * (n + 1));
// Allocate rows and set pointers
for (i=0;i<=n;i++)
p[i]=(double *) malloc(sizeof(double) * (n+1)*n);
for (i = 0; i <= n; i++)
p[i] = (double *) malloc (sizeof (double) * (n + 1) * n);
// Fill simplex
for (i=0;i<=n;i++) {
for (j=0;j<n;j++) {
if (i<j) p[i][j]=a[j];
if (i==j) p[i][j]=a[j]+da[j];
if (i>j) p[i][j]=a[j]-da[j];
for (i = 0; i <= n; i++)
{
for (j = 0; j < n; j++)
{
if (i < j)
p[i][j] = a[j];
if (i == j)
p[i][j] = a[j] + da[j];
if (i > j)
p[i][j] = a[j] - da[j];
}
}
return p;
}

View File

@ -20,102 +20,111 @@
#define PORT 7624
#define IP "127.0.0.1"
struct map {
double alpha0,delta0,ra0,de0,azi0,alt0,q;
struct map
{
double alpha0, delta0, ra0, de0, azi0, alt0, q;
char orientation[LIM];
char nfd[LIM];
char datadir[LIM],observer[32];
double lat,lng;
char datadir[LIM], observer[32];
double lat, lng;
double mjd;
float alt,timezone;
float alt, timezone;
int site_id;
} m;
void usage(void)
void
usage (void)
{
return;
}
// Compute Date from Julian Day
void mjd2nfd(double mjd,char *nfd)
void
mjd2nfd (double mjd, char *nfd)
{
double f,jd,dday;
int z,alpha,a,b,c,d,e;
int year,month,day,hour,min;
float sec,x;
double f, jd, dday;
int z, alpha, a, b, c, d, e;
int year, month, day, hour, min;
float sec, x;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
dday=b-d-floor(30.6001*e)+f;
if (e<14)
month=e-1;
dday = b - d - floor (30.6001 * e) + f;
if (e < 14)
month = e - 1;
else
month=e-13;
month = e - 13;
if (month>2)
year=c-4716;
if (month > 2)
year = c - 4716;
else
year=c-4715;
year = c - 4715;
day=(int) floor(dday);
x=24.0*(dday-day);
x=3600.*fabs(x);
sec=fmod(x,60.);
x=(x-sec)/60.;
min=fmod(x,60.);
x=(x-min)/60.;
hour=x;
sec=floor(1000.0*sec)/1000.0;
day = (int) floor (dday);
x = 24.0 * (dday - day);
x = 3600. * fabs (x);
sec = fmod (x, 60.);
x = (x - sec) / 60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
hour = x;
sec = floor (1000.0 * sec) / 1000.0;
sprintf(nfd,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec);
sprintf (nfd, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour,
min, sec);
return;
}
// Send new position to telescope
void send_position(char *sra,char *sde)
void
send_position (char *sra, char *sde)
{
int skt;
struct hostent *he;
struct sockaddr_in addr;
char packet[2048];
FILE *file;
float ra,de;
float ra, de;
// Old packet style
// sprintf(packet,"<newNumberVector device='Celestron GPS' name='EQUATORIAL_EOD_COORD_REQUEST'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",sra,sde);
// New packet style (as of 2013-08-20)
sprintf(packet,"<newNumberVector device='iEQ' name='EQUATORIAL_EOD_COORD'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",sra,sde);
sprintf (packet,
"<newNumberVector device='iEQ' name='EQUATORIAL_EOD_COORD'><oneNumber name='RA'>%s</oneNumber><oneNumber name='DEC'>%s</oneNumber></newNumberVector>",
sra, sde);
// Send TCP packet
skt=socket(AF_INET,SOCK_STREAM,0);
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
he=gethostbyname(IP);
bcopy(he->h_addr,(struct in_addr *) &addr.sin_addr,he->h_length);
if(connect(skt,(struct sockaddr *) &addr,sizeof(addr))<0) {
fprintf(stderr,"Connection refused by remote host.\n");
skt = socket (AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons (PORT);
he = gethostbyname (IP);
bcopy (he->h_addr, (struct in_addr *) &addr.sin_addr, he->h_length);
if (connect (skt, (struct sockaddr *) &addr, sizeof (addr)) < 0)
{
fprintf (stderr, "Connection refused by remote host.\n");
return;
}
write(skt,packet,strlen(packet));
close(skt);
write (skt, packet, strlen (packet));
close (skt);
// Set restart
// file=fopen("/media/video/satobs/control/state.txt","w");
@ -135,80 +144,90 @@ void send_position(char *sra,char *sde)
}
// Get observing site
void get_site(int site_id)
void
get_site (int site_id)
{
int i=0;
int i = 0;
char line[LIM];
FILE *file;
int id;
double lat,lng;
double lat, lng;
float alt;
char abbrev[3],observer[64],filename[LIM];
char abbrev[3], observer[64], filename[LIM];
sprintf(filename,"%s/data/sites.txt",m.datadir);
file=fopen(filename,"r");
if (file==NULL) {
printf("File with site information not found!\n");
sprintf (filename, "%s/data/sites.txt", m.datadir);
file = fopen (filename, "r");
if (file == NULL)
{
printf ("File with site information not found!\n");
return;
}
while (fgets(line,LIM,file)!=NULL) {
while (fgets (line, LIM, file) != NULL)
{
// Skip
if (strstr(line,"#")!=NULL)
if (strstr (line, "#") != NULL)
continue;
// Strip newline
line[strlen(line)-1]='\0';
line[strlen (line) - 1] = '\0';
// Read data
sscanf(line,"%4d %2s %lf %lf %f",
&id,abbrev,&lat,&lng,&alt);
strcpy(observer,line+38);
sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt);
strcpy (observer, line + 38);
// Change to km
alt/=1000.0;
alt /= 1000.0;
if (id==site_id) {
m.lat=lat;
m.lng=lng;
m.alt=alt;
m.site_id=id;
strcpy(m.observer,observer);
if (id == site_id)
{
m.lat = lat;
m.lng = lng;
m.alt = alt;
m.site_id = id;
strcpy (m.observer, observer);
}
}
fclose(file);
fclose (file);
return;
}
void initialize(void)
void
initialize (void)
{
int i;
char *env;
// Default Map parameters
m.azi0=0;
m.alt0=90.0;
m.azi0 = 0;
m.alt0 = 90.0;
m.lat=0.0;
m.lng=0.0;
m.alt=0.0;
m.lat = 0.0;
m.lng = 0.0;
m.alt = 0.0;
// Default settings
m.site_id=0;
m.site_id = 0;
// Get environment variables
env=getenv("ST_DATADIR");
if (env!=NULL) {
strcpy(m.datadir,env);
} else {
printf("ST_DATADIR environment variable not found.\n");
env = getenv ("ST_DATADIR");
if (env != NULL)
{
strcpy (m.datadir, env);
}
env=getenv("ST_COSPAR");
if (env!=NULL) {
get_site(atoi(env));
} else {
printf("ST_COSPAR environment variable not found.\n");
else
{
printf ("ST_DATADIR environment variable not found.\n");
}
env = getenv ("ST_COSPAR");
if (env != NULL)
{
get_site (atoi (env));
}
else
{
printf ("ST_COSPAR environment variable not found.\n");
}
return;
@ -216,265 +235,322 @@ void initialize(void)
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Greenwich Mean Sidereal Time
double gmst(double mjd)
double
gmst (double mjd)
{
double t,gmst;
double t, gmst;
t=(mjd-51544.5)/36525.0;
t = (mjd - 51544.5) / 36525.0;
gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0);
gmst =
modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) +
t * t * (0.000387933 - t / 38710000), 360.0);
return gmst;
}
// Convert Sexagesimal into Decimal
double s2dec(char *s)
double
s2dec (char *s)
{
double x;
float deg,min,sec;
float deg, min, sec;
char t[LIM];
strcpy(t,s);
strcpy (t, s);
deg=fabs(atof(strtok(t," :")));
min=fabs(atof(strtok(NULL," :")));
sec=fabs(atof(strtok(NULL," :")));
deg = fabs (atof (strtok (t, " :")));
min = fabs (atof (strtok (NULL, " :")));
sec = fabs (atof (strtok (NULL, " :")));
x=(double) deg+(double) min/60.+(double) sec/3600.;
if (s[0]=='-') x= -x;
x = (double) deg + (double) min / 60. + (double) sec / 3600.;
if (s[0] == '-')
x = -x;
return x;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// Present nfd
void nfd_now(char *s)
void
nfd_now (char *s)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
time(&rawtime);
ptm=gmtime(&rawtime);
time (&rawtime);
ptm = gmtime (&rawtime);
sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900,
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
ptm->tm_sec);
return;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
// Convert horizontal into equatorial coordinates
void horizontal2equatorial(double mjd,double azi,double alt,double *ra,double *de)
void
horizontal2equatorial (double mjd, double azi, double alt, double *ra,
double *de)
{
double h;
h=atan2(sin(azi*D2R),cos(azi*D2R)*sin(m.lat*D2R)+tan(alt*D2R)*cos(m.lat*D2R))*R2D;
*ra=modulo(gmst(mjd)+m.lng-h,360.0);
*de=asin(sin(m.lat*D2R)*sin(alt*D2R)-cos(m.lat*D2R)*cos(alt*D2R)*cos(azi*D2R))*R2D;
if (*ra<0.0)
*ra+=360.0;
h =
atan2 (sin (azi * D2R),
cos (azi * D2R) * sin (m.lat * D2R) +
tan (alt * D2R) * cos (m.lat * D2R)) * R2D;
*ra = modulo (gmst (mjd) + m.lng - h, 360.0);
*de =
asin (sin (m.lat * D2R) * sin (alt * D2R) -
cos (m.lat * D2R) * cos (alt * D2R) * cos (azi * D2R)) * R2D;
if (*ra < 0.0)
*ra += 360.0;
return;
}
// Convert equatorial into horizontal coordinates
void equatorial2horizontal(double mjd,double ra,double de,double *azi,double *alt)
void
equatorial2horizontal (double mjd, double ra, double de, double *azi,
double *alt)
{
double h;
h=gmst(mjd)+m.lng-ra;
h = gmst (mjd) + m.lng - ra;
*azi=modulo(atan2(sin(h*D2R),cos(h*D2R)*sin(m.lat*D2R)-tan(de*D2R)*cos(m.lat*D2R))*R2D,360.0);
*alt=asin(sin(m.lat*D2R)*sin(de*D2R)+cos(m.lat*D2R)*cos(de*D2R)*cos(h*D2R))*R2D;
*azi =
modulo (atan2
(sin (h * D2R),
cos (h * D2R) * sin (m.lat * D2R) -
tan (de * D2R) * cos (m.lat * D2R)) * R2D, 360.0);
*alt =
asin (sin (m.lat * D2R) * sin (de * D2R) +
cos (m.lat * D2R) * cos (de * D2R) * cos (h * D2R)) * R2D;
return;
}
double parallactic_angle(double mjd,double ra,double de)
double
parallactic_angle (double mjd, double ra, double de)
{
double h,q;
double h, q;
h=gmst(mjd)+m.lng-ra;
h = gmst (mjd) + m.lng - ra;
q=atan2(sin(h*D2R),(tan(m.lat*D2R)*cos(de*D2R)-sin(de*D2R)*cos(h*D2R)))*R2D;
q =
atan2 (sin (h * D2R),
(tan (m.lat * D2R) * cos (de * D2R) -
sin (de * D2R) * cos (h * D2R))) * R2D;
return q;
}
// Convert Decimal into Sexagesimal
void dec2s(double x,char *s,int f,int len)
void
dec2s (double x, char *s, int f, int len)
{
int i;
double sec,deg,min;
double sec, deg, min;
char sign;
char *form[]={"::",",,","hms"," "};
char *form[] = { "::", ",,", "hms", " " };
sign=(x<0 ? '-' : ' ');
x=3600.*fabs(x);
sign = (x < 0 ? '-' : ' ');
x = 3600. * fabs (x);
sec=fmod(x,60.);
x=(x-sec)/60.;
min=fmod(x,60.);
x=(x-min)/60.;
sec = fmod (x, 60.);
x = (x - sec) / 60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
// deg=fmod(x,60.);
deg=x;
deg = x;
if (len==7) sprintf(s,"%c%02i%c%02i%c%07.4f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]);
if (len==6) sprintf(s,"%c%02i%c%02i%c%06.3f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]);
if (len==5) sprintf(s,"%c%02i%c%02i%c%05.2f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]);
if (len==4) sprintf(s,"%c%02i%c%02i%c%04.1f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]);
if (len==2) sprintf(s,"%c%02i%c%02i%c%02i%c",sign,(int) deg,form[f][0],(int) min,form[f][1],(int) floor(sec),form[f][2]);
if (len == 7)
sprintf (s, "%c%02i%c%02i%c%07.4f%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], sec, form[f][2]);
if (len == 6)
sprintf (s, "%c%02i%c%02i%c%06.3f%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], sec, form[f][2]);
if (len == 5)
sprintf (s, "%c%02i%c%02i%c%05.2f%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], sec, form[f][2]);
if (len == 4)
sprintf (s, "%c%02i%c%02i%c%04.1f%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], sec, form[f][2]);
if (len == 2)
sprintf (s, "%c%02i%c%02i%c%02i%c", sign, (int) deg, form[f][0],
(int) min, form[f][1], (int) floor (sec), form[f][2]);
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int arg=0,haflag=0,dry=0;
char sra[16],sde[16];
int arg = 0, haflag = 0, dry = 0;
char sra[16], sde[16];
double ha;
FILE *file;
// Initialize
initialize();
initialize ();
// Get time
nfd_now(m.nfd);
m.mjd=nfd2mjd(m.nfd);
nfd_now (m.nfd);
m.mjd = nfd2mjd (m.nfd);
// Decode options
while ((arg=getopt(argc,argv,"m:t:H:R:D:A:E:hn"))!=-1) {
switch(arg) {
while ((arg = getopt (argc, argv, "m:t:H:R:D:A:E:hn")) != -1)
{
switch (arg)
{
case 'n':
dry=1;
dry = 1;
break;
case 't':
strcpy(m.nfd,optarg);
m.mjd=nfd2mjd(m.nfd);
strcpy (m.nfd, optarg);
m.mjd = nfd2mjd (m.nfd);
break;
case 'm':
m.mjd=atof(optarg);
mjd2nfd(m.mjd,m.nfd);
m.mjd = atof (optarg);
mjd2nfd (m.mjd, m.nfd);
break;
case 'H':
ha=atof(optarg);
haflag=1;
strcpy(m.orientation,"equatorial");
ha = atof (optarg);
haflag = 1;
strcpy (m.orientation, "equatorial");
break;
case 'R':
m.ra0=15.0*s2dec(optarg);
strcpy(m.orientation,"equatorial");
m.ra0 = 15.0 * s2dec (optarg);
strcpy (m.orientation, "equatorial");
break;
case 'D':
m.de0=s2dec(optarg);
strcpy(m.orientation,"equatorial");
m.de0 = s2dec (optarg);
strcpy (m.orientation, "equatorial");
break;
case 'A':
m.azi0=modulo(atof(optarg)+180.0,360.0);
strcpy(m.orientation,"horizontal");
m.azi0 = modulo (atof (optarg) + 180.0, 360.0);
strcpy (m.orientation, "horizontal");
break;
case 'E':
m.alt0=atof(optarg);
strcpy(m.orientation,"horizontal");
m.alt0 = atof (optarg);
strcpy (m.orientation, "horizontal");
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
// Compute RA from HA
if (haflag==1) {
m.ra0=modulo(gmst(m.mjd)+m.lng-ha,360.0);
} else {
ha=modulo(gmst(m.mjd)+m.lng-m.ra0,360.0);
if (ha>180.0)
ha-=360.0;
if (haflag == 1)
{
m.ra0 = modulo (gmst (m.mjd) + m.lng - ha, 360.0);
}
else
{
ha = modulo (gmst (m.mjd) + m.lng - m.ra0, 360.0);
if (ha > 180.0)
ha -= 360.0;
}
// Compute RA and Dec
if (strcmp(m.orientation,"horizontal")==0)
horizontal2equatorial(m.mjd,m.azi0,m.alt0,&m.ra0,&m.de0);
else if (strcmp(m.orientation,"equatorial")==0)
equatorial2horizontal(m.mjd,m.ra0,m.de0,&m.azi0,&m.alt0);
if (strcmp (m.orientation, "horizontal") == 0)
horizontal2equatorial (m.mjd, m.azi0, m.alt0, &m.ra0, &m.de0);
else if (strcmp (m.orientation, "equatorial") == 0)
equatorial2horizontal (m.mjd, m.ra0, m.de0, &m.azi0, &m.alt0);
// Parallactic angle
m.q=parallactic_angle(m.mjd,m.ra0,m.de0);
m.q = parallactic_angle (m.mjd, m.ra0, m.de0);
// Get sexagesimal
dec2s(m.ra0/15.0,sra,0,5);
dec2s(m.de0,sde,0,4);
dec2s (m.ra0 / 15.0, sra, 0, 5);
dec2s (m.de0, sde, 0, 4);
// Print to screen
printf("%s R:%s D: %s H: %7.3f A: %6.3f E: %6.3f q: %5.2f\n",m.nfd,sra,sde,ha,modulo(m.azi0-180.0,360.0),m.alt0,m.q);
printf ("%s R:%s D: %s H: %7.3f A: %6.3f E: %6.3f q: %5.2f\n", m.nfd, sra,
sde, ha, modulo (m.azi0 - 180.0, 360.0), m.alt0, m.q);
if (dry==0) {
if (dry == 0)
{
// Send position
send_position(sra,sde);
send_position (sra, sde);
// Log
file=fopen("position.txt","a");
fprintf(file,"%s %lf %lf %f\n",m.nfd,m.ra0,m.de0,m.q);
fclose(file);
file = fopen ("position.txt", "a");
fprintf (file, "%s %lf %lf %f\n", m.nfd, m.ra0, m.de0, m.q);
fclose (file);
}
return 0;

View File

@ -10,121 +10,137 @@
#define D2R M_PI/180.0
#define R2D 180.0/M_PI
struct image {
struct image
{
char filename[64];
int naxis1,naxis2,naxis3,nframes;
float *zavg,*zstd,*zmax,*znum,*ztrk;
double ra0,de0;
float x0,y0;
float a[3],b[3],xrms,yrms;
int naxis1, naxis2, naxis3, nframes;
float *zavg, *zstd, *zmax, *znum, *ztrk;
double ra0, de0;
float x0, y0;
float a[3], b[3], xrms, yrms;
double mjd;
float *dt,exptime;
float *dt, exptime;
char nfd[32];
int cospar;
};
struct image read_fits(char *filename);
void write_composite_pgm(char *filename,struct image img);
void write_pgm(char *filename,struct image img);
struct image read_fits (char *filename);
void write_composite_pgm (char *filename, struct image img);
void write_pgm (char *filename, struct image img);
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int i;
struct image img;
img=read_fits(argv[1]);
img = read_fits (argv[1]);
write_composite_pgm("avg.pgm",img);
write_pgm("f1.pgm",img);
write_composite_pgm ("avg.pgm", img);
write_pgm ("f1.pgm", img);
return 0;
}
// Read fits image
struct image read_fits(char *filename)
struct image
read_fits (char *filename)
{
int i,j,k,l,m;
int i, j, k, l, m;
qfitsloader ql;
char key[FITS_LINESZ+1];
char val[FITS_LINESZ+1];
char key[FITS_LINESZ + 1];
char val[FITS_LINESZ + 1];
struct image img;
// Copy filename
strcpy(img.filename,filename);
strcpy (img.filename, filename);
// Image size
img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1"));
img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2"));
img.naxis3=atoi(qfits_query_hdr(filename,"NAXIS3"));
img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1"));
img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2"));
img.naxis3 = atoi (qfits_query_hdr (filename, "NAXIS3"));
// MJD
img.mjd=(double) atof(qfits_query_hdr(filename,"MJD-OBS"));
strcpy(img.nfd,qfits_query_hdr(filename,"DATE-OBS"));
img.mjd = (double) atof (qfits_query_hdr (filename, "MJD-OBS"));
strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS"));
// COSPAR ID
img.cospar=atoi(qfits_query_hdr(filename,"COSPAR"));
img.cospar = atoi (qfits_query_hdr (filename, "COSPAR"));
// Transformation
img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS"));
img.ra0=atof(qfits_query_hdr(filename,"CRVAL1"));
img.de0=atof(qfits_query_hdr(filename,"CRVAL2"));
img.x0=atof(qfits_query_hdr(filename,"CRPIX1"));
img.y0=atof(qfits_query_hdr(filename,"CRPIX2"));
img.a[0]=0.0;
img.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1"));
img.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2"));
img.b[0]=0.0;
img.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1"));
img.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2"));
img.xrms=3600.0*atof(qfits_query_hdr(filename,"CRRES1"));
img.yrms=3600.0*atof(qfits_query_hdr(filename,"CRRES2"));
img.exptime=atof(qfits_query_hdr(filename,"EXPTIME"));
img.nframes=atoi(qfits_query_hdr(filename,"NFRAMES"));
img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS"));
img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1"));
img.de0 = atof (qfits_query_hdr (filename, "CRVAL2"));
img.x0 = atof (qfits_query_hdr (filename, "CRPIX1"));
img.y0 = atof (qfits_query_hdr (filename, "CRPIX2"));
img.a[0] = 0.0;
img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1"));
img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2"));
img.b[0] = 0.0;
img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1"));
img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2"));
img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1"));
img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2"));
img.exptime = atof (qfits_query_hdr (filename, "EXPTIME"));
img.nframes = atoi (qfits_query_hdr (filename, "NFRAMES"));
// Timestamps
img.dt=(float *) malloc(sizeof(float)*img.nframes);
for (i=0;i<img.nframes;i++) {
sprintf(key,"DT%04d",i);
strcpy(val,qfits_query_hdr(filename,key));
sscanf(val+1,"%f",&img.dt[i]);
img.dt = (float *) malloc (sizeof (float) * img.nframes);
for (i = 0; i < img.nframes; i++)
{
sprintf (key, "DT%04d", i);
strcpy (val, qfits_query_hdr (filename, key));
sscanf (val + 1, "%f", &img.dt[i]);
// img.dt[i]=atof(qfits_query_hdr(filename,key));
}
// Allocate image memory
img.zavg=(float *) malloc(sizeof(float)*img.naxis1*img.naxis2);
img.zstd=(float *) malloc(sizeof(float)*img.naxis1*img.naxis2);
img.zmax=(float *) malloc(sizeof(float)*img.naxis1*img.naxis2);
img.znum=(float *) malloc(sizeof(float)*img.naxis1*img.naxis2);
if (img.naxis3==5)
img.ztrk=(float *) malloc(sizeof(float)*img.naxis1*img.naxis2);
img.zavg = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
img.zstd = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
img.zmax = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
img.znum = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
if (img.naxis3 == 5)
img.ztrk = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2);
// Set parameters
ql.xtnum=0;
ql.ptype=PTYPE_FLOAT;
ql.filename=filename;
ql.xtnum = 0;
ql.ptype = PTYPE_FLOAT;
ql.filename = filename;
// Loop over planes
for (k=0;k<img.naxis3;k++) {
ql.pnum=k;
for (k = 0; k < img.naxis3; k++)
{
ql.pnum = k;
// Initialize load
if (qfitsloader_init(&ql) != 0)
printf("Error initializing data loading\n");
if (qfitsloader_init (&ql) != 0)
printf ("Error initializing data loading\n");
// Test load
if (qfits_loadpix(&ql) != 0)
printf("Error loading actual data\n");
if (qfits_loadpix (&ql) != 0)
printf ("Error loading actual data\n");
// Fill z array
for (i=0,l=0;i<img.naxis1;i++) {
for (j=0;j<img.naxis2;j++) {
if (k==1) img.zstd[l]=ql.fbuf[l];
if (k==2) img.zmax[l]=ql.fbuf[l];
if (k==3) img.znum[l]=ql.fbuf[l];
if (img.naxis3==5) {
if (k==0) img.ztrk[l]=ql.fbuf[l];
if (k==4) img.zavg[l]=ql.fbuf[l];
} else {
if (k==0) img.zavg[l]=ql.fbuf[l];
for (i = 0, l = 0; i < img.naxis1; i++)
{
for (j = 0; j < img.naxis2; j++)
{
if (k == 1)
img.zstd[l] = ql.fbuf[l];
if (k == 2)
img.zmax[l] = ql.fbuf[l];
if (k == 3)
img.znum[l] = ql.fbuf[l];
if (img.naxis3 == 5)
{
if (k == 0)
img.ztrk[l] = ql.fbuf[l];
if (k == 4)
img.zavg[l] = ql.fbuf[l];
}
else
{
if (k == 0)
img.zavg[l] = ql.fbuf[l];
}
l++;
@ -136,120 +152,140 @@ struct image read_fits(char *filename)
}
// Write pgm file
void write_composite_pgm(char *filename,struct image img)
void
write_composite_pgm (char *filename, struct image img)
{
int i,j,k,l,n;
int i, j, k, l, n;
FILE *file;
float z,zavgmin,zavgmax,zstdmin,zstdmax,zmaxmin,zmaxmax;
float s1,s2,avg,std;
float z, zavgmin, zavgmax, zstdmin, zstdmax, zmaxmin, zmaxmax;
float s1, s2, avg, std;
unsigned char *buffer;
n=img.naxis1*img.naxis2;
for (j=0;j<3;j++) {
for (i=0,s1=0.0,s2=0.0;i<n;i++) {
if (j==0) z=img.zavg[i];
if (j==1) z=img.zstd[i];
if (j==2) z=img.zmax[i];
s1+=z;
s2+=z*z;
n = img.naxis1 * img.naxis2;
for (j = 0; j < 3; j++)
{
for (i = 0, s1 = 0.0, s2 = 0.0; i < n; i++)
{
if (j == 0)
z = img.zavg[i];
if (j == 1)
z = img.zstd[i];
if (j == 2)
z = img.zmax[i];
s1 += z;
s2 += z * z;
}
avg=s1/(float) n;
std=sqrt(s2/(float) n-avg*avg);
if (j==0) {
zavgmin=avg-2*std;
zavgmax=avg+3*std;
avg = s1 / (float) n;
std = sqrt (s2 / (float) n - avg * avg);
if (j == 0)
{
zavgmin = avg - 2 * std;
zavgmax = avg + 3 * std;
}
if (j==1) {
zstdmin=avg-2*std;
zstdmax=avg+3*std;
if (j == 1)
{
zstdmin = avg - 2 * std;
zstdmax = avg + 3 * std;
}
if (j==2) {
zmaxmin=avg-2*std;
zmaxmax=avg+3*std;
if (j == 2)
{
zmaxmin = avg - 2 * std;
zmaxmax = avg + 3 * std;
}
}
buffer=(unsigned char *) malloc(sizeof(unsigned char)*4*n);
buffer = (unsigned char *) malloc (sizeof (unsigned char) * 4 * n);
for (j=0,l=0;j<img.naxis2;j++) {
for (i=0;i<img.naxis1;i++) {
k=i+(img.naxis2-j-1)*img.naxis1;
z=255.0*(img.zavg[k]-zavgmin)/(zavgmax-zavgmin);
if (z>=255.0)
z=255.0;
if (z<0.0)
z=0.0;
buffer[l++]=(unsigned char) z;
for (j = 0, l = 0; j < img.naxis2; j++)
{
for (i = 0; i < img.naxis1; i++)
{
k = i + (img.naxis2 - j - 1) * img.naxis1;
z = 255.0 * (img.zavg[k] - zavgmin) / (zavgmax - zavgmin);
if (z >= 255.0)
z = 255.0;
if (z < 0.0)
z = 0.0;
buffer[l++] = (unsigned char) z;
}
for (i=0;i<img.naxis1;i++) {
k=i+(img.naxis2-j-1)*img.naxis1;
z=255.0*(img.zstd[k]-zstdmin)/(zstdmax-zstdmin);
if (z>=255.0)
z=255.0;
if (z<0.0)
z=0.0;
buffer[l++]=(unsigned char) z;
for (i = 0; i < img.naxis1; i++)
{
k = i + (img.naxis2 - j - 1) * img.naxis1;
z = 255.0 * (img.zstd[k] - zstdmin) / (zstdmax - zstdmin);
if (z >= 255.0)
z = 255.0;
if (z < 0.0)
z = 0.0;
buffer[l++] = (unsigned char) z;
}
}
for (j=0;j<img.naxis2;j++) {
for (i=0;i<img.naxis1;i++) {
k=i+(img.naxis2-j-1)*img.naxis1;
z=255*(img.zmax[k]-zmaxmin)/(zmaxmax-zmaxmin);
if (z>=255.0)
z=255.0;
if (z<0.0)
z=0.0;
buffer[l++]=(unsigned char) z;
for (j = 0; j < img.naxis2; j++)
{
for (i = 0; i < img.naxis1; i++)
{
k = i + (img.naxis2 - j - 1) * img.naxis1;
z = 255 * (img.zmax[k] - zmaxmin) / (zmaxmax - zmaxmin);
if (z >= 255.0)
z = 255.0;
if (z < 0.0)
z = 0.0;
buffer[l++] = (unsigned char) z;
}
for (i=0;i<img.naxis1;i++) {
k=i+(img.naxis2-j-1)*img.naxis1;
z=img.znum[k];
if (z>=255.0)
z=255.0;
if (z<0.0)
z=0.0;
buffer[l++]=(unsigned char) z;
for (i = 0; i < img.naxis1; i++)
{
k = i + (img.naxis2 - j - 1) * img.naxis1;
z = img.znum[k];
if (z >= 255.0)
z = 255.0;
if (z < 0.0)
z = 0.0;
buffer[l++] = (unsigned char) z;
}
}
file=fopen(filename,"wb");
fprintf(file,"P5\n%d %d\n255\n",2*img.naxis1,2*img.naxis2);
fwrite(buffer,4*n,sizeof(unsigned char),file);
fclose(file);
file = fopen (filename, "wb");
fprintf (file, "P5\n%d %d\n255\n", 2 * img.naxis1, 2 * img.naxis2);
fwrite (buffer, 4 * n, sizeof (unsigned char), file);
fclose (file);
return;
}
// Write pgm file
void write_pgm(char *filename,struct image img)
void
write_pgm (char *filename, struct image img)
{
int i,j,k,n;
int i, j, k, n;
FILE *file;
float s1,s2,z,avg,std,zavgmin,zavgmax;
float s1, s2, z, avg, std, zavgmin, zavgmax;
n=img.naxis1*img.naxis2;
for (i=0,s1=0.0,s2=0.0;i<n;i++) {
z=img.zavg[i];
s1+=z;
s2+=z*z;
n = img.naxis1 * img.naxis2;
for (i = 0, s1 = 0.0, s2 = 0.0; i < n; i++)
{
z = img.zavg[i];
s1 += z;
s2 += z * z;
}
avg=s1/(float) n;
std=sqrt(s2/(float) n-avg*avg);
zavgmin=avg-2*std;
zavgmax=avg+3*std;
avg = s1 / (float) n;
std = sqrt (s2 / (float) n - avg * avg);
zavgmin = avg - 2 * std;
zavgmax = avg + 3 * std;
file=fopen(filename,"w");
fprintf(file,"P5\n# %.23s\n%d %d\n255\n",img.nfd+1,img.naxis1,img.naxis2);
for (j=0;j<img.naxis2;j++) {
for (i=0;i<img.naxis1;i++) {
k=i+(img.naxis2-j-1)*img.naxis1;
z=255.0*(img.zavg[k]-zavgmin)/(zavgmax-zavgmin);
if (z>255.0)
z=255.0;
if (z<0.0)
z=0.0;
fprintf(file,"%c",(unsigned char) z);
file = fopen (filename, "w");
fprintf (file, "P5\n# %.23s\n%d %d\n255\n", img.nfd + 1, img.naxis1,
img.naxis2);
for (j = 0; j < img.naxis2; j++)
{
for (i = 0; i < img.naxis1; i++)
{
k = i + (img.naxis2 - j - 1) * img.naxis1;
z = 255.0 * (img.zavg[k] - zavgmin) / (zavgmax - zavgmin);
if (z > 255.0)
z = 255.0;
if (z < 0.0)
z = 0.0;
fprintf (file, "%c", (unsigned char) z);
}
}
fclose(file);
fclose (file);
return;
}

View File

@ -6,11 +6,12 @@
#define LIM 256
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
// if (c == '\n')
// s[i++] = c;
@ -18,53 +19,64 @@ int fgetline(FILE *file,char *s,int lim)
return i;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int reverse=0;
char line[LIM],pline[LIM],tlefile[LIM];
char line0[70],line1[70],line2[70];
int reverse = 0;
char line[LIM], pline[LIM], tlefile[LIM];
char line0[70], line1[70], line2[70];
FILE *file;
int arg=0;
int arg = 0;
// Decode options
while ((arg=getopt(argc,argv,"c:rh"))!=-1) {
switch(arg) {
while ((arg = getopt (argc, argv, "c:rh")) != -1)
{
switch (arg)
{
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 'r':
reverse=1;
reverse = 1;
break;
case 'h':
default:
printf("-c <catalog>\n-r reverse\n");
printf ("-c <catalog>\n-r reverse\n");
return 0;
}
}
if (reverse==0) {
file=fopen(tlefile,"r");
while (fgetline(file,line,LIM)>0) {
if (line[0]=='1') {
strcpy(line0,pline);
strcpy(line1,line);
fgetline(file,line,LIM);
strcpy(line2,line);
printf("%s | %s | %s\n",line1,line2,line0);
} else {
strcpy(pline,line);
if (reverse == 0)
{
file = fopen (tlefile, "r");
while (fgetline (file, line, LIM) > 0)
{
if (line[0] == '1')
{
strcpy (line0, pline);
strcpy (line1, line);
fgetline (file, line, LIM);
strcpy (line2, line);
printf ("%s | %s | %s\n", line1, line2, line0);
}
else
{
strcpy (pline, line);
}
}
fclose(file);
} else {
file=fopen(tlefile,"r");
while (fgetline(file,line,LIM)>0) {
printf("%.70s\n%.70s\n%.70s\n",line+144,line,line+72);
fclose (file);
}
fclose(file);
else
{
file = fopen (tlefile, "r");
while (fgetline (file, line, LIM) > 0)
{
printf ("%.70s\n%.70s\n%.70s\n", line + 144, line, line + 72);
}
fclose (file);
}
return 0;

View File

@ -18,251 +18,284 @@
extern double SGDP4_jd0;
// Nutation series
static const struct {
int nm1,nm,nf,nd,nn;
double s,st;
double c,ct;
} nut[]={
{ 0, 0, 0, 0, 1, -171996.0, -174.2, 92025.0, 8.9 },
{ 0, 0, 0, 0, 2, 2062.0, 0.2, -895.0, 0.5 },
{ -2, 0, 2, 0, 1, 46.0, 0.0, -24.0, 0.0 },
{ 2, 0, -2, 0, 0, 11.0, 0.0, 0.0, 0.0 },
{ -2, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 },
{ 1, -1, 0, -1, 0, -3.0, 0.0, 0.0, 0.0 },
{ 0, -2, 2, -2, 1, -2.0, 0.0, 1.0, 0.0 },
{ 2, 0, -2, 0, 1, 1.0, 0.0, 0.0, 0.0 },
{ 0, 0, 2, -2, 2, -13187.0, -1.6, 5736.0, -3.1 },
{ 0, 1, 0, 0, 0, 1426.0, -3.4, 54.0, -0.1 },
{ 0, 1, 2, -2, 2, -517.0, 1.2, 224.0, -0.6 },
{ 0, -1, 2, -2, 2, 217.0, -0.5, -95.0, 0.3 },
{ 0, 0, 2, -2, 1, 129.0, 0.1, -70.0, 0.0 },
{ 2, 0, 0, -2, 0, 48.0, 0.0, 1.0, 0.0 },
{ 0, 0, 2, -2, 0, -22.0, 0.0, 0.0, 0.0 },
{ 0, 2, 0, 0, 0, 17.0, -0.1, 0.0, 0.0 },
{ 0, 1, 0, 0, 1, -15.0, 0.0, 9.0, 0.0 },
{ 0, 2, 2, -2, 2, -16.0, 0.1, 7.0, 0.0 },
{ 0, -1, 0, 0, 1, -12.0, 0.0, 6.0, 0.0 },
{ -2, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0 },
{ 0, -1, 2, -2, 1, -5.0, 0.0, 3.0, 0.0 },
{ 2, 0, 0, -2, 1, 4.0, 0.0, -2.0, 0.0 },
{ 0, 1, 2, -2, 1, 4.0, 0.0, -2.0, 0.0 },
{ 1, 0, 0, -1, 0, -4.0, 0.0, 0.0, 0.0 },
{ 2, 1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0 },
{ 0, 0, -2, 2, 1, 1.0, 0.0, 0.0, 0.0 },
{ 0, 1, -2, 2, 0, -1.0, 0.0, 0.0, 0.0 },
{ 0, 1, 0, 0, 2, 1.0, 0.0, 0.0, 0.0 },
{ -1, 0, 0, 1, 1, 1.0, 0.0, 0.0, 0.0 },
{ 0, 1, 2, -2, 0, -1.0, 0.0, 0.0, 0.0 },
{ 0, 0, 2, 0, 2, -2274.0, -0.2, 977.0, -0.5 },
{ 1, 0, 0, 0, 0, 712.0, 0.1, -7.0, 0.0 },
{ 0, 0, 2, 0, 1, -386.0, -0.4, 200.0, 0.0 },
{ 1, 0, 2, 0, 2, -301.0, 0.0, 129.0, -0.1 },
{ 1, 0, 0, -2, 0, -158.0, 0.0, -1.0, 0.0 },
{ -1, 0, 2, 0, 2, 123.0, 0.0, -53.0, 0.0 },
{ 0, 0, 0, 2, 0, 63.0, 0.0, -2.0, 0.0 },
{ 1, 0, 0, 0, 1, 63.0, 0.1, -33.0, 0.0 },
{ -1, 0, 0, 0, 1, -58.0, -0.1, 32.0, 0.0 },
{ -1, 0, 2, 2, 2, -59.0, 0.0, 26.0, 0.0 },
{ 1, 0, 2, 0, 1, -51.0, 0.0, 27.0, 0.0 },
{ 0, 0, 2, 2, 2, -38.0, 0.0, 16.0, 0.0 },
{ 2, 0, 0, 0, 0, 29.0, 0.0, -1.0, 0.0 },
{ 1, 0, 2, -2, 2, 29.0, 0.0, -12.0, 0.0 },
{ 2, 0, 2, 0, 2, -31.0, 0.0, 13.0, 0.0 },
{ 0, 0, 2, 0, 0, 26.0, 0.0, -1.0, 0.0 },
{ -1, 0, 2, 0, 1, 21.0, 0.0, -10.0, 0.0 },
{ -1, 0, 0, 2, 1, 16.0, 0.0, -8.0, 0.0 },
{ 1, 0, 0, -2, 1, -13.0, 0.0, 7.0, 0.0 },
{ -1, 0, 2, 2, 1, -10.0, 0.0, 5.0, 0.0 },
{ 1, 1, 0, -2, 0, -7.0, 0.0, 0.0, 0.0 },
{ 0, 1, 2, 0, 2, 7.0, 0.0, -3.0, 0.0 },
{ 0, -1, 2, 0, 2, -7.0, 0.0, 3.0, 0.0 },
{ 1, 0, 2, 2, 2, -8.0, 0.0, 3.0, 0.0 },
{ 1, 0, 0, 2, 0, 6.0, 0.0, 0.0, 0.0 },
{ 2, 0, 2, -2, 2, 6.0, 0.0, -3.0, 0.0 },
{ 0, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0 },
{ 0, 0, 2, 2, 1, -7.0, 0.0, 3.0, 0.0 },
{ 1, 0, 2, -2, 1, 6.0, 0.0, -3.0, 0.0 },
{ 0, 0, 0, -2, 1, -5.0, 0.0, 3.0, 0.0 },
{ 1, -1, 0, 0, 0, 5.0, 0.0, 0.0, 0.0 },
{ 2, 0, 2, 0, 1, -5.0, 0.0, 3.0, 0.0 },
{ 0, 1, 0, -2, 0, -4.0, 0.0, 0.0, 0.0 },
{ 1, 0, -2, 0, 0, 4.0, 0.0, 0.0, 0.0 },
{ 0, 0, 0, 1, 0, -4.0, 0.0, 0.0, 0.0 },
{ 1, 1, 0, 0, 0, -3.0, 0.0, 0.0, 0.0 },
{ 1, 0, 2, 0, 0, 3.0, 0.0, 0.0, 0.0 },
{ 1, -1, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 },
{ -1, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0 },
{ -2, 0, 0, 0, 1, -2.0, 0.0, 1.0, 0.0 },
{ 3, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 },
{ 0, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0 },
{ 1, 1, 2, 0, 2, 2.0, 0.0, -1.0, 0.0 },
{ -1, 0, 2, -2, 1, -2.0, 0.0, 1.0, 0.0 },
{ 2, 0, 0, 0, 1, 2.0, 0.0, -1.0, 0.0 },
{ 1, 0, 0, 0, 2, -2.0, 0.0, 1.0, 0.0 },
{ 3, 0, 0, 0, 0, 2.0, 0.0, 0.0, 0.0 },
{ 0, 0, 2, 1, 2, 2.0, 0.0, -1.0, 0.0 },
{ -1, 0, 0, 0, 2, 1.0, 0.0, -1.0, 0.0 },
{ 1, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0 },
{ -2, 0, 2, 2, 2, 1.0, 0.0, -1.0, 0.0 },
{ -1, 0, 2, 4, 2, -2.0, 0.0, 1.0, 0.0 },
{ 2, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0 },
{ 1, 1, 2, -2, 2, 1.0, 0.0, -1.0, 0.0 },
{ 1, 0, 2, 2, 1, -1.0, 0.0, 1.0, 0.0 },
{ -2, 0, 2, 4, 2, -1.0, 0.0, 1.0, 0.0 },
{ -1, 0, 4, 0, 2, 1.0, 0.0, 0.0, 0.0 },
{ 1, -1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0 },
{ 2, 0, 2, -2, 1, 1.0, 0.0, -1.0, 0.0 },
{ 2, 0, 2, 2, 2, -1.0, 0.0, 0.0, 0.0 },
{ 1, 0, 0, 2, 1, -1.0, 0.0, 0.0, 0.0 },
{ 0, 0, 4, -2, 2, 1.0, 0.0, 0.0, 0.0 },
{ 3, 0, 2, -2, 2, 1.0, 0.0, 0.0, 0.0 },
{ 1, 0, 2, -2, 0, -1.0, 0.0, 0.0, 0.0 },
{ 0, 1, 2, 0, 1, 1.0, 0.0, 0.0, 0.0 },
{ -1, -1, 0, 2, 1, 1.0, 0.0, 0.0, 0.0 },
{ 0, 0, -2, 0, 1, -1.0, 0.0, 0.0, 0.0 },
{ 0, 0, 2, -1, 2, -1.0, 0.0, 0.0, 0.0 },
{ 0, 1, 0, 2, 0, -1.0, 0.0, 0.0, 0.0 },
{ 1, 0, -2, -2, 0, -1.0, 0.0, 0.0, 0.0 },
{ 0, -1, 2, 0, 1, -1.0, 0.0, 0.0, 0.0 },
{ 1, 1, 0, -2, 1, -1.0, 0.0, 0.0, 0.0 },
{ 1, 0, -2, 2, 0, -1.0, 0.0, 0.0, 0.0 },
{ 2, 0, 0, 2, 0, 1.0, 0.0, 0.0, 0.0 },
{ 0, 0, 2, 4, 2, -1.0, 0.0, 0.0, 0.0 },
{ 0, 1, 0, 1, 0, 1.0, 0.0, 0.0, 0.0 }
static const struct
{
int nm1, nm, nf, nd, nn;
double s, st;
double c, ct;
} nut[] = {
{0, 0, 0, 0, 1, -171996.0, -174.2, 92025.0, 8.9},
{0, 0, 0, 0, 2, 2062.0, 0.2, -895.0, 0.5},
{-2, 0, 2, 0, 1, 46.0, 0.0, -24.0, 0.0},
{2, 0, -2, 0, 0, 11.0, 0.0, 0.0, 0.0},
{-2, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0},
{1, -1, 0, -1, 0, -3.0, 0.0, 0.0, 0.0},
{0, -2, 2, -2, 1, -2.0, 0.0, 1.0, 0.0},
{2, 0, -2, 0, 1, 1.0, 0.0, 0.0, 0.0},
{0, 0, 2, -2, 2, -13187.0, -1.6, 5736.0, -3.1},
{0, 1, 0, 0, 0, 1426.0, -3.4, 54.0, -0.1},
{0, 1, 2, -2, 2, -517.0, 1.2, 224.0, -0.6},
{0, -1, 2, -2, 2, 217.0, -0.5, -95.0, 0.3},
{0, 0, 2, -2, 1, 129.0, 0.1, -70.0, 0.0},
{2, 0, 0, -2, 0, 48.0, 0.0, 1.0, 0.0},
{0, 0, 2, -2, 0, -22.0, 0.0, 0.0, 0.0},
{0, 2, 0, 0, 0, 17.0, -0.1, 0.0, 0.0},
{0, 1, 0, 0, 1, -15.0, 0.0, 9.0, 0.0},
{0, 2, 2, -2, 2, -16.0, 0.1, 7.0, 0.0},
{0, -1, 0, 0, 1, -12.0, 0.0, 6.0, 0.0},
{-2, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0},
{0, -1, 2, -2, 1, -5.0, 0.0, 3.0, 0.0},
{2, 0, 0, -2, 1, 4.0, 0.0, -2.0, 0.0},
{0, 1, 2, -2, 1, 4.0, 0.0, -2.0, 0.0},
{1, 0, 0, -1, 0, -4.0, 0.0, 0.0, 0.0},
{2, 1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0},
{0, 0, -2, 2, 1, 1.0, 0.0, 0.0, 0.0},
{0, 1, -2, 2, 0, -1.0, 0.0, 0.0, 0.0},
{0, 1, 0, 0, 2, 1.0, 0.0, 0.0, 0.0},
{-1, 0, 0, 1, 1, 1.0, 0.0, 0.0, 0.0},
{0, 1, 2, -2, 0, -1.0, 0.0, 0.0, 0.0},
{0, 0, 2, 0, 2, -2274.0, -0.2, 977.0, -0.5},
{1, 0, 0, 0, 0, 712.0, 0.1, -7.0, 0.0},
{0, 0, 2, 0, 1, -386.0, -0.4, 200.0, 0.0},
{1, 0, 2, 0, 2, -301.0, 0.0, 129.0, -0.1},
{1, 0, 0, -2, 0, -158.0, 0.0, -1.0, 0.0},
{-1, 0, 2, 0, 2, 123.0, 0.0, -53.0, 0.0},
{0, 0, 0, 2, 0, 63.0, 0.0, -2.0, 0.0},
{1, 0, 0, 0, 1, 63.0, 0.1, -33.0, 0.0},
{-1, 0, 0, 0, 1, -58.0, -0.1, 32.0, 0.0},
{-1, 0, 2, 2, 2, -59.0, 0.0, 26.0, 0.0},
{1, 0, 2, 0, 1, -51.0, 0.0, 27.0, 0.0},
{0, 0, 2, 2, 2, -38.0, 0.0, 16.0, 0.0},
{2, 0, 0, 0, 0, 29.0, 0.0, -1.0, 0.0},
{1, 0, 2, -2, 2, 29.0, 0.0, -12.0, 0.0},
{2, 0, 2, 0, 2, -31.0, 0.0, 13.0, 0.0},
{0, 0, 2, 0, 0, 26.0, 0.0, -1.0, 0.0},
{-1, 0, 2, 0, 1, 21.0, 0.0, -10.0, 0.0},
{-1, 0, 0, 2, 1, 16.0, 0.0, -8.0, 0.0},
{1, 0, 0, -2, 1, -13.0, 0.0, 7.0, 0.0},
{-1, 0, 2, 2, 1, -10.0, 0.0, 5.0, 0.0},
{1, 1, 0, -2, 0, -7.0, 0.0, 0.0, 0.0},
{0, 1, 2, 0, 2, 7.0, 0.0, -3.0, 0.0},
{0, -1, 2, 0, 2, -7.0, 0.0, 3.0, 0.0},
{1, 0, 2, 2, 2, -8.0, 0.0, 3.0, 0.0},
{1, 0, 0, 2, 0, 6.0, 0.0, 0.0, 0.0},
{2, 0, 2, -2, 2, 6.0, 0.0, -3.0, 0.0},
{0, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0},
{0, 0, 2, 2, 1, -7.0, 0.0, 3.0, 0.0},
{1, 0, 2, -2, 1, 6.0, 0.0, -3.0, 0.0},
{0, 0, 0, -2, 1, -5.0, 0.0, 3.0, 0.0},
{1, -1, 0, 0, 0, 5.0, 0.0, 0.0, 0.0},
{2, 0, 2, 0, 1, -5.0, 0.0, 3.0, 0.0},
{0, 1, 0, -2, 0, -4.0, 0.0, 0.0, 0.0},
{1, 0, -2, 0, 0, 4.0, 0.0, 0.0, 0.0},
{0, 0, 0, 1, 0, -4.0, 0.0, 0.0, 0.0},
{1, 1, 0, 0, 0, -3.0, 0.0, 0.0, 0.0},
{1, 0, 2, 0, 0, 3.0, 0.0, 0.0, 0.0},
{1, -1, 2, 0, 2, -3.0, 0.0, 1.0, 0.0},
{-1, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0},
{-2, 0, 0, 0, 1, -2.0, 0.0, 1.0, 0.0},
{3, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0},
{0, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0},
{1, 1, 2, 0, 2, 2.0, 0.0, -1.0, 0.0},
{-1, 0, 2, -2, 1, -2.0, 0.0, 1.0, 0.0},
{2, 0, 0, 0, 1, 2.0, 0.0, -1.0, 0.0},
{1, 0, 0, 0, 2, -2.0, 0.0, 1.0, 0.0},
{3, 0, 0, 0, 0, 2.0, 0.0, 0.0, 0.0},
{0, 0, 2, 1, 2, 2.0, 0.0, -1.0, 0.0},
{-1, 0, 0, 0, 2, 1.0, 0.0, -1.0, 0.0},
{1, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0},
{-2, 0, 2, 2, 2, 1.0, 0.0, -1.0, 0.0},
{-1, 0, 2, 4, 2, -2.0, 0.0, 1.0, 0.0},
{2, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0},
{1, 1, 2, -2, 2, 1.0, 0.0, -1.0, 0.0},
{1, 0, 2, 2, 1, -1.0, 0.0, 1.0, 0.0},
{-2, 0, 2, 4, 2, -1.0, 0.0, 1.0, 0.0},
{-1, 0, 4, 0, 2, 1.0, 0.0, 0.0, 0.0},
{1, -1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0},
{2, 0, 2, -2, 1, 1.0, 0.0, -1.0, 0.0},
{2, 0, 2, 2, 2, -1.0, 0.0, 0.0, 0.0},
{1, 0, 0, 2, 1, -1.0, 0.0, 0.0, 0.0},
{0, 0, 4, -2, 2, 1.0, 0.0, 0.0, 0.0},
{3, 0, 2, -2, 2, 1.0, 0.0, 0.0, 0.0},
{1, 0, 2, -2, 0, -1.0, 0.0, 0.0, 0.0},
{0, 1, 2, 0, 1, 1.0, 0.0, 0.0, 0.0},
{-1, -1, 0, 2, 1, 1.0, 0.0, 0.0, 0.0},
{0, 0, -2, 0, 1, -1.0, 0.0, 0.0, 0.0},
{0, 0, 2, -1, 2, -1.0, 0.0, 0.0, 0.0},
{0, 1, 0, 2, 0, -1.0, 0.0, 0.0, 0.0},
{1, 0, -2, -2, 0, -1.0, 0.0, 0.0, 0.0},
{0, -1, 2, 0, 1, -1.0, 0.0, 0.0, 0.0},
{1, 1, 0, -2, 1, -1.0, 0.0, 0.0, 0.0},
{1, 0, -2, 2, 0, -1.0, 0.0, 0.0, 0.0},
{2, 0, 0, 2, 0, 1.0, 0.0, 0.0, 0.0},
{0, 0, 2, 4, 2, -1.0, 0.0, 0.0, 0.0},
{0, 1, 0, 1, 0, 1.0, 0.0, 0.0, 0.0}
};
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Present nfd
void nfd_now(char *s)
void
nfd_now (char *s)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
time(&rawtime);
ptm=gmtime(&rawtime);
time (&rawtime);
ptm = gmtime (&rawtime);
sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900,
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
ptm->tm_sec);
return;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
// Nutation
void nutation(double mjd,double *dpsi,double *deps,double *eps)
void
nutation (double mjd, double *dpsi, double *deps, double *eps)
{
int i;
double t,t2,t3;
double d,m,m1,f,n;
double t, t2, t3;
double d, m, m1, f, n;
double arg;
// Julian centuries
t=(mjd-51544.5)/36525.0;
t2=t*t;
t3=t2*t;
t = (mjd - 51544.5) / 36525.0;
t2 = t * t;
t3 = t2 * t;
// Angles
d=modulo(297.85036+445267.111480*t-0.0019142*t2+t3/189474.0,360.0)*D2R;
m=modulo(357.52772+35999.050340*t-0.0001603*t2-t3/300000.0,360.0)*D2R;
m1=modulo(134.96298+477198.867398*t+0.0086972*t2+t3/56250.0,360.0)*D2R;
f=modulo(93.27191+483202.017538*t-0.0036825*t2+t3/327270.0,360.0)*D2R;
n=modulo(125.04452-1934.136261*t+0.0020708*t2+t3/450000.0,360.0)*D2R;
d =
modulo (297.85036 + 445267.111480 * t - 0.0019142 * t2 + t3 / 189474.0,
360.0) * D2R;
m =
modulo (357.52772 + 35999.050340 * t - 0.0001603 * t2 - t3 / 300000.0,
360.0) * D2R;
m1 =
modulo (134.96298 + 477198.867398 * t + 0.0086972 * t2 + t3 / 56250.0,
360.0) * D2R;
f =
modulo (93.27191 + 483202.017538 * t - 0.0036825 * t2 + t3 / 327270.0,
360.0) * D2R;
n =
modulo (125.04452 - 1934.136261 * t + 0.0020708 * t2 + t3 / 450000.0,
360.0) * D2R;
// Compute sums
*dpsi=0.0;
*deps=0.0;
for (i=0;i<106;i++) {
arg=nut[i].nd*d+nut[i].nm*m+nut[i].nm1*m1+nut[i].nf*f+nut[i].nn*n;
*dpsi+=(nut[i].s+nut[i].st*t)*sin(arg);
*deps+=(nut[i].c+nut[i].ct*t)*cos(arg);
*dpsi = 0.0;
*deps = 0.0;
for (i = 0; i < 106; i++)
{
arg =
nut[i].nd * d + nut[i].nm * m + nut[i].nm1 * m1 + nut[i].nf * f +
nut[i].nn * n;
*dpsi += (nut[i].s + nut[i].st * t) * sin (arg);
*deps += (nut[i].c + nut[i].ct * t) * cos (arg);
}
*dpsi*=0.0001/3600*D2R;
*deps*=0.0001/3600*D2R;
*eps=-46.8150*t-0.00059*t2+0.001813*t3;
*eps=(23.4392911+ *eps/3600.0)*D2R;
*dpsi *= 0.0001 / 3600 * D2R;
*deps *= 0.0001 / 3600 * D2R;
*eps = -46.8150 * t - 0.00059 * t2 + 0.001813 * t3;
*eps = (23.4392911 + *eps / 3600.0) * D2R;
return;
}
// Precession
void precess(double mjd0,double mjd,double *zeta,double *z,double *theta)
void
precess (double mjd0, double mjd, double *zeta, double *z, double *theta)
{
double t0,t;
double t0, t;
// Time in centuries
t0=(mjd0-51544.5)/36525.0;
t=(mjd-mjd0)/36525.0;
t0 = (mjd0 - 51544.5) / 36525.0;
t = (mjd - mjd0) / 36525.0;
// Precession angles
*zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t;
*zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t;
*zeta*=D2R/3600.0;
*z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t;
*z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t;
*z*=D2R/3600.0;
*theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t;
*theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t;
*theta*=D2R/3600.0;
*zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t;
*zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t;
*zeta *= D2R / 3600.0;
*z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t;
*z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t;
*z *= D2R / 3600.0;
*theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t;
*theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t;
*theta *= D2R / 3600.0;
return;
}
// Set identity matrix
void identity_matrix(double a[3][3])
void
identity_matrix (double a[3][3])
{
int i,j;
int i, j;
for (i=0;i<3;i++) {
for (j=0;j<3;j++) {
if (i==j)
a[i][j]=1.0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
if (i == j)
a[i][j] = 1.0;
else
a[i][j]=0.0;
a[i][j] = 0.0;
}
}
@ -270,90 +303,96 @@ void identity_matrix(double a[3][3])
}
// Rotate around x-axis
void rotate_x(double phi, double a[3][3])
void
rotate_x (double phi, double a[3][3])
{
double s,c,a10,a11,a12,a20,a21,a22;
double s, c, a10, a11, a12, a20, a21, a22;
s=sin(phi);
c=cos(phi);
s = sin (phi);
c = cos (phi);
a10=c*a[1][0]+s*a[2][0];
a11=c*a[1][1]+s*a[2][1];
a12=c*a[1][2]+s*a[2][2];
a20=-s*a[1][0]+c*a[2][0];
a21=-s*a[1][1]+c*a[2][1];
a22=-s*a[1][2]+c*a[2][2];
a10 = c * a[1][0] + s * a[2][0];
a11 = c * a[1][1] + s * a[2][1];
a12 = c * a[1][2] + s * a[2][2];
a20 = -s * a[1][0] + c * a[2][0];
a21 = -s * a[1][1] + c * a[2][1];
a22 = -s * a[1][2] + c * a[2][2];
a[1][0]=a10;
a[1][1]=a11;
a[1][2]=a12;
a[2][0]=a20;
a[2][1]=a21;
a[2][2]=a22;
a[1][0] = a10;
a[1][1] = a11;
a[1][2] = a12;
a[2][0] = a20;
a[2][1] = a21;
a[2][2] = a22;
return;
}
// Rotate around y-axis
void rotate_y(double phi, double a[3][3])
void
rotate_y (double phi, double a[3][3])
{
double s,c,a00,a01,a02,a20,a21,a22;
double s, c, a00, a01, a02, a20, a21, a22;
s=sin(phi);
c=cos(phi);
s = sin (phi);
c = cos (phi);
a00=c*a[0][0]-s*a[2][0];
a01=c*a[0][1]-s*a[2][1];
a02=c*a[0][2]-s*a[2][2];
a20=s*a[0][0]+c*a[2][0];
a21=s*a[0][1]+c*a[2][1];
a22=s*a[0][2]+c*a[2][2];
a00 = c * a[0][0] - s * a[2][0];
a01 = c * a[0][1] - s * a[2][1];
a02 = c * a[0][2] - s * a[2][2];
a20 = s * a[0][0] + c * a[2][0];
a21 = s * a[0][1] + c * a[2][1];
a22 = s * a[0][2] + c * a[2][2];
a[0][0]=a00;
a[0][1]=a01;
a[0][2]=a02;
a[2][0]=a20;
a[2][1]=a21;
a[2][2]=a22;
a[0][0] = a00;
a[0][1] = a01;
a[0][2] = a02;
a[2][0] = a20;
a[2][1] = a21;
a[2][2] = a22;
return;
}
// Rotate around z-axis
void rotate_z(double phi, double a[3][3])
void
rotate_z (double phi, double a[3][3])
{
double s,c,a00,a01,a02,a10,a11,a12;
double s, c, a00, a01, a02, a10, a11, a12;
s=sin(phi);
c=cos(phi);
s = sin (phi);
c = cos (phi);
a00=c*a[0][0]+s*a[1][0];
a01=c*a[0][1]+s*a[1][1];
a02=c*a[0][2]+s*a[1][2];
a10=-s*a[0][0]+c*a[1][0];
a11=-s*a[0][1]+c*a[1][1];
a12=-s*a[0][2]+c*a[1][2];
a00 = c * a[0][0] + s * a[1][0];
a01 = c * a[0][1] + s * a[1][1];
a02 = c * a[0][2] + s * a[1][2];
a10 = -s * a[0][0] + c * a[1][0];
a11 = -s * a[0][1] + c * a[1][1];
a12 = -s * a[0][2] + c * a[1][2];
a[0][0]=a00;
a[0][1]=a01;
a[0][2]=a02;
a[1][0]=a10;
a[1][1]=a11;
a[1][2]=a12;
a[0][0] = a00;
a[0][1] = a01;
a[0][2] = a02;
a[1][0] = a10;
a[1][1] = a11;
a[1][2] = a12;
return;
}
// Matrix multiply
void matrix_multiply(double a[3][3],double b[3][3],double c[3][3])
void
matrix_multiply (double a[3][3], double b[3][3], double c[3][3])
{
int i,j,k;
int i, j, k;
for (i=0;i<3;i++) {
for (j=0;j<3;j++) {
c[i][j]=0.0;
for (k=0;k<3;k++)
c[i][j]+=a[i][k]*b[k][j];
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
c[i][j] = 0.0;
for (k = 0; k < 3; k++)
c[i][j] += a[i][k] * b[k][j];
}
}
@ -361,230 +400,247 @@ void matrix_multiply(double a[3][3],double b[3][3],double c[3][3])
}
// Vector multiply
void vector_multiply_in_place(double a[3][3],double b[3])
void
vector_multiply_in_place (double a[3][3], double b[3])
{
int i,j,k;
int i, j, k;
double c[3];
for (i=0;i<3;i++) {
c[i]=0.0;
for (j=0;j<3;j++)
c[i]+=a[i][j]*b[j];
for (i = 0; i < 3; i++)
{
c[i] = 0.0;
for (j = 0; j < 3; j++)
c[i] += a[i][j] * b[j];
}
for (i=0;i<3;i++)
b[i]=c[i];
for (i = 0; i < 3; i++)
b[i] = c[i];
return;
}
// Vector multiply
void vector_multiply(double a[3][3],double b[3],double c[3])
void
vector_multiply (double a[3][3], double b[3], double c[3])
{
int i,j,k;
int i, j, k;
for (i=0;i<3;i++) {
c[i]=0.0;
for (j=0;j<3;j++)
c[i]+=a[i][j]*b[j];
for (i = 0; i < 3; i++)
{
c[i] = 0.0;
for (j = 0; j < 3; j++)
c[i] += a[i][j] * b[j];
}
return;
}
// Transpose
void matrix_transpose(double a[3][3],double b[3][3])
void
matrix_transpose (double a[3][3], double b[3][3])
{
int i,j;
int i, j;
for (i=0;i<3;i++)
for (j=0;j<3;j++)
b[i][j]=a[j][i];
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
b[i][j] = a[j][i];
return;
}
// Dot product
double dot_product(double a[3],double b[3])
double
dot_product (double a[3], double b[3])
{
return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
// Magnitude
double magnitude(double a[3])
double
magnitude (double a[3])
{
return sqrt(dot_product(a,a));
return sqrt (dot_product (a, a));
}
// Cross product
void cross_product(double a[3],double b[3],double c[3])
void
cross_product (double a[3], double b[3], double c[3])
{
c[0]=a[1]*b[2]-a[2]*b[1];
c[1]=a[2]*b[0]-a[0]*b[2];
c[2]=a[0]*b[1]-a[1]*b[0];
c[0] = a[1] * b[2] - a[2] * b[1];
c[1] = a[2] * b[0] - a[0] * b[2];
c[2] = a[0] * b[1] - a[1] * b[0];
return;
}
// ICRS to TEME conversion
void icrs_to_teme(double mjd,double a[3][3])
void
icrs_to_teme (double mjd, double a[3][3])
{
int i,j;
double dpsi,deps,eps,z,theta,zeta,h;
double p[3][3],n[3][3],q[3][3],b[3][3];
int i, j;
double dpsi, deps, eps, z, theta, zeta, h;
double p[3][3], n[3][3], q[3][3], b[3][3];
// Precession
precess(51544.5,mjd,&zeta,&z,&theta);
identity_matrix(p);
rotate_z(-zeta,p);
rotate_y(theta,p);
rotate_z(-z,p);
precess (51544.5, mjd, &zeta, &z, &theta);
identity_matrix (p);
rotate_z (-zeta, p);
rotate_y (theta, p);
rotate_z (-z, p);
// Nutation
nutation(mjd,&dpsi,&deps,&eps);
identity_matrix(n);
rotate_x(eps,n);
rotate_z(-dpsi,n);
rotate_x(-eps-deps,n);
nutation (mjd, &dpsi, &deps, &eps);
identity_matrix (n);
rotate_x (eps, n);
rotate_z (-dpsi, n);
rotate_x (-eps - deps, n);
// Equation of equinoxes
identity_matrix(q);
rotate_z(dpsi*cos(eps+deps),q);
identity_matrix (q);
rotate_z (dpsi * cos (eps + deps), q);
// Multiply matrices (left to right)
matrix_multiply(q,n,b);
matrix_multiply(b,p,a);
matrix_multiply (q, n, b);
matrix_multiply (b, p, a);
return;
}
void usage(void)
void
usage (void)
{
printf("tle2rv c:i:t:m:efh\n\n");
printf("-c Catalog to load [classfd.tle]\n");
printf("-i Object to convert [all]\n");
printf("-t Epoch (YYYY-mm-ddThh:mm:ss)\n");
printf("-m Epoch (MJD)\n");
printf("-e Use TLE epoch\n");
printf("-j J2000 output\n");
printf("-g GMAT output (J2000)\n");
printf("-h This help\n");
printf ("tle2rv c:i:t:m:efh\n\n");
printf ("-c Catalog to load [classfd.tle]\n");
printf ("-i Object to convert [all]\n");
printf ("-t Epoch (YYYY-mm-ddThh:mm:ss)\n");
printf ("-m Epoch (MJD)\n");
printf ("-e Use TLE epoch\n");
printf ("-j J2000 output\n");
printf ("-g GMAT output (J2000)\n");
printf ("-h This help\n");
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int imode,arg,satno=0,useepoch=0,format=0,gmat=0;
int imode, arg, satno = 0, useepoch = 0, format = 0, gmat = 0;
FILE *file;
char *env;
char tlefile[LIM],nfd[32];
char tlefile[LIM], nfd[32];
double mjd;
xyz_t r,v;
xyz_t r, v;
orbit_t orb;
double rr[3],vv[3],e[3][3],et[3][3];
double rr[3], vv[3], e[3][3], et[3][3];
// Get environment variable
env=getenv("ST_TLEDIR");
sprintf(tlefile,"%s/classfd.tle",env);
env = getenv ("ST_TLEDIR");
sprintf (tlefile, "%s/classfd.tle", env);
// Set date
nfd_now(nfd);
mjd=nfd2mjd(nfd);
nfd_now (nfd);
mjd = nfd2mjd (nfd);
// Decode options
while ((arg=getopt(argc,argv,"c:i:t:m:hejg"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "c:i:t:m:hejg")) != -1)
{
switch (arg)
{
case 't':
strcpy(nfd,optarg);
mjd=nfd2mjd(nfd);
strcpy (nfd, optarg);
mjd = nfd2mjd (nfd);
break;
case 'm':
mjd=atof(optarg);
mjd = atof (optarg);
break;
case 'e':
useepoch=1;
useepoch = 1;
break;
case 'j':
format=1;
format = 1;
break;
case 'g':
gmat=1;
gmat = 1;
break;
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
// Open file
file=fopen(tlefile,"r");
while (read_twoline(file,satno,&orb)==0) {
file = fopen (tlefile, "r");
while (read_twoline (file, satno, &orb) == 0)
{
// Propagate
imode=init_sgdp4(&orb);
imode = init_sgdp4 (&orb);
// Use epoch instead of user supplied date
if (useepoch==1)
mjd=SGDP4_jd0-2400000.5;
if (useepoch == 1)
mjd = SGDP4_jd0 - 2400000.5;
// Compute position and velocity
imode=satpos_xyz(mjd+2400000.5,&r,&v);
imode = satpos_xyz (mjd + 2400000.5, &r, &v);
// Output
if (format==0 && gmat==0)
printf("%05d %14.8lf %f %f %f %f %f %f TEME\n",orb.satno,mjd,r.x,r.y,r.z,v.x,v.y,v.z);
if (format == 0 && gmat == 0)
printf ("%05d %14.8lf %f %f %f %f %f %f TEME\n", orb.satno, mjd, r.x,
r.y, r.z, v.x, v.y, v.z);
// To vectors
rr[0]=r.x;
rr[1]=r.y;
rr[2]=r.z;
vv[0]=v.x;
vv[1]=v.y;
vv[2]=v.z;
rr[0] = r.x;
rr[1] = r.y;
rr[2] = r.z;
vv[0] = v.x;
vv[1] = v.y;
vv[2] = v.z;
// Matrices
icrs_to_teme(mjd,e);
matrix_transpose(e,et);
icrs_to_teme (mjd, e);
matrix_transpose (e, et);
// Transform
vector_multiply_in_place(et,rr);
vector_multiply_in_place(et,vv);
vector_multiply_in_place (et, rr);
vector_multiply_in_place (et, vv);
// Output J2000
if (format==1 && gmat==0)
printf("%05d %14.8lf %f %f %f %f %f %f J2000\n",orb.satno,mjd,rr[0],rr[1],rr[2],vv[0],vv[1],vv[2]);
if (format == 1 && gmat == 0)
printf ("%05d %14.8lf %f %f %f %f %f %f J2000\n", orb.satno, mjd,
rr[0], rr[1], rr[2], vv[0], vv[1], vv[2]);
// GMAT output
if (gmat==1) {
printf("UTCModJulian = %14.8lf\n",mjd-29999.5);
printf("CoordinateSystem = EarthMJ2000Eq\n");
printf("X = %lf\n",rr[0]);
printf("Y = %lf\n",rr[1]);
printf("Z = %lf\n",rr[2]);
printf("VX = %lf\n",vv[0]);
printf("VY = %lf\n",vv[1]);
printf("VZ = %lf\n",vv[2]);
if (gmat == 1)
{
printf ("UTCModJulian = %14.8lf\n", mjd - 29999.5);
printf ("CoordinateSystem = EarthMJ2000Eq\n");
printf ("X = %lf\n", rr[0]);
printf ("Y = %lf\n", rr[1]);
printf ("Z = %lf\n", rr[2]);
printf ("VX = %lf\n", vv[0]);
printf ("VY = %lf\n", vv[1]);
printf ("VZ = %lf\n", vv[2]);
}
}
fclose(file);
fclose (file);
return 0;
}

View File

@ -17,86 +17,105 @@
extern double SGDP4_jd0;
void usage(void)
void
usage (void)
{
printf("usage: tleinfo [-c TLEFILE] [-u] [|-1|-f] [ |-n|-d] [-i SATNO] [-I INTLDESG ] [ |-a|-b] [-H] [-h]\n\n");
printf
("usage: tleinfo [-c TLEFILE] [-u] [|-1|-f] [ |-n|-d] [-i SATNO] [-I INTLDESG ] [ |-a|-b] [-H] [-h]\n\n");
printf("-c TLEFILE The file containing orbital elements in the form of TLEs, 3 lines per object\n");
printf(" default: ./bulk.tle\n");
printf("-i SATNO Filter only elements for objects with this NORAD catalog identifier\n");
printf("-I INTLDESG Filter only elements for objects with this international designator\n");
printf("-u Show only one object (MODE0 only)\n");
printf
("-c TLEFILE The file containing orbital elements in the form of TLEs, 3 lines per object\n");
printf (" default: ./bulk.tle\n");
printf
("-i SATNO Filter only elements for objects with this NORAD catalog identifier\n");
printf
("-I INTLDESG Filter only elements for objects with this international designator\n");
printf ("-u Show only one object (MODE0 only)\n");
printf("\nSelect MODE:\n");
printf(" MODE0: Show TLEs, object names or COSPAR designations\n");
printf("-1 MODE1: Show list of elements (one line per object)\n");
printf("-f MODE2: Show human-readable parameters\n\n");
printf ("\nSelect MODE:\n");
printf
(" MODE0: Show TLEs, object names or COSPAR designations\n");
printf ("-1 MODE1: Show list of elements (one line per object)\n");
printf ("-f MODE2: Show human-readable parameters\n\n");
printf("Select INFOTYPE\n");
printf("MODE0:\n");
printf(" default Show the TLEs itself\n");
printf(" -n Show only the name of the objects\n");
printf(" -d Show only the COSPAR designation of the objects\n\n");
printf("MODE1:\n");
printf(" default SATNO, YEAR, DOY, INCL, ASCN, ARGP, MA, ECC, MM, BSTAR\n");
printf(" -a SATNO, SEMI, PERIGEE, APOGEE, INCL, PERIOD, ECC\n");
printf(" -b SATNO, YEAR, DOY, INCL, ASCN, ARGP, MA, ECC, MM, floor(MJD), LNG_AT_MIDNIGHT\n\n");
printf ("Select INFOTYPE\n");
printf ("MODE0:\n");
printf (" default Show the TLEs itself\n");
printf (" -n Show only the name of the objects\n");
printf (" -d Show only the COSPAR designation of the objects\n\n");
printf ("MODE1:\n");
printf
(" default SATNO, YEAR, DOY, INCL, ASCN, ARGP, MA, ECC, MM, BSTAR\n");
printf (" -a SATNO, SEMI, PERIGEE, APOGEE, INCL, PERIOD, ECC\n");
printf
(" -b SATNO, YEAR, DOY, INCL, ASCN, ARGP, MA, ECC, MM, floor(MJD), LNG_AT_MIDNIGHT\n\n");
printf("-H Show header (MODE1 only), default: disabled\n");
printf("-h Print usage\n");
printf ("-H Show header (MODE1 only), default: disabled\n");
printf ("-h Print usage\n");
}
double modulo(double x,double y);
double modulo (double x, double y);
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// DOY to MJD
double doy2mjd(int year,double doy)
double
doy2mjd (int year, double doy)
{
int month,k=2;
int month, k = 2;
double day;
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
month=floor(9.0*(k+doy)/275.0+0.98);
month = floor (9.0 * (k + doy) / 275.0 + 0.98);
if (doy<32)
month=1;
if (doy < 32)
month = 1;
day=doy-floor(275.0*month/9.0)+k*floor((month+9.0)/12.0)+30.0;
day =
doy - floor (275.0 * month / 9.0) + k * floor ((month + 9.0) / 12.0) +
30.0;
return date2mjd(year,month,day);
return date2mjd (year, month, day);
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
// if (c == '\n')
// s[i++] = c;
@ -104,204 +123,221 @@ int fgetline(FILE *file,char *s,int lim)
return i;
}
void orbit(orbit_t orb,float *aodp,float *perigee,float *apogee,float *period)
void
orbit (orbit_t orb, float *aodp, float *perigee, float *apogee, float *period)
{
float xno,eo,xincl;
float a1,betao2,betao,temp0,del1,a0,del0,xnodp;
float xno, eo, xincl;
float a1, betao2, betao, temp0, del1, a0, del0, xnodp;
xno=orb.rev*2.0*M_PI/XMNPDA;
eo=orb.ecc;
xincl=orb.eqinc;
xno = orb.rev * 2.0 * M_PI / XMNPDA;
eo = orb.ecc;
xincl = orb.eqinc;
a1 = pow(XKE / xno, 2.0/3.0);
a1 = pow (XKE / xno, 2.0 / 3.0);
betao2 = 1.0 - eo * eo;
betao = sqrt(betao2);
temp0 = (1.5 * CK2) * cos(xincl)*cos(xincl) / (betao * betao2);
betao = sqrt (betao2);
temp0 = (1.5 * CK2) * cos (xincl) * cos (xincl) / (betao * betao2);
del1 = temp0 / (a1 * a1);
a0 = a1 * (1.0 - del1 * (1.0/3.0 + del1 * (1.0 + del1 * 134.0/81.0)));
a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0)));
del0 = temp0 / (a0 * a0);
xnodp = xno / (1.0 + del0);
*aodp = (a0 / (1.0 - del0));
*perigee = (*aodp * (1.0 - eo) - 1) * XKMPER;
*apogee = (*aodp * (1.0 + eo) - 1) * XKMPER;
*period = (TWOPI * 1440.0 / XMNPDA) / xnodp;
*aodp=(*aodp-1)*XKMPER;
*aodp = (*aodp - 1) * XKMPER;
return;
}
// Compute Date from Julian Day
void mjd2nfd(double mjd,char *nfd)
void
mjd2nfd (double mjd, char *nfd)
{
double f,jd,dday;
int z,alpha,a,b,c,d,e;
int year,month,day,hour,min;
float sec,x;
double f, jd, dday;
int z, alpha, a, b, c, d, e;
int year, month, day, hour, min;
float sec, x;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
dday=b-d-floor(30.6001*e)+f;
if (e<14)
month=e-1;
dday = b - d - floor (30.6001 * e) + f;
if (e < 14)
month = e - 1;
else
month=e-13;
month = e - 13;
if (month>2)
year=c-4716;
if (month > 2)
year = c - 4716;
else
year=c-4715;
year = c - 4715;
day=(int) floor(dday);
x=24.0*(dday-day);
x=3600.*fabs(x);
sec=fmod(x,60.);
x=(x-sec)/60.;
min=fmod(x,60.);
x=(x-min)/60.;
hour=x;
sec=floor(1000.0*sec)/1000.0;
day = (int) floor (dday);
x = 24.0 * (dday - day);
x = 3600. * fabs (x);
sec = fmod (x, 60.);
x = (x - sec) / 60.;
min = fmod (x, 60.);
x = (x - min) / 60.;
hour = x;
sec = floor (1000.0 * sec) / 1000.0;
sprintf(nfd,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec);
sprintf (nfd, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour,
min, sec);
return;
}
float orbital_longitude_at_midnight(orbit_t orb,double mjd0)
float
orbital_longitude_at_midnight (orbit_t orb, double mjd0)
{
int rv,imode;
double jd,tsince,mjd;
int rv, imode;
double jd, tsince, mjd;
kep_t K;
imode=init_sgdp4(&orb);
imode = init_sgdp4 (&orb);
mjd=floor(mjd0);
mjd = floor (mjd0);
jd=mjd+2400000.5;
tsince=1440.0*(jd-SGDP4_jd0);
rv=sgdp4(tsince,1,&K);
jd = mjd + 2400000.5;
tsince = 1440.0 * (jd - SGDP4_jd0);
rv = sgdp4 (tsince, 1, &K);
return modulo(K.theta*R2D,360.0);
return modulo (K.theta * R2D, 360.0);
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int arg=0,satno=0,header=0,oneline=0,no,name=0,desig=0,has_intldesg=0;
int arg = 0, satno = 0, header = 0, oneline = 0, no, name = 0, desig =
0, has_intldesg = 0;
char tlefile[LIM];
char line0[LIM],line1[LIM],line2[LIM],nfd[32],intldesg[16]="",desg[16]="";
char line0[LIM], line1[LIM], line2[LIM], nfd[32], intldesg[16] =
"", desg[16] = "";
FILE *file;
orbit_t orb;
float aodp,perigee,apogee,period,lng;
int info=0,unique=0;
float aodp, perigee, apogee, period, lng;
int info = 0, unique = 0;
double mjd;
char *env;
env=getenv("ST_TLEDIR");
sprintf(tlefile,"%s/bulk.tle",env);
env = getenv ("ST_TLEDIR");
sprintf (tlefile, "%s/bulk.tle", env);
// Decode options
while ((arg=getopt(argc,argv,"c:i:I:aH1ftndbu"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "c:i:I:aH1ftndbu")) != -1)
{
switch (arg)
{
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 'u':
unique=1;
unique = 1;
break;
case '1':
oneline=1;
oneline = 1;
break;
case 'f':
oneline=2;
oneline = 2;
break;
case 'n':
name=1;
name = 1;
break;
case 'd':
desig=1;
desig = 1;
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'I':
strcpy(intldesg,optarg);
has_intldesg=1;
strcpy (intldesg, optarg);
has_intldesg = 1;
break;
case 'a':
info=1;
info = 1;
break;
case 'b':
info=2;
info = 2;
break;
case 'H':
header=1;
header = 1;
break;
case 'h':
usage();
usage ();
return 0;
break;
default:
usage();
usage ();
return 0;
}
}
if (oneline==0) {
if (oneline == 0)
{
// Open file
file=fopen(tlefile,"rb");
if (file==NULL)
fatal_error("File open failed for reading \"%s\"",tlefile);
file = fopen (tlefile, "rb");
if (file == NULL)
fatal_error ("File open failed for reading \"%s\"", tlefile);
while (fgetline(file,line1,LIM)>0) {
while (fgetline (file, line1, LIM) > 0)
{
// Find TLE line
if (line1[0]=='1') {
fgetline(file,line2,LIM);
sscanf(line1+2,"%d",&no);
sscanf(line1+9,"%s",&desg);
if (line1[0] == '1')
{
fgetline (file, line2, LIM);
sscanf (line1 + 2, "%d", &no);
sscanf (line1 + 9, "%s", &desg);
if ((satno==0 || satno==no) && (has_intldesg==0)) {
if (name==1 && desig==0)
printf("%s\n",line0);
else if (name==0 && desig==1)
printf("%.8s\n",line1+9);
if ((satno == 0 || satno == no) && (has_intldesg == 0))
{
if (name == 1 && desig == 0)
printf ("%s\n", line0);
else if (name == 0 && desig == 1)
printf ("%.8s\n", line1 + 9);
else
printf("%s\n%s\n%s\n",line0,line1,line2);
if (unique==1)
printf ("%s\n%s\n%s\n", line0, line1, line2);
if (unique == 1)
break;
} else if (has_intldesg==1) {
if (strcmp(desg,intldesg)==0) {
printf("%s\n%s\n%s\n",line0,line1,line2);
}
else if (has_intldesg == 1)
{
if (strcmp (desg, intldesg) == 0)
{
printf ("%s\n%s\n%s\n", line0, line1, line2);
}
}
}
strcpy(line0,line1);
strcpy (line0, line1);
}
/*
@ -330,56 +366,78 @@ int main(int argc,char *argv[])
}
}
*/
fclose(file);
} else if (oneline==1) {
fclose (file);
}
else if (oneline == 1)
{
// Open file
file=fopen(tlefile,"rb");
if (file==NULL)
fatal_error("File open failed for reading \"%s\"",tlefile);
file = fopen (tlefile, "rb");
if (file == NULL)
fatal_error ("File open failed for reading \"%s\"", tlefile);
if (header==1) {
if (info==0)
printf("SATNO YEAR DOY INCL ASCN ARGP MA ECC MM BSTAR\n");
else if (info==1)
printf("SATNO SEMI PERIGEE APOGEE PERIOD ECC\n");
else if (info==2)
printf("SATNO YEAR DOY INCL ASCN ARGP MA ECC MM floor(MJD) LNG_AT_MIDNIGHT\n");
if (header == 1)
{
if (info == 0)
printf
("SATNO YEAR DOY INCL ASCN ARGP MA ECC MM BSTAR\n");
else if (info == 1)
printf ("SATNO SEMI PERIGEE APOGEE PERIOD ECC\n");
else if (info == 2)
printf
("SATNO YEAR DOY INCL ASCN ARGP MA ECC MM floor(MJD) LNG_AT_MIDNIGHT\n");
}
// Loop over file
while (read_twoline(file,satno,&orb)==0) {
orbit(orb,&aodp,&perigee,&apogee,&period);
mjd=doy2mjd(orb.ep_year,orb.ep_day);
mjd2nfd(mjd,nfd);
if (info==0) printf("%05d %10.4lf %8.4f %8.4f %8.4f %8.4f %8.6f %8.5f %e\n",orb.satno,mjd,DEG(orb.eqinc),DEG(orb.ascn),DEG(orb.argp),DEG(orb.mnan),orb.ecc,orb.rev,orb.bstar);
if (info==1) printf("%05d %6.0f x %6.0f x %6.2f %8.2f %8.6f %14.8lf\n",orb.satno,perigee,apogee,DEG(orb.eqinc),period,orb.ecc,mjd);
if (info==2) {
lng=orbital_longitude_at_midnight(orb,mjd);
printf("%05d %10.4lf %8.4f %8.4f %8.4f %8.4f %8.6f %8.5f %10.4lf %8.4f\n",orb.satno,mjd,DEG(orb.eqinc),DEG(orb.ascn),DEG(orb.argp),DEG(orb.mnan),orb.ecc,orb.rev,floor(mjd),lng);
while (read_twoline (file, satno, &orb) == 0)
{
orbit (orb, &aodp, &perigee, &apogee, &period);
mjd = doy2mjd (orb.ep_year, orb.ep_day);
mjd2nfd (mjd, nfd);
if (info == 0)
printf ("%05d %10.4lf %8.4f %8.4f %8.4f %8.4f %8.6f %8.5f %e\n",
orb.satno, mjd, DEG (orb.eqinc), DEG (orb.ascn),
DEG (orb.argp), DEG (orb.mnan), orb.ecc, orb.rev,
orb.bstar);
if (info == 1)
printf ("%05d %6.0f x %6.0f x %6.2f %8.2f %8.6f %14.8lf\n",
orb.satno, perigee, apogee, DEG (orb.eqinc), period,
orb.ecc, mjd);
if (info == 2)
{
lng = orbital_longitude_at_midnight (orb, mjd);
printf
("%05d %10.4lf %8.4f %8.4f %8.4f %8.4f %8.6f %8.5f %10.4lf %8.4f\n",
orb.satno, mjd, DEG (orb.eqinc), DEG (orb.ascn),
DEG (orb.argp), DEG (orb.mnan), orb.ecc, orb.rev,
floor (mjd), lng);
}
}
fclose(file);
} else if (oneline==2) {
fclose (file);
}
else if (oneline == 2)
{
// Open file
file=fopen(tlefile,"rb");
if (file==NULL)
fatal_error("File open failed for reading \"%s\"",tlefile);
file = fopen (tlefile, "rb");
if (file == NULL)
fatal_error ("File open failed for reading \"%s\"", tlefile);
// Loop over file
while (read_twoline(file,satno,&orb)==0)
print_orb(&orb);
while (read_twoline (file, satno, &orb) == 0)
print_orb (&orb);
fclose(file);
fclose (file);
}
return 0;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}

View File

@ -6,159 +6,171 @@
#define LIM 128
int fgetline(FILE *file,char *s,int lim);
int find_satno(char *desig0)
int fgetline (FILE * file, char *s, int lim);
int
find_satno (char *desig0)
{
FILE *file;
int satno=99999,status;
int satno = 99999, status;
char desig[16];
char *env,filename[LIM];
char *env, filename[LIM];
env=getenv("ST_DATADIR");
sprintf(filename,"%s/data/desig.txt",env);
file=fopen(filename,"r");
if (file==NULL) {
fprintf(stderr,"Designation file not found!\n");
exit(0);
env = getenv ("ST_DATADIR");
sprintf (filename, "%s/data/desig.txt", env);
file = fopen (filename, "r");
if (file == NULL)
{
fprintf (stderr, "Designation file not found!\n");
exit (0);
}
while (!feof(file)) {
status=fscanf(file,"%d %s",&satno,desig);
if (strcmp(desig,desig0)==0)
while (!feof (file))
{
status = fscanf (file, "%d %s", &satno, desig);
if (strcmp (desig, desig0) == 0)
break;
}
fclose(file);
fclose (file);
return satno;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
FILE *file;
char line[LIM];
int intidy,intido,piece,site,year,month,day,hour,min,sec,fsec,satno;
char desig[16],pdesig[16];
int format,epoch;
float csec,cang,x;
int rah,ram,rafm,ded,dem,defm;
float tm,tx,am,ax;
int intidy, intido, piece, site, year, month, day, hour, min, sec, fsec,
satno;
char desig[16], pdesig[16];
int format, epoch;
float csec, cang, x;
int rah, ram, rafm, ded, dem, defm;
float tm, tx, am, ax;
char sign;
file=fopen(argv[1],"r");
while (fgetline(file,line,LIM)>0) {
file = fopen (argv[1], "r");
while (fgetline (file, line, LIM) > 0)
{
// Skip wrong lines
if (!isdigit(line[0]))
if (!isdigit (line[0]))
continue;
// Skip short lines
if (strlen(line)<55)
if (strlen (line) < 55)
continue;
// Scan line
sscanf(line,"%02d%03d%02d%04d%02d%02d%02d%02d%02d%02d%03d",&intidy,&intido,
&piece,
&site,
&year,
&month,
&day,
&hour,
&min,
&sec,
sscanf (line, "%02d%03d%02d%04d%02d%02d%02d%02d%02d%02d%03d", &intidy,
&intido, &piece, &site, &year, &month, &day, &hour, &min, &sec,
&fsec);
sscanf(line+27,"%f",&csec);
sscanf(line+33,"%1d",&format);
if (format==2) {
sscanf(line+34,"%02d%02d%d",&rah,&ram,&rafm);
sscanf(line+42,"%c%02d%02d%d",&sign,&ded,&dem,&defm);
} else if (format==3) {
sscanf(line+34,"%02d%02d%d",&rah,&ram,&rafm);
sscanf(line+42,"%c%02d%02d",&sign,&ded,&dem);
sscanf (line + 27, "%f", &csec);
sscanf (line + 33, "%1d", &format);
if (format == 2)
{
sscanf (line + 34, "%02d%02d%d", &rah, &ram, &rafm);
sscanf (line + 42, "%c%02d%02d%d", &sign, &ded, &dem, &defm);
}
sscanf(line+50,"%f",&cang);
sscanf(line+54,"%d",&epoch);
else if (format == 3)
{
sscanf (line + 34, "%02d%02d%d", &rah, &ram, &rafm);
sscanf (line + 42, "%c%02d%02d", &sign, &ded, &dem);
}
sscanf (line + 50, "%f", &cang);
sscanf (line + 54, "%d", &epoch);
// Year switch
if (year>50)
year+=1900;
if (year > 50)
year += 1900;
else
year+=2000;
year += 2000;
// Format designation
if (piece<26) {
sprintf(desig,"%02d %03d%c",intidy,intido,piece+'A'-1);
sprintf(pdesig,"%02d%03d%c",intidy,intido,piece+'A'-1);
} else {
fprintf(stderr,"Failed to understand designation!\n");
fprintf(stderr,"%s\n",line);
if (piece < 26)
{
sprintf (desig, "%02d %03d%c", intidy, intido, piece + 'A' - 1);
sprintf (pdesig, "%02d%03d%c", intidy, intido, piece + 'A' - 1);
}
else
{
fprintf (stderr, "Failed to understand designation!\n");
fprintf (stderr, "%s\n", line);
continue;
}
// Test data format
if (format==3) {
x=dem*0.6;
dem=(int) floor(x);
defm=(int) (100.0*(x-dem));
} else if (format!=2) {
fprintf(stderr,"Angle format not implemented!\n");
fprintf(stderr,"%s\n",line);
if (format == 3)
{
x = dem * 0.6;
dem = (int) floor (x);
defm = (int) (100.0 * (x - dem));
}
else if (format != 2)
{
fprintf (stderr, "Angle format not implemented!\n");
fprintf (stderr, "%s\n", line);
continue;
}
// Fractional seconds
if (fsec<10)
fsec*=100;
else if (fsec<100)
fsec*=10;
if (fsec < 10)
fsec *= 100;
else if (fsec < 100)
fsec *= 10;
// Time accuracy
if (csec<10)
csec*=0.1;
else if (csec<100)
csec*=0.01;
tx=floor(log10(csec))+8;
tm=floor(csec/pow(10.0,tx-8));
if (csec < 10)
csec *= 0.1;
else if (csec < 100)
csec *= 0.01;
tx = floor (log10 (csec)) + 8;
tm = floor (csec / pow (10.0, tx - 8));
// angle accuracy
if (cang<10)
cang*=1;
else if (cang<100)
cang*=0.1;
ax=floor(log10(cang))+8;
am=floor(cang/pow(10.0,ax-8));
if (cang < 10)
cang *= 1;
else if (cang < 100)
cang *= 0.1;
ax = floor (log10 (cang)) + 8;
am = floor (cang / pow (10.0, ax - 8));
// Fractional RA
if (rafm<10)
rafm*=100;
else if (rafm<100)
rafm*=10;
if (rafm < 10)
rafm *= 100;
else if (rafm < 100)
rafm *= 10;
// Fractional DE
if (defm<10)
defm*=10;
else if (defm<100)
defm*=1;
if (defm < 10)
defm *= 10;
else if (defm < 100)
defm *= 1;
// Get satellite number
satno=find_satno(pdesig);
satno = find_satno (pdesig);
// Format IOD line
printf("%05d %s %04d G %04d%02d%02d%02d%02d%02d%03d %1.0f%1.0f %d%d ",satno,desig,site,year,month,day,hour,min,sec,fsec,tm,tx,format,epoch);
printf("%02d%02d%03d%c%02d%02d%02d %1.0f%1.0f\n",rah,ram,rafm,sign,ded,dem,defm,am,ax);
printf
("%05d %s %04d G %04d%02d%02d%02d%02d%02d%03d %1.0f%1.0f %d%d ",
satno, desig, site, year, month, day, hour, min, sec, fsec, tm, tx,
format, epoch);
printf ("%02d%02d%03d%c%02d%02d%02d %1.0f%1.0f\n", rah, ram, rafm, sign,
ded, dem, defm, am, ax);
}
fclose(file);
fclose (file);
return 0;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}

View File

@ -18,435 +18,491 @@
extern double SGDP4_jd0;
// Dot product
float dot(xyz_t a,xyz_t b)
float
dot (xyz_t a, xyz_t b)
{
return a.x*b.x+a.y*b.y+a.z*b.z;
return a.x * b.x + a.y * b.y + a.z * b.z;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
double
modulo (double x, double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
x = fmod (x, y);
if (x < 0.0)
x += y;
return x;
}
// Magnitude
double magnitude(xyz_t a)
double
magnitude (xyz_t a)
{
return sqrt(dot(a,a));
return sqrt (dot (a, a));
}
// Cross product
xyz_t cross(xyz_t a,xyz_t b)
xyz_t
cross (xyz_t a, xyz_t b)
{
xyz_t c;
c.x=a.y*b.z-a.z*b.y;
c.y=a.z*b.x-a.x*b.z;
c.z=a.x*b.y-a.y*b.x;
c.x = a.y * b.z - a.z * b.y;
c.y = a.z * b.x - a.x * b.z;
c.z = a.x * b.y - a.y * b.x;
return c;
}
// Compute Date from Julian Day
void mjd2date(double mjd,int *year,int *month,double *day)
void
mjd2date (double mjd, int *year, int *month, double *day)
{
double f,jd;
int z,alpha,a,b,c,d,e;
double f, jd;
int z, alpha, a, b, c, d, e;
jd=mjd+2400000.5;
jd+=0.5;
jd = mjd + 2400000.5;
jd += 0.5;
z=floor(jd);
f=fmod(jd,1.);
z = floor (jd);
f = fmod (jd, 1.);
if (z<2299161)
a=z;
else {
alpha=floor((z-1867216.25)/36524.25);
a=z+1+alpha-floor(alpha/4.);
if (z < 2299161)
a = z;
else
{
alpha = floor ((z - 1867216.25) / 36524.25);
a = z + 1 + alpha - floor (alpha / 4.);
}
b=a+1524;
c=floor((b-122.1)/365.25);
d=floor(365.25*c);
e=floor((b-d)/30.6001);
b = a + 1524;
c = floor ((b - 122.1) / 365.25);
d = floor (365.25 * c);
e = floor ((b - d) / 30.6001);
*day=b-d-floor(30.6001*e)+f;
if (e<14)
*month=e-1;
*day = b - d - floor (30.6001 * e) + f;
if (e < 14)
*month = e - 1;
else
*month=e-13;
*month = e - 13;
if (*month>2)
*year=c-4716;
if (*month > 2)
*year = c - 4716;
else
*year=c-4715;
*year = c - 4715;
return;
}
// MJD to DOY
double mjd2doy(double mjd,int *yr)
double
mjd2doy (double mjd, int *yr)
{
int year,month,k=2;
double day,doy;
int year, month, k = 2;
double day, doy;
mjd2date(mjd,&year,&month,&day);
mjd2date (mjd, &year, &month, &day);
if (year%4==0 && year%400!=0)
k=1;
if (year % 4 == 0 && year % 400 != 0)
k = 1;
doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30;
doy =
floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30;
*yr=year;
*yr = year;
return doy;
}
// Clasical elements
orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v)
orbit_t
classel (int ep_year, double ep_day, xyz_t r, xyz_t v)
{
int i;
double rm,vm,vm2,rvm,mu=1.0;;
double chi,xp,yp,sx,cx,b,ee;
double a,ecc,incl,node,peri,mm,n;
xyz_t h,e,kk,nn;
double rm, vm, vm2, rvm, mu = 1.0;;
double chi, xp, yp, sx, cx, b, ee;
double a, ecc, incl, node, peri, mm, n;
xyz_t h, e, kk, nn;
orbit_t orb;
r.x/=XKMPER;
r.y/=XKMPER;
r.z/=XKMPER;
v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0);
v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0);
v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0);
r.x /= XKMPER;
r.y /= XKMPER;
r.z /= XKMPER;
v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0);
rm=magnitude(r);
vm2=dot(v,v);
rvm=dot(r,v);
h=cross(r,v);
chi=dot(h,h)/mu;
rm = magnitude (r);
vm2 = dot (v, v);
rvm = dot (r, v);
h = cross (r, v);
chi = dot (h, h) / mu;
e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x;
e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y;
e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z;
e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x;
e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y;
e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z;
a=pow(2.0/rm-vm2/mu,-1);
ecc=magnitude(e);
incl=acos(h.z/magnitude(h))*R2D;
a = pow (2.0 / rm - vm2 / mu, -1);
ecc = magnitude (e);
incl = acos (h.z / magnitude (h)) * R2D;
kk.x=0.0;
kk.y=0.0;
kk.z=1.0;
nn=cross(kk,h);
if (nn.x==0.0 && nn.y==0.0)
nn.x=1.0;
node=atan2(nn.y,nn.x)*R2D;
if (node<0.0)
node+=360.0;
kk.x = 0.0;
kk.y = 0.0;
kk.z = 1.0;
nn = cross (kk, h);
if (nn.x == 0.0 && nn.y == 0.0)
nn.x = 1.0;
node = atan2 (nn.y, nn.x) * R2D;
if (node < 0.0)
node += 360.0;
peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D;
if (e.z<0.0)
peri=360.0-peri;
if (peri<0.0)
peri+=360.0;
peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D;
if (e.z < 0.0)
peri = 360.0 - peri;
if (peri < 0.0)
peri += 360.0;
// Elliptic motion
if (ecc<1.0) {
xp=(chi-rm)/ecc;
yp=rvm/ecc*sqrt(chi/mu);
b=a*sqrt(1.0-ecc*ecc);
cx=xp/a+ecc;
sx=yp/b;
ee=atan2(sx,cx);
n=XKE*sqrt(mu/(a*a*a));
mm=(ee-ecc*sx)*R2D;
if (ecc < 1.0)
{
xp = (chi - rm) / ecc;
yp = rvm / ecc * sqrt (chi / mu);
b = a * sqrt (1.0 - ecc * ecc);
cx = xp / a + ecc;
sx = yp / b;
ee = atan2 (sx, cx);
n = XKE * sqrt (mu / (a * a * a));
mm = (ee - ecc * sx) * R2D;
}
if (mm<0.0)
mm+=360.0;
if (mm < 0.0)
mm += 360.0;
// Fill
orb.satno=0;
orb.eqinc=incl*D2R;
orb.ascn=node*D2R;
orb.argp=peri*D2R;
orb.mnan=mm*D2R;
orb.ecc=ecc;
orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI);
orb.bstar=0.0;
orb.ep_year=ep_year;
orb.ep_day=ep_day;
orb.norb=0;
orb.satno = 0;
orb.eqinc = incl * D2R;
orb.ascn = node * D2R;
orb.argp = peri * D2R;
orb.mnan = mm * D2R;
orb.ecc = ecc;
orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI);
orb.bstar = 0.0;
orb.ep_year = ep_year;
orb.ep_day = ep_day;
orb.norb = 0;
return orb;
}
orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0)
orbit_t
rv2el (int satno, double mjd, xyz_t r0, xyz_t v0)
{
int i,imode;
orbit_t orb[5],orb1[5];
xyz_t r,v;
int i, imode;
orbit_t orb[5], orb1[5];
xyz_t r, v;
kep_t kep;
char line1[70],line2[70];
char line1[70], line2[70];
int ep_year;
double ep_day;
// Epoch
ep_day=mjd2doy(mjd,&ep_year);
ep_day = mjd2doy (mjd, &ep_year);
// Initial guess
orb[0]=classel(ep_year,ep_day,r0,v0);
orb[0].satno=satno;
orb[0] = classel (ep_year, ep_day, r0, v0);
orb[0].satno = satno;
for (i=0;i<4;i++) {
for (i = 0; i < 4; i++)
{
// Propagate
imode=init_sgdp4(&orb[i]);
imode=satpos_xyz(mjd+2400000.5,&r,&v);
imode = init_sgdp4 (&orb[i]);
imode = satpos_xyz (mjd + 2400000.5, &r, &v);
// Compute initial orbital elements
orb1[i]=classel(ep_year,ep_day,r,v);
orb1[i] = classel (ep_year, ep_day, r, v);
// Adjust
orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev;
orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn;
orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp;
orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan;
orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc;
orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc;
orb[i+1].ep_year=orb[i].ep_year;
orb[i+1].ep_day=orb[i].ep_day;
orb[i+1].satno=orb[i].satno;
orb[i+1].norb=orb[i].norb;
orb[i+1].bstar=orb[i].bstar;
orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev;
orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn;
orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp;
orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan;
orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc;
orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc;
orb[i + 1].ep_year = orb[i].ep_year;
orb[i + 1].ep_day = orb[i].ep_day;
orb[i + 1].satno = orb[i].satno;
orb[i + 1].norb = orb[i].norb;
orb[i + 1].bstar = orb[i].bstar;
// Keep in range
if (orb[i+1].ecc<0.0)
orb[i+1].ecc=0.0;
if (orb[i+1].eqinc<0.0)
orb[i+1].eqinc=0.0;
if (orb[i + 1].ecc < 0.0)
orb[i + 1].ecc = 0.0;
if (orb[i + 1].eqinc < 0.0)
orb[i + 1].eqinc = 0.0;
}
orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI);
orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI);
orb[i].argp=modulo(orb[i].argp,2.0*M_PI);
orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI);
orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI);
orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI);
return orb[i];
}
// Format TLE
void format_tle(orbit_t orb,char *line1,char *line2)
void
format_tle (orbit_t orb, char *line1, char *line2)
{
int i,csum;
char sbstar[]=" 00000-0",bstar[13];
int i, csum;
char sbstar[] = " 00000-0", bstar[13];
// Format Bstar term
if (fabs(orb.bstar)>1e-9) {
sprintf(bstar,"%11.4e",10*orb.bstar);
sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4];
sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0';
if (fabs (orb.bstar) > 1e-9)
{
sprintf (bstar, "%11.4e", 10 * orb.bstar);
sbstar[0] = bstar[0];
sbstar[1] = bstar[1];
sbstar[2] = bstar[3];
sbstar[3] = bstar[4];
sbstar[4] = bstar[5];
sbstar[5] = bstar[6];
sbstar[6] = bstar[8];
sbstar[7] = bstar[10];
sbstar[8] = '\0';
}
// Print lines
sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar);
sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev);
sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",
orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar);
sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",
orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc,
DEG (orb.argp), DEG (orb.mnan), orb.rev);
// Compute checksums
for (i=0,csum=0;i<strlen(line1);i++) {
if (isdigit(line1[i]))
csum+=line1[i]-'0';
else if (line1[i]=='-')
for (i = 0, csum = 0; i < strlen (line1); i++)
{
if (isdigit (line1[i]))
csum += line1[i] - '0';
else if (line1[i] == '-')
csum++;
}
sprintf(line1,"%s%d",line1,csum%10);
for (i=0,csum=0;i<strlen(line2);i++) {
if (isdigit(line2[i]))
csum+=line2[i]-'0';
else if (line2[i]=='-')
sprintf (line1, "%s%d", line1, csum % 10);
for (i = 0, csum = 0; i < strlen (line2); i++)
{
if (isdigit (line2[i]))
csum += line2[i] - '0';
else if (line2[i] == '-')
csum++;
}
sprintf(line2,"%s%d",line2,csum%10);
sprintf (line2, "%s%d", line2, csum % 10);
return;
}
// Present nfd
void nfd_now(char *s)
void
nfd_now (char *s)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
time(&rawtime);
ptm=gmtime(&rawtime);
time (&rawtime);
ptm = gmtime (&rawtime);
sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900,
ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min,
ptm->tm_sec);
return;
}
// Compute Julian Day from Date
double date2mjd(int year,int month,double day)
double
date2mjd (int year, int month, double day)
{
int a,b;
int a, b;
double jd;
if (month<3) {
if (month < 3)
{
year--;
month+=12;
month += 12;
}
a=floor(year/100.);
b=2.-a+floor(a/4.);
a = floor (year / 100.);
b = 2. - a + floor (a / 4.);
if (year<1582) b=0;
if (year==1582 && month<10) b=0;
if (year==1582 && month==10 && day<=4) b=0;
if (year < 1582)
b = 0;
if (year == 1582 && month < 10)
b = 0;
if (year == 1582 && month == 10 && day <= 4)
b = 0;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
jd =
floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b -
1524.5;
return jd-2400000.5;
return jd - 2400000.5;
}
// nfd2mjd
double nfd2mjd(char *date)
double
nfd2mjd (char *date)
{
int year,month,day,hour,min,sec;
double mjd,dday;
int year, month, day, hour, min, sec;
double mjd, dday;
sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec);
dday=day+hour/24.0+min/1440.0+sec/86400.0;
sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour,
&min, &sec);
dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0;
mjd=date2mjd(year,month,dday);
mjd = date2mjd (year, month, dday);
return mjd;
}
void usage(void)
void
usage (void)
{
printf("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n");
printf
("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n");
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int imode,satno=0,arg,satnomin,flag=0,satnonew=-1;
int imode, satno = 0, arg, satnomin, flag = 0, satnonew = -1;
FILE *file;
orbit_t orb;
xyz_t r,v,n,dv;
char tlefile[LIM],nfd[32];
char line1[80],line2[80],desig[20];
double mjd,ra,de,dr,drmin;
float vadd=0.0;
char direction[16]="radial";
xyz_t r, v, n, dv;
char tlefile[LIM], nfd[32];
char line1[80], line2[80], desig[20];
double mjd, ra, de, dr, drmin;
float vadd = 0.0;
char direction[16] = "radial";
char *env;
// Get environment variable
env=getenv("ST_TLEDIR");
sprintf(tlefile,"%s/classfd.tle",env);
env = getenv ("ST_TLEDIR");
sprintf (tlefile, "%s/classfd.tle", env);
// Set date
nfd_now(nfd);
mjd=nfd2mjd(nfd);
nfd_now (nfd);
mjd = nfd2mjd (nfd);
// Decode options
while ((arg=getopt(argc,argv,"c:i:t:m:hv:d:I:"))!=-1) {
switch (arg) {
while ((arg = getopt (argc, argv, "c:i:t:m:hv:d:I:")) != -1)
{
switch (arg)
{
case 't':
strcpy(nfd,optarg);
mjd=nfd2mjd(nfd);
strcpy (nfd, optarg);
mjd = nfd2mjd (nfd);
break;
case 'm':
mjd=(double) atof(optarg);
mjd = (double) atof (optarg);
break;
case 'c':
strcpy(tlefile,optarg);
strcpy (tlefile, optarg);
break;
case 'i':
satno=atoi(optarg);
satno = atoi (optarg);
break;
case 'h':
usage();
usage ();
return 0;
break;
case 'v':
vadd=atof(optarg);
vadd = atof (optarg);
break;
case 'd':
strcpy(direction,optarg);
strcpy (direction, optarg);
break;
case 'I':
satnonew=atoi(optarg);
satnonew = atoi (optarg);
break;
default:
usage();
usage ();
return 0;
}
}
// Reloop stderr
freopen("/tmp/stderr.txt","w",stderr);
freopen ("/tmp/stderr.txt", "w", stderr);
// Open file
file=fopen(tlefile,"r");
while (read_twoline(file,satno,&orb)==0) {
format_tle(orb,line1,line2);
strcpy(desig,orb.desig);
file = fopen (tlefile, "r");
while (read_twoline (file, satno, &orb) == 0)
{
format_tle (orb, line1, line2);
strcpy (desig, orb.desig);
// Propagate
imode=init_sgdp4(&orb);
imode=satpos_xyz(mjd+2400000.5,&r,&v);
imode = init_sgdp4 (&orb);
imode = satpos_xyz (mjd + 2400000.5, &r, &v);
// Compute normal
n=cross(r,v);
n = cross (r, v);
// Add velocity
if (strcmp(direction,"prograde")==0) {
dv.x=vadd*v.x/magnitude(v);
dv.y=vadd*v.y/magnitude(v);
dv.z=vadd*v.z/magnitude(v);
} else if (strcmp(direction,"radial")==0) {
dv.x=vadd*r.x/magnitude(r);
dv.y=vadd*r.y/magnitude(r);
dv.z=vadd*r.z/magnitude(r);
} else if (strcmp(direction,"normal")==0) {
dv.x=vadd*n.x/magnitude(n);
dv.y=vadd*n.y/magnitude(n);
dv.z=vadd*n.z/magnitude(n);
} else {
dv.x=0.0;
dv.y=0.0;
dv.z=0.0;
if (strcmp (direction, "prograde") == 0)
{
dv.x = vadd * v.x / magnitude (v);
dv.y = vadd * v.y / magnitude (v);
dv.z = vadd * v.z / magnitude (v);
}
v.x+=dv.x/1000.0;
v.y+=dv.y/1000.0;
v.z+=dv.z/1000.0;
else if (strcmp (direction, "radial") == 0)
{
dv.x = vadd * r.x / magnitude (r);
dv.y = vadd * r.y / magnitude (r);
dv.z = vadd * r.z / magnitude (r);
}
else if (strcmp (direction, "normal") == 0)
{
dv.x = vadd * n.x / magnitude (n);
dv.y = vadd * n.y / magnitude (n);
dv.z = vadd * n.z / magnitude (n);
}
else
{
dv.x = 0.0;
dv.y = 0.0;
dv.z = 0.0;
}
v.x += dv.x / 1000.0;
v.y += dv.y / 1000.0;
v.z += dv.z / 1000.0;
// Convert
orb=rv2el(orb.satno,mjd,r,v);
orb = rv2el (orb.satno, mjd, r, v);
if (satnonew==-1) {
strcpy(orb.desig,desig);
} else {
strcpy(orb.desig,"15999A");
orb.satno=satnonew;
if (satnonew == -1)
{
strcpy (orb.desig, desig);
}
else
{
strcpy (orb.desig, "15999A");
orb.satno = satnonew;
}
// Print tle
format_tle(orb,line1,line2);
printf("%s\n%s\n# %05d + %g m/s %s\n",line1,line2,satno,vadd,direction);
format_tle (orb, line1, line2);
printf ("%s\n%s\n# %05d + %g m/s %s\n", line1, line2, satno, vadd,
direction);
}
fclose(file);
fclose (file);
return 0;

View File

@ -4,12 +4,12 @@
#include <math.h>
#include <string.h>
int OUTPUT=1; // Print output on screen (1 = yes; 0 = no)
int ERRCOMP=0; // Set reduced Chi-Squared to unity (1 = yes; 0 = no)
int OUTPUT = 1; // Print output on screen (1 = yes; 0 = no)
int ERRCOMP = 0; // Set reduced Chi-Squared to unity (1 = yes; 0 = no)
int dsmin(double **,double *,int,double,double (*func)(double *));
double **simplex(int,double *,double *);
double parabolic_root(double,double,double,double);
int dsmin (double **, double *, int, double, double (*func) (double *));
double **simplex (int, double *, double *);
double parabolic_root (double, double, double, double);
// Versafit fitting routine
//
@ -23,126 +23,148 @@ double parabolic_root(double,double,double,double);
// tol: tolerance
// opt: options
// - n: no output
void versafit(int m,int n,double *a,double *da,double (*func)(double *),double dchisq,double tol,char *opt)
void
versafit (int m, int n, double *a, double *da, double (*func) (double *),
double dchisq, double tol, char *opt)
{
int i,j,k,l,nfunk,kmax=50;
int i, j, k, l, nfunk, kmax = 50;
double chisqmin;
double *b,*db;
double **p,*y;
double d[2],errcomp;
double *b, *db;
double **p, *y;
double d[2], errcomp;
// Decode options
if (strchr(opt,'n')!=NULL) OUTPUT=0;
if (strchr(opt,'e')!=NULL) ERRCOMP=1;
if (strchr (opt, 'n') != NULL)
OUTPUT = 0;
if (strchr (opt, 'e') != NULL)
ERRCOMP = 1;
// Intialize y
y=(double *) malloc(sizeof(double) * (n+1));
y = (double *) malloc (sizeof (double) * (n + 1));
if (dchisq>=0.) {
if (dchisq >= 0.)
{
// Compute simplex and minimize function
p=simplex(n,a,da);
nfunk=dsmin(p,y,n,tol,func);
p = simplex (n, a, da);
nfunk = dsmin (p, y, n, tol, func);
// Average parameters
for (i=0;i<n;i++) {
a[i]=0.;
for (j=0;j<=n;j++)
a[i]+=p[j][i];
a[i]/=(double) (n+1);
for (i = 0; i < n; i++)
{
a[i] = 0.;
for (j = 0; j <= n; j++)
a[i] += p[j][i];
a[i] /= (double) (n + 1);
}
// Compute minimum
chisqmin=func(a);
chisqmin = func (a);
// Compute error compensation
if (ERRCOMP) errcomp=sqrt(chisqmin/(double) (m-n));
if (ERRCOMP)
errcomp = sqrt (chisqmin / (double) (m - n));
}
// Basic Information
if (OUTPUT) {
printf("VersaFIT:\n");
if (m!=0)
printf("Number of datapoints: %i\n",m);
printf("Number of parameters: %i\n",n);
printf("Chi-squared: %14.5f\n",chisqmin);
if (m!=0)
printf("Reduced Chi-squared: %14.5f\n",chisqmin/(double) (m-n));
if (ERRCOMP) printf("Error compensation: %.4f\n",errcomp);
printf("Number of iterations: %i\n",nfunk);
if (OUTPUT)
{
printf ("VersaFIT:\n");
if (m != 0)
printf ("Number of datapoints: %i\n", m);
printf ("Number of parameters: %i\n", n);
printf ("Chi-squared: %14.5f\n", chisqmin);
if (m != 0)
printf ("Reduced Chi-squared: %14.5f\n", chisqmin / (double) (m - n));
if (ERRCOMP)
printf ("Error compensation: %.4f\n", errcomp);
printf ("Number of iterations: %i\n", nfunk);
printf("\nParameters:\n");
printf ("\nParameters:\n");
// No error estimation
if (dchisq==0.) {
for (i=0;i<n;i++)
printf(" a(%i): %12.5f\n",i+1,a[i]);
if (dchisq == 0.)
{
for (i = 0; i < n; i++)
printf (" a(%i): %12.5f\n", i + 1, a[i]);
}
}
// With error estimation
if (dchisq!=0.) {
b=(double *) malloc(sizeof(double) * n);
db=(double *) malloc(sizeof(double) * n);
if (dchisq != 0.)
{
b = (double *) malloc (sizeof (double) * n);
db = (double *) malloc (sizeof (double) * n);
for (i=0;i<n;i++) {
if (da[i]!=0.) {
for (j=0;j<n;j++) {
b[j]=a[j];
db[j]=da[j];
for (i = 0; i < n; i++)
{
if (da[i] != 0.)
{
for (j = 0; j < n; j++)
{
b[j] = a[j];
db[j] = da[j];
}
d[0]=-da[i];
db[i]=0.;
d[0] = -da[i];
db[i] = 0.;
for (k=0;k<kmax;k++) {
b[i]=a[i]+d[0];
for (k = 0; k < kmax; k++)
{
b[i] = a[i] + d[0];
// Minimize
p=simplex(n,b,db);
nfunk+=dsmin(p,y,n,tol,func);
p = simplex (n, b, db);
nfunk += dsmin (p, y, n, tol, func);
// Average parameters
for (l=0;l<n;l++) {
b[l]=0.;
for (j=0;j<=n;j++)
b[l]+=p[j][l];
b[l]/=(double) (n+1);
for (l = 0; l < n; l++)
{
b[l] = 0.;
for (j = 0; j <= n; j++)
b[l] += p[j][l];
b[l] /= (double) (n + 1);
}
d[0]=parabolic_root(d[0],func(b),chisqmin,dchisq);
d[0] = parabolic_root (d[0], func (b), chisqmin, dchisq);
if (fabs(chisqmin+dchisq-func(b))<tol) break;
if (fabs (chisqmin + dchisq - func (b)) < tol)
break;
}
d[1]=-d[0];
db[i]=0.;
d[1] = -d[0];
db[i] = 0.;
for (k=0;k<kmax;k++) {
b[i]=a[i]+d[1];
for (k = 0; k < kmax; k++)
{
b[i] = a[i] + d[1];
// Minimize
p=simplex(n,b,db);
nfunk+=dsmin(p,y,n,tol,func);
p = simplex (n, b, db);
nfunk += dsmin (p, y, n, tol, func);
// Average parameters
for (l=0;l<n;l++) {
b[l]=0.;
for (j=0;j<=n;j++)
b[l]+=p[j][l];
b[l]/=(double) (n+1);
for (l = 0; l < n; l++)
{
b[l] = 0.;
for (j = 0; j <= n; j++)
b[l] += p[j][l];
b[l] /= (double) (n + 1);
}
d[1]=parabolic_root(d[1],func(b),chisqmin,dchisq);
d[1] = parabolic_root (d[1], func (b), chisqmin, dchisq);
if (fabs(chisqmin+dchisq-func(b))<tol) break;
if (fabs (chisqmin + dchisq - func (b)) < tol)
break;
}
da[i]=0.5*(fabs(d[0])+fabs(d[1]));
if (ERRCOMP) da[i]*=errcomp;
da[i] = 0.5 * (fabs (d[0]) + fabs (d[1]));
if (ERRCOMP)
da[i] *= errcomp;
}
}
if (OUTPUT)
for (i=0;i<n;i++)
printf(" a(%i): %12.5f +- %9.5f\n",i+1,a[i],da[i]);
for (i = 0; i < n; i++)
printf (" a(%i): %12.5f +- %9.5f\n", i + 1, a[i], da[i]);
}
if (OUTPUT) printf("\nTotal number of iterations: %i\n",nfunk);
if (OUTPUT)
printf ("\nTotal number of iterations: %i\n", nfunk);
// free(p);
// free(y);
@ -153,16 +175,18 @@ void versafit(int m,int n,double *a,double *da,double (*func)(double *),double d
}
// Compute root
double parabolic_root(double x,double y,double y0,double dy)
double
parabolic_root (double x, double y, double y0, double dy)
{
double a;
if (fabs(x)<1e-9) {
printf("Division by zero in function 'parabolic_root'\n");
x=1e-9;
if (fabs (x) < 1e-9)
{
printf ("Division by zero in function 'parabolic_root'\n");
x = 1e-9;
}
a=(y-y0)/(x*x);
a = (y - y0) / (x * x);
return sqrt(fabs(dy/a))*x/fabs(x);
return sqrt (fabs (dy / a)) * x / fabs (x);
}

View File

@ -4,13 +4,15 @@
#include <math.h>
#include <sys/time.h>
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
struct timeval tv;
for (;;) {
gettimeofday(&tv,0);
if (tv.tv_usec>999000)
for (;;)
{
gettimeofday (&tv, 0);
if (tv.tv_usec > 999000)
break;
}

View File

@ -12,174 +12,195 @@
#define R2D 180.0/M_PI
#define NMAX 4096
struct catalog {
struct catalog
{
int n;
float x[NMAX],y[NMAX];
double ra[NMAX],de[NMAX];
double rx[NMAX],ry[NMAX];
float xres[NMAX],yres[NMAX],res[NMAX];
float xrms,yrms,rms;
float x[NMAX], y[NMAX];
double ra[NMAX], de[NMAX];
double rx[NMAX], ry[NMAX];
float xres[NMAX], yres[NMAX], res[NMAX];
float xrms, yrms, rms;
int usage[NMAX];
};
struct image {
int naxis1,naxis2,nframes;
float *zavg,*zstd,*zmax,*znum;
double ra0,de0;
float x0,y0;
float a[2],b[2];
struct image
{
int naxis1, naxis2, nframes;
float *zavg, *zstd, *zmax, *znum;
double ra0, de0;
float x0, y0;
float a[2], b[2];
double mjd;
float *dt;
};
struct transformation {
double ra0,de0;
float a[3],b[3];
float x0,y0;
struct transformation
{
double ra0, de0;
float a[3], b[3];
float x0, y0;
};
int fgetline(FILE *file,char *s,int lim);
void forward(double ra0,double de0,double ra,double de,double *x,double *y);
void reverse(double ra0,double de0,double x,double y,double *ra,double *de);
struct catalog read_catalog(char *filename);
void lfit2d(float *x,float *y,float *z,int n,float *a);
void add_fits_keywords(struct transformation t,char *filename);
struct image read_fits(char *filename);
int fgetline (FILE * file, char *s, int lim);
void forward (double ra0, double de0, double ra, double de, double *x,
double *y);
void reverse (double ra0, double de0, double x, double y, double *ra,
double *de);
struct catalog read_catalog (char *filename);
void lfit2d (float *x, float *y, float *z, int n, float *a);
void add_fits_keywords (struct transformation t, char *filename);
struct image read_fits (char *filename);
// Modify FITS keywords
void modify_fits_keywords(struct transformation t,char *filename)
void
modify_fits_keywords (struct transformation t, char *filename)
{
char card[FITS_LINESZ+1];
char key[FITS_LINESZ+1];
char val[FITS_LINESZ+1];
char com[FITS_LINESZ+1];
char card[FITS_LINESZ + 1];
char key[FITS_LINESZ + 1];
char val[FITS_LINESZ + 1];
char com[FITS_LINESZ + 1];
sprintf(val,"%f",t.x0);
keytuple2str(card,"CRPIX1",val,"");
qfits_replace_card(filename,"CRPIX1",card);
sprintf (val, "%f", t.x0);
keytuple2str (card, "CRPIX1", val, "");
qfits_replace_card (filename, "CRPIX1", card);
sprintf(val,"%f",t.y0);
keytuple2str(card,"CRPIX2",val,"");
qfits_replace_card(filename,"CRPIX2",card);
sprintf (val, "%f", t.y0);
keytuple2str (card, "CRPIX2", val, "");
qfits_replace_card (filename, "CRPIX2", card);
sprintf(val,"%f",t.ra0);
keytuple2str(card,"CRVAL1",val,"");
qfits_replace_card(filename,"CRVAL1",card);
sprintf (val, "%f", t.ra0);
keytuple2str (card, "CRVAL1", val, "");
qfits_replace_card (filename, "CRVAL1", card);
sprintf(val,"%f",t.de0);
keytuple2str(card,"CRVAL2",val,"");
qfits_replace_card(filename,"CRVAL2",card);
sprintf (val, "%f", t.de0);
keytuple2str (card, "CRVAL2", val, "");
qfits_replace_card (filename, "CRVAL2", card);
sprintf(val,"%e",t.a[1]/3600.0);
keytuple2str(card,"CD1_1",val,"");
qfits_replace_card(filename,"CD1_1",card);
sprintf (val, "%e", t.a[1] / 3600.0);
keytuple2str (card, "CD1_1", val, "");
qfits_replace_card (filename, "CD1_1", card);
sprintf(val,"%e",t.a[2]/3600.0);
keytuple2str(card,"CD1_2",val,"");
qfits_replace_card(filename,"CD1_2",card);
sprintf (val, "%e", t.a[2] / 3600.0);
keytuple2str (card, "CD1_2", val, "");
qfits_replace_card (filename, "CD1_2", card);
sprintf(val,"%e",t.b[1]/3600.0);
keytuple2str(card,"CD2_1",val,"");
qfits_replace_card(filename,"CD2_1",card);
sprintf (val, "%e", t.b[1] / 3600.0);
keytuple2str (card, "CD2_1", val, "");
qfits_replace_card (filename, "CD2_1", card);
sprintf(val,"%e",t.b[2]/3600.0);
keytuple2str(card,"CD2_2",val,"");
qfits_replace_card(filename,"CD2_2",card);
sprintf (val, "%e", t.b[2] / 3600.0);
keytuple2str (card, "CD2_2", val, "");
qfits_replace_card (filename, "CD2_2", card);
return;
}
int main(int argc,char *argv[])
int
main (int argc, char *argv[])
{
int i,j,k,l,m;
int i, j, k, l, m;
struct catalog c;
struct transformation t;
double ra0,de0;
double ra0, de0;
float rmsmin;
float x[NMAX],y[NMAX],rx[NMAX],ry[NMAX];
float x[NMAX], y[NMAX], rx[NMAX], ry[NMAX];
struct image img;
char filename[128];
if (argc==1)
strcpy(filename,"test.fits");
else if (argc==2)
strcpy(filename,argv[1]);
if (argc == 1)
strcpy (filename, "test.fits");
else if (argc == 2)
strcpy (filename, argv[1]);
img=read_fits(filename);
printf("files read\n");
c=read_catalog("out.dat");
printf("files read\n");
img = read_fits (filename);
printf ("files read\n");
c = read_catalog ("out.dat");
printf ("files read\n");
// Initial fit
t.ra0=c.ra[0];
t.de0=c.de[0];
t.x0=(float) img.naxis1/2.0;
t.y0=(float) img.naxis2/2.0;
t.ra0 = c.ra[0];
t.de0 = c.de[0];
t.x0 = (float) img.naxis1 / 2.0;
t.y0 = (float) img.naxis2 / 2.0;
for (l=0;l<10;l++) {
for (j=0;j<5;j++) {
for (l = 0; l < 10; l++)
{
for (j = 0; j < 5; j++)
{
// Transform
for (i=0;i<c.n;i++) {
forward(t.ra0,t.de0,c.ra[i],c.de[i],&c.rx[i],&c.ry[i]);
for (i = 0; i < c.n; i++)
{
forward (t.ra0, t.de0, c.ra[i], c.de[i], &c.rx[i], &c.ry[i]);
}
// Select
for (i=0,k=0;i<c.n;i++) {
if (c.usage[i]==1) {
x[k]=c.x[i];
y[k]=c.y[i];
rx[k]=c.rx[i];
ry[k]=c.ry[i];
for (i = 0, k = 0; i < c.n; i++)
{
if (c.usage[i] == 1)
{
x[k] = c.x[i];
y[k] = c.y[i];
rx[k] = c.rx[i];
ry[k] = c.ry[i];
k++;
}
}
// Fit
lfit2d(x,y,rx,k,t.a);
lfit2d(x,y,ry,k,t.b);
printf("%f %f %f %f %f %f %f %f\n",t.ra0,t.de0,t.a[0],t.a[1],t.a[2],t.b[0],t.b[1],t.b[2]);
lfit2d (x, y, rx, k, t.a);
lfit2d (x, y, ry, k, t.b);
printf ("%f %f %f %f %f %f %f %f\n", t.ra0, t.de0, t.a[0], t.a[1],
t.a[2], t.b[0], t.b[1], t.b[2]);
// Move reference point
reverse(t.ra0,t.de0,t.a[0],t.b[0],&ra0,&de0);
t.ra0=ra0;
t.de0=de0;
reverse (t.ra0, t.de0, t.a[0], t.b[0], &ra0, &de0);
t.ra0 = ra0;
t.de0 = de0;
}
// Compute and plot residuals
for (i=0,c.xrms=0.0,c.yrms=0.0,m=0;i<c.n;i++) {
if (c.usage[i]==1) {
c.xres[i]=c.rx[i]-(t.a[0]+t.a[1]*c.x[i]+t.a[2]*c.y[i]);
c.yres[i]=c.ry[i]-(t.b[0]+t.b[1]*c.x[i]+t.b[2]*c.y[i]);
printf("%12.4f %12.4f %12.4f %12.4f %10.4f %10.4f\n",c.x[i],c.y[i],c.rx[i],c.ry[i],c.xres[i],c.yres[i]);
c.res[i]=sqrt(c.xres[i]*c.xres[i]+c.yres[i]*c.yres[i]);
c.xrms+=c.xres[i]*c.xres[i];
c.yrms+=c.yres[i]*c.yres[i];
c.rms+=c.xres[i]*c.xres[i]+c.yres[i]*c.yres[i];
for (i = 0, c.xrms = 0.0, c.yrms = 0.0, m = 0; i < c.n; i++)
{
if (c.usage[i] == 1)
{
c.xres[i] =
c.rx[i] - (t.a[0] + t.a[1] * c.x[i] + t.a[2] * c.y[i]);
c.yres[i] =
c.ry[i] - (t.b[0] + t.b[1] * c.x[i] + t.b[2] * c.y[i]);
printf ("%12.4f %12.4f %12.4f %12.4f %10.4f %10.4f\n", c.x[i],
c.y[i], c.rx[i], c.ry[i], c.xres[i], c.yres[i]);
c.res[i] = sqrt (c.xres[i] * c.xres[i] + c.yres[i] * c.yres[i]);
c.xrms += c.xres[i] * c.xres[i];
c.yrms += c.yres[i] * c.yres[i];
c.rms += c.xres[i] * c.xres[i] + c.yres[i] * c.yres[i];
m++;
}
}
c.xrms=sqrt(c.xrms/(float) m);
c.yrms=sqrt(c.yrms/(float) m);
c.rms=sqrt(c.rms/(float) m);
c.xrms = sqrt (c.xrms / (float) m);
c.yrms = sqrt (c.yrms / (float) m);
c.rms = sqrt (c.rms / (float) m);
// Deselect outliers
for (i=0;i<c.n;i++) {
if (c.res[i]>2*c.rms)
c.usage[i]=0;
for (i = 0; i < c.n; i++)
{
if (c.res[i] > 2 * c.rms)
c.usage[i] = 0;
}
}
printf("%12.8lf %10.6lf %10.6lf %8.4f %8.4f %8.4f %8.4f\n",img.mjd,t.ra0,t.de0,t.a[1],t.a[2],t.b[1],t.b[2]);
printf("%d/%d %f %f %f\n",m,c.n,c.xrms,c.yrms,c.rms);
printf ("%12.8lf %10.6lf %10.6lf %8.4f %8.4f %8.4f %8.4f\n", img.mjd, t.ra0,
t.de0, t.a[1], t.a[2], t.b[1], t.b[2]);
printf ("%d/%d %f %f %f\n", m, c.n, c.xrms, c.yrms, c.rms);
// add_fits_keywords(t,"test.fits");
modify_fits_keywords(t,filename);
modify_fits_keywords (t, filename);
return 0;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
int
fgetline (FILE * file, char *s, int lim)
{
int c,i=0;
int c, i = 0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
@ -188,170 +209,179 @@ int fgetline(FILE *file,char *s,int lim)
}
// Read catalog
struct catalog read_catalog(char *filename)
struct catalog
read_catalog (char *filename)
{
int i=0;
int i = 0;
char line[LIM];
FILE *file;
struct catalog c;
file=fopen(filename,"r");
while (fgetline(file,line,LIM)>0) {
sscanf(line,"%f %f %lf %lf",&c.x[i],&c.y[i],&c.ra[i],&c.de[i]);
c.usage[i]=1;
file = fopen (filename, "r");
while (fgetline (file, line, LIM) > 0)
{
sscanf (line, "%f %f %lf %lf", &c.x[i], &c.y[i], &c.ra[i], &c.de[i]);
c.usage[i] = 1;
i++;
}
fclose(file);
c.n=i;
fclose (file);
c.n = i;
return c;
}
// Linear 2D fit
void lfit2d(float *x,float *y,float *z,int n,float *a)
void
lfit2d (float *x, float *y, float *z, int n, float *a)
{
int i,j,m;
int i, j, m;
double chisq;
gsl_matrix *X,*cov;
gsl_vector *yy,*w,*c;
gsl_matrix *X, *cov;
gsl_vector *yy, *w, *c;
X=gsl_matrix_alloc(n,3);
yy=gsl_vector_alloc(n);
w=gsl_vector_alloc(n);
X = gsl_matrix_alloc (n, 3);
yy = gsl_vector_alloc (n);
w = gsl_vector_alloc (n);
c=gsl_vector_alloc(3);
cov=gsl_matrix_alloc(3,3);
c = gsl_vector_alloc (3);
cov = gsl_matrix_alloc (3, 3);
// Fill matrices
for(i=0;i<n;i++) {
gsl_matrix_set(X,i,0,1.0);
gsl_matrix_set(X,i,1,x[i]);
gsl_matrix_set(X,i,2,y[i]);
for (i = 0; i < n; i++)
{
gsl_matrix_set (X, i, 0, 1.0);
gsl_matrix_set (X, i, 1, x[i]);
gsl_matrix_set (X, i, 2, y[i]);
gsl_vector_set(yy,i,z[i]);
gsl_vector_set(w,i,1.0);
gsl_vector_set (yy, i, z[i]);
gsl_vector_set (w, i, 1.0);
}
// Do fit
gsl_multifit_linear_workspace *work=gsl_multifit_linear_alloc(n,3);
gsl_multifit_wlinear(X,w,yy,c,cov,&chisq,work);
gsl_multifit_linear_free(work);
gsl_multifit_linear_workspace *work = gsl_multifit_linear_alloc (n, 3);
gsl_multifit_wlinear (X, w, yy, c, cov, &chisq, work);
gsl_multifit_linear_free (work);
// Save parameters
for (i=0;i<3;i++)
a[i]=gsl_vector_get(c,(i));
for (i = 0; i < 3; i++)
a[i] = gsl_vector_get (c, (i));
gsl_matrix_free(X);
gsl_vector_free(yy);
gsl_vector_free(w);
gsl_vector_free(c);
gsl_matrix_free(cov);
gsl_matrix_free (X);
gsl_vector_free (yy);
gsl_vector_free (w);
gsl_vector_free (c);
gsl_matrix_free (cov);
return;
}
// Add FITS keywords
void add_fits_keywords(struct transformation t,char *filename)
void
add_fits_keywords (struct transformation t, char *filename)
{
int i,j,k,l,m;
int naxis1,naxis2,naxis3;
int i, j, k, l, m;
int naxis1, naxis2, naxis3;
qfits_header *qh;
qfitsdumper qd;
qfitsloader ql;
char key[FITS_LINESZ+1];
char val[FITS_LINESZ+1];
char com[FITS_LINESZ+1];
char lin[FITS_LINESZ+1];
char key[FITS_LINESZ + 1];
char val[FITS_LINESZ + 1];
char com[FITS_LINESZ + 1];
char lin[FITS_LINESZ + 1];
FILE *file;
float *fbuf;
naxis1=atoi(qfits_query_hdr(filename,"NAXIS1"));
naxis2=atoi(qfits_query_hdr(filename,"NAXIS2"));
naxis3=atoi(qfits_query_hdr(filename,"NAXIS3"));
naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1"));
naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2"));
naxis3 = atoi (qfits_query_hdr (filename, "NAXIS3"));
fbuf=malloc(sizeof(float)*naxis1*naxis2*naxis3);
fbuf = malloc (sizeof (float) * naxis1 * naxis2 * naxis3);
// Read header
qh=qfits_header_read(filename);
qh = qfits_header_read (filename);
ql.xtnum=0;
ql.ptype=PTYPE_FLOAT;
ql.filename=filename;
for (k=0,l=0;k<naxis3;k++) {
ql.pnum=k;
ql.xtnum = 0;
ql.ptype = PTYPE_FLOAT;
ql.filename = filename;
for (k = 0, l = 0; k < naxis3; k++)
{
ql.pnum = k;
// Initialize load
if (qfitsloader_init(&ql) != 0)
printf("Error initializing data loading\n");
if (qfitsloader_init (&ql) != 0)
printf ("Error initializing data loading\n");
// Test load
if (qfits_loadpix(&ql) != 0)
printf("Error loading actual data\n");
if (qfits_loadpix (&ql) != 0)
printf ("Error loading actual data\n");
for (i=0,m=0;i<naxis1;i++) {
for (j=0;j<naxis2;j++) {
fbuf[l]=ql.fbuf[m];
for (i = 0, m = 0; i < naxis1; i++)
{
for (j = 0; j < naxis2; j++)
{
fbuf[l] = ql.fbuf[m];
l++;
m++;
}
}
}
qfits_header_add_after(qh,"MJD-OBS","CUNIT2","'deg'"," ",NULL);
qfits_header_add_after(qh,"MJD-OBS","CUNIT1","'deg'"," ",NULL);
qfits_header_add_after(qh,"MJD-OBS","CTYPE2","'DEC--TAN'"," ",NULL);
qfits_header_add_after(qh,"MJD-OBS","CTYPE1","'RA---TAN'"," ",NULL);
sprintf(val,"%e",t.b[2]/3600.0);
qfits_header_add_after(qh,"MJD-OBS","CD2_2",val," ",NULL);
sprintf(val,"%e",t.b[1]/3600.0);
qfits_header_add_after(qh,"MJD-OBS","CD2_1",val," ",NULL);
sprintf(val,"%e",t.a[2]/3600.0);
qfits_header_add_after(qh,"MJD-OBS","CD1_2",val," ",NULL);
sprintf(val,"%e",t.a[1]/3600.0);
qfits_header_add_after(qh,"MJD-OBS","CD1_1",val," ",NULL);
sprintf(val,"%f",t.de0);
qfits_header_add_after(qh,"MJD-OBS","CRVAL2",val," ",NULL);
sprintf(val,"%f",t.ra0);
qfits_header_add_after(qh,"MJD-OBS","CRVAL1",val," ",NULL);
sprintf(val,"%f",t.y0);
qfits_header_add_after(qh,"MJD-OBS","CRPIX2",val," ",NULL);
sprintf(val,"%f",t.x0);
qfits_header_add_after(qh,"MJD-OBS","CRPIX1",val," ",NULL);
qfits_header_add_after (qh, "MJD-OBS", "CUNIT2", "'deg'", " ", NULL);
qfits_header_add_after (qh, "MJD-OBS", "CUNIT1", "'deg'", " ", NULL);
qfits_header_add_after (qh, "MJD-OBS", "CTYPE2", "'DEC--TAN'", " ", NULL);
qfits_header_add_after (qh, "MJD-OBS", "CTYPE1", "'RA---TAN'", " ", NULL);
sprintf (val, "%e", t.b[2] / 3600.0);
qfits_header_add_after (qh, "MJD-OBS", "CD2_2", val, " ", NULL);
sprintf (val, "%e", t.b[1] / 3600.0);
qfits_header_add_after (qh, "MJD-OBS", "CD2_1", val, " ", NULL);
sprintf (val, "%e", t.a[2] / 3600.0);
qfits_header_add_after (qh, "MJD-OBS", "CD1_2", val, " ", NULL);
sprintf (val, "%e", t.a[1] / 3600.0);
qfits_header_add_after (qh, "MJD-OBS", "CD1_1", val, " ", NULL);
sprintf (val, "%f", t.de0);
qfits_header_add_after (qh, "MJD-OBS", "CRVAL2", val, " ", NULL);
sprintf (val, "%f", t.ra0);
qfits_header_add_after (qh, "MJD-OBS", "CRVAL1", val, " ", NULL);
sprintf (val, "%f", t.y0);
qfits_header_add_after (qh, "MJD-OBS", "CRPIX2", val, " ", NULL);
sprintf (val, "%f", t.x0);
qfits_header_add_after (qh, "MJD-OBS", "CRPIX1", val, " ", NULL);
file=fopen(filename,"w");
qfits_header_dump(qh,file);
fclose(file);
file = fopen (filename, "w");
qfits_header_dump (qh, file);
fclose (file);
qfits_header_destroy(qh);
qfits_header_destroy (qh);
qd.filename=filename;
qd.npix=naxis1*naxis2*naxis3;
qd.ptype=PTYPE_FLOAT;
qd.fbuf=fbuf;
qd.out_ptype=-32;
qd.filename = filename;
qd.npix = naxis1 * naxis2 * naxis3;
qd.ptype = PTYPE_FLOAT;
qd.fbuf = fbuf;
qd.out_ptype = -32;
qfits_pixdump(&qd);
free(fbuf);
qfits_pixdump (&qd);
free (fbuf);
return;
}
// Read fits image
struct image read_fits(char *filename)
struct image
read_fits (char *filename)
{
int i,j,k,l,m;
int i, j, k, l, m;
qfitsloader ql;
char key[FITS_LINESZ+1];
char val[FITS_LINESZ+1];
char key[FITS_LINESZ + 1];
char val[FITS_LINESZ + 1];
struct image img;
// Image size
img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1"));
img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2"));
img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1"));
img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2"));
// MJD
// img.mjd=(double) atof(qfits_query_hdr(filename,"MJD-OBS"));
img.mjd=0.0;
img.mjd = 0.0;
return img;

File diff suppressed because it is too large Load Diff