예제 #1
0
파일: OrbitUtil.cs 프로젝트: yxw027/GNSSer
        public static RmsedXYZ GetPosXYZ(EphemerisParam eph, double secOfWeek)
        {
            GpstkOrbitUtil o   = new GpstkOrbitUtil(eph);
            Xvt            xvt = o.svXvt(secOfWeek);

            XYZ xyzGpstk  = XYZ.Parse(xvt.x);
            XYZ velercity = XYZ.Parse(xvt.v);

            return(new RmsedXYZ(xyzGpstk, velercity));
        }
예제 #2
0
        // Compute satellite position at the given time.
        public Xvt svXvt(double t)
        {
            //  if(!dataLoadedFlag)
            //  GPSTK_THROW(InvalidRequest("Data not loaded"));

            Xvt    sv = new Xvt();
            double E;           // eccentric anomaly
            // double delea;           // delta eccentric anomaly during iteration
            double tk;          // elapsed time since Toe
            //double elaptc;          // elapsed time since Toc
            //double dtc,dtr;
            double q, sinE, cosE;
            double GSTA, GCTA;
            double en;
            double M;           // mean anomaly
            // double F;
            double G;           // temporary real variables
            double u, u_u, cos2u, sin2u, du, dr, di, U, R, f, eyek;
            double omgk, cosu, sinu, xip, yip, cosOmgk, sinOmgk, cosEyek, sinEyek;
            double xef, yef, zef, dek, dlk, div, domk, duv, drv;
            double dxp, dyp, vxef, vyef, vzef;


            Geo.Referencing.IEllipsoid ell = GnssSystem.GetGnssSystem(prn.SatelliteType).Ellipsoid;
            double sqrtGM = SQRT(ell.GM);
            double twoPI  = 2.0e0 * PI;
            double e;                   // eccentricity
            double eyeDot;              // dt inclination
            double sqrtA  = SQRT(A);    // A is semi-major axis of orbit
            double ToeSOW = this.ctToe; // GPSWeekSecond(ctToe).sow;    // SOW is time-system-independent

            e      = ecc;
            eyeDot = idot;

            // Compute time since ephemeris & clock epochs
            tk = Time.GetDifferSecondOfWeek(t, ctToe);// t - ctToe;

            // Compute A at time of interest (LNAV: Adot==0)
            double Ak = A + Adot * tk;

            // Compute mean motion (LNAV: dndot==0)
            double dnA = dn + 0.5 * dndot * tk;

            en = (sqrtGM / (A * sqrtA)) + dnA;     // Eqn specifies A0, not Ak

            // In-plane angles
            //     meana - Mean anomaly
            //     ea    - Eccentric anomaly
            //     truea - True anomaly
            M = M0 + tk * en;
            M = fmod(M, twoPI);

            E = OrbitUtil.KeplerEqForEccAnomaly(M, e);
            //E = M + e * sin(M);

            //int loop_cnt = 1;
            //do
            //{
            //    F = M - (E - e * sin(E));
            //    G = 1.0 - e * cos(E);
            //    delea = F / G;
            //    E = E + delea;
            //    loop_cnt++;
            //} while ((fabs(delea) > 1.0e-11) && (loop_cnt <= 20));

            // Compute clock corrections
            sv.relcorr  = svRelativity(t);
            sv.clkbias  = svClockBias(t);
            sv.clkdrift = svClockDrift(t);
            // sv.frame = ReferenceFrame.WGS84;

            // Compute true anomaly
            sinE = sin(E);
            cosE = cos(E);

            q = SQRT(1.0 - e * e);

            G = 1.0 - e * cosE;

            //  G*SIN(TA) AND G*COS(TA)
            GSTA = q * sinE;
            GCTA = cosE - e;

            //  True anomaly
            f = atan2(GSTA, GCTA);

            // Argument of lat and correction terms (2nd harmonic)
            u     = f + Omega;
            u_u   = 2.0 * u;
            cos2u = cos(u_u);
            sin2u = sin(u_u);

            du = cos2u * Cuc + sin2u * Cus;
            dr = cos2u * Crc + sin2u * Crs;
            di = cos2u * Cic + sin2u * Cis;

            // U = updated argument of lat, R = radius, AINC = inclination
            U    = u + du;
            R    = Ak * G + dr;
            eyek = eye0 + eyeDot * tk + di;

            //  Longitude of ascending node (ANLON)
            omgk = OMEGA0 + (OMEGAdot - ell.AngleVelocity) * tk
                   - ell.AngleVelocity * ToeSOW;

            // In plane location
            cosu = cos(U);
            sinu = sin(U);
            xip  = R * cosu;
            yip  = R * sinu;

            //  Angles for rotation to earth fixed
            cosOmgk = cos(omgk);
            sinOmgk = sin(omgk);
            cosEyek = cos(eyek);
            sinEyek = sin(eyek);

            // Earth fixed coordinates in meters
            xef     = xip * cosOmgk - yip * cosEyek * sinOmgk;
            yef     = xip * sinOmgk + yip * cosEyek * cosOmgk;
            zef     = yip * sinEyek;
            sv.x[0] = xef;
            sv.x[1] = yef;
            sv.x[2] = zef;

            // Compute velocity of rotation coordinates
            dek  = en * Ak / R;
            dlk  = sqrtA * q * sqrtGM / (R * R);
            div  = eyeDot - 2.0e0 * dlk * (Cic * sin2u - Cis * cos2u);
            domk = OMEGAdot - ell.AngleVelocity;
            duv  = dlk * (1.0 + 2.0 * (Cus * cos2u - Cuc * sin2u));
            drv  = Ak * e * dek * sinE - 2.0 * dlk * (Crc * sin2u - Crs * cos2u);
            dxp  = drv * cosu - R * sinu * duv;
            dyp  = drv * sinu + R * cosu * duv;

            // Calculate velocities
            vxef = dxp * cosOmgk - xip * sinOmgk * domk - dyp * cosEyek * sinOmgk
                   + yip * (sinEyek * sinOmgk * div - cosEyek * cosOmgk * domk);
            vyef = dxp * sinOmgk + xip * cosOmgk * domk + dyp * cosEyek * cosOmgk
                   - yip * (sinEyek * cosOmgk * div + cosEyek * sinOmgk * domk);
            vzef = dyp * sinEyek + yip * cosEyek * div;

            // Move results into output variables
            sv.v[0] = vxef;
            sv.v[1] = vyef;
            sv.v[2] = vzef;

            return(sv);
        }