Beispiel #1
0
        /*标准单点定位*/
        public static int pntpos(List <obs_s> obs, nav_t nav, spp_t spp, dcb_t dcb) //obs均已按照PRN号大小排列好
        {
            /*
             * n为观测历元观测到的卫星总数,stat为解算状态
             * vsat为卫星的状态 0为error,1为正常
             * svh为卫星坐标和钟差计算的状态,-1为不正常
             * rs包括卫星坐标和速度,dts包括卫星钟差和钟漂,azel包括卫星方位角和高度角
             * var为卫星坐标和钟差的方差
             */
            int n = obs.Count, stat = 1;

            int[]      vsat = new int[32], svh = new int[32];
            double[][] rs   = new double[n][], dts = new double[n][], azel = new double[n][];
            double[]   var  = new double[n], resp = new double[n];
            for (int i = 0; i < n; i++)
            {
                rs[i]   = new double[6]; //卫星坐标和速度
                dts[i]  = new double[2]; //卫星的钟差和钟漂
                azel[i] = new double[2]; //卫星的方位角和高度角
            }
            pppcmn.satpos(obs, nav, sat, clk, pcv, rs, dts, var, svh);
            stat = estpos(spp, obs, dcb, nav, n, rs, dts, var, azel, vsat, svh);

            for (int i = 0; i < n; i++)
            {
                int sat = int.Parse(obs[i].sprn.Substring(1, 2));
                if (vsat[i] == 1)
                {
                    spp.vsat[sat - 1] = 1;
                }
            }
            return(stat);
        }
Beispiel #2
0
        public static double Prange(obs_s obs, dcb_t dcb, double[] azel, double[] var)
        {
            double PC, P1 = 0.0, P1_P2, P1_C1, gamma;
            int    prn;

            gamma = (FREQ1 * FREQ1) / (FREQ2 * FREQ2);//f1^2/f2^2
            foreach (var v in obs.type_value)
            {
                if (v.type == "C1")
                {
                    P1 = v.value; break;
                }
            }
            prn   = int.Parse(obs.sprn.Substring(1, 2));
            P1_C1 = dcb.dcbdata[prn - 1].P1_C1;
            P1_P2 = dcb.dcbdata[prn - 1].P1_P2;

            if (P1 == 0)
            {
                return(0.0);
            }
            P1    += P1_C1;
            PC     = P1 - P1_P2 / (1.0 - gamma);
            var[0] = ERR_CBIAS * ERR_CBIAS;
            return(PC);
        }
Beispiel #3
0
        public static int rescod(int iter, List <obs_s> obs, nav_t nav, int n, double[][] rs, double[][] dts, double[] vare, double[][] azel, int[] vsat,
                                 dcb_t dcb, double[] x, matrix H, double[] v, double[] var, int[] svh)
        {
            double r, dtr, P, elmin = 15 * D2R, el = 0.0;;
            int    i, j, nv = 0;

            double[] rr = new double[3], pos = new double[3], e = new double[3], vardcb = new double[1], ion = new double[2], trop = new double[2];
            matrix   p  = new matrix(3, 1);

            for (i = 0; i < 3; i++)
            {
                rr[i] = x[i];
            }
            dtr = x[3];
            transcoor.ecef2pos(matrix.Array2matrix(rr), p);
            pos = matrix.matrx2Array(p);

            for (i = 0; i < n; i++)
            {
                vsat[i] = 0; azel[i][0] = azel[i][1] = 0;
                if (svh[i] < 0)
                {
                    continue;
                }
                if ((r = geodist(rs[i], rr, e)) < 0 || (el = pppcmn.satel(rr, rs[i], azel[i])) < elmin)
                {
                    continue;
                }

                if ((P = Prange(obs[i], dcb, azel[i], vardcb)) == 0)
                {
                    continue;
                }

                if (ioncorr(obs[i].t, obs[i].rtkt, nav, pos, azel[i], ion) != 1)
                {
                    continue;                                                             //克罗布歇电离层模型
                }
                if (tropcorr(obs[i].t, pos, azel[i], trop) != 1)
                {
                    continue;              //对流层改正
                }
                /* pseudorange residual */ //伪距残差
                v[nv] = P - (r + dtr - CLIGHT * dts[i][0] + ion[0] + trop[0]);

                for (j = 1; j <= 4; j++)
                {
                    H[nv + 1, j] = j <= 3 ? -e[j - 1] : 1.0;                     //观测矩阵
                }
                vsat[i] = 1;
                //测量误差
                var[nv++] = Math.Pow(100, 2) * (Math.Pow(0.003, 2) + Math.Pow(0.003, 2) / Math.Sin(azel[i][1])) + vardcb[0] + ion[1] + trop[1] + vare[i];
            }



            return(nv);
        }
