strf/rftrace.c

782 lines
18 KiB
C
Raw Normal View History

2014-03-24 05:22:20 -06:00
#include <stdio.h>
#include <string.h>
#include <math.h>
2014-03-24 09:41:38 -06:00
#include <stdlib.h>
2014-03-24 05:22:20 -06:00
#include "sgdp4h.h"
#include "satutl.h"
2018-02-13 09:26:03 -07:00
#include "rftime.h"
2014-03-24 09:41:38 -06:00
#include "rftrace.h"
#include <sys/time.h>
#include <time.h>
2014-03-24 05:22:20 -06:00
#include "rftles.h"
2014-03-24 05:22:20 -06:00
#define LIM 80
#define D2R M_PI/180.0
#define R2D 180.0/M_PI
#define XKMPER 6378.135 // Earth radius in km
#define XKMPAU 149597879.691 // AU in km
#define FLAT (1.0/298.257)
#define C 299792.458 // Speed of light in km/s
struct point {
xyz_t obspos,obsvel;
2014-12-14 15:03:37 -07:00
xyz_t grpos,grvel;
2014-03-24 05:22:20 -06:00
};
struct site {
int id;
double lng,lat;
float alt;
char observer[64];
};
// Return x modulo y [0,y)
double modulo(double x,double y)
{
x=fmod(x,y);
if (x<0.0) x+=y;
return x;
}
// Read a line of maximum length int lim from file FILE into string s
int fgetline(FILE *file,char *s,int lim)
{
int c,i=0;
2014-03-24 05:22:20 -06:00
while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n')
s[i++] = c;
// if (c == '\n')
// s[i++] = c;
s[i] = '\0';
return i;
}
// 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;
}
// Greenwich Mean Sidereal Time
double dgmst(double mjd)
{
double t,dgmst;
t=(mjd-51544.5)/36525.0;
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)
{
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;
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;
2014-03-24 05:22:20 -06:00
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;
2014-03-24 05:22:20 -06:00
vel->z=0.0;
return;
}
2015-05-25 15:15:20 -06:00
// Convert equatorial into horizontal coordinates
void equatorial2horizontal(double mjd,double ra,double de,double lng,double lat,double *azi,double *alt)
{
double h;
h=gmst(mjd)+lng-ra;
2015-05-25 15:15:20 -06:00
*azi=modulo(atan2(sin(h*D2R),cos(h*D2R)*sin(lat*D2R)-tan(de*D2R)*cos(lat*D2R))*R2D,360.0);
*alt=asin(sin(lat*D2R)*sin(de*D2R)+cos(lat*D2R)*cos(de*D2R)*cos(h*D2R))*R2D;
return;
}
2014-03-24 05:22:20 -06:00
// Get observing site
struct site get_site(int site_id)
{
2014-09-24 01:30:00 -06:00
int i=0,status;
2014-03-24 05:22:20 -06:00
char line[LIM];
FILE *file;
int id;
double lat,lng;
float alt;
char abbrev[3],observer[64];
struct site s;
char *env,filename[LIM];
env=getenv("ST_DATADIR");
if(env==NULL||strlen(env)==0)
env=".";
2014-03-24 05:22:20 -06:00
sprintf(filename,"%s/data/sites.txt",env);
file=fopen(filename,"r");
if (file==NULL) {
printf("File with site information not found!\n");
2018-02-13 09:26:03 -07:00
return s;
2014-03-24 05:22:20 -06:00
}
while (fgets(line,LIM,file)!=NULL) {
// Skip
if (strstr(line,"#")!=NULL)
continue;
// Strip newline
line[strlen(line)-1]='\0';
// Read data
2014-09-24 01:30:00 -06:00
status=sscanf(line,"%4d %2s %lf %lf %f",
2014-03-24 05:22:20 -06:00
&id,abbrev,&lat,&lng,&alt);
strcpy(observer,line+38);
// Change to km
alt/=1000.0;
2014-03-24 05:22:20 -06:00
// Copy site
if (id==site_id) {
s.lat=lat;
s.lng=lng;
s.alt=alt;
s.id=id;
strcpy(s.observer,observer);
}
}
fclose(file);
return s;
}
2015-05-26 01:19:33 -06:00
// Identify trace
void identify_trace_graves(char *tlefile,struct trace t,int satno,char *freqlist)
2015-05-26 01:19:33 -06:00
{
int i,imode,flag=0,status,imid;
struct point *p;
struct site s,sg;
double *v,*vg;
orbit_t *orb;
2015-05-26 01:19:33 -06:00
xyz_t satpos,satvel;
FILE *file;
double dx,dy,dz,dvx,dvy,dvz,r,za;
double sum1,sum2,beta,freq0,rms,mjd0;
char nfd[32],nfdmin[32],text[16];
int satnomin;
double rmsmin,freqmin,altmin,azimin;
double ra,de,azi,alt;
// Reloop stderr
if (freopen("/tmp/stderr.txt","w",stderr)==NULL)
fprintf(stderr,"Failed to redirect stderr\n");
// Get sites
s=get_site(t.site);
sg=get_site(9999);
// Allocate
p=(struct point *) malloc(sizeof(struct point)*t.n);
v=(double *) malloc(sizeof(double)*t.n);
vg=(double *) malloc(sizeof(double)*t.n);
// Get observer position
for (i=0;i<t.n;i++) {
obspos_xyz(t.mjd[i],s.lng,s.lat,s.alt,&p[i].obspos,&p[i].obsvel);
obspos_xyz(t.mjd[i],sg.lng,sg.lat,sg.alt,&p[i].grpos,&p[i].grvel);
}
printf("Fitting trace:\n");
// Mid point
imid=t.n/2;
// Load TLEs
tles_t twolines = load_tles(tlefile);
if (twolines.number_of_elements == 0) {
fprintf(stderr,"TLE file %s not found or empty\n", tlefile);
2015-05-26 01:19:33 -06:00
return;
}
for (long elem = 0; elem < twolines.number_of_elements; elem++) {
// Get TLE
orb = get_orbit_by_index(&twolines, elem);
2015-05-26 01:19:33 -06:00
// Initialize
imode=init_sgdp4(orb);
2022-02-03 15:31:47 -07:00
if (imode==SGDP4_ERROR) {
printf("Error with %d, skipping\n",orb->satno);
2022-02-03 15:31:47 -07:00
continue;
}
2015-05-26 01:19:33 -06:00
// Loop over points
for (i=0,sum1=0.0,sum2=0.0;i<t.n;i++) {
// Get satellite position
satpos_xyz(t.mjd[i]+2400000.5,&satpos,&satvel);
dx=satpos.x-p[i].obspos.x;
2015-05-26 01:19:33 -06:00
dy=satpos.y-p[i].obspos.y;
dz=satpos.z-p[i].obspos.z;
dvx=satvel.x-p[i].obsvel.x;
dvy=satvel.y-p[i].obsvel.y;
dvz=satvel.z-p[i].obsvel.z;
r=sqrt(dx*dx+dy*dy+dz*dz);
v[i]=(dvx*dx+dvy*dy+dvz*dz)/r;
za=acos((p[i].obspos.x*dx+p[i].obspos.y*dy+p[i].obspos.z*dz)/(r*XKMPER))*R2D;
if (i==imid) {
ra=modulo(atan2(dy,dx)*R2D,360.0);
de=asin(dz/r)*R2D;
equatorial2horizontal(t.mjd[i],ra,de,s.lng,s.lat,&azi,&alt);
}
dx=satpos.x-p[i].grpos.x;
2015-05-26 01:19:33 -06:00
dy=satpos.y-p[i].grpos.y;
dz=satpos.z-p[i].grpos.z;
dvx=satvel.x-p[i].grvel.x;
dvy=satvel.y-p[i].grvel.y;
dvz=satvel.z-p[i].grvel.z;
r=sqrt(dx*dx+dy*dy+dz*dz);
vg[i]=(dvx*dx+dvy*dy+dvz*dz)/r;
// t[j].freq[i]=(1.0-v/C)*(1.0-vg/C)*freq0;
// if (!((azi<90.0 || azi>270.0) && alt>15.0 && alt<40.0))
// t[j].za[i]=100.0;
}
freq0=143050000.0;
// Compute residuals
for (i=0,rms=0.0;i<t.n;i++)
2015-05-26 01:19:33 -06:00
rms+=pow(t.freq[i]-(1.0-v[i]/C)*(1.0-vg[i]/C)*freq0,2);
rms=sqrt(rms/(double) t.n);
// Find TCA
2021-08-06 15:19:46 -06:00
for (i=1,mjd0=0.0;i<t.n;i++)
2015-05-26 01:19:33 -06:00
if (v[i]*v[i-1]<0.0)
mjd0=t.mjd[i];
2015-05-26 01:19:33 -06:00
if (mjd0>0.0)
mjd2nfd(mjd0,nfd);
else
strcpy(nfd,"0000-00-00T00:00:00");
2015-05-26 01:19:33 -06:00
if (rms<1000) {
if (rms<50.0)
printf("%05d: %s %8.1f Hz (%.1f,%.1f)\n",orb->satno,nfd,rms,modulo(azi+180.0,360.0),alt);
// printf("%05d: %s %8.3f MHz %8.3f kHz\n",orb->satno,nfd,1e-6*freq0,1e-3*rms);
2015-05-26 01:19:33 -06:00
if (flag==0 || rms<rmsmin) {
satnomin=orb->satno;
2015-05-26 01:19:33 -06:00
strcpy(nfdmin,nfd);
freqmin=freq0;
rmsmin=rms;
altmin=alt;
azimin=azi;
flag=1;
}
}
}
fclose(stderr);
if (flag==1) {
printf("\nBest fitting object:\n");
printf("%05d: %s %8.1f Hz (%.1f,%.1f)\n",satnomin,nfdmin,rmsmin,modulo(azimin+180.0,360.0),altmin);
printf("Store frequency? [y/n]\n");
status=scanf("%s",text);
if (text[0]=='y') {
file=fopen(freqlist,"a");
fprintf(file,"%05d %lf\n",satnomin,1e-6*freqmin);
2015-05-26 01:19:33 -06:00
fclose(file);
file=fopen("log.txt","a");
fprintf(file,"%05d %lf %.3f %.19s\n",satnomin,1e-6*freqmin,1e-3*rmsmin,nfdmin);
2015-05-26 01:19:33 -06:00
fclose(file);
printf("Frequency stored\n\n");
}
} else {
printf("\nTrace not identified..\n");
}
// Free
free_tles(&twolines);
2015-05-26 01:19:33 -06:00
free(p);
free(v);
2021-07-06 09:02:52 -06:00
free(vg);
2015-05-26 01:19:33 -06:00
return;
}
2014-03-24 09:41:38 -06:00
// Identify trace
void identify_trace(char *tlefile,struct trace t,int satno,char *freqlist)
2014-03-24 09:41:38 -06:00
{
2014-09-24 01:30:00 -06:00
int i,imode,flag=0,status;
2014-03-24 09:41:38 -06:00
struct point *p;
struct site s;
double *v;
orbit_t *orb;
2014-03-24 09:41:38 -06:00
xyz_t satpos,satvel;
FILE *file;
double dx,dy,dz,dvx,dvy,dvz,r,za;
double sum1,sum2,beta,freq0,rms,mjd0;
char nfd[32],nfdmin[32],text[16];
int satnomin;
double rmsmin,freqmin;
struct timeval tv;
char tbuf[30];
2014-03-24 09:41:38 -06:00
// Reloop stderr
2015-05-25 15:15:20 -06:00
if (freopen("/tmp/stderr.txt","w",stderr)==NULL)
fprintf(stderr,"Failed to redirect stderr\n");
2014-03-24 09:41:38 -06:00
// Get site
s=get_site(t.site);
// Allocate
p=(struct point *) malloc(sizeof(struct point)*t.n);
v=(double *) malloc(sizeof(double)*t.n);
// Get observer position
for (i=0;i<t.n;i++)
2014-03-24 09:41:38 -06:00
obspos_xyz(t.mjd[i],s.lng,s.lat,s.alt,&p[i].obspos,&p[i].obsvel);
printf("Fitting trace:\n");
// Load TLEs
tles_t twolines = load_tles(tlefile);
if (twolines.number_of_elements == 0) {
fprintf(stderr,"TLE file %s not found or empty\n", tlefile);
2014-06-23 22:02:38 -06:00
return;
}
for (long elem = 0; elem < twolines.number_of_elements; elem++) {
// Get TLE
orb = get_orbit_by_index(&twolines, elem);
2014-03-24 09:41:38 -06:00
// Initialize
imode=init_sgdp4(orb);
2022-02-03 15:31:47 -07:00
if (imode==SGDP4_ERROR) {
printf("Error with %d, skipping\n",orb->satno);
2022-02-03 15:31:47 -07:00
continue;
}
2014-03-24 09:41:38 -06:00
// Loop over points
for (i=0,sum1=0.0,sum2=0.0;i<t.n;i++) {
// Get satellite position
satpos_xyz(t.mjd[i]+2400000.5,&satpos,&satvel);
dx=satpos.x-p[i].obspos.x;
2014-03-24 09:41:38 -06:00
dy=satpos.y-p[i].obspos.y;
dz=satpos.z-p[i].obspos.z;
dvx=satvel.x-p[i].obsvel.x;
dvy=satvel.y-p[i].obsvel.y;
dvz=satvel.z-p[i].obsvel.z;
r=sqrt(dx*dx+dy*dy+dz*dz);
v[i]=(dvx*dx+dvy*dy+dvz*dz)/r;
za=acos((p[i].obspos.x*dx+p[i].obspos.y*dy+p[i].obspos.z*dz)/(r*XKMPER))*R2D;
2015-05-25 15:15:20 -06:00
2014-03-24 09:41:38 -06:00
beta=(1.0-v[i]/C);
sum1+=beta*t.freq[i];
sum2+=beta*beta;
}
freq0=sum1/sum2;
// Compute residuals
for (i=0,rms=0.0;i<t.n;i++)
2014-03-24 09:41:38 -06:00
rms+=pow(t.freq[i]-(1.0-v[i]/C)*freq0,2);
rms=sqrt(rms/(double) t.n);
// Find TCA
2021-08-06 15:19:46 -06:00
for (i=1,mjd0=0.0;i<t.n;i++)
2014-03-24 09:41:38 -06:00
if (v[i]*v[i-1]<0.0)
mjd0=t.mjd[i];
2014-03-24 09:41:38 -06:00
if (mjd0>0.0)
mjd2nfd(mjd0,nfd);
else
strcpy(nfd,"0000-00-00T00:00:00");
2014-03-24 09:41:38 -06:00
if (rms<1000) {
printf("%05d: %s %8.3f MHz %8.3f kHz\n",orb->satno,nfd,1e-6*freq0,1e-3*rms);
2014-03-24 09:41:38 -06:00
if (flag==0 || rms<rmsmin) {
satnomin=orb->satno;
2014-03-24 09:41:38 -06:00
strcpy(nfdmin,nfd);
freqmin=freq0;
rmsmin=rms;
flag=1;
}
}
}
fclose(stderr);
if (flag==1) {
printf("\nBest fitting object:\n");
printf("%05d: %s %8.3f MHz %8.3f kHz\n",satnomin,nfdmin,1e-6*freqmin,1e-3*rmsmin);
printf("Store frequency? [y/n]\n");
2014-09-24 01:30:00 -06:00
status=scanf("%s",text);
2014-03-24 09:41:38 -06:00
if (text[0]=='y') {
gettimeofday(&tv,0);
strftime(tbuf,30,"%Y-%m-%dT%T",gmtime(&tv.tv_sec));
2014-06-23 22:02:38 -06:00
file=fopen(freqlist,"a");
fprintf(file,"%05d %lf %.19s %04d\n",satnomin,1e-6*freqmin,tbuf,s.id);
2014-03-24 09:41:38 -06:00
fclose(file);
file=fopen("log.txt","a");
fprintf(file,"%05d %lf %.3f %.19s\n",satnomin,1e-6*freqmin,1e-3*rmsmin,nfdmin);
2014-03-24 09:41:38 -06:00
fclose(file);
printf("Frequency stored\n\n");
}
} else {
printf("\nTrace not identified..\n");
}
// Free
free_tles(&twolines);
2014-03-24 09:41:38 -06:00
free(p);
free(v);
return;
}
// Is it a classified satellite
int is_classified(int satno)
{
int flag=0,no;
char *env,tlefile[128],line[LIM];
FILE *file;
// Get classfd.tle path
env=getenv("ST_TLEDIR");
if(env==NULL||strlen(env)==0)
env=".";
sprintf(tlefile,"%s/classfd.tle",env);
// Does it exist
file=fopen(tlefile,"r");
if (file==NULL) {
printf("%s not found\n",tlefile);
flag=0;
} else {
// Loop over TLEs
while (fgetline(file,line,LIM)>0) {
// Use 1st TLE line
if (line[0]=='1') {
sscanf(line+2,"%d",&no);
if (no==satno) flag=1;
}
}
fclose(file);
}
return flag;
}
2014-03-24 05:22:20 -06:00
// Compute trace
struct trace *compute_trace(char *tlefile,double *mjd,int n,int site_id,float freq,float bw,int *nsat,int graves,char *freqlist)
2014-03-24 05:22:20 -06:00
{
2022-10-18 11:40:34 -06:00
int i,j,imode,flag,satno,tflag,m,status,hastle;
2014-03-24 05:22:20 -06:00
struct point *p;
2014-12-14 15:03:37 -07:00
struct site s,sg;
2014-03-24 05:22:20 -06:00
FILE *file,*infile;
orbit_t *orb;
2014-03-24 05:22:20 -06:00
xyz_t satpos,satvel;
2014-12-14 15:03:37 -07:00
double dx,dy,dz,dvx,dvy,dvz,r,v,za,vg;
2014-03-24 09:41:38 -06:00
double freq0;
2022-10-18 11:40:34 -06:00
char line[LIM];
2014-03-24 05:22:20 -06:00
struct trace *t;
2014-03-24 09:41:38 -06:00
float fmin,fmax;
2015-05-25 15:15:20 -06:00
double ra,de,azi,alt;
2014-06-23 22:02:38 -06:00
2014-03-24 09:41:38 -06:00
// Frequency limits
fmin=freq-0.5*bw;
fmax=freq+0.5*bw;
// Reloop stderr
2015-05-25 15:15:20 -06:00
if (freopen("/tmp/stderr.txt","w",stderr)==NULL)
fprintf(stderr,"Failed to redirect stderr\n");
2014-03-24 05:22:20 -06:00
// Find number of satellites in frequency range
2014-06-23 22:02:38 -06:00
infile=fopen(freqlist,"r");
2018-02-13 09:35:51 -07:00
if (infile==NULL) {
printf("%s not found\n",freqlist);
*nsat=0;
return NULL;
2018-02-13 09:35:51 -07:00
} else {
for (i=0;;) {
if (fgetline(infile,line,LIM)<=0)
2018-02-13 09:35:51 -07:00
break;
2021-08-19 05:15:19 -06:00
if (line[0]=='#')
continue;
2018-02-13 09:35:51 -07:00
status=sscanf(line,"%d %lf",&satno,&freq0);
2018-03-15 01:32:29 -06:00
if (graves==1 && fabs(freq0-143.050)<1e-3)
i++;
else if (freq0>=fmin && freq0<=fmax && graves==0)
2018-02-13 09:35:51 -07:00
i++;
2018-02-13 09:35:51 -07:00
}
fclose(infile);
*nsat=i;
2014-03-24 05:22:20 -06:00
}
2014-06-02 04:32:01 -06:00
// Break out
if (i==0)
{
*nsat=0;
return NULL;
}
2014-03-24 05:22:20 -06:00
2014-03-24 09:41:38 -06:00
// Valid MJDs
for (i=0;i<n;i++)
if (mjd[i]==0.0)
break;
m=i;
2014-03-24 05:22:20 -06:00
// Allocate traces
t=(struct trace *) malloc(sizeof(struct trace)* *nsat);
// Get site
s=get_site(site_id);
// Allocate
2014-03-24 09:41:38 -06:00
p=(struct point *) malloc(sizeof(struct point)*m);
2014-03-24 05:22:20 -06:00
// Get observer position
for (i=0;i<m;i++)
2014-03-24 05:22:20 -06:00
obspos_xyz(mjd[i],s.lng,s.lat,s.alt,&p[i].obspos,&p[i].obsvel);
2014-12-14 15:03:37 -07:00
// Compute Graves positions
2015-04-28 11:01:13 -06:00
if (graves==1) {
2014-12-14 15:03:37 -07:00
sg=get_site(9999);
for (i=0;i<m;i++)
2014-12-14 15:03:37 -07:00
obspos_xyz(mjd[i],sg.lng,sg.lat,sg.alt,&p[i].grpos,&p[i].grvel);
}
// Load TLEs
tles_t twolines = load_tles(tlefile);
if (twolines.number_of_elements == 0) {
fprintf(stderr,"TLE file %s not found or empty\n", tlefile);
return NULL;
}
2014-06-23 22:02:38 -06:00
infile=fopen(freqlist,"r");
2014-03-24 05:22:20 -06:00
for (j=0;;) {
if (fgetline(infile,line,LIM)<=0)
break;
2014-09-24 01:30:00 -06:00
status=sscanf(line,"%d %lf",&satno,&freq0);
flag=0;
if (graves==1 && fabs(freq0-143.050)<1e-3)
flag=1;
else if (freq0>=fmin && freq0<=fmax && graves==0)
flag=1;
if (flag==0)
2014-03-24 05:22:20 -06:00
continue;
2014-03-24 05:22:20 -06:00
// Allocate
t[j].satno=satno;
2014-03-24 09:41:38 -06:00
t[j].site=site_id;
t[j].n=m;
2015-04-16 01:31:57 -06:00
t[j].freq0=freq0;
2014-03-24 09:41:38 -06:00
t[j].mjd=(double *) malloc(sizeof(double)*m);
t[j].freq=(double *) malloc(sizeof(double)*m);
t[j].za=(float *) malloc(sizeof(float)*m);
t[j].classfd=is_classified(t[j].satno);
t[j].graves=graves;
2022-10-18 11:40:34 -06:00
// Get TLE
orb = get_orbit_by_catalog_id(&twolines, satno);
if (orb) {
2014-03-24 05:22:20 -06:00
// Initialize
imode=init_sgdp4(orb);
2022-02-03 15:31:47 -07:00
if (imode==SGDP4_ERROR) {
printf("Error with %d, skipping\n",orb->satno);
2022-02-03 15:31:47 -07:00
continue;
}
2014-03-24 05:22:20 -06:00
// Loop over points
2014-03-24 09:41:38 -06:00
for (i=0,flag=0,tflag=0;i<m;i++) {
2014-03-24 05:22:20 -06:00
// Get satellite position
satpos_xyz(mjd[i]+2400000.5,&satpos,&satvel);
dx=satpos.x-p[i].obspos.x;
2014-03-24 05:22:20 -06:00
dy=satpos.y-p[i].obspos.y;
dz=satpos.z-p[i].obspos.z;
dvx=satvel.x-p[i].obsvel.x;
dvy=satvel.y-p[i].obsvel.y;
dvz=satvel.z-p[i].obsvel.z;
r=sqrt(dx*dx+dy*dy+dz*dz);
v=(dvx*dx+dvy*dy+dvz*dz)/r;
za=acos((p[i].obspos.x*dx+p[i].obspos.y*dy+p[i].obspos.z*dz)/(r*XKMPER))*R2D;
2014-03-24 05:22:20 -06:00
// Store
t[j].mjd[i]=mjd[i];
2014-12-14 15:03:37 -07:00
t[j].freq[i]=(1.0-v/C)*freq0;
2014-03-24 05:22:20 -06:00
t[j].za[i]=za;
2014-12-14 15:03:37 -07:00
// Compute Graves velocity/frequency
2015-04-28 11:01:13 -06:00
if (graves==1) {
dx=satpos.x-p[i].grpos.x;
2014-12-14 15:03:37 -07:00
dy=satpos.y-p[i].grpos.y;
dz=satpos.z-p[i].grpos.z;
dvx=satvel.x-p[i].grvel.x;
dvy=satvel.y-p[i].grvel.y;
dvz=satvel.z-p[i].grvel.z;
r=sqrt(dx*dx+dy*dy+dz*dz);
vg=(dvx*dx+dvy*dy+dvz*dz)/r;
2015-05-25 15:15:20 -06:00
ra=modulo(atan2(dy,dx)*R2D,360.0);
de=asin(dz/r)*R2D;
equatorial2horizontal(mjd[i],ra,de,sg.lng,sg.lat,&azi,&alt);
2014-12-14 15:03:37 -07:00
t[j].freq[i]=(1.0-v/C)*(1.0-vg/C)*freq0;
2015-05-25 15:15:20 -06:00
if (!((azi<90.0 || azi>270.0) && alt>15.0 && alt<40.0))
t[j].za[i]=100.0;
2014-12-14 15:03:37 -07:00
}
2014-03-24 05:22:20 -06:00
}
// Increment
2022-10-18 11:40:34 -06:00
j++;
}
2014-03-24 05:22:20 -06:00
}
fclose(infile);
2014-03-24 09:41:38 -06:00
fclose(stderr);
2014-03-24 05:22:20 -06:00
// Free
free_tles(&twolines);
2014-03-24 05:22:20 -06:00
free(p);
2022-10-18 11:40:34 -06:00
// Update counter
*nsat=j;
2014-03-24 05:22:20 -06:00
return t;
}
2019-04-30 15:02:40 -06:00
// Compute trace
void compute_doppler(char *tlefile,double *mjd,int n,int site_id,int satno,int graves, int skiphigh, char *outfname)
{
int i,j,imode,flag,tflag,m,status;
struct point *p;
struct site s,sg;
FILE *outfile;
orbit_t *orb;
2019-04-30 15:02:40 -06:00
xyz_t satpos,satvel;
double dx,dy,dz,dvx,dvy,dvz,r,v,rg,vg;
double freq0;
char line[LIM],text[8];
struct trace *t;
float fmin,fmax;
double ra,de,azi,alt;
double rag,deg,azig,altg;
// Reloop stderr
if (freopen("/tmp/stderr.txt","w",stderr)==NULL)
fprintf(stderr,"Failed to redirect stderr\n");
2019-04-30 15:02:40 -06:00
// Get site
s=get_site(site_id);
// Allocate
p=(struct point *) malloc(sizeof(struct point)*n);
// Get observer position
for (i=0;i<n;i++)
2019-04-30 15:02:40 -06:00
obspos_xyz(mjd[i],s.lng,s.lat,s.alt,&p[i].obspos,&p[i].obsvel);
// Compute Graves positions
if (graves==1) {
sg=get_site(9999);
for (i=0;i<n;i++)
2019-04-30 15:02:40 -06:00
obspos_xyz(mjd[i],sg.lng,sg.lat,sg.alt,&p[i].grpos,&p[i].grvel);
}
// Open output file
outfile=fopen(outfname, "w");
// Print header
if (graves==1)
fprintf(outfile, "# satno mjd r v azi alt rg vg azig altg\n");
else
fprintf(outfile, "# satno mjd r v azi alt\n");
// Load TLEs
tles_t twolines = load_tles(tlefile);
if (twolines.number_of_elements == 0) {
fprintf(stderr,"TLE file %s not found or empty\n", tlefile);
return;
}
// Get TLE
orb = get_orbit_by_catalog_id(&twolines, satno);
// Skip high satellites
if (orb && !(skiphigh == 1 && orb->rev < 10.0)) {
2019-04-30 15:02:40 -06:00
// Initialize
imode=init_sgdp4(orb);
2022-02-03 15:31:47 -07:00
if (imode==SGDP4_ERROR) {
printf("Error with %d, skipping\n",orb->satno);
}
2022-02-04 07:56:42 -07:00
2019-04-30 15:02:40 -06:00
// Loop over points
for (i=0,flag=0,tflag=0;i<n;i++) {
// Get satellite position
satpos_xyz(mjd[i]+2400000.5,&satpos,&satvel);
dx=satpos.x-p[i].obspos.x;
2019-04-30 15:02:40 -06:00
dy=satpos.y-p[i].obspos.y;
dz=satpos.z-p[i].obspos.z;
dvx=satvel.x-p[i].obsvel.x;
dvy=satvel.y-p[i].obsvel.y;
dvz=satvel.z-p[i].obsvel.z;
r=sqrt(dx*dx+dy*dy+dz*dz);
v=(dvx*dx+dvy*dy+dvz*dz)/r;
ra=modulo(atan2(dy,dx)*R2D,360.0);
de=asin(dz/r)*R2D;
2022-02-04 07:56:42 -07:00
equatorial2horizontal(mjd[i],ra,de,s.lng,s.lat,&azi,&alt);
2019-04-30 15:02:40 -06:00
// Compute Graves velocity/frequency
if (graves==1) {
dx=satpos.x-p[i].grpos.x;
2019-04-30 15:02:40 -06:00
dy=satpos.y-p[i].grpos.y;
dz=satpos.z-p[i].grpos.z;
dvx=satvel.x-p[i].grvel.x;
dvy=satvel.y-p[i].grvel.y;
dvz=satvel.z-p[i].grvel.z;
rg=sqrt(dx*dx+dy*dy+dz*dz);
vg=(dvx*dx+dvy*dy+dvz*dz)/rg;
rag=modulo(atan2(dy,dx)*R2D,360.0);
deg=asin(dz/rg)*R2D;
equatorial2horizontal(mjd[i],rag,deg,sg.lng,sg.lat,&azig,&altg);
fprintf(outfile,"%05d %14.8lf %f %f %f %f %f %f %f %f\n",orb->satno,mjd[i],r,v,azi,alt,rg,vg,azig,altg);
2019-04-30 15:02:40 -06:00
} else {
fprintf(outfile,"%05d %14.8lf %f %f %f %f\n",orb->satno,mjd[i],r,v,azi,alt);
2019-04-30 15:02:40 -06:00
}
}
}
fclose(outfile);
fclose(stderr);
// Free
free_tles(&twolines);
2019-04-30 15:02:40 -06:00
free(p);
return;
}