コード例 #1
0
ファイル: SPP.cs プロジェクト: eglrp/SPP
        /// <summary>
        /// 根据O_FileDataHead中的卫星PRN和TOC找出N_FileData中对应的星历序号
        /// </summary>
        /// <param name="sat_PRN">O_FileDataHead中的卫星PRN</param>
        /// <param name="epoch">O_FileDataHead中的TOC</param>
        /// <returns>N_FileData中对应的星历序号</returns>
        public int FindBestEph(int sat_PRN, Time epoch)
        {
            GPSTime oTime = TimeToGPSTime(epoch);

            for (int i = 0; i < N_FileSum.n_FileDataSum.Count; i++)
            {
                if (sat_PRN == N_FileSum.n_FileDataSum[i].PRN)
                {
                    GPSTime nTime = TimeToGPSTime(N_FileSum.n_FileDataSum[i].TOC);
                    if (Math.Abs(oTime.GPSSecond - nTime.GPSSecond) < 3600.0)
                    {
                        return(i);
                    }
                }
            }
            return(-1);
        }
コード例 #2
0
ファイル: SPP.cs プロジェクト: eglrp/SPP
        /// <summary>
        /// 计算卫星在信号发射时的位置
        /// </summary>
        /// <param name="n_FileData">星历数据</param>
        /// <param name="satSendTime">卫星信号发射的时间</param>
        /// <returns>卫星在地心坐标系中的空间直角坐标</returns>
        public Position SatellitePosition(N_FileData n_FileData, GPSTime satSendTime)
        {
            Position satPosition = new Position();
            double   A, n0, tk, n, Mk, Ek, E0, f, uu, omega_uk, omega_rk, omega_ik, uk, rk, ik, xk, yk, Lk;

            A  = Math.Pow(n_FileData.SqrtA, 2);//轨道长半轴
            n0 = Math.Sqrt((Constant.GM / Math.Pow(A, 3)));
            tk = satSendTime.GPSWeek * 604800 + satSendTime.GPSSecond - n_FileData.GPSWeek * 604800 - n_FileData.TOE;
            if (tk > 302400)
            {
                tk = tk - 604800;
            }
            else if (tk < -302400)
            {
                tk = tk + 604800;
            }
            n  = n0 + n_FileData.DetlaN;
            Mk = n_FileData.M0 + n * tk;
            E0 = Mk;
            Ek = Mk + n_FileData.E * Math.Sin(E0);
            while (Math.Abs(Ek - E0) > Math.Pow(10, -12))
            {
                E0 = Ek;
                Ek = Mk + n_FileData.E * Math.Sin(E0);
            }
            f              = Math.Atan2((Math.Sqrt(1 - Math.Pow(n_FileData.E, 2))) * Math.Sin(Ek), Math.Cos(Ek) - n_FileData.E);
            uu             = f + n_FileData.OmegaLow;
            omega_uk       = n_FileData.Cus * Math.Sin(2 * uu) + n_FileData.Cuc * Math.Cos(2 * uu);
            omega_rk       = n_FileData.Crs * Math.Sin(2 * uu) + n_FileData.Crc * Math.Cos(2 * uu);
            omega_ik       = n_FileData.Cis * Math.Sin(2 * uu) + n_FileData.Cic * Math.Cos(2 * uu);
            uk             = uu + omega_uk;
            rk             = A * (1 - n_FileData.E * Math.Cos(Ek)) + omega_rk;
            ik             = n_FileData.I0 + omega_ik + n_FileData.IDot * tk;
            xk             = rk * Math.Cos(uk);
            yk             = rk * Math.Sin(uk);
            Lk             = n_FileData.Omega + (n_FileData.OmegaDot - Constant.OmegaDotE) * tk - Constant.OmegaDotE * n_FileData.TOE;
            satPosition.XX = xk * Math.Cos(Lk) - yk * Math.Cos(ik) * Math.Sin(Lk);
            satPosition.YY = xk * Math.Sin(Lk) + yk * Math.Cos(ik) * Math.Cos(Lk);
            satPosition.ZZ = yk * Math.Sin(ik);
            return(satPosition);
        }
コード例 #3
0
ファイル: SPP.cs プロジェクト: eglrp/SPP
        /// <summary>
        /// 通用时转换为GPS时
        /// </summary>
        /// <param name="time">通用时</param>
        /// <returns>GPS时</returns>
        public GPSTime TimeToGPSTime(Time time)
        {
            GPSTime gpsTime = new GPSTime();
            double  JD, UT;
            int     y, m;

            UT = time.Hour + (time.Minute / 60.0) + (time.Second / 3600.0);
            if (time.Month <= 2)
            {
                y = time.Year - 1;
                m = time.Month + 12;
            }
            else
            {
                y = time.Year;
                m = time.Month;
            }
            JD = (int)(365.25 * y) + (int)(30.6001 * (m + 1)) + time.Day + (UT / 24) + 1720981.5;
            gpsTime.GPSWeek   = (int)((JD - 2444244.5) / 7);
            gpsTime.GPSSecond = (JD - 2444244.5) * 3600 * 24 - gpsTime.GPSWeek * 3600 * 24 * 7;
            return(gpsTime);
        }
