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

📄 svcalc.c

📁 GPS导航定位程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    sok = sin((double)ok);
    cok = cos((double)ok);

    /* Transform position in the orbital plane to position in space. */

    *x = (double)(xpk*cok - ypk*cik*sok);
    *y = (double)(xpk*sok + ypk*cik*cok);
    *z = (double)(ypk*sik);

    *vx = (double)(xdot*cok - ydot*cik*sok + WGS84oe*(*y));
    *vy = (double)(xdot*sok + ydot*cik*cok - WGS84oe*(*x));
    *vz = (double)(ydot*sik);
}

/****************************************************************************    
* Function: void EphemerisPrediction(int sv, int wk, double sec,
*                                    double *svirel
*                                    double *x, double *y, double *z,
*                                    double *vx, double *vy, double *vz)
*
* Predictions a satellite position and velocity vector from the ephemeris.
*
* Input: sv - the satellite PRN number.
*        wk - the GPS week number.
*        sec - second in the GPS week.
*
* Output: svirel - relativistic correction term, s.
*         x - the satellite x co-ordinate, m.
*         y - the satellite y co-ordinate, m.
*         z - the satellite z co-ordinate, m.
*         vx - the satellite x co-ordinate velocity, m/s.
*         vy- the satellite y co-ordinate velocity, m/s.
*         vz - the satellite z co-ordinate velocity, m/s.
*
* Return Value: None.
****************************************************************************/
void EphemerisPrediction(int sv, double sec, double *svirel,
			 double *x, double *y,double *z,
			 double *vx, double *vy, double *vz)
{
    int iter;

    double dtemp,tk,M,E,cE,sE,dEdM,P,U,R,I,cU,sU,Xp,Yp,L,sI,cI,sL,cL,
	   ecc,s2P,c2P;
    double Edot,Pdot,Udot,Rdot,sUdot,cUdot,Xpdot,Ypdot,Idot,Ldot;
    double Mdot,sqrt1mee;

    ephstruc Ephem;

    PROTECT++;
    Ephem = ephs[sv-1];         /* Get the ephemeris for the SV concerned. */
    PROTECT--;

    /* Compute the difference, in seconds, between the epoch and wk & sec. */

    tk = sec - Ephem.toe;

    if(tk>SECONDS_IN_WEEK/2.0)
	tk -= SECONDS_IN_WEEK;
    else if(tk<(-SECONDS_IN_WEEK/2.0))
	tk += SECONDS_IN_WEEK;

    /* Mean anomaly, M (rads). */

    Mdot = Ephem.n0 + Ephem.deltan;
    M = Ephem.m0 + Mdot*tk;

    /* Obtain eccentric anomaly E by solving Kepler's equation. */

    ecc = Ephem.ecc;
    sqrt1mee = sqrt(1.0-ecc*ecc);
    E = M;
    for(iter=0;iter<20;iter++)
    {
	sE = sin(E);
	cE = cos(E);
	dEdM = 1.0 / (1.0 - ecc*cE);
	if(fabs(dtemp=(M-E+ecc*sE)*dEdM) < 1.0E-14)
	    break;
	E += dtemp;
    }

    /* Compute the relativistic correction term (seconds). */

    *svirel = -4.442809305E-10 * ecc * Ephem.sqrta * sE;

    Edot = dEdM * Mdot;

    /* Compute the argument of latitude, P. */

    P = atan2(sqrt1mee*sE,cE-ecc) + Ephem.olc;
    Pdot = sqrt1mee * dEdM * Edot;

    /* Generate harmonic correction terms for P and R. */

    s2P = sin(2.0*P);
    c2P = cos(2.0*P);

    /* Compute the corrected argument of latitude, U. */

    U = P + (dtemp=Ephem.cus*s2P+Ephem.cuc*c2P);
    sU = sin(U);
    cU = cos(U);
    Udot = Pdot * (1.0 + 2.0*(Ephem.cus*c2P - Ephem.cuc*s2P));
    sUdot = cU*Udot;
    cUdot = -sU*Udot;

    /* Compute the corrected radius, R. */

    R = Ephem.a*(1.0-ecc*cE) + (dtemp=Ephem.crs*s2P+Ephem.crc*c2P);
    Rdot = Ephem.a*ecc*sE*Edot + 2.0*Pdot*(Ephem.crs*c2P - Ephem.crc*s2P);

    /* Compute the corrected orbital inclination, I. */

    I = Ephem.in0 + Ephem.idot*tk + (dtemp=Ephem.cis*s2P+Ephem.cic*c2P);
    sI = sin(I);
    cI = cos(I);
    Idot = Ephem.idot + 2.0*Pdot*(Ephem.cis*c2P - Ephem.cic*s2P);

    /* Compute the satellite's position in its orbital plane, (Xp,Yp). */

    Xp = R*cU;
    Yp = R*sU;
    Xpdot = Rdot*cU + R*cUdot;
    Ypdot = Rdot*sU + R*sUdot;

    /* Compute the longitude of the ascending node, L. */

    L = Ephem.om0 + tk*(Ephem.omd-WGS84oe) - WGS84oe*Ephem.toe;
    Ldot = Ephem.omd - WGS84oe;
    sL = sin(L);
    cL = cos(L);

    /* Compute the satellite's position in space, (x,y,z). */

    *x = Xp*cL - Yp*cI*sL;
    *y = Xp*sL + Yp*cI*cL;
    *z = Yp*sI;

    /* Satellite's velocity, (vx,vy,vz). */

    *vx = - Ldot*(*y)
	  + Xpdot*cL
	  - Ypdot*cI*sL
	  + Yp*sI*Idot*sL;

    *vy = Ldot*(*x)
	  + Xpdot*sL
	  + Ypdot*cI*cL
	  - Yp*sI*Idot*cL;

    *vz = + Yp*cI*Idot
	  + Ypdot*sI;
}

