GNSS伪距测量

一、Datacenter.cs

1.1 sat卫星数据类

        包含txt文件中的单个卫星的:PRN号、空间坐标、卫星钟差、高度角、伪距、对流层延迟以及站星估计几何距离R0

/// <summary>
    /// 卫星类
    /// </summary>
    public class Sat
    {
        public Matrix stapos;       //卫星位置
        public string PRN;          //卫星PRN
        public double satColck;     //卫星钟差
        public double elevation;    //卫星高度角
        public double cl;           //伪距
        public double tropDely;     //对流层延迟
        public double R0;           //估计几何距离
    }

 1.2 Epoch历元数据类

        题目要求的是计算每个历元的平差数据。

        包含txt文件中单个历元的:卫星数、历元GPS时间、历元内sat卫星类列表、最小二乘求得的坐标增量dx、最小二乘估计的位置、单位权中误差、各个方向的中误差、PDOP、协因数阵Q、权阵P、系数矩阵B、观测残差向量L、验后残差V。

/// <summary>
    /// 历元类
    /// </summary>
    public class Epoch
    {
        public int satNum;      //卫星数
        public int gpsTime;     //历元时间
        public List<Sat> sats;  //卫星观测值列表
        public Matrix dx;       //最小二乘求得的增量dx
        public Matrix pos;      //最小二乘估计的位置
        public double sigma0;   //延后单位权中误差
        public Matrix sigma;    //各个方向的中误差
        public double PDOP;     //PDOP
        public Matrix Q;        //协因数阵
        public Matrix P;        //权阵
        public Matrix B;        //设计矩阵
        public Matrix L;        //观测残差向量
        public Matrix V;        //验后残差
    }

1.3 DataCenter数据中心

        用于储存:测站近似坐标(计算R0)、文件所有Epoch历元列表。

/// <summary>
    /// 数据中心类
    /// </summary>
    public class DataCenter
    {
        public List<Epoch> Epoches;     //历元列表
        public Matrix APPROX_POSITION;  //近似坐标
    }

