⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.cpp

📁 卫星计算码
💻 CPP
字号:
#include <math.h>
#include <stdio.h>
#include "norad.h"
#include "norad_in.h"

#define x3thm1       params[0]
#define x1mth2       params[1]
#define c1           params[2]
#define c4           params[3]
#define xnodcf       params[4]
#define t2cof        params[5]
#define xlcof        params[6]
#define aycof        params[7]
#define x7thm1       params[8]

void sxpx_common_init( double *params, const tle_t *tle,
                                  init_t *init, deep_arg_t *deep_arg)
{
   double
         a1, ao, c2, del1,
         delo, eeta, etasq, perige, pinvsq,
         psisq, qoms24, temp1, temp2, temp3,
         theta4, tsi_squared, x1m5th, xhdot1;

   /* Recover original mean motion (xnodp) and   */
   /* semimajor axis (aodp) from input elements. */
   a1 = pow(xke/tle->xno,two_thirds);
   deep_arg->cosio = cos(tle->xincl);
   deep_arg->theta2 = deep_arg->cosio*deep_arg->cosio;
   x3thm1 = 3*deep_arg->theta2-1;
   deep_arg->eosq = tle->eo*tle->eo;
   deep_arg->betao2 = 1-deep_arg->eosq;
   deep_arg->betao = sqrt(deep_arg->betao2);
   del1 = 1.5*ck2*x3thm1/(a1*a1*deep_arg->betao*deep_arg->betao2);
   ao = a1*(1-del1*(0.5*two_thirds+del1*(1.+134./81.*del1)));
   delo = 1.5*ck2*x3thm1/(ao*ao*deep_arg->betao*deep_arg->betao2);
   deep_arg->xnodp = tle->xno/(1+delo);
   deep_arg->aodp = ao/(1-delo);

   /* For perigee below 156 km, the values */
   /* of s and qoms2t are altered.         */
   init->s4 = s;
   qoms24 = qoms2t;
   perige = (deep_arg->aodp*(1-tle->eo)-ae)*xkmper;
   if(perige < 156)
      {
      double temp_val, temp_val_squared;

      if(perige <= 98)
         init->s4 = 20;
      else
         init->s4 = perige-78;
      temp_val = (120. - init->s4) * ae / xkmper;
      temp_val_squared = temp_val * temp_val;
      qoms24 = temp_val_squared * temp_val_squared;
      init->s4 = init->s4/xkmper+ae;
      }  /* End of if(perige <= 156) */

   pinvsq = 1/(deep_arg->aodp*deep_arg->aodp*
            deep_arg->betao2*deep_arg->betao2);
   init->tsi = 1/(deep_arg->aodp-init->s4);
   init->eta = deep_arg->aodp*tle->eo*init->tsi;
   etasq = init->eta*init->eta;
   eeta = tle->eo*init->eta;
   psisq = fabs(1-etasq);
   tsi_squared = init->tsi * init->tsi;
   init->coef = qoms24 * tsi_squared * tsi_squared;
   init->coef1 = init->coef / pow(psisq,3.5);
   c2 = init->coef1 * deep_arg->xnodp * (deep_arg->aodp*(1+1.5*etasq+eeta*
   (4+etasq))+0.75*ck2*init->tsi/psisq*x3thm1*(8+3*etasq*(8+etasq)));
   c1 = tle->bstar*c2;
   deep_arg->sinio = sin(tle->xincl);
   init->a3ovk2 = -xj3/ck2*ae*ae*ae;
   x1mth2 = 1-deep_arg->theta2;
   c4 = 2*deep_arg->xnodp*init->coef1*deep_arg->aodp*deep_arg->betao2*
        (init->eta*(2+0.5*etasq)+tle->eo*(0.5+2*etasq)-2*ck2*init->tsi/
        (deep_arg->aodp*psisq)*(-3*x3thm1*(1-2*eeta+etasq*
        (1.5-0.5*eeta))+0.75*x1mth2*(2*etasq-eeta*(1+etasq))*
        cos(2*tle->omegao)));
   theta4 = deep_arg->theta2*deep_arg->theta2;
   temp1 = 3*ck2*pinvsq*deep_arg->xnodp;
   temp2 = temp1*ck2*pinvsq;
   temp3 = 1.25*ck4*pinvsq*pinvsq*deep_arg->xnodp;
   deep_arg->xmdot = deep_arg->xnodp+0.5*temp1*deep_arg->betao*
               x3thm1+0.0625*temp2*deep_arg->betao*
                    (13-78*deep_arg->theta2+137*theta4);
   x1m5th = 1-5*deep_arg->theta2;
   deep_arg->omgdot = -0.5*temp1*x1m5th+0.0625*temp2*
                     (7-114*deep_arg->theta2+395*theta4)+
                temp3*(3-36*deep_arg->theta2+49*theta4);
   xhdot1 = -temp1*deep_arg->cosio;
   deep_arg->xnodot = xhdot1+(0.5*temp2*(4-19*deep_arg->theta2)+
           2*temp3*(3-7*deep_arg->theta2))*deep_arg->cosio;
   xnodcf = 3.5*deep_arg->betao2*xhdot1*c1;
   t2cof = 1.5*c1;
   xlcof = 0.125*init->a3ovk2*deep_arg->sinio*(3+5*deep_arg->cosio)/
           (1+deep_arg->cosio);
   aycof = 0.25*init->a3ovk2*deep_arg->sinio;
   x7thm1 = 7*deep_arg->theta2-1;
}

