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

📄 sgp8.cpp

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

#define a3cof        (-(xj3)/ck2*(ae*ae*ae))
#define cosi         params[1]
#define cosio2       params[2]
#define ed           params[3]
#define edot         params[4]
#define gamma        params[5]
#define omgdt        params[6]
#define ovgpp        params[7]
#define pp           params[8]
#define qq           params[9]
#define sini         params[10]
#define sinio2       params[11]
#define theta2       params[12]
#define tthmun       params[13]
#define unm5th       params[14]
#define unmth2       params[15]
#define xgdt1        params[16]
#define xhdt1        params[17]
#define xlldot       params[18]
#define xmdt1        params[19]
#define xnd          params[20]
#define xndt         params[21]
#define xnodot       params[22]
#define xnodp        params[23]
#define simple_flag *((int *)( params + 24))

void DLL_FUNC SGP8_init( double *params, const tle_t *tle)
{
   /* Recover original mean motion (xnodp) and semimajor   */
   /* axis (aodp) from input elements. Calculate ballistic */
   /* coefficient (b term) from input b* drag term         */
   const double a1 = pow(xke / tle->xno, two_thirds);
   const double eosq = tle->eo*tle->eo;
   const double betao2 = 1.-eosq;
   const double betao = sqrt(betao2);
   const double b = tle->bstar*2./rho;
   const double sing = sin(tle->omegao);
   const double cosg = cos(tle->omegao);
   const double cos2g = cosg * cosg * 2. - 1.;
   const double half_inclination = tle->xincl*.5;
   double     alpha2, ao, aodp, b1, b2, b3,
              c0, c1, c4, c5,
              d1, d2, d3, d4, d5, del1, delo,
              eddot, eeta, eta, eta2, etdt,
              pardt1, pardt2, pardt4, po, pom2, psim2,
              r1, theta4, tsi, xndtn;

   cosi = cos(tle->xincl);
   theta2 = cosi * cosi;
   tthmun = theta2 * 3. - 1.;
   del1 = ck2*1.5*tthmun/(a1*a1*betao*betao2);
   ao = a1*(1.-del1*(two_thirds*.5 +
                    del1*(del1*1.654320987654321+1.)));
   delo = ck2*1.5*tthmun/(ao*ao*betao*betao2);
   aodp = ao/(1.-delo);
   xnodp = tle->xno/(delo+1.);

   /* Initialization */
   po = aodp*betao2;
   pom2 = 1./(po*po);
   sini = sin(tle->xincl);
   sinio2 = sin( half_inclination);
   cosio2 = cos( half_inclination);
   r1 = theta2;
   theta4 = r1*r1;
   unm5th = 1.-theta2*5.;
   unmth2 = 1.-theta2;
   r1 = ae;
   pardt1 = ck2*3.*pom2*xnodp;
   pardt2 = pardt1*ck2*pom2;
   pardt4 = ck4*1.25*pom2*pom2*xnodp;
   xmdt1 = pardt1*.5*betao*tthmun;
   xgdt1 = pardt1*-.5*unm5th;
   xhdt1 = -pardt1*cosi;
   xlldot = xnodp + xmdt1 + pardt2 * .0625 * betao *
                 (13. - theta2 * 78. + theta4 * 137.);
   omgdt = xgdt1 + pardt2 * .0625 * (7. - theta2 * 114. + theta4*
           395.) + pardt4 * (3. - theta2 * 36. + theta4 * 49.);
   xnodot = xhdt1+(pardt2*.5*(4.-theta2*19.)+
       pardt4 *2.*(3.-theta2*7.))*cosi;
   tsi = 1./(po-s);
   eta = tle->eo*s*tsi;
   r1 = eta;
   eta2 = r1*r1;
   psim2 = (r1 = 1./(1.-eta2), fabs(r1));
   alpha2 = eosq+1.;
   eeta = tle->eo*eta;
   r1 = cosg;
   d5 = tsi*psim2;
   d1 = d5/po;
   d2 = eta2*(eta2*4.5+36.)+12.;
   d3 = eta2*(eta2*2.5+15.);
   d4 = eta*(eta2*3.75+5.);
   b1 = ck2*tthmun;
   b2 = -ck2*unmth2;
   b3 = a3cof*sini;
   r1 = tsi, r1 *= r1;
   c0 = b*.5*rho*qoms2t*xnodp*aodp*(r1*r1)*
                pow(psim2, 3.5)/sqrt(alpha2);
   r1 = alpha2;
   c1 = xnodp*1.5*(r1*r1)*c0;
   c4 = d1*d3*b2;
   c5 = d5*d4*b3;
   xndt = c1*(eta2*(eosq*34.+3.)+2.+eeta*5.*(eta2+4.)
     +eosq*8.5+d1*d2*b1+c4*cos2g+c5*sing);
   xndtn = xndt/xnodp;

   /* If drag is very small, the isimp flag is set and the */
   /* equations are truncated to linear variation in mean  */
   /* motion and quadratic variation in mean anomaly       */
   r1 = xndtn*xmnpda;
   if( fabs(r1) > .00216)
      {
      const double d6 = eta*(eta2*22.5+30.);
      const double d7 = eta*(eta2*12.5+5.);
      const double d8 = eta2*(eta2+6.75)+1.;
      const double d9 = eta*(eosq*68.+6.)+tle->eo*(eta2*15.+20.);
      const double d10 = eta*5.*(eta2+4.)+tle->eo*(eta2*68.+17.);
      const double d11 = eta*(eta2*18.+72.);
      const double d12 = eta*(eta2*10.+30.);
      const double d13 = eta2*11.25+5.;
      const double d20 = two_thirds*.5*xndtn;
      const double c8 = d1*d7*b2;
      const double c9 = d5*d8*b3;
      const double tsdtts = aodp*2.*tsi*(d20*betao2+tle->eo*edot);
      const double sin2g = sing*2.*cosg;
      double d1dt, d2dt, d3dt, d4dt, d5dt, temp;
      double d14, d15, d16, d17, d18, d19, d23, d25, aldtal, psdtps;
      double c4dt, c5dt, c0dtc0, c1dtc1, rr2;
      double d1ddt, etddt, tmnddt, tsddts, xnddt, xntrdt;

      simple_flag = 0;
      edot = -c0*(eta*(eta2+4.+eosq*(eta2*7.+15.5))+tle->eo*
                 (eta2*15.+5.)+d1*d6*b1+c8*cos2g+c9*sing);
      aldtal = tle->eo*edot/alpha2;
      etdt = (edot+tle->eo*tsdtts)*tsi*s;
      psdtps = -eta*etdt*psim2;
      c0dtc0 = d20+tsdtts*4.-aldtal-psdtps*7.;
      c1dtc1 = xndtn+aldtal*4.+c0dtc0;
      d14 = tsdtts-psdtps*2.;
      d15 = (d20+tle->eo*edot/betao2)*2.;
      d1dt = d1*(d14+d15);
      d2dt = etdt*d11;
      d3dt = etdt*d12;
      d4dt = etdt*d13;
      d5dt = d5*d14;
      c4dt = b2*(d1dt*d3+d1*d3dt);
      c5dt = b3*(d5dt*d4+d5*d4dt);
      d16 = d9*etdt+d10*edot+b1*(d1dt*d2+d1*d2dt)+c4dt*
            cos2g+c5dt*sing+xgdt1*(c5*cosg-c4*2.*sin2g);
      xnddt = c1dtc1*xndt+c1*d16;
      eddot = c0dtc0*edot-c0*((eta2*3.+4.+eeta*30.+eosq*
        (eta2*21.+15.5))*etdt+(eta2*15.+5.+eeta*
         (eta2*14.+31.))*edot+b1*(d1dt*d6+d1*etdt*
             (eta2*67.5+30.))+b2*(d1dt*d7+d1*etdt*
        (eta2*37.5+5.))*cos2g+b3*(d5dt*d8+d5*etdt*eta*
        (eta2*4.+13.5))*sing+xgdt1*(c9*cosg-c8*2.*sin2g));
      r1 = edot;
      d25 = r1*r1;
      r1 = xndtn;
      d17 = xnddt/xnodp-r1*r1;
      tsddts = tsdtts*2.*(tsdtts-d20)+aodp*tsi*
               (two_thirds*betao2*d17-d20*4.*tle->eo*edot+
               (d25+tle->eo*eddot)*2.);
      etddt = (eddot+edot*2.*tsdtts)*tsi*s+tsddts*eta;
      r1 = tsdtts;
      d18 = tsddts-r1*r1;
      r1 = psdtps;
      rr2 = psdtps;
      d19 = -(r1*r1)/eta2-eta*etddt*psim2-rr2*rr2;
      d23 = etdt*etdt;
      d1ddt = d1dt*(d14+d15)+d1*(d18-d19*2.+two_thirds*d17+
         (alpha2*d25/betao2+tle->eo*eddot)*2./betao2);
      r1  = aldtal;
      xntrdt = xndt*(two_thirds*2.*d17+(d25+tle->eo*eddot)*3./
               alpha2-r1*r1*6.+d18*4.-d19*7.)+
                    c1dtc1*xnddt+c1*(c1dtc1*d16+d9*etddt+d10*
          eddot+d23*(eeta*30.+6.+eosq*68.)+etdt*edot*
          (eta2*30.+40.+eeta*272.)+d25*(eta2*68.+17.)+
          b1*(d1ddt*d2+d1dt*2.*d2dt+d1*(etddt*d11+d23*
          (eta2*54.+72.)))+b2*(d1ddt*d3+d1dt*2.*d3dt+d1
          *(etddt*d12+d23*(eta2*30.+30.)))*cos2g+b3*
          ((d5dt*d14+d5*(d18-d19*2.))*d4+d4dt*2.*d5dt+
          d5*(etddt*d13+eta*22.5*d23))*sing+xgdt1*((d20*
          7.+tle->eo*4.*edot/betao2)*(c5*cosg-c4*2.*
          sin2g)+(c5dt*2.*cosg-c4dt*4.*sin2g-xgdt1*
          (c5*sing+c4*4.*cos2g))));
      tmnddt = xnddt*1e9;
      r1 = tmnddt;
      temp = r1*r1-xndt*1e18*xntrdt;
      r1 = tmnddt;
      pp = (temp+r1*r1)/temp;
      gamma = -xntrdt/(xnddt*(pp-2.));
      xnd = xndt/(pp*gamma);
      qq = 1.-eddot/(edot*gamma);
      ed = edot/(qq*gamma);
      ovgpp = 1./(gamma*(pp+1.));
      }
   else
      {
      simple_flag = 1;
      edot = -two_thirds*xndtn*(1.-tle->eo);
      }  /* End of if (fabs(r1) > .00216) */
} /* End of SGP8() initialization */

