void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    //The Julan date in TT at the epoch used in the orbital propagation
    //algorithm: 0:00 January 1 1950
    const double epochDate=2433281.5;
    double *deltaT;
    size_t numTimes;
    double SGP4Elements[7],elementEpochTime;
    bool opsMode=0;
    char opsChar;
    bool gravityModel=0;
    gravconsttype gravConstType;
    mxArray *retMat;
    double *retVec;
    mxArray *errorMat;
    double *errorVals;

    if(nrhs<2||nrhs>6||nrhs==3) {
        mexErrMsgTxt("Incorrect number of inputs.");
        return;
    }
    
    if(nlhs>2) {
        mexErrMsgTxt("Wrong number of outputs.");
        return;
    }
    
    {
        const size_t M=mxGetM(prhs[0]);
        const size_t N=mxGetN(prhs[0]);
        if(!((M==7&&N==1)||(N==7&&M==1))) {
            mexErrMsgTxt("The SGP4 elements have the wrong dimensionality.");
            return; 
        }
    }
    
    checkRealDoubleArray(prhs[0]);
    {
        size_t i;
        double *theEls;
        theEls=(double*)mxGetData(prhs[0]);
        
        //Copy the elements into SGP4Elements, adjusting the units from SI
        //to the values used here.
        for(i=0;i<5;i++) {
            SGP4Elements[i]=theEls[i];
        }
        //The multipliation by 60 changes the value from radians per second
        //to radians per minute as desired by the SGP4 code.
        SGP4Elements[5]=theEls[5]*60.0;
        SGP4Elements[6]=theEls[6];
    }
    
    {
        const size_t M=mxGetM(prhs[1]);
        const size_t N=mxGetN(prhs[1]);
        
        if((M!=1&&N!=1)||mxIsEmpty(prhs[1])) {
            mexErrMsgTxt("The times have the wrong dimensionality.");
            return;
        }
        numTimes=std::max(M,N);
    }
    checkRealDoubleArray(prhs[1]);
    deltaT=(double*)mxGetData(prhs[1]);

    if(nrhs>2&&!mxIsEmpty(prhs[2])&&!mxIsEmpty(prhs[3])) {
        const double TT1=getDoubleFromMatlab(prhs[2]);
        const double TT2=getDoubleFromMatlab(prhs[3]);
        
        if(TT1>TT2) {
            elementEpochTime=(TT1-epochDate)+TT2;
        } else {
            elementEpochTime=(TT2-epochDate)+TT1;
        }
    } else {
        //No time is given. Make sure that the deep space propagator is not
        //going to be used. Otherwise, the time value does not matter.
        elementEpochTime=0;
        
        if(2*pi/SGP4Elements[5]>=225) {
            mexErrMsgTxt("The elements imply the use of the deep space propagator, but no time was given.");
            return;  
        }
    }
    
    if(nrhs>4) {
        opsMode=getBoolFromMatlab(prhs[4]);
    }
    
    if(opsMode==0) {
        opsChar='a';
    } else {
        opsChar='i';
    }
    
    if(nrhs>5) {
        gravityModel=getBoolFromMatlab(prhs[5]);
    }
    
    if(gravityModel==0) {
        gravConstType=wgs72;
    } else {
        gravConstType=wgs84;
    }
    
    //Allocate space for the return values
    retMat=mxCreateDoubleMatrix(6,numTimes,mxREAL);
    retVec=(double*)mxGetData(retMat);
    errorMat=mxCreateDoubleMatrix(numTimes,1,mxREAL);
    errorVals=(double*)mxGetData(errorMat);
    {
        //This will be filled with the ephemeris information needed for
        //propagating the satellite.
        elsetrec satRec;
        size_t i;
        
        sgp4init(gravConstType,//Specified WGS-84 or WGS-72
                 opsChar,
                 elementEpochTime,//Epoch time of the orbital elements.
                 SGP4Elements[6],//BSTAR drag term.
                 SGP4Elements[0],//Eccentricity
                 SGP4Elements[2],//Argument of perigee
                 SGP4Elements[1],//Inclination
                 SGP4Elements[4],//Mean anomaly
                 SGP4Elements[5],//Mean motion
                 SGP4Elements[3],//Righ ascension of the ascending node.
                 satRec);//Gets filled by the function.
                
        //Do the actual propagation.
        //The division by 60 transforms the time value from seconds to
        //minutes, as the SGP4 code wants the result in minutes.
        for(i=0;i<numTimes;i++) {
            double *r=retVec+6*i;
            double *v=retVec+6*i+3;
            int j;
            
            sgp4(gravConstType, satRec,  deltaT[i]/60.0, r,  v);
            
            //Convert the units from kilometers and kilometers per second
            //to meters and meters per second.
            for(j=0;j<3;j++) {
                r[j]=1000*r[j];
                v[j]=1000*v[j];
            }
            
            errorVals[i]=(double)satRec.error;
        }
    }
    
    //Save the result
    plhs[0]=retMat;
    
    //If the error value is desired.
    if(nlhs>1) {
        plhs[1]=errorMat;
    } else{
        mxDestroyArray(errorMat);
    }
}
Пример #2
0
void twoline2rv
     (
      char      longstr1[130], char longstr2[130],
      char      typerun,  char typeinput, char opsmode,
      gravconsttype       whichconst,
      double& startmfe, double& stopmfe, double& deltamin,
      sgp4struct &satrec
     )
     {
       const double deg2rad  =   pi / 180.0;         //   0.0174532925199433
       const double xpdotp   =  1440.0 / (2.0 * pi); // 229.1831180523293

       double sec, mu, radiusearthkm, tumin, xke, j2, j3, j4, j3oj2;
       double startsec, stopsec, startdayofyr, stopdayofyr, jdstart, jdstop;
       int startyear, stopyear, startmon, stopmon, startday, stopday,
           starthr, stophr, startmin, stopmin;
       int cardnumb, numb, j;
       long revnum = 0, elnum = 0;
       char classification, intldesg[11];
       int year = 0;
       int mon, day, hr, minute, nexp, ibexp;

       getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 );

       satrec.error = 0;

       // set the implied decimal points since doing a formated read
       // fixes for bad input data values (missing, ...)
       for (j = 10; j <= 15; j++)
           if (longstr1[j] == ' ')
               longstr1[j] = '_';

       if (longstr1[44] != ' ')
           longstr1[43] = longstr1[44];
       longstr1[44] = '.';
       if (longstr1[7] == ' ')
           longstr1[7] = 'U';
       if (longstr1[9] == ' ')
           longstr1[9] = '.';
       for (j = 45; j <= 49; j++)
           if (longstr1[j] == ' ')
               longstr1[j] = '0';
       if (longstr1[51] == ' ')
           longstr1[51] = '0';
       if (longstr1[53] != ' ')
           longstr1[52] = longstr1[53];
       longstr1[53] = '.';
       longstr2[25] = '.';
       for (j = 26; j <= 32; j++)
           if (longstr2[j] == ' ')
               longstr2[j] = '0';
       if (longstr1[62] == ' ')
           longstr1[62] = '0';
       if (longstr1[68] == ' ')
           longstr1[68] = '0';

       sscanf(longstr1,"%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ",
                       &cardnumb,&satrec.noradNum,&classification, intldesg, &satrec.epochyr,
                       &satrec.epochdays,&satrec.ndot, &satrec.nddot, &nexp, &satrec.bstar,
                       &ibexp, &numb, &elnum );

       if (typerun == 'v')  // run for specified times from the file
         {
           if (longstr2[52] == ' ')
               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld %lf %lf %lf \n",
                       &cardnumb,&satrec.noradNum, &satrec.inclination,
                       &satrec.rightAscNode,&satrec.eccentricity, &satrec.argpo, &satrec.meanAnomaly, &satrec.meanMotion,
                       &revnum, &startmfe, &stopmfe, &deltamin );
             else
               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld %lf %lf %lf \n",
                       &cardnumb,&satrec.noradNum, &satrec.inclination,
                       &satrec.rightAscNode,&satrec.eccentricity, &satrec.argpo, &satrec.meanAnomaly, &satrec.meanMotion,
                       &revnum, &startmfe, &stopmfe, &deltamin );
         }
         else  // simply run -1 day to +1 day or user input times
         {
           if (longstr2[52] == ' ')
               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld \n",
                       &cardnumb,&satrec.noradNum, &satrec.inclination,
                       &satrec.rightAscNode,&satrec.eccentricity, &satrec.argpo, &satrec.meanAnomaly, &satrec.meanMotion,
                       &revnum );
             else
               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld \n",
                       &cardnumb,&satrec.noradNum, &satrec.inclination,
                       &satrec.rightAscNode,&satrec.eccentricity, &satrec.argpo, &satrec.meanAnomaly, &satrec.meanMotion,
                       &revnum );
         }

       // ---- find no, ndot, nddot ----
       satrec.meanMotionRad   = satrec.meanMotion / xpdotp; //* rad/min
       satrec.nddot= satrec.nddot * pow(10.0, nexp);
       satrec.bstar= satrec.bstar * pow(10.0, ibexp);

       // ---- convert to sgp4 units ----
       satrec.a    = pow( satrec.meanMotionRad*tumin , (-2.0/3.0) );
       satrec.ndot = satrec.ndot  / (xpdotp*1440.0);  //* ? * minperday
       satrec.nddot= satrec.nddot / (xpdotp*1440.0*1440);

       // ---- find standard orbital elements ----
       satrec.inclination = satrec.inclination  * deg2rad;
       satrec.rightAscNode = satrec.rightAscNode  * deg2rad;
       satrec.argpo = satrec.argpo  * deg2rad;
       satrec.meanAnomaly    = satrec.meanAnomaly     * deg2rad;

       satrec.alta = satrec.a*(1.0 + satrec.eccentricity) - 1.0;
       satrec.altp = satrec.a*(1.0 - satrec.eccentricity) - 1.0;

       // ----------------------------------------------------------------
       // find sgp4epoch time of element set
       // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
       // and minutes from the epoch (time)
       // ----------------------------------------------------------------

       // ---------------- temp fix for years from 1957-2056 -------------------
       // --------- correct fix will occur when year is 4-digit in tle ---------
       if (satrec.epochyr < 57)
           year= satrec.epochyr + 2000;
         else
           year= satrec.epochyr + 1900;

       days2mdhms ( year,satrec.epochdays, mon,day,hr,minute,sec );
       jday( year,mon,day,hr,minute,sec, satrec.jdsatepoch );

       // ---- input start stop times manually
       if ((typerun != 'v') && (typerun != 'c'))
         {
         // ------------- enter start/stop ymd hms values --------------------
           if (typeinput == 'e')
             {
               printf("input start prop year mon day hr min sec \n");
               // make sure there is no space at the end of the format specifiers in scanf!
               scanf( "%i %i %i %i %i %lf",&startyear, &startmon, &startday, &starthr, &startmin, &startsec);
               fflush(stdin);
               jday( startyear,startmon,startday,starthr,startmin,startsec, jdstart );

               printf("input stop prop year mon day hr min sec \n");
               scanf( "%i %i %i %i %i %lf",&stopyear, &stopmon, &stopday, &stophr, &stopmin, &stopsec);
               fflush(stdin);
               jday( stopyear,stopmon,stopday,stophr,stopmin,stopsec, jdstop );

               startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
               stopmfe  = (jdstop - satrec.jdsatepoch) * 1440.0;

               printf("input time step in minutes \n");
               scanf( "%lf",&deltamin );
             }
           // -------- enter start/stop year and days of year values -----------
           if (typeinput == 'd')
             {
               printf("input start year dayofyr \n");
               scanf( "%i %lf",&startyear, &startdayofyr );
               printf("input stop year dayofyr \n");
               scanf( "%i %lf",&stopyear, &stopdayofyr );

               days2mdhms ( startyear,startdayofyr, mon,day,hr,minute,sec );
               jday( startyear,mon,day,hr,minute,sec, jdstart );
               days2mdhms ( stopyear,stopdayofyr, mon,day,hr,minute,sec );
               jday( stopyear,mon,day,hr,minute,sec, jdstop );

               startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
               stopmfe  = (jdstop - satrec.jdsatepoch) * 1440.0;

               printf("input time step in minutes \n");
               scanf( "%lf",&deltamin );
             }
           // ------------------ enter start/stop mfe values -------------------
           if (typeinput == 'm')
             {
               printf("input start min from epoch \n");
               scanf( "%lf",&startmfe );
               printf("input stop min from epoch \n");
               scanf( "%lf",&stopmfe );
               printf("input time step in minutes \n");
               scanf( "%lf",&deltamin );
             }
         }

       // ------------ perform complete catalog evaluation, -+ 1 day ----------- 
       if (typerun == 'c')
         {
           startmfe = -1440.0;
           stopmfe  =  1440.0;
           deltamin =    10.0;
         }

       // ---------------- initialize the orbit at sgp4epoch -------------------
       sgp4init( whichconst, opsmode, satrec.noradNum, satrec.jdsatepoch-2433281.5,
               satrec.bstar, satrec.eccentricity, satrec.argpo, satrec.inclination,
               satrec.meanAnomaly, satrec.meanMotionRad, satrec.rightAscNode, satrec);
    } // end twoline2rv
