1
0
Fork 0
sattools/geolon.c

205 lines
3.5 KiB
C

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <getopt.h>
#include "sgdp4h.h"
#define LIM 128
#define D2R M_PI/180.0
#define R2D 180.0/M_PI
#define XKMPER 6378.135 // Earth radius in km
long Isat=0;
long Isatsel=0;
extern double SGDP4_jd0;
struct map {
long satno;
double mjd;
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)
{
int a,b;
double jd;
if (month<3) {
year--;
month+=12;
}
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;
jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5;
return jd-2400000.5;
}
// nfd2mjd
double nfd2mjd(char *date)
{
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;
mjd=date2mjd(year,month,dday);
return mjd;
}
void usage()
{
printf("Usage goes here.\n");
return;
}
// Return x modulo y [0,y)
double modulo(double x,double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
return x;
}
// Greenwich Mean Sidereal Time
double gmst(double mjd)
{
double t,gmst;
t=(mjd-51544.5)/36525.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)
{
time_t rawtime;
struct tm *ptm;
// Get UTC time
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);
return;
}
// Compute longitude
void compute_longitude(char *tlefile,long satno,double mjd)
{
FILE *fp=NULL;
orbit_t orb;
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);
// Loop over elements
while(read_twoline(fp, satno, &orb) == 0) {
Isat = orb.satno;
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)
continue;
// Get Julian Date
jd=mjd+2400000.5;
// Get positions
satpos_xyz(jd,&satpos,&satvel);
// Greenwich Mean Sidereal time
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;
printf("%05d %10s %8.3lf %8.3lf %6.0lf\n",orb.satno,orb.desig,l,b,r-XKMPER);
}
fclose(fp);
return;
}
int main(int argc,char *argv[])
{
int arg=0;
long satno=0;
double mjd;
char nfd[LIM],tlefile[LIM];
nfd_now(nfd);
mjd=nfd2mjd(nfd);
// Decode options
if (argc>1) {
while ((arg=getopt(argc,argv,"t:c:i:h"))!=-1) {
switch (arg) {
case 't':
strcpy(nfd,optarg);
mjd=nfd2mjd(nfd);
break;
case 'c':
strcpy(tlefile,optarg);
break;
case 'i':
satno=atoi(optarg);
break;
case 'h':
usage();
return 0;
break;
default:
usage();
return 0;
}
}
} else {
usage();
return 0;
}
// Compute longitudes of satellites
compute_longitude(tlefile,satno,mjd);
return 0;
}