/****************************************************************************    
* Function: void AzimuthElevationAndDoppler(int calcsv)
*
* Calculate the azimuth, elevation and Doppler for a satellite.
*
* Input: calcsv - the satellite PRN number.
*
* Output: None.
*
* Return Value: None.
****************************************************************************/
void AzimuthElevationAndDoppler(int calcsv)
{
    int gwk;
    unsigned long ctic;
    double gsec;
    float elevation,azimuth,doppler;

    navstatestruc N;

    if(alms[calcsv].vflg!=VALID && ephs[calcsv].vflg!=VALID)
	return;

    CurrentTIC(&ctic);
    TICToGpsTime(ctic,&gwk,&gsec);

    /* Obtain a local copy of the current navigation state. */

    PROTECT++;
    N = CurNavState;
    PROTECT--;


    /* Update elevation, azimuth and Doppler predictions for this SV. */

    SVPredicts(calcsv+1,gwk,gsec,N.topo,N.x,N.y,N.z,&elevation,
	       &azimuth,&doppler,&sverc[calcsv],
	       &sviono[calcsv],&svtropo[calcsv]);
    ielvd[calcsv] = elevation * R2D;
    iazid[calcsv] = azimuth * R2D;

    /* Convert to range of 0 to 360 degrees. */

    if(iazid[calcsv] < 0)
	iazid[calcsv] = iazid[calcsv] + 360;
    idopp[calcsv] = doppler + 0.5;
}

/****************************************************************************    
* Function: void ElevationList(int highest[])
*
* Produces a satellite list ordered by elevation.
*
* Input: None.
*
* Output: highest - SV numbers order by elevation (highest first).
*
* Return Value: None.
****************************************************************************/
void ElevationList(int highest[])
{
    int i,isat,highelv[MAXCHANNELS],itemp;

    /* Select the highest SV's. */

    for(i=0;i<ActiveChannels;i++)
    {
	highest[i] = 0;
	highelv[i] = -99;                    /* Initial highest elevation. */
    }

    for(isat=1;isat<33;isat++)
    {
	if((alms[isat-1].vflg!=1) && (ephs[isat-1].vflg==0))
	    continue;
	if(Deselect[isat-1])
	    continue;
	if( ((ephs[isat-1].vflg==1) && (ephs[isat-1].s1hlth))
	    || ((alms[isat-1].vflg==1) && (alms[isat-1].almhlth)) )
	    continue;

	if((ielvd[isat-1]) > highelv[ActiveChannels-1])
	{
	    highest[ActiveChannels-1] = isat;
	    highelv[ActiveChannels-1] = ielvd[isat-1];
	    for(i=ActiveChannels-2; i>=0; --i)
	    {
		if (highelv[i+1] <= highelv[i])
		    break;
		itemp = highest[i+1];
		highest[i+1] = highest[i];
		highest[i] = itemp;
		itemp = highelv[i+1];
		highelv[i+1] = highelv[i];
		highelv[i] = itemp;
	    }
	}
    }
}

/****************************************************************************    
* Function: void PredictAll(void)
*
* Predicts Doppler, elevation, azimuth, and deterministic corrections for
* all satellites having ephemeris or almanac data.
*
* Input: None.
*
* Output: None.
*
* Return Value: None.
****************************************************************************/
void PredictAll(void)
{
    int isat,gwk;

    unsigned long ctic;

    float elevation,azimuth,doppler;

    double gsec;

    navstatestruc N;

    PROTECT++;
    N = CurNavState;
    PROTECT--;

    CurrentTIC(&ctic);
    TICToGpsTime(ctic,&gwk,&gsec);
    for(isat=1;isat<MAXSATELLITES;isat++)
    {
	if(alms[isat-1].vflg!=1 && ephs[isat-1].vflg!=1)
	    continue;
	PROTECT++;
	SVPredicts(isat,gwk,gsec,N.topo,N.x,N.y,N.z,&elevation,&azimuth,
		   &doppler,&sverc[isat-1],&sviono[isat-1],&svtropo[isat-1]);
	ielvd[isat-1] = elevation * R2D;
	iazid[isat-1] = azimuth * R2D;
	if(iazid[isat-1] < 0)
	    iazid[isat-1] = iazid[isat-1] + 360;               /* degrees. */
	idopp[isat-1] = doppler + 0.5;
	PROTECT--;
    }
}

⌨️ 快捷键说明

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