Пример #3
0
/* ��GPS�������������� */
void GetTLEFromGPS(elsetrec *satrecFromGPS,double orbInfoGPS[6],double *tTime)
{
	  double MeanKepler[6];
	  double loops,RMS,PosNorm[3],endwhile;
	  double PosInTEME[3],VelInTEME[3];
	  double error[6],JToTEME[3][3],TEMEToJ[3][3];
	  double PosInJ[3],VelInJ[3],meanorbInfo[6];
	  int i,j,k,m;
	
	  cordMtxJToTEMEGet(JToTEME,tTime);
	  mtxInv((double *)TEMEToJ,(double *)JToTEME,3);
	
	  for (m=0;m<6;m++)
	  {
			meanorbInfo[m] = orbInfoGPS[m];
		}
	  Get_KplInfo(MeanKepler,meanorbInfo);
	  satrecFromGPS->bstar = 0.0002;
	  satrecFromGPS->inclo = MeanKepler[2]*PI/180;
	  satrecFromGPS->nodeo = MeanKepler[3]*PI/180;
	  satrecFromGPS->ecco = MeanKepler[1];
	  satrecFromGPS->argpo = MeanKepler[4]*PI/180;
	  satrecFromGPS->mo = MeanKepler[5]*PI/180;
	  satrecFromGPS->no = 60*sqrt(GM/(MeanKepler[0]*MeanKepler[0]*MeanKepler[0]));
	
	  loops = 0;
	  RMS = 10000;
	  endwhile = 1;
	
	  while (endwhile !=0)
		{
			loops = loops+1;
			sgp4init(satrecFromGPS);
			sgp4(PosInTEME,VelInTEME,satrecFromGPS,0);
			mtxMtp((double *)PosInJ,(double *)TEMEToJ,3,3,(double *)PosInTEME,3,1); 
			mtxMtp((double *)VelInJ,(double *)TEMEToJ,3,3,(double *)VelInTEME,3,1); 
			for (i=0;i<3;i++)
			{
				error[i] = orbInfoGPS[i]-PosInJ[i];
				PosNorm[i] = error[i];
			}
			for (j=0;j<3;j++)
			{
				error[j+3] = orbInfoGPS[j+3]-VelInJ[j];
			}
			RMS = sqrt(norm(PosNorm,3)/3);
			
			if ((RMS >= 0.01) && (loops <= 20))
			{
				for (k=0;k<6;k++)
			  {
					meanorbInfo[k] = meanorbInfo[k]+error[k];
				}
				Get_KplInfo(MeanKepler,meanorbInfo);
				satrecFromGPS->bstar = 0.0002;
				satrecFromGPS->inclo = MeanKepler[2]*PI/180;
				satrecFromGPS->nodeo = MeanKepler[3]*PI/180;
				satrecFromGPS->ecco = MeanKepler[1];
				satrecFromGPS->argpo = MeanKepler[4]*PI/180;
				satrecFromGPS->mo = MeanKepler[5]*PI/180;
				satrecFromGPS->no = 60*sqrt(GM/(MeanKepler[0]*MeanKepler[0]*MeanKepler[0]));
			}
			else
			{
				endwhile = 0;
			}
		}
    return;	
}