void DLL_FUNC SGP8( const double tsince, const tle_t *tle, const double *params,
                                           double *pos, double *vel)
{
   int i;
   double
        am, aovr, axnm, aynm, beta, beta2m,
        cose, cosos, cs2f2g, csf, csfg,
        cslamb, di, diwc, dr, ecosf, em, fm,
        g1, g10, g13, g14, g2, g3, g4, g5,
        omgasm, pm, r1, rdot, rm, rr, rvdot,
        sine, sinos, sn2f2g, snf, snfg,
        sni2du, snlamb, temp, ux, uy,
        uz, vx, vy, vz, xlamb, xmam, xn,
        xnodes, y4, y5, z1, z7, zc2, zc5;

  /* Update for secular gravity and atmospheric drag */
  r1 = tle->xmo+xlldot*tsince;
  xmam = FMod2p(r1);
  omgasm = tle->omegao+omgdt*tsince;
  xnodes = tle->xnodeo+xnodot*tsince;
  if( !simple_flag)
    {
      double temp1;

      temp = 1.-gamma*tsince;
      temp1 = pow(temp, pp);
      xn = xnodp+xnd*(1.-temp1);
      em = tle->eo+ed*(1.-pow(temp, qq));
      z1 = xnd*(tsince+ovgpp*(temp*temp1-1.));
    }
  else
    {
      xn = xnodp+xndt*tsince;
      em = tle->eo+edot*tsince;
      z1 = xndt*.5*tsince*tsince;
    }  /* if(isFlagClear(SIMPLE_FLAG)) */

  z7 = two_thirds*3.5*z1/xnodp;
  r1 = xmam+z1+z7*xmdt1;
  xmam = FMod2p(r1);
  omgasm += z7*xgdt1;
  xnodes += z7*xhdt1;

  /* Solve Kepler's equation */
  zc2 = xmam+em*sin(xmam)*(em*cos(xmam)+1.);

  i = 0;
  do
    {
      double cape;

      sine = sin(zc2);
      cose = cos(zc2);
      zc5 = 1./(1.-em*cose);
      cape = (xmam+em*sine-zc2)*zc5+zc2;
      r1 = cape-zc2;
      if(fabs(r1) <= e6a) break;
      zc2 = cape;
    }
  while(i++ < 10 );

  /* Short period preliminary quantities */
  am = pow( xke / xn, two_thirds);
  beta2m = 1.-em*em;
  sinos = sin(omgasm);
  cosos = cos(omgasm);
  axnm = em*cosos;
  aynm = em*sinos;
  pm = am*beta2m;
  g1 = 1./pm;
  g2 = ck2*.5*g1;
  g3 = g2*g1;
  beta = sqrt(beta2m);
  g4 = a3cof * .25 * sini;
  g5 = a3cof * .25 * g1;
  snf = beta*sine*zc5;
  csf = (cose-em)*zc5;
  fm = atan2(snf, csf);
  if( fm < 0.)
     fm += pi + pi;
  snfg = snf*cosos+csf*sinos;
  csfg = csf*cosos-snf*sinos;
  sn2f2g = snfg*2.*csfg;
  r1 = csfg;
  cs2f2g = r1*r1*2.-1.;
  ecosf = em*csf;
  g10 = fm-xmam+em*snf;
  rm = pm/(ecosf+1.);
  aovr = am/rm;
  g13 = xn*aovr;
  g14 = -g13*aovr;
  dr = g2*(unmth2*cs2f2g-tthmun*3.)-g4*snfg;
  diwc = g3*3.*sini*cs2f2g-g5*aynm;
  di = diwc*cosi;

  /* Update for short period periodics */
  sni2du = sinio2*(g3*((1.-theta2*7.)*.5*sn2f2g-unm5th*3.*g10)-
      g5*sini*csfg*(ecosf+2.))-g5*.5f*theta2*axnm/cosio2;
  xlamb = fm+omgasm+xnodes+g3*((cosi*6.+1.-theta2*7.)*
     .5*sn2f2g-(unm5th+cosi*2.)*3.*g10)+g5*sini*
          (cosi*axnm/(cosi+1.)-(ecosf+2.)*csfg);
  y4 = sinio2*snfg+csfg*sni2du+snfg*.5*cosio2*di;
  y5 = sinio2*csfg-snfg*sni2du+csfg*.5*cosio2*di;
  rr = rm+dr;
  rdot = xn*am*em*snf/beta+g14*(g2*2.*unmth2*sn2f2g+g4*csfg);
  r1 = am;
  rvdot = xn*(r1*r1)*beta/rm+g14 *
          dr+am*g13*sini*diwc;

  /* Orientation vectors */
  snlamb = sin(xlamb);
  cslamb = cos(xlamb);
  temp = (y5*snlamb-y4*cslamb)*2.;
  ux = y4*temp+cslamb;
  vx = y5*temp-snlamb;
  temp = (y5*cslamb+y4*snlamb)*2.;
  uy = -y4*temp+snlamb;
  vy = -y5*temp+cslamb;
  temp = sqrt(1.-y4*y4-y5*y5)*2.;
  uz = y4*temp;
  vz = y5*temp;

  /* Position and velocity */
  pos[0] = rr*ux*xkmper;
  pos[1] = rr*uy*xkmper;
  pos[2] = rr*uz*xkmper;
  if( vel)
     {
     vel[0] = (rdot*ux+rvdot*vx)*xkmper;
     vel[1] = (rdot*uy+rvdot*vy)*xkmper;
     vel[2] = (rdot*uz+rvdot*vz)*xkmper;
     }

} /* SGP8 */

⌨️ 快捷键说明

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