Beispiel #4
0
        public static int corrmens(obs_s obs, dcb_t dcb, double[] pos, double[] dantr, double[] dants,
                                   double[] phw, double[] meas, double[] var)
        {
            double c1, c2, L1 = 0.0, L2 = 0.0, P1 = 0.0, P2 = 0.0, P1_C1, gamma, lam1, lam2;
            int    i = 0, j = 1, k, sat;

            lam1  = CLIGHT / FREQ1; lam2 = CLIGHT / FREQ2;
            gamma = Math.Pow(FREQ1, 2) / Math.Pow(FREQ2, 2);
            c1    = gamma / (gamma - 1.0); /*  f1^2/(f1^2-f2^2) */
            c2    = -1.0 / (gamma - 1.0);  /* -f2^2/(f1^2-f2^2) */
            sat   = int.Parse(obs.sprn.Substring(1, 2));

            foreach (var v in obs.type_value)
            {
                if (v.type == "L1")
                {
                    L1 = v.value * lam1;
                }
                if (v.type == "L2")
                {
                    L2 = v.value * lam2;
                }
                if (v.type == "P2")
                {
                    P2 = v.value;
                }
                if (v.type == "C1")
                {
                    P1 = v.value;
                }
            }
            P1_C1 = dcb.dcbdata[sat - 1].P1_C1; //L1C/A

            if (L1 == 0.0 || L2 == 0.0 || P1 == 0.0 || P2 == 0.0)
            {
                return(0);
            }

            meas[0] = c1 * L1 + c2 * L2 - (c1 * lam1 + c2 * lam2) * phw[0];
            P1     += P1_C1;
            meas[1] = c1 * P1 + c2 * P2; //伪距IF组合
            var[1]  = Math.Pow(ERR_CBIAS, 2);

            for (k = 0; k < 2; k++)
            {
                if (dants != null)
                {
                    meas[k] -= c1 * dants[i] + c2 * dants[j];
                }
                if (dantr != null)
                {
                    meas[k] -= c1 * dantr[i] + c2 * dantr[j];
                }
            }
            return(1);
        }
Beispiel #5
0
        /*读取码偏差文件*/
        public static void readdcb(string[] path, dcb_t dcb)
        {
            for (int i = 0; i < 32; i++)
            {
                dcb.dcbdata.Add(new dcbb());
            }

            for (int i = 0; i < path.Length; i++)
            {
                using (StreamReader sr = new StreamReader(path[i]))
                {
                    dcbb     data;
                    string   line = "";
                    int      state = 0, nprn = 0;
                    string[] ss = null;
                    while (!sr.EndOfStream)
                    {
                        line = sr.ReadLine();
                        if (line.Contains("DIFFERENTIAL (P1-C1) CODE BIASES"))
                        {
                            state = 1;
                        }
                        if (line.Contains("DIFFERENTIAL (P1-P2) CODE BIASES"))
                        {
                            state = 2;
                        }
                        if (state == 0)
                        {
                            continue;
                        }
                        if ((ss = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)) == null || ss.Count() != 3)
                        {
                            continue;
                        }

                        nprn = int.Parse(ss[0].Substring(1, 2));
                        if (nprn != 0 && nprn <= 32 && state == 1)
                        {
                            dcb.dcbdata[nprn - 1].prn   = nprn;
                            dcb.dcbdata[nprn - 1].P1_C1 = double.Parse(ss[1]) * 1E-9 * CLIGHT;
                        }
                        if (nprn != 0 && nprn <= 32 && state == 2)
                        {
                            dcb.dcbdata[nprn - 1].prn   = nprn;
                            dcb.dcbdata[nprn - 1].P1_P2 = double.Parse(ss[1]) * 1E-9 * CLIGHT;
                        }
                    }
                }
            }
        }
