64 #define OMGE 7.2921151467E-5
65 #define PI 3.1415926535897932
69 #define NSATGPS (MAXPRNGPS-MINPRNGPS+1)
72 #define NSATGLO (MAXPRNGLO-MINPRNGLO+1)
75 #define NSATGAL (MAXPRNGAL-MINPRNGAL+1)
78 #define NSATQZS (MAXPRNQZS-MINPRNQZS+1)
81 #define NSATCMP (MAXPRNCMP-MINPRNCMP+1)
84 #define NSATLEO (MAXPRNLEO-MINPRNLEO+1)
87 #define NSATSBS (MAXPRNSBS-MINPRNSBS+1)
88 #define MAXSAT (NSATGPS+NSATGLO+NSATGAL+NSATQZS+NSATCMP+NSATSBS+NSATLEO)
100 {1994,7,1,0,0,0,-10},
101 {1993,7,1,0,0,0, -9},
102 {1992,7,1,0,0,0, -8},
103 {1991,1,1,0,0,0, -7},
104 {1990,1,1,0,0,0, -6},
105 {1988,1,1,0,0,0, -5},
106 {1985,7,1,0,0,0, -4},
107 {1983,7,1,0,0,0, -3},
108 {1982,7,1,0,0,0, -2},
109 {1981,7,1,0,0,0, -1},
113 void trace(
int level,
const char *format, ...)
127 t.sec+=sec; tt=floor(
t.sec);
t.time+=(
int)tt;
t.sec-=tt;
147 const int doy[]={1,32,60,91,121,152,182,213,244,274,305,335};
154 days=(
year-1970)*365+(
year-1969)/4+doy[mon-1]+
day-2+(
year%4==0&&mon>=3?1:0);
155 sec=(
int)floor(ep[5]);
156 time.time=(time_t)days*86400+(
int)ep[3]*3600+(
int)ep[4]*60+sec;
172 for (i=0;
leaps[i][0]>0;i++) {
183 for (i=0;
leaps[i][0]>0;i++) {
198 const double ep[]={2000,1,1,12,0,0};
202 trace(4,
"geterp:\n");
204 if (erp->
n<=0)
return 0;
224 for (j=0,k=erp->
n-1;j<k-1;) {
226 if (mjd<erp->
data[i].
mjd) k=i;
else j=i;
251 31,28,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31,
252 31,29,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31
254 int days,sec,mon,
day;
257 days=(
int)(
t.time/86400);
258 sec=(
int)(
t.time-(time_t)days*86400);
259 for (
day=days%1461,mon=0;mon<48;mon++) {
260 if (
day>=mday[mon])
day-=mday[mon];
else break;
262 ep[0]=1970+days/1461*4+mon/12; ep[1]=mon%12+1; ep[2]=
day+1;
263 ep[3]=sec/3600; ep[4]=sec%3600/60; ep[5]=sec%60+
t.sec;
271 sec=ep[3]*3600.0+ep[4]*60.0+ep[5];
272 ep[3]=ep[4]=ep[5]=0.0;
285 const double ep2000[]={2000,1,1,12,0,0};
287 double ut,t1,t2,t3,gmst0,gmst;
293 gmst0=24110.54841+8640184.812866*t1+0.093104*t2-6.2E-6*t3;
294 gmst=gmst0+1.002737909350795*ut;
296 return fmod(gmst,86400.0)*
PI/43200.0;
300 void matmul(
const char *tr,
int n,
int k,
int m,
double alpha,
301 const double *A,
const double *B,
double beta,
double *C)
304 int i,j,x,
f=tr[0]==
'N'?(tr[1]==
'N'?1:2):(tr[1]==
'N'?3:4);
306 for (i=0;i<n;i++)
for (j=0;j<k;j++) {
309 case 1:
for (x=0;x<m;x++)
d+=A[i+x*n]*B[x+j*m];
break;
310 case 2:
for (x=0;x<m;x++)
d+=A[i+x*n]*B[j+x*k];
break;
311 case 3:
for (x=0;x<m;x++)
d+=A[x+i*m]*B[x+j*m];
break;
312 case 4:
for (x=0;x<m;x++)
d+=A[x+i*m]*B[j+x*k];
break;
314 if (
beta==0.0) C[i+j*n]=alpha*
d;
else C[i+j*n]=alpha*
d+
beta*C[i+j*n];
327 char str[256],*p=str;
329 if (i<0||(
int)strlen(
s)<i||(
int)
sizeof(str)-1<n)
return 0.0;
330 for (
s+=i;*
s&&--n>=0;
s++) *p++=*
s==
'd'||*
s==
'D'?
'E':*
s; *p=
'\0';
331 return sscanf(str,
"%lf",&value)==1?value:0.0;
336 #define DE2RA 0.174532925E-1
338 #define TOTHRD 0.66666667
339 #define TWOPI 6.2831853
340 #define XJ3 -0.253881E-5
341 #define XKE 0.743669161E-1
342 #define XKMPER 6378.135
343 #define XMNPDA 1440.0
345 #define CK2 5.413080E-4
346 #define CK4 0.62098875E-6
347 #define QOMS2T 1.88027916E-9
352 double xnodeo,omegao,xmo,eo,xincl,xno,xndt2o,xndd6o,bstar;
353 double a1,cosio,theta2,x3thm1,eosq,betao2,betao,del1,ao,delo,xnodp,aodp,s4;
354 double qoms24,perige,pinvsq,tsi,eta,etasq,eeta,psisq,coef,coef1,c1,c2,c3,c4;
355 double c5,sinio,a3ovk2,x1mth2,theta4,xmdot,x1m5th,omgdot,xhdot1,xnodot;
356 double omgcof,xmcof,xnodcf,t2cof,xlcof,aycof,delmo,sinmo,x7thm1,c1sq,d2,d3;
357 double d4,t3cof,t4cof,t5cof,xmdf,omgadf,xnoddf,omega,xmp,tsq,xnode,delomg;
358 double delm,tcube,tfour,a,e,xl,
beta,xn,axn,xll,aynl,xlt,ayn,capu,sinepw;
359 double cosepw,epw,ecose,esine,elsq,pl,r,rdot,rfdot,betal,cosu,sinu,u,sin2u;
360 double cos2u,rk,uk,xnodek,xinck,rdotk,rfdotk,sinuk,cosuk,sinik,cosik,sinnok;
361 double cosnok,xmx,xmy,ux,uy,uz,vx,vy,vz,x,
y,z,xdot,ydot,zdot;
362 double temp,temp1,temp2,temp3,temp4,temp5,temp6,tempa,tempe,templ;
382 x3thm1=3.0*theta2-1.0;
386 del1=1.5*
CK2*x3thm1/(a1*a1*betao*betao2);
387 ao=a1*(1.0-del1*(0.5*
TOTHRD+del1*(1.0+134.0/81.0*del1)));
388 delo=1.5*
CK2*x3thm1/(ao*ao*betao*betao2);
389 xnodp=xno/(1.0+delo);
399 if ((aodp*(1.0-eo)/
AE)<(220.0/
XKMPER+
AE)) isimp=1;
407 if (perige<=98.0) s4=20.0;
408 qoms24=pow((120.0-s4)*
AE/
XKMPER,4.0);
411 pinvsq=1.0/(aodp*aodp*betao2*betao2);
416 psisq=fabs(1.0-etasq);
417 coef=qoms24*pow(tsi,4.0);
418 coef1=coef/pow(psisq,3.5);
419 c2=coef1*xnodp*(aodp*(1.0+1.5*etasq+eeta*(4.0+etasq))+0.75*
420 CK2*tsi/psisq*x3thm1*(8.0+3.0*etasq*(8.0+etasq)));
424 c3=coef*tsi*a3ovk2*xnodp*
AE*sinio/eo;
426 c4=2.0*xnodp*coef1*aodp*betao2*(eta*
427 (2.0+0.5*etasq)+eo*(0.5+2.0*etasq)-2.0*
CK2*tsi/
428 (aodp*psisq)*(-3.0*x3thm1*(1.0-2.0*eeta+etasq*
429 (1.5-0.5*eeta))+0.75*x1mth2*(2.0*etasq-eeta*
430 (1.0+etasq))*
cos(2.0*omegao)));
431 c5=2.0*coef1*aodp*betao2*(1.0+2.75*(etasq+eeta)+eeta*etasq);
432 theta4=theta2*theta2;
433 temp1=3.0*
CK2*pinvsq*xnodp;
434 temp2=temp1*
CK2*pinvsq;
435 temp3=1.25*
CK4*pinvsq*pinvsq*xnodp;
436 xmdot=xnodp+0.5*temp1*betao*x3thm1+0.0625*temp2*betao*
437 (13.0-78.0*theta2+137.0*theta4);
438 x1m5th=1.0-5.0*theta2;
439 omgdot=-0.5*temp1*x1m5th+0.0625*temp2*(7.0-114.0*theta2+
440 395.0*theta4)+temp3*(3.0-36.0*theta2+49.0*theta4);
442 xnodot=xhdot1+(0.5*temp2*(4.0-19.0*theta2)+2.0*temp3*(3.0-
444 omgcof=bstar*c3*
cos(omegao);
446 xnodcf=3.5*betao2*xhdot1*c1;
448 xlcof=0.125*a3ovk2*sinio*(3.0+5.0*cosio)/(1.0+cosio);
449 aycof=0.25*a3ovk2*sinio;
450 delmo=pow(1.0+eta*
cos(xmo),3.0);
452 x7thm1=7.0*theta2-1.0;
456 d2=4.0*aodp*tsi*c1sq;
458 d3=(17.0*aodp+s4)*
temp;
459 d4=0.5*
temp*aodp*tsi*(221.0*aodp+31.0*s4)*c1;
461 t4cof=0.25*(3.0*d3+c1*(12.0*d2+10.0*c1sq));
462 t5cof=0.2*(3.0*d4+12.0*c1*d3+6.0*d2*d2+15.0*c1sq*(2.0*d2+c1sq));
465 d2=d3=d4=t3cof=t4cof=t5cof=0.0;
468 xmdf=xmo+xmdot*tsince;
469 omgadf=omegao+omgdot*tsince;
470 xnoddf=xnodeo+xnodot*tsince;
474 xnode=xnoddf+xnodcf*tsq;
476 tempe=bstar*c4*tsince;
479 delomg=omgcof*tsince;
480 delm=xmcof*(pow(1.0+eta*
cos(xmdf),3.0)-delmo);
486 tempa=tempa-d2*tsq-d3*tcube-d4*tfour;
487 tempe=tempe+bstar*c5*(
sin(xmp)-sinmo);
488 templ=templ+t3cof*tcube+tfour*(t4cof+tsince*t5cof);
490 a=aodp*pow(tempa,2.0);
492 xl=xmp+omega+xnode+xnodp*templ;
502 ayn=e*
sin(omega)+aynl;
505 capu=fmod(xlt-xnode,
TWOPI);
514 epw=(capu-temp4+temp3-temp2)/(1.0-temp5-temp6)+temp2;
515 if (fabs(epw-temp2)<=
E6A)
break;
521 elsq=axn*axn+ayn*ayn;
526 rdot=
XKE*sqrt(a)*esine*temp1;
527 rfdot=
XKE*sqrt(pl)*temp1;
530 temp3=1.0/(1.0+betal);
531 cosu=temp2*(cosepw-axn+ayn*esine*temp3);
532 sinu=temp2*(sinepw-ayn-axn*esine*temp3);
535 cos2u=2.0*cosu*cosu-1.0;
541 rk=r*(1.0-1.5*temp2*betal*x3thm1)+0.5*temp1*x1mth2*cos2u;
542 uk=u-0.25*temp2*x7thm1*sin2u;
543 xnodek=xnode+1.5*temp2*cosio*sin2u;
544 xinck=xincl+1.5*temp2*cosio*sinio*cos2u;
545 rdotk=rdot-xn*temp1*x1mth2*sin2u;
546 rfdotk=rfdot+xn*temp1*(x1mth2*cos2u+1.5*x3thm1);
557 ux=xmx*sinuk+cosnok*cosuk;
558 uy=xmy*sinuk+sinnok*cosuk;
560 vx=xmx*cosuk-cosnok*sinuk;
561 vy=xmy*cosuk-sinnok*sinuk;
568 xdot=rdotk*ux+rfdotk*vx;
569 ydot=rdotk*uy+rfdotk*vy;
570 zdot=rdotk*uz+rfdotk*vz;
583 for (i=strlen(buff)-1;i>=0;i--) {
584 if (buff[i]==
' '||buff[i]==
'\r'||buff[i]==
'\n') buff[i]=
'\0';
593 if (strlen(buff)<69)
return 0;
596 if (
'0'<=buff[i]&&buff[i]<=
'9') cs+=(
int)(buff[i]-
'0');
597 else if (buff[i]==
'-') cs+=1;
599 return (
int)(buff[68]-
'0')==cs%10;
604 double year,doy,nddot,exp1,bstar,exp2,ep[6]={2000,1,1};
606 strncpy(
data->satno,buff+2,5);
610 data->satclass=buff[7];
611 strncpy(
data->desig,buff+9,8);
624 data->nddot=nddot*1E-5*pow(10.0,exp1);
625 data->bstar=bstar*1E-5*pow(10.0,exp2);
627 ep[0]=
year+(
year<57.0?2000.0:1900.0);
639 strncpy(satno,buff+2,5);
651 if (strcmp(satno,
data->satno)) {
652 trace(2,
"tle satno mismatch: %s %s\n",
data->satno,satno);
656 trace(2,
"tle data error: %s\n",satno);
666 if (tle->
n>=tle->
nmax) {
670 trace(1,
"tle malloc error\n");
683 return strcmp(q1->
name,q2->name);
693 if (!(fp=fopen(
file,
"r"))) {
694 trace(2,
"tle file open error: %s\n",
file);
697 while (fgets(buff,
sizeof(buff),fp)) {
700 if ((p=strchr(buff,
'#'))) *p=
'\0';
708 else if (line==1&&buff[0]==
'2'&&
checksum(buff)) {
724 strcpy(
data.name,buff);
727 if ((p=strchr(
data.name,
'('))) *p=
'\0';
740 const char *desig,
const tle_t *tle,
const erp_t *erp,
744 double tsince,rs_tle[6],rs_pef[6],gmst;
745 double R1[9]={0},R2[9]={0},R3[9]={0},W[9],erpv[5]={0};
750 for (i=j=0,k=tle->
n-1;j<=k;) {
752 if (!(stat=strcmp(name,tle->
data[i].
name)))
break;
753 if (stat<0) k=i-1;
else j=i+1;
757 if (stat&&(*satno||*desig)) {
758 for (i=0;i<tle->
n;i++) {
760 !strcmp(tle->
data[i].
desig,desig))
break;
762 if (i<tle->n) stat=0;
765 trace(3,
"no tle data: name=%s satno=%s desig=%s\n",name,satno,desig);
783 R1[0]=1.0; R1[4]=R1[8]=
cos(-erpv[1]); R1[7]=
sin(-erpv[1]); R1[5]=-R1[7];
784 R2[4]=1.0; R2[0]=R2[8]=
cos(-erpv[0]); R2[2]=
sin(-erpv[0]); R2[6]=-R2[2];
785 R3[8]=1.0; R3[0]=R3[4]=
cos(gmst); R3[3]=
sin(gmst); R3[1]=-R3[3];
786 matmul(
"NN",3,1,3,1.0,R3,rs_tle ,0.0,rs_pef );
787 matmul(
"NN",3,1,3,1.0,R3,rs_tle+3,0.0,rs_pef+3);
788 rs_pef[3]+=
OMGE*rs_pef[1];
789 rs_pef[4]-=
OMGE*rs_pef[0];
790 matmul(
"NN",3,3,3,1.0,R1,R2,0.0,W);
791 matmul(
"NN",3,1,3,1.0,W,rs_pef ,0.0,rs );
792 matmul(
"NN",3,1,3,1.0,W,rs_pef+3,0.0,rs+3);