Ejemplo n.º 1
0
        /// <summary>
        /// 非差轨道确定
        /// </summary>
        /// <param name="Material">历元信息</param>
        /// <param name="ResultMatrix">平差信息</param>
        /// <param name="ParamNameBuilder">钟差估计器</param>
        /// <param name="previousResult">上一历元结果</param>
        public RangeOrbitResult(
            MultiSiteEpochInfo Material,
            AdjustResultMatrix ResultMatrix,
            RangeOrbitParamNameBuilder ParamNameBuilder,
            RangeOrbitResult previousResult = null)
            : base(Material, ResultMatrix, ParamNameBuilder)
        {
            //测站接收机钟差改正
            foreach (var site in Material)
            {
                var clkName = ParamNameBuilder.GetReceiverClockParamName(site.SiteName);
                var val     = ResultMatrix.Estimated.Get(clkName);
                site.Time.Correction = GetTimeCorrectionSeconds(val.Value);
            }

            //提取星历参数,可以用于改正卫星位置,进行迭代计算
            EphemerisResults = new BaseDictionary <SatelliteNumber, EphemerisResult>();
            foreach (var site in Material)
            {
                foreach (var sat in site)
                {
                    var prn = sat.Prn;

                    Ephemeris estimated = new Ephemeris(sat.Ephemeris.Prn, sat.Ephemeris.Time)
                    {
                        XyzDotRms = new XYZ()
                    };
                    var clkName = ParamNameBuilder.GetSatClockParamName(prn);
                    var val     = ResultMatrix.Estimated.Get(clkName);
                    estimated.ClockBias    = GetTimeCorrectionSeconds(val.Value);
                    estimated.ClockBiasRms = val.Rms / GnssConst.LIGHT_SPEED;

                    var names = ParamNameBuilder.GetSatDxyz(prn);
                    foreach (var item in names)
                    {
                        val = ResultMatrix.Estimated.Get(item);
                        if (item.Contains(Gnsser.ParamNames.Dx))
                        {
                            estimated.XYZ.X       = val.Value;
                            estimated.XyzDotRms.X = val.Rms;
                        }
                        if (item.Contains(Gnsser.ParamNames.Dy))
                        {
                            estimated.XYZ.Y       = val.Value;
                            estimated.XyzDotRms.Y = val.Rms;
                        }
                        if (item.Contains(Gnsser.ParamNames.Dz))
                        {
                            estimated.XYZ.Z       = val.Value;
                            estimated.XyzDotRms.Z = val.Rms;
                        }
                    }

                    EphemerisResults[prn] = new EphemerisResult((Ephemeris)sat.Ephemeris, estimated);
                }
            }
        }