コード例 #4
0
ファイル: SPP.cs プロジェクト: eglrp/SPP
        public bool Positioning()
        {
            ReceiverPositionSum.receiverPositionSum.Clear();

            OneEpochData        oneEpochData    = new OneEpochData();
            List <OneEpochData> oneEpochDataSum = new List <OneEpochData>();

            GPSTime  TR = new GPSTime(); //历元时刻
            double   x, y, z, cdtr;      //测站位置和钟差
            double   xx = 0;
            double   yy = 0;
            double   zz = 0;                //用于储存每个历元的定位结果,用于赋值给下一历元的初值
            double   deltaT0Si;             //卫星信号传播时间
            double   dtSi;                  //卫星钟差
            double   deltaT1Si;
            double   rho;                   //伪距
            GPSTime  TSi  = new GPSTime();  //卫星信号发射概略时刻
            Position XSi  = new Position(); //卫星在TSi时刻的位置
            Position XSiW = new Position(); //卫星自转改正后的位置
            GPSTime  T1Si = new GPSTime();  //卫星信号发射时刻
            double   RSi;                   //测站和卫星的几何距离

            double b0Si, b1Si, b2Si, b3Si;  //卫星方向余弦
            double ISi;                     //卫星在观测方程中的余数项

            double[,] A;
            double[,] AT;
            double[,] ATA    = new double[4, 4];
            double[,] revATA = new double[4, 4];
            double[,] L;
            double[,] ATL = new double[4, 1];
            double[,] xi;

            double sumX = 0;
            double sumY = 0;
            double sumZ = 0;

            if (O_FlieSum.o_FileDataSum.Count == 0)
            {
                MessageBox.Show("没有打开观测数据文件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }
            if (N_FileSum.n_FileDataSum.Count == 0)
            {
                MessageBox.Show("没有打开导航电文文件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            for (int i = 0; i < O_FlieSum.o_FileDataSum.Count; i++)//循环全部历元
            {
                x    = xx;
                y    = yy;
                z    = zz; //每个历元初值等于上个历元的定位结果,第一个历元为0
                cdtr = 0;  //第一次循环为0
                xi   = new double[4, 1];

                do//解算一个历元
                {
                    //************************有改动,X+
                    x    = x + xi[0, 0];//第一次改正数为0,以后每次循环将改正数累加。
                    y    = y + xi[1, 0];
                    z    = z + xi[2, 0];
                    cdtr = cdtr + xi[3, 0];

                    for (int j = 0; j < O_FlieSum.o_FileDataSum[i].o_FileDataHead.Sat_Num; j++) //循环一个历元中的全部卫星
                    {
                        TR = TimeToGPSTime(O_FlieSum.o_FileDataSum[i].o_FileDataHead.Epoch);    //O-FileDataHead中的历元时刻转换为GPS时

                        int prnNum = FindBestEph(O_FlieSum.o_FileDataSum[i].o_FileDataHead.Sat_PRN[j], O_FlieSum.o_FileDataSum[i].o_FileDataHead.Epoch);
                        if (prnNum == -1)
                        {
                            MessageBox.Show("卫星{0}没有对应的星历文件", O_FlieSum.o_FileDataSum[i].o_FileDataHead.Sat_PRN[j].ToString());
                        }

                        rho = O_FlieSum.o_FileDataSum[i].o_FileDataObs[j].C1;

                        //************有改动,-cdtr/Constant.SpeedOfLight
                        GPSTime gpsTimeTOC = TimeToGPSTime(N_FileSum.n_FileDataSum[prnNum].TOC);
                        dtSi      = N_FileSum.n_FileDataSum[prnNum].ClkBias + N_FileSum.n_FileDataSum[prnNum].ClkDrift * (TR.GPSSecond - gpsTimeTOC.GPSSecond) + N_FileSum.n_FileDataSum[prnNum].ClkDriftRate * Math.Pow((TR.GPSSecond - gpsTimeTOC.GPSSecond), 2);
                        deltaT1Si = (rho / Constant.SpeedOfLight) + N_FileSum.n_FileDataSum[prnNum].ClkBias + N_FileSum.n_FileDataSum[prnNum].ClkDrift * (TR.GPSSecond - gpsTimeTOC.GPSSecond) + N_FileSum.n_FileDataSum[prnNum].ClkDriftRate * Math.Pow((TR.GPSSecond - gpsTimeTOC.GPSSecond), 2) - cdtr / Constant.SpeedOfLight;
                        do
                        {
                            deltaT0Si     = deltaT1Si;
                            TSi.GPSSecond = TR.GPSSecond - deltaT0Si;
                            TSi.GPSWeek   = TR.GPSWeek;
                            XSi           = SatellitePosition(N_FileSum.n_FileDataSum[prnNum], TSi);
                            XSiW          = EarthRotationCorrection(deltaT0Si, XSi);
                            //******************有改动,O_FlieSum.o_FileHeadSum.Approx_Position.XX.YY.ZZ   XYZ
                            RSi       = Math.Sqrt(Math.Pow(XSiW.XX - (O_FlieSum.o_FileHeadSum.Approx_Position.XX + x), 2) + Math.Pow(XSiW.YY - (O_FlieSum.o_FileHeadSum.Approx_Position.YY + y), 2) + Math.Pow(XSiW.ZZ - (O_FlieSum.o_FileHeadSum.Approx_Position.ZZ + z), 2));
                            deltaT1Si = RSi / Constant.SpeedOfLight;
                        } while (Math.Abs(deltaT1Si - deltaT0Si) > Math.Pow(10, -7));
                        T1Si.GPSSecond = TR.GPSSecond - deltaT1Si;
                        T1Si.GPSWeek   = TR.GPSWeek;
                        //*********************有改动O_FlieSum.o_FileHeadSum.Approx_Position.XX + X,以及/RSi
                        b0Si = (O_FlieSum.o_FileHeadSum.Approx_Position.XX + x - XSiW.XX) / rho;
                        b1Si = (O_FlieSum.o_FileHeadSum.Approx_Position.YY + y - XSiW.YY) / rho;
                        b2Si = (O_FlieSum.o_FileHeadSum.Approx_Position.ZZ + z - XSiW.ZZ) / rho;
                        b3Si = 1.0;
                        //****************************有改动
                        ISi = rho - RSi + dtSi * Constant.SpeedOfLight - cdtr;

                        oneEpochData.b0S = b0Si;
                        oneEpochData.b1S = b1Si;
                        oneEpochData.b2S = b2Si;
                        oneEpochData.b3S = b3Si;
                        oneEpochData.IS  = ISi;
                        oneEpochDataSum.Add(oneEpochData);
                        oneEpochData = new OneEpochData();
                    }//for j

                    A  = new double[oneEpochDataSum.Count, 4];
                    L  = new double[oneEpochDataSum.Count, 1];
                    AT = new double[4, oneEpochDataSum.Count];
                    for (int k = 0; k < oneEpochDataSum.Count; k++)
                    {
                        A[k, 0] = oneEpochDataSum[k].b0S;
                        A[k, 1] = oneEpochDataSum[k].b1S;
                        A[k, 2] = oneEpochDataSum[k].b2S;
                        A[k, 3] = oneEpochDataSum[k].b3S;
                        L[k, 0] = oneEpochDataSum[k].IS;
                    }
                    AT     = Matrix.Transfer(A, oneEpochDataSum.Count, 4);
                    ATA    = Matrix.Multiply(AT, A, 4, oneEpochDataSum.Count, 4);
                    revATA = Matrix.MatrixOpp(ATA);
                    ATL    = Matrix.Multiply(AT, L, 4, oneEpochDataSum.Count, 1);
                    xi     = Matrix.Multiply(revATA, ATL, 4, 4, 1);
                    //*************有改动,添加
                    oneEpochDataSum.Clear();
                } while (Math.Abs(xi[0, 0]) > 0.001 && Math.Abs(xi[1, 0]) > 0.001 && Math.Abs(xi[2, 0]) > 0.001); //循环条件是否应该直接判断每次计算的坐标增量
                xx = x + xi[0, 0];                                                                                //之前全部的改正加最后一次循环的改正数,这个历元的最终结果
                yy = y + xi[1, 0];
                zz = z + xi[2, 0];
                receiverPosition.X                = O_FlieSum.o_FileHeadSum.Approx_Position.XX + xx;
                receiverPosition.Y                = O_FlieSum.o_FileHeadSum.Approx_Position.YY + yy;
                receiverPosition.Z                = O_FlieSum.o_FileHeadSum.Approx_Position.ZZ + zz;
                receiverPosition.Cdtr             = (cdtr + xi[3, 0]) / Constant.SpeedOfLight;//是否是除以光速之后才能得出
                receiverPosition.RPTime.GPSWeek   = TR.GPSWeek;
                receiverPosition.RPTime.GPSSecond = TR.GPSSecond;
                ReceiverPositionSum.receiverPositionSum.Add(receiverPosition);
                receiverPosition = new ReceiverPosition();
                oneEpochDataSum.Clear();
            }//for i

            for (int i = 0; i < ReceiverPositionSum.receiverPositionSum.Count; i++)
            {
                sumX = sumX + ReceiverPositionSum.receiverPositionSum[i].X;
                sumY = sumY + ReceiverPositionSum.receiverPositionSum[i].Y;
                sumZ = sumZ + ReceiverPositionSum.receiverPositionSum[i].Z;
            }
            Result.X = sumX / ReceiverPositionSum.receiverPositionSum.Count;
            Result.Y = sumY / ReceiverPositionSum.receiverPositionSum.Count;
            Result.Z = sumZ / ReceiverPositionSum.receiverPositionSum.Count;


            //Result.X = ReceiverPositionSum.receiverPositionSum[ReceiverPositionSum.receiverPositionSum.Count - 1].X;
            //Result.Y = ReceiverPositionSum.receiverPositionSum[ReceiverPositionSum.receiverPositionSum.Count - 1].Y;
            //Result.Z = ReceiverPositionSum.receiverPositionSum[ReceiverPositionSum.receiverPositionSum.Count - 1].Z;


            return(true);
        }