Beispiel #6
0
        public static void udstate(ppp_t ppp, dcb_t dcb, List <obs_s> obs)
        {
            //更新位置
            if ((ppp.x[0] * ppp.x[0] + ppp.x[1] * ppp.x[1] + ppp.x[2] * ppp.x[2]) <= 0)//第一个历元
            {
                for (int i = 0; i < 3; i++)
                {
                    initx(ppp, ppp.spp.rr[i], VAR_POS, i);
                }
            }
            //更新钟差
            initx(ppp, ppp.spp.dtr * CLIGHT, VAR_CLK, 3);

            //更新对流层参数
            uptrop(ppp);
            //更新相位偏差
            upbias_ppp(ppp, obs, dcb);
        }
Beispiel #7
0
        public static void propos(obs_t obss, dcb_t dcb, pcv_t pcv, station sta, nav_t nav, erp_t erp, List <result> res, RichTextBox text)
        {
            int     nobs    = 0;
            rtktime solt    = new rtktime();
            string  timestr = null;
            obs_t   obs     = new obs_t();
            ppp_t   p3      = new ppp_t();
            spp_t   spp     = new spp_t();

            while ((nobs = inputobs(obs, obss)) > 0)
            {
                result re = new result();
                solt = spp.tcur;
                if (pntpos(obs.obs_b, nav, spp, dcb) == 0)
                {
                    continue;
                }
                p3.spp     = spp;
                p3.soltime = spp.tcur;
                if (solt.time_int != 0)
                {
                    p3.tt = rtklibcmn.timediff(p3.soltime, solt);
                }
                if (pppos(p3, obs.obs_b, nav, dcb, sta, erp) != 1)
                {
                    continue;
                }

                for (int j = 0; j < 3; j++)
                {
                    spp.rr[j] = p3.x[j];
                }
                spp.dtr = p3.x[4];
                re.time = obs.obs_b[0].t.calend;
                re.X    = p3.x[0]; re.Y = p3.x[1]; re.Z = p3.x[2];
                timestr = re.time[0] + "/" + re.time[1] + "/" + re.time[2] + " " + re.time[3] + ":" + re.time[4] + ":" + re.time[5];
                text.AppendText(string.Format("{0,-20}", timestr) + string.Format("{0,-20}", re.X) + string.Format("{0,-20}", re.Y) + string.Format("{0,-20}", re.Z) + "\r\n");

                res.Add(re);
            }
        }
Beispiel #8
0
        public static int res_ppp(List <obs_s> obs, station sta, ppp_t p3, int n, double[][] rs, double[][] dts, double[][] azel, double[] vare, erp_t erp,
                                  dcb_t dcb, double[] x, double[] R, double[] v, matrix H, int[] svh)
        {
            double r, dtrp, vart = Math.Pow(0.01, 2), elmin = 15 * D2R;

            double[] rr = new double[3], disp = new double[3], pos = new double[3], e = new double[3], meas = new double[2], varm = new double[2];
            double[] dtdx = new double[3], dantr = new double[3], var = new double[nx * 2], dants = new double[2], phw = new double[1];
            matrix   pos_ = new matrix(3, 1);
            int      i, j, nv = 0, k, sat;

            for (i = 0; i < 3; i++)
            {
                rr[i] = x[i];
            }

            /* earth tides correction */ //地球潮汐改正 固体潮
            tidedisp(obs[0].t, rtklibcmn.gpst2utc(obs[0].rtkt), rr, erp, disp);
            for (i = 0; i < 3; i++)
            {
                rr[i] += disp[i];
            }
            transcoor.ecef2pos(matrix.Array2matrix(rr), pos_);
            for (i = 0; i < 3; i++)
            {
                pos[i] = pos_[i + 1, 1];
            }

            for (i = 0; i < 32; i++)
            {
                p3.vsat[i] = 0;
            }

            for (i = 0; i < n; i++)
            {
                sat = int.Parse(obs[i].sprn.Substring(1, 2));

                //
                if (p3.spp.vsat[sat - 1] == 0 || svh[i] < 0)
                {
                    continue;
                }
                if ((r = geodist(rs[i], rr, e)) <= 0 || pppcmn.satel(rr, rs[i], azel[i]) < elmin)
                {
                    continue;
                }

                dtrp = pppcmn.prectrop(obs[i].t, pos, azel[i], x[4], dtdx); //精密对流层模型

                pppcmn.satanxpcv(rs[i], rr, pcv, dants, obs[i].sprn);       //卫星天线相位偏差,返回每个频率的改正值
                pppcmn.antxmodel(pcv, sta.atxdel, azel[i], dantr, sta.anxtype);
                pppcmn.windup(obs[i].t, p3.soltime, rs[i], rr, phw);

                if (corrmens(obs[i], dcb, pos, dantr, dants, phw, meas, varm) != 1)
                {
                    continue;
                }
                /* satellite clock and tropospheric delay */ //卫星钟差和电离层延迟
                r += -CLIGHT * dts[i][0] + dtrp;

                for (j = 0; j < 2; j++)
                {
                    if (meas[j] == 0)
                    {
                        continue;
                    }
                    v[nv] = meas[j] - r;
                    for (k = 0; k < nx; k++)
                    {
                        H[nv + 1, k + 1] = 0.0;
                    }
                    for (k = 0; k < 3; k++)
                    {
                        H[nv + 1, k + 1] = -e[k];
                    }
                    v[nv]       -= x[3]; H[nv + 1, 4] = 1.0;
                    H[nv + 1, 5] = dtdx[0];

                    if (j == 0)
                    {
                        v[nv] -= x[4 + sat];
                        H[nv + 1, 5 + sat] = 1.0;
                    }
                    var[nv] = varm[j] + vare[i] + vart + varerr(azel[i][1], j);

                    if (Math.Abs(v[nv]) > 30)
                    {
                        continue;
                    }

                    if (j == 0)
                    {
                        p3.vsat[sat - 1] = 1;
                    }
                    nv++;
                }
            }
            for (i = 0; i < nv; i++)
            {
                R[i] = var[i];
            }

            return(nv);
        }
Beispiel #9
0
        //obs均已按照PRN号大小排列好
        public static int estpos(spp_t spp, List <obs_s> obs, dcb_t dcb, nav_t nav, int n, double[][] rs, double[][] dts,
                                 double[] vare, double[][] azel, int[] vsat, int[] svh)
        {
            double[] v_ = new double[n], x = new double[4], var = new double[n];
            matrix   H_ = new matrix(n, 4), H, v, dx, Q, P;
            int      nv;
            double   sig;
            int      i, j, k, stat = 1;

            for (i = 0; i < 3; i++)
            {
                x[i] = spp.rr[i];
            }

            for (i = 0; i < 10; i++)//迭代
            {
                nv = rescod(i, obs, nav, n, rs, dts, vare, azel, vsat, dcb, x, H_, v_, var, svh);
                if (nv < 4)
                {
                    break;        //nv是参与解算的实际卫星数
                }
                H = new matrix(nv, 4); v = new matrix(nv, 1); P = new matrix(nv, nv);
                for (j = 0; j < nv; j++)
                {
                    sig         = Math.Sqrt(var[j]);
                    v[j + 1, 1] = v_[j] / sig;
                    for (k = 1; k <= 4; k++)
                    {
                        H[j + 1, k] = H_[j + 1, k] / sig;
                    }
                }
                dx = matrix.inv(matrix.transp(H) * H) * matrix.transp(H) * v;
                Q  = matrix.transp(H) * H;

                for (j = 0; j < 4; j++)
                {
                    x[j] += dx[j + 1, 1];
                }

                if (Math.Sqrt(dx[1, 1] * dx[1, 1] + dx[2, 1] * dx[2, 1] + dx[3, 1] * dx[3, 1] + dx[4, 1] * dx[4, 1]) < 1E-4)
                {
                    spp.dtr = x[3] / CLIGHT;
                    for (j = 0; j < 3; j++)
                    {
                        spp.rr[j] = x[j];
                    }
                    spp.tcurr.gpsec = obs[0].t.gpsec - spp.dtr;
                    spp.tcur        = rtklibcmn.timeadd(obs[0].rtkt, -x[3] / CLIGHT);
                    for (j = 0; j < 6; j++)
                    {
                        spp.tcurr.calend[j] = obs[0].t.calend[j];
                    }

                    stat = valsol(azel, vsat, 15.0 * D2R, n, v, nv, 4);
                    return(stat);
                }
            }


            return(1);
        }
Beispiel #10
0
        public static void upbias_ppp(ppp_t p3, List <obs_s> obs, dcb_t dcb)
        {
            double[] meas = new double[2], var = new double[2], bias = new double[32], pos = new double[3], rr = new double[3], phw = new double[1];
            double   offset = 0.0;
            matrix   pos_ = new matrix(3, 1);
            int      i, j, k, sat, n = obs.Count;

            for (i = 0; i < 32; i++)
            {
                p3.cyslip[i] = 0;
            }
            detslp_gf(p3, obs, n);
            /* reset phase-bias if expire obs outage counter */
            for (i = 0; i < 32; i++)
            {
                if (++p3.outc[i] > 5)
                {
                    initx(p3, 0.0, 0.0, i + 5);
                }
            }
            for (i = 0; i < 3; i++)
            {
                rr[i] = p3.spp.rr[i];
            }
            transcoor.ecef2pos(matrix.Array2matrix(rr), pos_);
            for (i = 0; i < 3; i++)
            {
                pos[i] = pos_[i + 1, 1];
            }


            for (i = k = 0; i < n; i++)
            {
                sat = int.Parse(obs[i].sprn.Substring(1, 2));
                j   = sat + 4;

                if ((corrmens(obs[i], dcb, pos, null, null, phw, meas, var)) != 1)
                {
                    continue;
                }
                ;

                bias[i] = meas[0] - meas[1];
                if (p3.x[j] == 0 || p3.cyslip[sat - 1] == 1)
                {
                    continue;
                }
                offset += bias[i] - p3.x[j];
                k++;
            }
            /* correct phase-code jump to enssure phase-code coherency */
            if (k >= 2 && Math.Abs(offset / k) > 0.0005 * CLIGHT)
            {
                for (i = 0; i < 32; i++)
                {
                    j = i + 5;
                    if (p3.x[j] != 0)
                    {
                        p3.x[j] += offset / k;
                    }
                }
            }
            for (i = 0; i < n; i++)
            {
                sat = int.Parse(obs[i].sprn.Substring(1, 2));
                j   = sat + 4;
                p3.P[j + 1, j + 1] += Math.Pow(1E-4, 2) * Math.Abs(p3.tt);
                if (p3.x[j] != 0 && p3.cyslip[sat - 1] != 1)
                {
                    continue;                                         //已初始化且不发生周跳
                }
                if (bias[i] == 0)
                {
                    continue;
                }
                initx(p3, bias[i], VAR_BIAS, j);
            }
        }
Beispiel #11
0
        /*精密单点定位*/
        public static int pppos(ppp_t pppt, List <obs_s> obs, nav_t nav, dcb_t dcb, station sta, erp_t erp)
        {
            int n = obs.Count, nv = 0, satprn;//当前历元观测的卫星个数

            double[][] rs  = new double[n][], dts = new double[n][], azel = new double[n][];
            double[]   var = new double[n], vare = new double[n];
            int[]      svh = new int[32];
            double[]   x   = new double[nx], v = new double[2 * n], R = new double[2 * n];
            matrix     P   = new matrix(37, 37);//
            matrix     H   = new matrix(2 * n, nx);

            for (int i = 0; i < n; i++)
            {
                rs[i]   = new double[6]; //卫星坐标和速度
                dts[i]  = new double[2]; //卫星的钟差和钟漂
                azel[i] = new double[2]; //卫星的方位角和高度角
            }

            //状态更新
            udstate(pppt, dcb, obs);
            pppcmn.satpos(obs, nav, sat, clk, pcv, rs, dts, vare, svh);

            for (int i = 0; i < nx; i++)
            {
                x[i] = pppt.x[i];
            }
            for (int i = 0; i < 10; i++)//滤波迭代
            {
                if ((nv = res_ppp(obs, sta, pppt, n, rs, dts, azel, vare, erp, dcb, x, R, v, H, svh)) <= 0)
                {
                    break;
                }

                for (int j = 0; j < nx; j++)
                {
                    for (int k = 0; k < nx; k++)
                    {
                        P[j + 1, k + 1] = pppt.P[j + 1, k + 1];
                    }
                }

                kalman(x, R, v, P, H, nv);
            }
            for (int i = 0; i < nx; i++)
            {
                pppt.x[i] = x[i];
                for (int j = 0; j < nx; j++)
                {
                    pppt.P[i + 1, j + 1] = P[i + 1, j + 1];
                }
            }
            for (int i = 0; i < 3; i++)
            {
                pppt.spp.rr[i] = pppt.x[i];
            }

            for (int i = 0; i < n; i++)
            {
                satprn = int.Parse(obs[i].sprn.Substring(1, 2));
                if (pppt.vsat[satprn - 1] == 0)
                {
                    continue;
                }
                pppt.outc[satprn - 1] = 0;
            }

            return(1);
        }