Ejemplo n.º 2
0
        private void Init()
        {
            int count = entities.Count;

            double[] x      = new double[count];
            double[] yX     = new double[count];
            double[] yY     = new double[count];
            double[] yZ     = new double[count];
            double[] yClock = new double[count];

            int i = 0;

            foreach (var item in entities)
            {
                Ephemeris record = item;
                x[i]      = (record.Time - entities.First.Time); //Y为GPS周秒。
                yX[i]     = record.XYZ.X;
                yY[i]     = record.XYZ.Y;
                yZ[i]     = record.XYZ.Z;
                yClock[i] = record.ClockBias;

                i++;
            }

            //for (int i = 0; i < count; i++)
            //{
            //    Ephemeris record = sortedRecords[i];
            //    x[i] = (record.Time - sortedRecords[0].Time); //Y为GPS周秒。
            //    yX[i] = record.XYZ.X;
            //    yY[i] = record.XYZ.Y;
            //    yZ[i] = record.XYZ.Z;
            //    yClock[i] = record.ClockBias;
            //}
            int order = 10;

            order = Math.Min(order, count);

            //fitX = new PolyFit(x, yX);
            //fitY = new PolyFit(x, yY);
            //fitZ = new PolyFit(x, yZ);
            //fitClock = new PolyFit(x, yClock);
            fitX     = new LagrangeInterplation(x, yX, order);
            fitY     = new LagrangeInterplation(x, yY, order);
            fitZ     = new LagrangeInterplation(x, yZ, order);
            fitClock = new LagrangeInterplation(x, yClock, 2);
            //fitClock = new LagrangeInterplation(x, yClock, 10);


            //fitX = new ChebyshevPolyFit(x, yX, order);
            //fitY = new ChebyshevPolyFit(x, yY, order);
            //fitZ = new ChebyshevPolyFit(x, yZ, order);
            //fitClock = new LagrangeInterplation(x, yClock, 2);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 获取指定时刻的卫星位置,考虑了地球自转改正置。
        /// </summary>
        /// <param name="gpsTime"></param>
        /// <param name="ephemeris"></param>
        /// <returns></returns>
        public static XYZ GetSatPosWithEarthRotateCorrection(Time gpsTime, Ephemeris ephemeris)
        {
            var dt = (ephemeris.Time - gpsTime); //相距参考时刻的秒数。

            #region 方案1:顾及地球自转效应
            //correction for earth rotation

            double sinL = Math.Sin(GnssConst.RotateVelocityOfEarth * dt);
            double cosL = Math.Cos(GnssConst.RotateVelocityOfEarth * dt);

            double newX   = cosL * ephemeris.XYZ.X - sinL * ephemeris.XYZ.Y;
            double newY   = sinL * ephemeris.XYZ.X + cosL * ephemeris.XYZ.Y;
            double newZ   = ephemeris.XYZ.Z;
            XYZ    newXyz = new XYZ(newX, newY, newZ);
            #endregion
            return(newXyz);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 星历相减
        /// </summary>
        /// <param name="first"></param>
        /// <param name="second"></param>
        /// <returns></returns>
        public static Ephemeris operator -(Ephemeris first, Ephemeris second)
        {
            if (first.Prn != second.Prn || first.Time != second.Time)
            {
                new Log(typeof(Ephemeris)).Error("不是同一卫星,不可相加," + first + ", " + second);
                return(first);
            }
            Ephemeris ephemeris = new Ephemeris(first.Prn, first.Time);

            ephemeris.XYZ = first.XYZ - second.XYZ;
            if (first.Rms != null && second.Rms != null)
            {
                ephemeris.Rms = XYZ.RmsPlus(first.Rms, second.Rms);
            }
            ephemeris.XyzDot       = first.XyzDot - second.XyzDot;
            ephemeris.ClockBias    = first.ClockBias - second.ClockBias;
            ephemeris.ClockBiasRms = Geo.Utils.DoubleUtil.RmsPlus(first.ClockBiasRms, first.ClockBiasRms);
            ephemeris.ClockDrift   = first.ClockDrift - second.ClockDrift;

            return(ephemeris);
        }
Ejemplo n.º 5
0
        public override IEphemeris Get()
        {
            SatelliteNumber prn           = EpochSat.Prn;
            Ephemeris       eph           = null;
            XYZ             receiverPos   = EpochSat.SiteInfo.EstimatedXyz;
            Time            receivingTime = EpochSat.RecevingTime;
            //2.1 坐标迭代法求解
            double transitTime  = 0.075;//传输时间初始值,GEO卫星应该更长,但此处并不影响。
            Time   transmitTime = receivingTime - transitTime;

            eph = EphemerisService.Get(prn, transmitTime);
            if (eph == null)
            {
                throw new NullReferenceException("没有找到 " + prn + " " + transmitTime + " 的星历");
            }


            double differ = Double.MaxValue;//亚纳秒级别则退出
            double DELTA  = 1e-10;
            double tmp    = transitTime;

            //  int count = 0;//测试,统计计算了多少次
            for (int i = 0; differ > DELTA && i < 5; i++) //一般循环一次,可满足精度
            {
                //由于第一次的时间求得的卫星坐标可能会很差(几十米即可带来较大时间误差),因此继续利用通过观测值求得的时间
                tmp          = transitTime;
                transitTime  = (eph.XYZ - receiverPos).Length / GnssConst.LIGHT_SPEED;
                transmitTime = receivingTime - transitTime;

                differ = Math.Abs(transitTime - tmp);

                eph = EphemerisService.Get(prn, transmitTime);
                //  count++;
            }

            //  System.IO.File.AppendAllText(@"D:\count.txt", count + "\t" + differ.ToString("E") + "\r\n");

            return(eph);
        }
Ejemplo n.º 6
0
        private void Init()
        {
            int count = sortedRecords.Count;

            double[] x      = new double[count];
            double[] yX     = new double[count];
            double[] yY     = new double[count];
            double[] yZ     = new double[count];
            double[] yClock = new double[count];

            for (int i = 0; i < count; i++)
            {
                Ephemeris record = sortedRecords[i];
                x[i]      = (record.Time - sortedRecords[0].Time); //Y为GPS周秒。
                yX[i]     = record.XYZ.X;
                yY[i]     = record.XYZ.Y;
                yZ[i]     = record.XYZ.Z;
                yClock[i] = record.ClockBias;
            }
            int order = 10;

            order = Math.Min(order, count);

            //fitX = new PolyFit(x, yX);
            //fitY = new PolyFit(x, yY);
            //fitZ = new PolyFit(x, yZ);
            //fitClock = new PolyFit(x, yClock);
            fitX = new LagrangeInterplation(x, yX, order);
            fitY = new LagrangeInterplation(x, yY, order);
            fitZ = new LagrangeInterplation(x, yZ, order);
            // fitClock = new LagrangeInterplation(x, yClock, 2);
            fitClock = new LagrangeInterplation(x, yClock, 10);


            //fitX = new ChebyshevPolyFit(x, yX, order);
            //fitY = new ChebyshevPolyFit(x, yY, order);
            //fitZ = new ChebyshevPolyFit(x, yZ, order);
            //fitClock = new LagrangeInterplation(x, yClock, 2);
        }
        public override IEphemeris Get()
        {
            //实质为计算发射时刻的系统时间, 只比较秒数
            SatelliteNumber prn           = EpochSat.Prn;
            Ephemeris       eph           = null;
            XYZ             receiverPos   = EpochSat.SiteInfo.EstimatedXyz;
            Time            receivingTime = EpochSat.RecevingTime;

            //2.需要接收机钟差
            if (EpochSat.Time.Correction != 0 && EpochSat.FrequenceA.DopplerShift != null)
            {
                //2.2 多普勒频移法
                eph = EphemerisService.Get(prn, receivingTime);
                double distance = (eph.XYZ - receiverPos).Length;
                double deltaT   = distance / GnssConst.LIGHT_SPEED;

                //这里的距离差是接收时刻与发射时刻的位移差,所以应该减去。
                distance -= EpochSat.AverageDopplorSpeed * deltaT;
                deltaT    = distance / GnssConst.LIGHT_SPEED;
                Time transmitTime = receivingTime - deltaT;
                eph = EphemerisService.Get(prn, transmitTime);
            }
            return(eph);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 差值计算
        /// </summary>
        /// <param name="rTime"></param>
        /// <param name="staXyz"></param>
        private void SatPo(Time rTime, XYZ staXyz)
        {
            int count = sortedRecords.Count;

            double[] TimeArr = new double[count];
            double[] XArr    = new double[count];
            double[] YArr    = new double[count];
            double[] ZArr    = new double[count];
            double[] CLKsat  = new double[count];

            for (int i = 0; i < count; i++)
            {
                Ephemeris record = sortedRecords[i];
                TimeArr[i] = record.Time.SecondsOfWeek; //Y为GPS周秒。
                XArr[i]    = record.XYZ.X;
                YArr[i]    = record.XYZ.Y;
                ZArr[i]    = record.XYZ.Z;
                CLKsat[i]  = record.ClockBias;
            }

            double Time      = rTime.SecondsOfWeek;//卫星发射时刻
            double startTime = TimeArr[0] - 5;
            double lastTime  = TimeArr[TimeArr.Length - 1] + 5;
            double timeInterval;

            int    d  = 9;
            double NA = 99999;

            double x1 = 0.0, y1 = 0.0, z1 = 0.0;

            double[] x2 = new double[d]; double[] y2 = new double[d]; double[] z2 = new double[d];
            double   x3 = 0.0, y3 = 0.0, z3 = 0.0;
            double   x4 = 0.0, y4 = 0.0, z4 = 0.0;

            double Xt, Yt, Zt;
            double rho; double recieveTime;

            if (Time >= startTime && Time <= lastTime)
            {
                timeInterval = TimeArr[2] - TimeArr[1];
                //
                XYZ(Time, TimeArr, XArr, d, NA, ref x1, ref x2, ref x3, ref x4);
                if (x4 == 0)
                {
                    satSpeed = new XYZ(0, 0, 0);
                    return;
                }
                //拉格朗日插值
                Xt = LG(d, x1, x2, NA);
                XYZ(Time, TimeArr, YArr, d, NA, ref y1, ref y2, ref y3, ref y4);
                Yt = LG(d, y1, y2, NA);
                XYZ(Time, TimeArr, ZArr, d, NA, ref z1, ref z2, ref z3, ref z4);
                Zt = LG(d, z1, z2, NA);

                //
                satPos = new XYZ(Xt, Yt, Zt);
                rho    = (satPos - staXyz).Length;

                recieveTime = rTime.SecondsOfWeek + rho / GnssConst.LIGHT_SPEED; //接受时刻
            }
            else
            {
                throw new Exception("rTime is out of range in TimeArr:SeeSatPo\n");
            }
            double t, stdx;

            for (int i = 1; i <= 3; i++)
            {
                t      = recieveTime - rho / GnssConst.LIGHT_SPEED;
                stdx   = ((Time - x3) / timeInterval) + 1;
                Xt     = LG(d, stdx, x2, NA);
                Yt     = LG(d, stdx, y2, NA);
                Zt     = LG(d, stdx, z2, NA);
                satPos = new XYZ(Xt, Yt, Zt);
                rho    = (satPos - staXyz).Length;
            }

            stdx = Convert.ToInt32(Math.Round(x1));
            double Dinterval;

            if (Convert.ToInt32(stdx) == 1 || Convert.ToInt32(stdx) == d)
            {
                Dinterval = timeInterval;
            }
            else
            {
                Dinterval = 2 * timeInterval;
            }
            int B, L;

            if (Convert.ToInt32(stdx) == 1)
            {
                B = 1;
            }
            else
            {
                B = Convert.ToInt32(stdx) - 1;
            }
            if (Convert.ToInt32(stdx) == d)
            {
                L = d;
            }
            else
            {
                L = Convert.ToInt32(stdx) + 1;
            }
            double Vx, Vy, Vz;

            Vx = (x2[L - 1] - x2[B - 1]) / Dinterval;
            Vy = (y2[L - 1] - y2[B - 1]) / Dinterval;
            Vz = (z2[L - 1] - z2[B - 1]) / Dinterval;

            satSpeed = new XYZ(Vx, Vy, Vz);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 获取指定数组中与 X 最相近的数组编号。
        /// </summary>
        /// <param name="XArray">递增或递减数组</param>
        /// <param name="xValue"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static List <int> GetNearstIndexes(List <Ephemeris> sortedRecords, double xValue, int order = 10)
        {
            int count = sortedRecords.Count;

            double[] XArray = new double[count];
            //double[] yX = new double[count];
            //double[] yY = new double[count];
            //double[] yZ = new double[count];
            //double[] yClock = new double[count];

            for (int i = 0; i < count; i++)
            {
                Ephemeris record = sortedRecords[i];
                XArray[i] = (record.Time - sortedRecords[0].Time);  //Y为GPS周秒。
                //yX[time] = record.XYZ.X;
                //yY[time] = record.XYZ.Y;
                //yZ[time] = record.XYZ.Z;
                //yClock[time] = record.Offset;
            }
            //int order = 10;
            order = Math.Min(order, count);



            List <int> indexes = new List <int>();

            //如果数量大于数组数量,则返回全部
            if (order >= XArray.Length)
            {
                for (int i = 0; i < order; i++)
                {
                    indexes.Add(i);
                }
                return(indexes);
            }
            //找到离X最小的编号
            int    halfCount = order / 2;
            int    index     = 0;
            double min       = double.MaxValue;

            for (int i = 0; i < XArray.Length; i++)
            {
                double diff = Math.Abs(XArray[i] - xValue);
                // if (diff == 0) return YArray[time];
                if (diff < min)
                {
                    min   = diff;
                    index = i;
                }
            }
            //在数组的头部
            if (index - halfCount <= 0)
            {
                for (int i = 0; i < order; i++)
                {
                    indexes.Add(i);
                }
            }
            //尾部
            else if (index + halfCount >= XArray.Length - 1)
            {
                for (int i = 0, j = XArray.Length - 1; i < order; i++, j--)
                {
                    indexes.Insert(0, j);
                }
            }
            //中间
            else
            {
                for (int i = 0; i < order; i++)
                {
                    indexes.Add(index - halfCount + i);
                }
            }

            if (indexes[0] < 0)
            {
                throw new Exception("出错了");
            }

            return(indexes);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// 获取插值后的 EphemerisInfo。
        /// 注意:不对钟差相对论误差进行改正,此处时间是卫星钟时间,没有相对信息。2014.09.08
        /// 失败,如超过时间,则返回null
        /// 由于一般没有卫星速度的数据,必须通过插值坐标计算速度。2015.03.
        /// 如果有速度信息,以下的方法就不合适了。
        /// </summary>
        /// <param name="gpsTime">时间</param>
        /// <returns></returns>
        public Ephemeris GetEphemerisInfo(Time gpsTime)
        {
            SatelliteNumber PRN = Ephemeris.Prn;
            Time            min = Ephemeris.Time;
            //Time max = sortedRecords[sortedRecords.Count - 1].Time;
            //double span = (double)(max - min);
            double gpsSecond = (gpsTime - min); //减去序列中第一个数
            ////老是在这里出问题,宽限一点呢??16分钟
            //double expand = 60 * 16;
            //if (gpsSecond + expand < 0 || gpsSecond - expand > span)
            //{
            //    //return null;
            //    throw new ArgumentException("历元在给定的时间段外,不可进行插值。");
            //}
            //计算位置
            double x = 0, y = 0, z = 0; double dtime = 0;
            double dx = 0, dy = 0, dz = 0; double ddtime = 0;


            int count = entities.Count;
            int order = 10;

            order = Math.Min(order, count);

            //czs
            //   List<int> indexes = GetNearstIndexes(sortedRecords, gpsSecond, order);
            //cy
            //List<int> indexes = GetNearstIndexes(sortedRecords, gpsTime, order);



            double[] t = new double[order];


            double[] tList = new double[order + 1];

            double[] xList     = new double[order + 1];
            double[] yList     = new double[order + 1];
            double[] zList     = new double[order + 1];
            double[] clockList = new double[order + 1];

            int i = 0;

            foreach (var item in this.entities)
            {
                Ephemeris record = item;

                t[i] = (record.Time - gpsTime);  //秒。


                #region 方案1:顾及地球自转效应
                //correction for earth rotation
                double sinl = Math.Sin(SunMoonPosition.OMGE * t[i]);
                double cosl = Math.Cos(SunMoonPosition.OMGE * t[i]);

                xList[i] = cosl * record.XYZ.X - sinl * record.XYZ.Y;
                yList[i] = sinl * record.XYZ.X + cosl * record.XYZ.Y;
                zList[i] = record.XYZ.Z;
                #endregion


                #region 方案2:不顾及地球自转效应

                //xList[time] = record.XYZ.X;
                //yList[time] = record.XYZ.Y;
                //zList[time] = record.XYZ.Z;

                #endregion

                //tList[i] = (record.Time - sortedRecords[0].Time); //秒。
                //  clockList[i] = record.ClockBias;

                i++;
            }


            //Lagrange(tList, xList, gpsSecond, ref x, ref dx);

            //Lagrange(tList, yList, gpsSecond, ref y, ref dy);

            //Lagrange(tList, zList, gpsSecond, ref z, ref dz);

            //Lagrange(tList, clockList, gpsSecond, ref dtime, ref ddtime);

            //int Nhalf = (int)(order / 2) - 1;
            //int Nmatch = indexes[Nhalf];



            x     = fitX.GetY(gpsSecond);
            y     = fitY.GetY(gpsSecond);
            z     = fitZ.GetY(gpsSecond);
            dtime = fitClock.GetY(gpsSecond);

            XYZ SatXyz = new XYZ(x, y, z);


            //精度赋值
            //XYZ SatXyzSig = sortedRecords[Nmatch].XyzSdev;
            //double clockSig = sortedRecords[Nmatch].ClockSdev;
            //XYZ SatXyzDotSig = new Geo.Coordinates.XYZ(0);

            //计算速度
            //double nextSecond = gpsSecond + 0.001;
            //XYZ xyzNext = new XYZ(fitX.GetY(nextSecond), fitY.GetY(nextSecond), fitZ.GetY(nextSecond));
            //XYZ speed = (xyzNext-xyz) / 0.001;


            XYZ SatSpeed = new XYZ(dx, dy, dz);

            //Add relativity correction to dtime
            //This only for consistency with GPSEphemerisInter
            //dtr=-2*dot(R,V)/(C*C)

            //dtime +=EphemerisUtil.GetRelativeCorrection(SatXyz, SatSpeed);

            return(new Ephemeris()
            {
                Prn = PRN,
                XYZ = SatXyz,
                //XyzSdev=SatXyzSig,
                // Clock = fitClock.GetY(gpsSecond),
                ClockBias = dtime,
                //ClockSdev = clockSig,
                ClockDrift = ddtime,
                Time = gpsTime,
                XyzDot = SatSpeed,
                //XyzDotSdev=SatXyzDotSig
            });
        }
Ejemplo n.º 11
0
 public EphemerisResult(Ephemeris Original, Ephemeris Estimated)
 {
     this.Original  = Original;
     this.Estimated = Estimated;
     this.Corrected = Original + Estimated;
 }