1.4 Matirx矩阵类

        用于声明、储存以及计算(加、减、乘、逆、转置)矩阵

 /// <summary>
    /// 矩阵类
    /// </summary>
    public class Matrix
    {
        public int m;
        public int n;
        public double[,] arr;

        /// <summary>
        /// 创建一个矩阵0*0
        /// </summary>
        public Matrix()
        {
            m = 0;
            n = 0;
            arr = new double[m, n];
        }

        /// <summary>
        /// 拷贝构造
        /// </summary>
        /// <param name="s"></param>
        public Matrix(Matrix s)
        {
            this.m = s.m;
            this.n = s.n;
            arr = new double[m, n];
            this.arr = s.arr;
        }

        public Matrix(int mm, int nn, double[,] arr)
        {
            m = mm;
            n = nn;
            this.arr = arr;
        }

        public Matrix(int mm, int nn)
        {
            m = mm;
            n = nn;
            arr = new double[m, n];
        }

        /// <summary>
        /// 创建单位阵
        /// </summary>
        /// <param name="mm"></param>
        /// <param name="nn"></param>
        /// <returns></returns>
        public Matrix MatrixE(int mm, int nn)
        {
            Matrix matrix = new Matrix(mm, nn);
            m = mm;
            n = nn;
            arr = new double[m, n];

            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    arr[i, j] = 1;
                }
            }
            return matrix;
        }

        /// <summary>
        /// 重载操作符实现矩阵加法
        /// </summary>
        /// <param name="A"></param>
        /// <param name="B"></param>
        /// <returns></returns>
        static public Matrix operator +(Matrix A, Matrix B)
        {
            Matrix C = new Matrix(A.m, A.n);
            //判断是否可以运算    
            if (A.m != B.m || A.n != B.n || A.m != C.m || A.n != C.n)
            {
                System.Windows.Forms.MessageBox.Show("矩阵维数不同");
            }
            for (int i = 0; i < C.m; i++)
            {
                for (int j = 0; j < C.n; j++)
                {
                    C.arr[i, j] = A.arr[i, j] + B.arr[i, j];
                }
            }

            return C;
        }

        /// <summary>
        /// 重载操作符实现矩阵减法
        /// </summary>
        /// <param name="A"></param>
        /// <param name="B"></param>
        /// <returns></returns>
        static public Matrix operator -(Matrix A, Matrix B)
        {
            int i = 0;
            int j = 0;
            Matrix C = new Matrix(A.m, B.n);
            //判断是否可以运算    
            if (A.m != B.m || A.n != B.n ||
                A.m != C.m || A.n != C.n)
            {
                Console.ReadKey();
            }
            for (i = 0; i < C.m; i++)
            {
                for (j = 0; j < C.n; j++)
                {
                    C.arr[i, j] = A.arr[i, j] - B.arr[i, j];
                }
            }
            return C;
        }

        /// <summary>
        /// 重载操作符实现矩阵乘法
        /// </summary>
        /// <param name="A"></param>
        /// <param name="B"></param>
        /// <returns></returns>
        static public Matrix operator *(Matrix A, Matrix B)
        {
            int i = 0;
            int j = 0;
            int k = 0;
            double temp = 0;
            Matrix C = new Matrix(A.m, B.n);
            //判断是否可以运算    
            if (A.m != C.m || B.n != C.n ||
                A.n != B.m)
            {
                return C;
            }
            //运算    
            for (i = 0; i < C.m; i++)
            {
                for (j = 0; j < C.n; j++)
                {
                    temp = 0;
                    for (k = 0; k < A.n; k++)
                    {
                        temp += A.arr[i, k] * B.arr[k, j];
                    }
                    C.arr[i, j] = temp;
                }
            }
            return C;
        }

        /// <summary>
        /// 矩阵转置
        /// </summary>
        /// <param name="A"></param>
        /// <returns></returns>
        public Matrix transposs(Matrix A)
        {
            int i = 0;
            int j = 0;
            Matrix B = new Matrix(A.n, A.m);
            for (i = 0; i < B.m; i++)
            {
                for (j = 0; j < B.n; j++)
                {
                    B.arr[i, j] = A.arr[j, i];
                }
            }
            return B;
        }

        public double[,] InverseMatrix(double[,] matrix)
        {
            int n = matrix.GetLength(0);
            double[,] result = new double[n, n];
            double[,] temp = new double[n, 2 * n];

            //将矩阵和单位矩阵拼接成一个2n*n的矩阵
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    temp[i, j] = matrix[i, j];
                    temp[i, j + n] = i == j ? 1 : 0;
                }
            }
            //高斯-约旦消元法
            for (int i = 0; i < n; i++)
            {
                double tempValue = temp[i, i];
                for (int j = i; j < 2 * n; j++)
                {
                    temp[i, j] /= tempValue;
                }
                for (int j = 0; j < n; j++)
                {
                    if (j != i)
                    {
                        tempValue = temp[j, i];
                        for (int k = i; k < 2 * n; k++)
                        {
                            temp[j, k] -= tempValue * temp[i, k];
                        }
                    }
                }
            }
            //取出逆矩阵
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    result[i, j] = temp[i, j + n];
                }
            }

            return result;
        }

        /// <summary>
        /// 矩阵求逆
        /// </summary>
        /// <param name="matrix"></param>
        /// <returns></returns>
        public Matrix Inverse(Matrix matrix)
        {
            matrix.arr = InverseMatrix(matrix.arr);
            return matrix;
        }


    }

二、Algorithm最小二乘方法

 

 2.1最小二乘代码汇总-1.CalBLB

 

 

 

 

2.2最小二乘代码汇总-2.Lsq

三、Form1

3.1 导入数据文件

 3.2 最小二乘解算

3.3 输出成果文件 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值