void sxpx_posn_vel( const double xnode, const double a, const double e,
      const double *params, const double cosio, const double sinio,
      const double xincl, const double omega,
      const double xl, double *pos, double *vel)
{
  /* Long period periodics */
   const double axn = e*cos(omega);
   double temp = 1/(a*(1.-e*e));
   const double xll = temp*xlcof*axn;
   const double aynl = temp*aycof;
   const double xlt = xl+xll;
   const double ayn = e*sin(omega)+aynl;
   const double elsq = axn*axn+ayn*ayn;
   const double capu = FMod2p(xlt-xnode);
   double temp1, temp2, temp3, temp4, temp5, temp6;
   double ecose, esine, pl, r;
   double betal;
   double u, sinu, cosu, sin2u, cos2u;
   double rk, uk, xnodek, xinck;
   double sinuk, cosuk, sinik, cosik, sinnok, cosnok, xmx, xmy;
   double sinepw, cosepw;
   double ux, uy, uz;
   int i;

                /* Added 29 Mar 2003:  extremely decayed satellites can    */
                /* end up "orbiting" within the earth, and then with a < 0 */
                /* or q < 0.  If evaluating the state vector would lead to */
                /* a math error,  we set a zero posn/vel and quit.         */
                /* Revised 16 Oct 2004 to catch a few other "problem cases" */

   if( a <= 0. || a * (1. - e) <= 0. || elsq >= 1.)
      {
      printf( "ERROR: a = %lf; e = %lf\n", a, e);
      for( i = 0; i < 3; i++)
         {
         pos[i] = 0.;
         if( vel)
            vel[i] = 0.;
         }
      return;
      }
  /* Solve Kepler's' Equation */
   i = 0;
   temp2 = capu;
   do
      {
      double epw;

      sinepw = sin(temp2);
      cosepw = cos(temp2);
      temp3 = axn*sinepw;
      temp4 = ayn*cosepw;
      temp5 = axn*cosepw;
      temp6 = ayn*sinepw;
      epw = (capu-temp4+temp3-temp2)/(1-temp5-temp6)+temp2;
      if(fabs(epw-temp2) <= e6a) break;
      temp2 = epw;
      }
   while( i++ < 10 );

  /* Short period preliminary quantities */
   ecose = temp5+temp6;
   esine = temp3-temp4;
   temp = 1-elsq;
   pl = a*temp;
   r = a*(1-ecose);
   temp1 = 1/r;
   temp2 = a*temp1;
   betal = sqrt(temp);
   temp3 = 1/(1+betal);
   cosu = temp2*(cosepw-axn+ayn*esine*temp3);
   sinu = temp2*(sinepw-ayn-axn*esine*temp3);
   u = atan2( sinu, cosu);
   sin2u = 2*sinu*cosu;
   cos2u = 2*cosu*cosu-1;
   temp = 1/pl;
   temp1 = ck2*temp;
   temp2 = temp1*temp;

  /* Update for short periodics */
   rk = r*(1-1.5*temp2*betal*x3thm1)+0.5*temp1*x1mth2*cos2u;
   uk = u-0.25*temp2*x7thm1*sin2u;
   xnodek = xnode+1.5*temp2*cosio*sin2u;
   xinck = xincl+1.5*temp2*cosio*sinio*cos2u;

  /* Orientation vectors */
   sinuk = sin(uk);
   cosuk = cos(uk);
   sinik = sin(xinck);
   cosik = cos(xinck);
   sinnok = sin(xnodek);
   cosnok = cos(xnodek);
   xmx = -sinnok*cosik;
   xmy = cosnok*cosik;
   ux = xmx*sinuk+cosnok*cosuk;
   uy = xmy*sinuk+sinnok*cosuk;
   uz = sinik*sinuk;

  /* Position and velocity */
   pos[0] = rk*ux*xkmper;
   pos[1] = rk*uy*xkmper;
   pos[2] = rk*uz*xkmper;
   if( vel)
      {
      const double rdot = xke*sqrt(a)*esine/r;
      const double rfdot = xke*sqrt(pl)/r;
      const double xn = xke/(a * sqrt(a));
      const double rdotk = rdot-xn*temp1*x1mth2*sin2u;
      const double rfdotk = rfdot+xn*temp1*(x1mth2*cos2u+1.5*x3thm1);
      const double vx = xmx*cosuk-cosnok*sinuk;
      const double vy = xmy*cosuk-sinnok*sinuk;
      const double vz = sinik*cosuk;

      vel[0] = (rdotk*ux+rfdotk*vx)*xkmper;
      vel[1] = (rdotk*uy+rfdotk*vy)*xkmper;
      vel[2] = (rdotk*uz+rfdotk*vz)*xkmper;
      }
} /*SGP4*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -