public override ulong Create(BitmapData image)
        {
            var data = new DenseMatrix(32, 32);
            using (var unmanaged = UnmanagedImage.FromManagedImage(image))
            using (var filtered = ExtractChannel.Apply(unmanaged))
            {
                new Convolution(Filter, 9).ApplyInPlace(filtered);
                using (var imgdata = new ResizeNearestNeighbor(32, 32).Apply(filtered))
                {
                    unsafe
                    {
                        byte* src = (byte*)imgdata.ImageData.ToPointer();
                        int offset = imgdata.Stride - imgdata.Width;
                        int width = imgdata.Width;
                        int height = imgdata.Height;
                        for (int y = 0; y < height; y++)
                        {
                            for (int x = 0; x < width; x++, src++)
                            {
                                data.At(y, x, (float)*src / 255);
                            }
                            src += offset;
                        }
                    }
                }
            }

            var dct = DctMatrix.FastDCT(data);

            int dctsize = 8;
            var vals = new List<double>();
            for (int r = 1; r <= dctsize; r++)
            {
                for (int c = 1; c <= dctsize; c++)
                {
                    vals.Add(dct[r, c]);
                }
            }

            var sorted = new List<double>(vals);
            sorted.Sort();
            var mid = dctsize * dctsize / 2;
            double median = (sorted[mid - 1] + sorted[mid]) / 2d;

            ulong index = 1;
            ulong result = 0;
            for (int i = 0; i < dctsize * dctsize; i++)
            {
                if (vals[i] > median)
                {
                    result |= index;
                }

                index = index << 1;
            }

            return result;
        }
        public void NormalizeMatrixTest()
        {
            //
            Matrix matrix = new DenseMatrix(3, 3, -15);
            Random random = new Random(2);
            foreach (var elem in matrix.IndexedEnumerator())
            {
                matrix.At(elem.Item1, elem.Item2, elem.Item3 + 5 * random.NextDouble());
            }
            double min = 1.0, max = 2.5;

            //
            var normalizedMatrix = matrix.Normalize(max, min);

            //
            foreach (var row in normalizedMatrix.RowEnumerator())
            {
                Assert.IsTrue(row.Item2.Minimum() >= min);
                Assert.IsTrue(row.Item2.Maximum() <= max);
            }
        }
示例#3
0
        /// <summary>
        /// Compute the inverse of the upper triangle (in place).
        /// </summary>
        public static void InvertUpperTriangle(this DenseMatrix matrix)
        {
            int    n = matrix.RowCount;
            double sum;

            for (int j = n - 1; j > -1; j--)
            {
                matrix.At(j, j, 1.0 / matrix.At(j, j));

                for (int i = j - 1; i > -1; i--)
                {
                    sum = 0.0;
                    for (int k = j; k > i; k--)
                    {
                        sum -= matrix.At(i, k) * matrix.At(k, j);
                    }

                    matrix.At(i, j, sum / matrix.At(i, i));
                }
            }
        }
示例#4
0
        /// <summary>
        /// Compute the inverse of the lower triangle (in place).
        /// </summary>
        public static void InvertLowerTriangle(this DenseMatrix matrix)
        {
            int    n = matrix.RowCount;
            double sum;

            for (int j = 0; j < n; j++)
            {
                matrix.At(j, j, 1.0 / matrix.At(j, j));

                for (int i = j + 1; i < n; i++)
                {
                    sum = 0.0;
                    for (int k = j; k < i; k++)
                    {
                        sum -= matrix.At(i, k) * matrix.At(k, j);
                    }

                    matrix.At(i, j, sum / matrix.At(i, i));
                }
            }
        }
示例#5
0
        /// <summary>
        /// Run example
        /// </summary>
        public void Run()
        {
            // Format vector output to console
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";

            // Create new empty square matrix
            var matrix = new DenseMatrix(10);
            Console.WriteLine(@"Empty matrix");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 1. Fill matrix by data using indexer []
            var k = 0;
            for (var i = 0; i < matrix.RowCount; i++)
            {
                for (var j = 0; j < matrix.ColumnCount; j++)
                {
                    matrix[i, j] = k++;
                }
            }

            Console.WriteLine(@"1. Fill matrix by data using indexer []");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Fill matrix by data using At. The element is set without range checking.
            for (var i = 0; i < matrix.RowCount; i++)
            {
                for (var j = 0; j < matrix.ColumnCount; j++)
                {
                    matrix.At(i, j, k--);
                }
            }

            Console.WriteLine(@"2. Fill matrix by data using At");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Clone matrix
            var clone = matrix.Clone();
            Console.WriteLine(@"3. Clone matrix");
            Console.WriteLine(clone.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 4. Clear matrix
            clone.Clear();
            Console.WriteLine(@"4. Clear matrix");
            Console.WriteLine(clone.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 5. Copy matrix into another matrix
            matrix.CopyTo(clone);
            Console.WriteLine(@"5. Copy matrix into another matrix");
            Console.WriteLine(clone.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 6. Get submatrix into another matrix
            var submatrix = matrix.SubMatrix(2, 2, 3, 3);
            Console.WriteLine(@"6. Copy submatrix into another matrix");
            Console.WriteLine(submatrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 7. Get part of the row as vector. In this example: get 4 elements from row 5 starting from column 3
            var row = matrix.Row(5, 3, 4);
            Console.WriteLine(@"7. Get part of the row as vector");
            Console.WriteLine(row.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 8. Get part of the column as vector. In this example: get 3 elements from column 2 starting from row 6
            var column = matrix.Column(2, 6, 3);
            Console.WriteLine(@"8. Get part of the column as vector");
            Console.WriteLine(column.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 9. Get columns using column enumerator. If you need all columns you may use ColumnEnumerator without parameters
            Console.WriteLine(@"9. Get columns using column enumerator");
            foreach (var keyValuePair in matrix.ColumnEnumerator(2, 4))
            {
                Console.WriteLine(@"Column {0}: {1}", keyValuePair.Item1, keyValuePair.Item2.ToString("#0.00\t", formatProvider));
            }

            Console.WriteLine();

            // 10. Get rows using row enumerator. If you need all rows you may use RowEnumerator without parameters
            Console.WriteLine(@"10. Get rows using row enumerator");
            foreach (var keyValuePair in matrix.RowEnumerator(4, 3))
            {
                Console.WriteLine(@"Row {0}: {1}", keyValuePair.Item1, keyValuePair.Item2.ToString("#0.00\t", formatProvider));
            }

            Console.WriteLine();

            // 11. Convert matrix into multidimensional array
            var data = matrix.ToArray();
            Console.WriteLine(@"11. Convert matrix into multidimensional array");
            for (var i = 0; i < data.GetLongLength(0); i++)
            {
                for (var j = 0; j < data.GetLongLength(1); j++)
                {
                    Console.Write(data[i, j].ToString("#0.00\t"));
                }

                Console.WriteLine();
            }

            Console.WriteLine();

            // 12. Convert matrix into row-wise array
            var rowwise = matrix.ToRowWiseArray();
            Console.WriteLine(@"12. Convert matrix into row-wise array");
            for (var i = 0; i < matrix.RowCount; i++)
            {
                for (var j = 0; j < matrix.ColumnCount; j++)
                {
                    Console.Write(rowwise[(i * matrix.ColumnCount) + j].ToString("#0.00\t"));
                }

                Console.WriteLine();
            }

            Console.WriteLine();

            // 13. Convert matrix into column-wise array
            var columnise = matrix.ToColumnWiseArray();
            Console.WriteLine(@"13. Convert matrix into column-wise array");
            for (var i = 0; i < matrix.RowCount; i++)
            {
                for (var j = 0; j < matrix.ColumnCount; j++)
                {
                    Console.Write(columnise[(j * matrix.RowCount) + i].ToString("#0.00\t"));
                }

                Console.WriteLine();
            }

            Console.WriteLine();

            // 14. Get matrix diagonal as vector
            var diagonal = matrix.Diagonal();
            Console.WriteLine(@"14. Get matrix diagonal as vector");
            Console.WriteLine(diagonal.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
        /// <summary>
        /// Create a matrix based on this vector in row form (one single row).
        /// </summary>
        /// <returns>This vector as a row matrix.</returns>
        public override Matrix<double> ToRowMatrix()
        {
            var matrix = new DenseMatrix(1, _length);
            for (var i = 0; i < _values.Length; i++)
            {
                matrix.At(0, i, _values[i]);
            }

            return matrix;
        }
示例#7
0
 public static Matrix quat_to_DCM(Matrix q)
 {
     Matrix DCM = new DenseMatrix(3, 3, 0);
     q = quat_norm(q);
     DCM.At(0, 0, (q.At(0, 0) * q.At(0, 0) + q.At(0, 1) * q.At(0, 1) - q.At(0, 2) * q.At(0, 2) - q.At(0, 3) * q.At(0, 3)));
     DCM.At(0, 1, 2 * (q.At(0, 1) * q.At(0, 2) + q.At(0, 0) * q.At(0, 3)));
     DCM.At(0, 2, 2 * (q.At(0, 1) * q.At(0, 3) - q.At(0, 0) * q.At(0, 2)));
     DCM.At(1, 0, 2 * (q.At(0, 1) * q.At(0, 2) - q.At(0, 0) * q.At(0, 3)));
     DCM.At(1, 1, (q.At(0, 0) * q.At(0, 0) - q.At(0, 1) * q.At(0, 1) + q.At(0, 2) * q.At(0, 2) - q.At(0, 3) * q.At(0, 3)));
     DCM.At(1, 2, 2 * (q.At(0, 2) * q.At(0, 3) + q.At(0, 0) * q.At(0, 1)));
     DCM.At(2, 0, 2 * (q.At(0, 1) * q.At(0, 3) + q.At(0, 0) * q.At(0, 2)));
     DCM.At(2, 1, 2 * (q.At(0, 2) * q.At(0, 3) - q.At(0, 0) * q.At(0, 1)));
     DCM.At(2, 2, (q.At(0, 0) * q.At(0, 0) - q.At(0, 1) * q.At(0, 1) - q.At(0, 2) * q.At(0, 2) + q.At(0, 3) * q.At(0, 3)));
     return DCM;
 }
示例#8
0
 public static Matrix mrotate(Matrix q, Matrix w, double dT)
 {
     double Fx = w.At(0, 0) * dT;
     double Fy = w.At(1, 0) * dT;
     double Fz = w.At(2, 0) * dT;
     double Fm = (double)Math.Sqrt(Fx * Fx + Fy * Fy + Fz * Fz);
     double sinFm2 = (double)Math.Sin(Fm / 2);
     double cosFm2 = (double)Math.Cos(Fm / 2);
     Matrix Nd = new DenseMatrix(1, 4, 0);
     if (Fm != (double)0)
     {
         Nd.At(0, 0, cosFm2);
         Nd.At(0, 1, (Fx / Fm) * sinFm2);
         Nd.At(0, 2, (Fy / Fm) * sinFm2);
         Nd.At(0, 3, (Fz / Fm) * sinFm2);
     }
     else Nd.At(0, 0, 1);
     q = quat_multi(q, Nd);
     return q;
 }
示例#9
0
 public static Matrix Matrix_Plus(Matrix A, Matrix B)
 {
     Matrix C = new DenseMatrix(A.RowCount, A.ColumnCount, 0);
     int i, j;
     if (A.RowCount != B.RowCount | A.ColumnCount != B.ColumnCount) return C;
     for (i = 0; i < A.RowCount; i++)
     {
         for (j = 0; j < A.ColumnCount; j++)
         {
             C.At(i, j, A.At(i, j) + B.At(i, j));
         }
     }
     return C;
 }
示例#10
0
 public static Matrix Matrix_Const_Mult(Matrix A, double B)
 {
     Matrix C = new DenseMatrix(A.RowCount, A.ColumnCount, 0);
     int i, j;
     for (i = 0; i < A.RowCount; i++)
     {
         for (j = 0; j < A.ColumnCount; j++)
         {
             C.At(i, j, A.At(i, j)*B);
         }
     }
     return C;
 }
示例#11
0
        public Matrix<double> Downsample_Skippixel(Matrix<double> baseImage)
        {
            int rows2 = baseImage.RowCount / 2;
            int cols2 = baseImage.ColumnCount / 2;

            var scaledImage = new DenseMatrix(rows2, cols2);

            // Save each second pixel
            for(int c = 0; c < scaledImage.ColumnCount; ++c)
            {
                for(int r = 0; r < scaledImage.RowCount; ++r)
                {
                    scaledImage.At(r, c,
                        baseImage.At(2 * r, 2 * c));
                }
            }

            return scaledImage;
        }
示例#12
0
        public Matrix<double> Downsample_Gauss33(Matrix<double> baseImage)
        {
            int rows2 = baseImage.RowCount / 2;
            int cols2 = baseImage.ColumnCount / 2;

            var scaledImage = new DenseMatrix(rows2, cols2);
            double sum;
            int lr = scaledImage.RowCount - 1;
            int lc = scaledImage.ColumnCount - 1;
            // TODO: borders
            for(int c = 0; c < lc; ++c)
            {
                for(int r = 0; r < lr; ++r)
                {
                    sum = baseImage.At(2 * r, 2 * c) * _gauss33[0] +
                        baseImage.At(2 * r, 2 * c + 1) * _gauss33[1] +
                        baseImage.At(2 * r, 2 * c + 2) * _gauss33[0] +
                        baseImage.At(2 * r + 1, 2 * c) * _gauss33[1] +
                        baseImage.At(2 * r + 1, 2 * c + 1) * _gauss33[2] +
                        baseImage.At(2 * r + 1, 2 * c + 2) * _gauss33[1] +
                        baseImage.At(2 * r + 2, 2 * c) * _gauss33[0] +
                        baseImage.At(2 * r + 2, 2 * c + 1) * _gauss33[1] +
                        baseImage.At(2 * r + 2, 2 * c + 2) * _gauss33[0];

                    scaledImage.At(r, c, sum);
                }
                // Last row -> mirror one out of bounds
                sum = baseImage.At(2 * lr, 2 * c) * _gauss33[0] * 2.0 +
                    baseImage.At(2 * lr, 2 * c + 1) * _gauss33[1] * 2.0 +
                    baseImage.At(2 * lr, 2 * c + 2) * _gauss33[0] * 2.0 +
                    baseImage.At(2 * lr + 1, 2 * c) * _gauss33[1] +
                    baseImage.At(2 * lr + 1, 2 * c + 1) * _gauss33[2] +
                    baseImage.At(2 * lr + 1, 2 * c + 2) * _gauss33[1];

                scaledImage.At(lr, c, sum);
            }
            // Last column -> mirror one out of bounds
            for(int r = 0; r < lr; ++r)
            {
                sum = baseImage.At(2 * r, 2 * lc) * _gauss33[0] * 2.0 +
                    baseImage.At(2 * r, 2 * lc + 1) * _gauss33[1] +
                    baseImage.At(2 * r + 1, 2 * lc) * _gauss33[1] * 2.0 +
                    baseImage.At(2 * r + 1, 2 * lc + 1) * _gauss33[2] +
                    baseImage.At(2 * r + 2, 2 * lc) * _gauss33[0] * 2.0 +
                    baseImage.At(2 * r + 2, 2 * lc + 1) * _gauss33[1];

                scaledImage.At(r, lc, sum);
            }
            // Last row -> mirror row/col out of bounds=
            sum = baseImage.At(2 * lr, 2 * lc) * _gauss33[0] * 4.0 +
                baseImage.At(2 * lr, 2 * lc + 1) * _gauss33[1] * 2.0 +
                baseImage.At(2 * lr + 1, 2 * lc) * _gauss33[1] * 2.0 +
                baseImage.At(2 * lr + 1, 2 * lc + 1) * _gauss33[2];

            scaledImage.At(lr, lc, sum);

            return scaledImage;
        }
示例#13
0
        public Matrix<double> Downsample_Average22(Matrix<double> baseImage)
        {
            int rows2 = baseImage.RowCount / 2;
            int cols2 = baseImage.ColumnCount / 2;

            var scaledImage = new DenseMatrix(rows2, cols2);

            // For each pixel set average of 2x2 neighbourhood
            for(int c = 0; c < scaledImage.ColumnCount; ++c)
            {
                for(int r = 0; r < scaledImage.RowCount; ++r)
                {
                    double sum = baseImage.At(2 * r, 2 * c) + baseImage.At(2 * r, 2 * c + 1) +
                        baseImage.At(2 * r + 1, 2 * c) + baseImage.At(2 * r + 1, 2 * c + 1);
                    scaledImage.At(r, c, 0.25 * sum);
                }
            }

            return scaledImage;
        }
示例#14
0
        private void write_data(packet[] source, int index)
        {
            int length = source.Length;
            saveBox.Text = "Сохранение файла " + index;
            saveBox.Update();
            progressBar.Value = 0;
            progressBar.Maximum = length;
            string additional = "";
            double[] magn_c = new double[12];
            double[] accl_c = new double[12];
            double[] gyro_c = new double[12];
            double Mk = 1;
            double Wk = 1;
            double Ak = 1;
            switch (index)
            {
                case 1:
                    additional = "left_oar";
                    double[] temp1 = { 0.021012275928952,   0.067860169975568,   0.000127689343889,   0.045296151352541,
                                      -0.009324017077391,   0.026722923577867,   0.008307857594568,   0.005284287915262,
                                      -0.035947192687517,  -0.012542925115207,   0.061512131892943,   0.004409782721854 };

                    accl_c = temp1;
                    Ak = 0.996259867299029;
                    double[] temp11 = { 0.002873025761360,  -0.000277783847693,  -0.008949237789463,   0.024839518300883,
                                        0.018134114269133,   0.004957678597933,   0.059903966032509,  -0.020001702990621,
                                       -0.048455202844697,   0.040007724599001,  -0.002723436449578,   0.028657182612509 };
                    magn_c = temp11;
                    Mk = 1.989928230657113;
                    Wk = 1.024951581925949;
                    break;
                case 2:
                    additional = "right_oar";
                    double[] temp2 = { 0.006489103530672,   0.007711972047671,   0.008910927008256,   0.004526628966860,
                                      -0.030613701020120,   0.009733926042102,   0.000520434141698,  -0.020438431372878,
                                      -0.000690207812167,   0.003527827615877,   0.003268096379523,  -0.009084146831565 };

                    accl_c = temp2;
                    Ak = 0.993917643789002;
                    double[] temp22 = {-0.004338472524034,  -0.007279143920897,  -0.016596561254121,  -0.040100105586272,
                                        0.026447190185438,   0.062723828297715,   0.014235202706375,  -0.032778454891706,
                                       -0.016686216543873,   0.049183804843751,  -0.170661765769371,   0.174784618340082 };
                    magn_c = temp22;
                    Mk = 1.981050375613622;
                    Wk = 0.999473669119779;
                    break;
                case 3:
                    additional = "first_hand";
                    double[] temp3 = { 0.012248789806271,   0.010963952889031,   0.010082940049261,   0.017732310046796,
                                      -0.010807018986018,  -0.017866987099261,  -0.038976713533177,   0.011937965171044,
                                       0.017418474194167,   0.010157002539499,   0.006639710879831,  -0.008997250633174 };

                    accl_c = temp3;
                    Ak = 0.995116429313122;
                    double[] temp33 = {-0.024902579646778,  -0.020478721707093,  -0.026353375666180,  -0.001744353714878,
                                        0.001038721251414,  -0.008552827405651,   0.000013148017514,   0.005334631470956,
                                       -0.004628038571913,  -0.041660570389140,   0.203013174006507,   0.110944181992475 };
                    magn_c = temp33;
                    Mk = 2.000804739331122;
                    Wk = 1.005957834380545;
                    break;
                case 4:
                    additional = "second_hand";
                    double[] temp4 = { 0.009773445955991,   0.010515969102165,   0.046332523300049,  -0.009734857220358,
                                       0.088901575635824,   0.011068909952491,  -0.012572850762404,   0.170713670954205,
                                      -0.008974449587517,   0.001063872406408,  -0.005104328004269,  -0.003338723771119 };
                    accl_c = temp4;
                    Ak = 0.995096553223738;
                    double[] temp44 = { 0.014780841871083,   0.018746310904878,   0.009620181136691,  -0.006116082059700,
                                       -0.000324924134046,  -0.004326570176434,  -0.007611544691470,   0.009652319917883,
                                        0.002813293660957,   0.093081170636918,   0.035125384985654,  -0.014316950547061 };
                    magn_c = temp44;
                    Mk = 2.063752665877927;
                    Wk = 1.013532577606638;
                    break;
                case 5:
                    additional = "seat";
                    double[] temp5 = { 0.018860976044349,   0.012994456079329,  -0.017726498806178,   0.014155888603851,
                                       0.135660705289298,  -0.005517590513633,  -0.006515740524433,   0.089222505526992,
                                       0.007556195473340,  -0.034224056011697,  -0.032625814493799,  -0.091725250270515 };
                    accl_c = temp5;
                    Ak = 0.990392687940513;
                    break;
            }
            FileStream fs_imu = File.Create(saveFileDialog.FileName + "_" + additional + ".imu", 2048, FileOptions.None);
            BinaryWriter str_imu = new BinaryWriter(fs_imu);
            Int16 buf16; Byte buf8; Int32 buf32;
            Double bufD; Single bufS; UInt32 bufU32;

            DenseVector Magn_coefs = new DenseVector(12);
            DenseVector Accl_coefs = new DenseVector(12);
            DenseVector Gyro_coefs = new DenseVector(12);
            Kalman_class.Parameters Parameters = new Kalman_class.Parameters(Accl_coefs, Magn_coefs, Gyro_coefs);
            Kalman_class.Sensors Sensors = new Kalman_class.Sensors(new DenseMatrix(1, 3, 0), new DenseMatrix(1, 3, 0), new DenseMatrix(1, 3, 0));
            Matrix Initia_quat = new DenseMatrix(1, 4, 0);
            Initia_quat.At(0, 0, 1);
            Kalman_class.State State = new Kalman_class.State(Kalman_class.ACCLERATION_NOISE, Kalman_class.MAGNETIC_FIELD_NOISE, Kalman_class.ANGULAR_VELOCITY_NOISE,
                Math.Pow(10, -6), Math.Pow(10, -15), Math.Pow(10, -15), Initia_quat);

            double[] angles = new double[3];
            double[] mw, ma, mm;
            ma = new double[3];
            mw = new double[3];
            mm = new double[3];
            Tuple<Vector, Kalman_class.Sensors, Kalman_class.State> AHRS_result;

            double[] w_helper = new double[source.Length];
            double[] anglex = new double[source.Length];
            double[] angley = new double[source.Length];
            double[] anglez = new double[source.Length];

            //for (int i = 0; i < w_helper.Length; i++) w_helper[i] = source[i].w[0];
            //anglex = Signal_processing.Zero_average_corr(w_helper, w_helper.Length);
            //for (int i = 0; i < w_helper.Length; i++) w_helper[i] = source[i].w[1];
            //angley = Signal_processing.Zero_average_corr(w_helper, w_helper.Length);
            //for (int i = 0; i < w_helper.Length; i++) w_helper[i] = source[i].w[2];
            //anglez = Signal_processing.Zero_average_corr(w_helper, w_helper.Length);

            double[] read_coefs = new double[0];
            double additional_mult = 1;
            switch (source[0].type)
                {
                    case 0x41:
                        double[] tempc1 = { 0.000833, 0.04 * Math.PI / 180F, 0.00014286, 0.00002, 31, 0.07386, 0, 0 };
                        read_coefs = tempc1;
                        break;
                    case 0x51:
                        double[] tempc2 = { 0.0039, 0, 0, 0, 0, 0, 0, 0 };
                        read_coefs = tempc2;
                        break;
                    case 0x61:
                        double[] tempc3 = { 0.0008, 0.02 * Math.PI / 180F, 0.0001, 0.00004, 25, 0.00565, 0.0055, 0.000030518 };
                        read_coefs = tempc3;
                        additional_mult = -1;
                        break;
                }

            double[] quats = new double[4];
            DenseMatrix quat_m = new DenseMatrix(1, 4);
            Matrix DCM = new DenseMatrix(3, 3);
            Matrix sens = new DenseMatrix(1, 3);
            Matrix res = new DenseMatrix(1, 3);
            double tempr = new double();
            double sqr = new double();

            for (int i = 0; i < length; i++)
            {
                progressBar.Value++;
                // умножены на -1 для того чтобы оси соответствовали правой тройке
                // и осям на датчиках
                mw[0] = source[i].w[0] * read_coefs[1]*Wk;// *-1;
                mw[1] = source[i].w[1] * read_coefs[1]*Wk;// * -1;
                mw[2] = source[i].w[2] * read_coefs[1]*Wk;// * -1;
                ma[0] = source[i].a[0] * read_coefs[0]*Ak;// * -1;
                ma[1] = source[i].a[1] * read_coefs[0]*Ak;// * -1;
                ma[2] = source[i].a[2] * read_coefs[0]*Ak;// * -1;
                mm[0] = source[i].m[0] * read_coefs[2]*Mk;// * -1;
                mm[1] = source[i].m[1] * read_coefs[2]*Mk;// * -1;
                mm[2] = source[i].m[2] * read_coefs[2]*Mk;// * -1;

                //mw = single_correction(gyro_c, w[i, 0], w[i, 1], w[i, 2]);

                Sensors.a.At(0, 0, ma[0]);
                Sensors.a.At(0, 1, ma[1]);
                Sensors.a.At(0, 2, ma[2]);

                Sensors.w.At(0, 0, mw[0]);
                Sensors.w.At(0, 1, mw[1]);
                Sensors.w.At(0, 2, mw[2]);

                Sensors.m.At(0, 0, mm[0]);
                Sensors.m.At(0, 1, mm[1]);
                Sensors.m.At(0, 2, mm[2]);

                AHRS_result = Kalman_class.AHRS_LKF_EULER(Sensors, State, Parameters);

                State = AHRS_result.Item3;
                mm = single_correction(magn_c, mm[0], mm[1], mm[2]);
                ma = single_correction(accl_c, ma[0], ma[1], ma[2]);
                //------------------------------------------------------------------------
                //mm = single_correction(magn_c, m[i, 0], m[i, 1], m[i, 2]);
                //ma = single_correction(accl_c, a[i, 0], a[i, 1], a[i, 2]);
                //mw = single_correction(gyro_c, w[i, 0], w[i, 1], w[i, 2]);
                //----------------------------------------------------------------------

                //----------------------------------------------------------------------
                angles[0] = (AHRS_result.Item1.At(0));
                angles[1] = (AHRS_result.Item1.At(1));
                angles[2] = (AHRS_result.Item1.At(2));
                //angles[0] = (anglez[i]);
                //angles[1] = (angley[i]);
                //angles[2] = (anglex[i]);

                //sqr = Math.Sqrt(mm[0]*mm[0] + mm[1]*mm[1] + mm[2]*mm[2]);
                //mm[0] = mm[0] / sqr;
                //mm[1] = mm[1] / sqr;
                //mm[2] = mm[2] / sqr;
                //sqr = sqr;

                //if (source[i].quat[1] != 0)
                //{
                //    quats[0] = source[i].quat[0] * read_coefs[6];
                //    quats[1] = source[i].quat[1] * read_coefs[7];
                //    quats[2] = source[i].quat[2] * read_coefs[7];
                //    quats[3] = source[i].quat[3] * read_coefs[7];
                //    quat_m.At(0, 0, quats[0]);
                //    quat_m.At(0, 1, quats[1]);
                //    quat_m.At(0, 2, quats[2]);
                //    quat_m.At(0, 3, quats[3]);
                //    DCM = Kalman_class.quat_to_DCM(quat_m);
                //    res = Kalman_class.dcm2angle(DCM);
                //    //angles = quat2angle(quats);
                //    //DCM = Kalman_class.Matrix_Transpose(quat2dcm(quats));
                //    angles[0] = res.At(0, 0);
                //    angles[1] = res.At(0, 1);
                //    angles[2] = res.At(0, 2);
                //    //DMC = Kalman_class.Matrix_Transpose(DMC);
                //    /*sens.At(0, 0, ma[0]);
                //    sens.At(0, 1, ma[1]);
                //    sens.At(0, 2, ma[2]);
                //    res = Kalman_class.Matrix_Mult(sens, DCM);
                //    ma[0] = res.At(0, 0);
                //    ma[1] = res.At(0, 1);
                //    ma[2] = res.At(0, 2);

                //    sens.At(0, 0, mw[0]);
                //    sens.At(0, 1, mw[1]);
                //    sens.At(0, 2, mw[2]);
                //    res = Kalman_class.Matrix_Mult(sens, DCM);
                //    mw[0] = res.At(0, 0);
                //    mw[1] = res.At(0, 1);
                //    mw[2] = res.At(0, 2);

                //    sens.At(0, 0, mm[0]);
                //    sens.At(0, 1, mm[1]);
                //    sens.At(0, 2, mm[2]);
                //    res = Kalman_class.Matrix_Mult(sens, DCM);
                //    mm[0] = res.At(0, 0);
                //    mm[1] = res.At(0, 1);
                //    mm[2] = res.At(0, 2);*/
                //}

                tempr = read_coefs[4] + source[i].temper * read_coefs[5];

                // IMU
                // QQ
                buf16 = (Int16)(angles[0] * 10000);
                str_imu.Write(buf16);
                buf16 = (Int16)(angles[1] * 10000);
                str_imu.Write(buf16);
                buf16 = (Int16)(angles[2] * 10000);
                str_imu.Write(buf16);

                // w
                buf16 = (Int16)(mw[0] * 3000);
                str_imu.Write(buf16);
                buf16 = (Int16)(mw[1] * 3000);
                str_imu.Write(buf16);
                buf16 = (Int16)(mw[2] * 3000);
                str_imu.Write(buf16);

                // a
                buf16 = (Int16)(ma[0] * 3000);
                str_imu.Write(buf16);
                buf16 = (Int16)(ma[1] * 3000);
                str_imu.Write(buf16);
                buf16 = (Int16)(ma[2] * 3000);
                str_imu.Write(buf16);
                // m
                buf16 = (Int16)(mm[0] * 3000);
                str_imu.Write(buf16);
                buf16 = (Int16)(mm[1] * 3000);
                str_imu.Write(buf16);
                buf16 = (Int16)(mm[2] * 3000);
                str_imu.Write(buf16);

                buf16 = (Int16)(tempr); // t
                str_imu.Write(buf16);

                //buf32 = (Int32)(counter[i]);
                buf32 = (Int32)(source[i].ticks); // pps_imu
                str_imu.Write(buf32);

                buf8 = (Byte)(0);   // check_sum
                str_imu.Write(buf8);
            }

            str_imu.Flush();
            str_imu.Close();
        }
示例#15
0
 private double[] single_correction(double[] coefs, double xdata, double ydata, double zdata)
 {
     double[] result = new double[3];
     Matrix B = new DiagonalMatrix(3, 3, 1);
     Matrix A = new DenseMatrix(3, 3);
     A.At(0, 0, coefs[0]);
     A.At(0, 1, coefs[3]);
     A.At(0, 2, coefs[4]);
     A.At(1, 0, coefs[5]);
     A.At(1, 1, coefs[1]);
     A.At(1, 2, coefs[6]);
     A.At(2, 0, coefs[7]);
     A.At(2, 1, coefs[8]);
     A.At(2, 2, coefs[2]);
     Matrix B1 = Kalman_class.Matrix_Minus(B, A);
     Matrix C = new DenseMatrix(3, 1);
     C.At(0, 0, xdata);
     C.At(1, 0, ydata);
     C.At(2, 0, zdata);
     Matrix D = new DenseMatrix(3, 1);
     D.At(0, 0, coefs[9]);
     D.At(1, 0, coefs[10]);
     D.At(2, 0, coefs[11]);
     Matrix res = new DenseMatrix(3, 1);
     res = Kalman_class.Matrix_Mult(B1, Kalman_class.Matrix_Minus(C, D));
     result[0] = res.At(0, 0);
     result[1] = res.At(1, 0);
     result[2] = res.At(2, 0);
     return result;
 }
示例#16
0
 private Matrix quat2dcm(double[] quat)
 {
     Matrix result = new DenseMatrix(3, 3, 0);
     result.At(0, 0, (1 - 2 * (quat[2] * quat[2] + quat[3] * quat[3])));
     result.At(0, 1, 2 * (quat[1] * quat[2] - quat[3] * quat[0]));
     result.At(0, 2, 2 * (quat[1] * quat[3] + quat[2] * quat[0]));
     result.At(1, 0, 2 * (quat[1] * quat[2] + quat[3] * quat[0]));
     result.At(1, 1, 1 - 2 * (quat[1] * quat[1] + quat[3] * quat[3]));
     result.At(1, 2, 2 * (quat[2] * quat[3] - quat[1] * quat[0]));
     result.At(2, 0, 2 * (quat[1] * quat[3] - quat[2] * quat[0]));
     result.At(2, 1, 2 * (quat[2] * quat[3] + quat[1] * quat[0]));
     result.At(2, 2, 1 - 2 * (quat[1] * quat[1] + quat[2] * quat[2]));
     return result;
 }
示例#17
0
    public static Matrix dcm2quat(Matrix DCM)
    {
        Matrix q = new DenseMatrix(1, 4, 0);
        double tr = trace (DCM);
        if (tr > 0)
        {
            double sqtrp1 = (double)Math.Sqrt(tr + 1);
            q.At(0, 0, (double)0.5 * sqtrp1);
            q.At(0, 1, (DCM.At(1, 2) - DCM.At(2, 1)) / (2 * sqtrp1));
            q.At(0, 2, (DCM.At(2, 0) - DCM.At(0, 2)) / (2 * sqtrp1));
            q.At(0, 3, (DCM.At(0, 1) - DCM.At(1, 0)) / (2 * sqtrp1));
            return q;
        }
        else
        {
            Matrix d = new DenseMatrix(1,3,0);

            d.At(0, 0, DCM.At(0, 0));
            d.At(0, 1, DCM.At(1, 1));
            d.At(0, 2, DCM.At(2, 2));

            if ((d.At(0,1)>d.At(0,0)&(d.At(0,1)>d.At(0,2))))
            {
                double sqdip1 = (double)Math.Sqrt(d.At(0, 1) - d.At(0, 0) - d.At(0, 2) + 1);
                q.At(0, 2, 0.5 * sqdip1);

                if (sqdip1 != 0)
                {
                    sqdip1 = 0.5 / sqdip1;
                }

                q.At(0, 0, (DCM.At(2, 0) - DCM.At(0, 2)) * sqdip1);
                q.At(0, 1, (DCM.At(0, 1) + DCM.At(1, 0)) * sqdip1);
                q.At(0, 3, (DCM.At(1, 2) + DCM.At(2, 1)) * sqdip1);
            }
            else if (d.At(0, 2) > d.At(0, 0))
            {
                double sqdip1 = (double)Math.Sqrt(d.At(0, 2) - d.At(0, 0) - d.At(0, 1) + 1);
                q.At(0, 3, 0.5 * sqdip1);

                if (sqdip1 != 0)
                {
                    sqdip1 = 0.5 / sqdip1;
                }

                q.At(0, 0, (DCM.At(0, 1) - DCM.At(1, 0)) * sqdip1);
                q.At(0, 1, (DCM.At(2, 0) + DCM.At(0, 2)) * sqdip1);
                q.At(0, 2, (DCM.At(1, 2) + DCM.At(2, 1)) * sqdip1);
            }
            else
            {
                double sqdip1 = (double)Math.Sqrt(d.At(0, 0) - d.At(0, 1) - d.At(0, 2) + 1);
                q.At(0, 1, 0.5 * sqdip1);

                if (sqdip1 != 0)
                {
                    sqdip1 = 0.5 * sqdip1;
                }

                q.At(0, 0, (DCM.At(1, 2) - DCM.At(2, 1)) * sqdip1);
                q.At(0, 2, (DCM.At(0, 1) + DCM.At(1, 0)) * sqdip1);
                q.At(0, 3, (DCM.At(2, 1) + DCM.At(1, 2)) * sqdip1);
            }
        }
        return q;
    }
示例#18
0
        public Matrix<double> Upsample_Copy(Matrix<double> baseImage)
        {
            int rows2 = baseImage.RowCount * 2;
            int cols2 = baseImage.ColumnCount * 2;

            var scaledImage = new DenseMatrix(rows2, cols2);

            for(int c = 0; c < baseImage.ColumnCount; ++c)
            {
                for(int r = 0; r < baseImage.RowCount; ++r)
                {
                    scaledImage.At(2 * r, 2 * c, baseImage.At(r, c));
                    scaledImage.At(2 * r + 1, 2 * c, baseImage.At(r, c));
                    scaledImage.At(2 * r, 2 * c + 1, baseImage.At(r, c));
                    scaledImage.At(2 * r + 1, 2 * c + 1, baseImage.At(r, c));
                }
            }

            return scaledImage;
        }
示例#19
0
 public static Matrix Matrix_Mult(Matrix A, Matrix B)
 {
     Matrix C = new DenseMatrix(A.RowCount, B.ColumnCount, 0);
     int i, j, k;
     double el;
     if (A.ColumnCount != B.RowCount) return C;
     for (i = 0; i < A.RowCount; i++)
     {
         for (j = 0; j < B.ColumnCount; j++)
         {
             el = 0;
             for (k = 0; k < B.RowCount; k++)
             {
                 el = el + A.At(i, k) * B.At(k, j);
             }
             C.At(i, j, el);
         }
     }
     return C;
 }
示例#20
0
        public Matrix<double> Upsample_CrossAverage(Matrix<double> baseImage)
        {
            int rows2 = baseImage.RowCount * 2;
            int cols2 = baseImage.ColumnCount * 2;
            double sum;
            int lr = baseImage.RowCount - 1;
            int lc = baseImage.ColumnCount - 1;
            var scaledImage = new DenseMatrix(rows2, cols2);

            // TODO consider borders
            // 1) Base image pixels have (2r0,2c0) coords
            // 2) For each (2r0+1,2c0+1) let it be average of 4 diagonal neighbours
            // 3 For each (2r0,2c0+1),(2r0+2,2c0) let it be average of 4 edge neighbours (including thise from 2)
            for(int c = 0; c < lc; ++c)
            {
                for(int r = 0; r < lr; ++r)
                {
                    sum = baseImage.At(r, c) + baseImage.At(r + 1, c + 1)
                        + baseImage.At(r, c + 1) + baseImage.At(r + 1, c);

                    scaledImage.At(2 * r, 2 * c, baseImage.At(r, c));
                    scaledImage.At(2 * r + 1, 2 * c + 1, 0.25 * sum);
                }

                sum = baseImage.At(lr, c) + baseImage.At(lr - 1, c + 1)
                    + baseImage.At(lr, c + 1) + baseImage.At(lr - 1, c);

                scaledImage.At(2 * lr, 2 * c, baseImage.At(lr, c));
                scaledImage.At(2 * lr + 1, 2 * c + 1, 0.25 * sum);

                scaledImage.At(lr, c, sum);
            }
            // Last column -> mirror one out of bounds
            for(int r = 0; r < lr; ++r)
            {
                sum = baseImage.At(r, lc) + baseImage.At(r + 1, lc - 1)
                    + baseImage.At(r, lc - 1) + baseImage.At(r + 1, lc);

                scaledImage.At(2 * r, 2 * lc, baseImage.At(r, lc));
                scaledImage.At(2 * r + 1, 2 * lc + 1, 0.25 * sum);
            }
            // Last row -> mirror row/col out of bounds
            sum = baseImage.At(lr, lc) + baseImage.At(lr - 1, lc - 1)
                + baseImage.At(lr, lc - 1) + baseImage.At(lr - 1, lc);

            scaledImage.At(2 * lr, 2 * lc, baseImage.At(lr, lc));
            scaledImage.At(2 * lr + 1, 2 * lc + 1, 0.25 * sum);

            // First row/column
            for(int r = 0; r < lr; ++r)
            {
                sum = baseImage.At(r, 0) + baseImage.At(r + 1, 0) +
                    scaledImage.At(2 * r + 1, 1) * 2.0;
                scaledImage.At(2 * r + 1, 0, 0.25 * sum);
            }
            sum = baseImage.At(lr, 0) + baseImage.At(lr - 1, 0) +
                scaledImage.At(2 * lr + 1, 1) * 2.0;
            scaledImage.At(2 * lr + 1, 0, 0.25 * sum);

            for(int c = 0; c < lc; ++c)
            {
                sum = baseImage.At(0, c) + baseImage.At(0, c + 1) +
                    scaledImage.At(1, 2 * c + 1) * 2.0;
                scaledImage.At(0, 2 * c + 1, 0.25 * sum);
            }
            sum = baseImage.At(0, lc) + baseImage.At(0, lc - 1) +
                scaledImage.At(1, 2 * lc + 1) * 2.0;
            scaledImage.At(0, 2 * lc + 1, 0.25 * sum);

            for(int c = 0; c < lc; ++c)
            {
                for(int r = 0; r < lr; ++r)
                {
                    sum = baseImage.At(r, c) + baseImage.At(r + 1, c) +
                        scaledImage.At(2 * r + 1, 2 * c + 1) + scaledImage.At(2 * r + 1, 2 * c - 1);
                    scaledImage.At(2 * r + 1, 2 * c, 0.25 * sum);

                    sum = baseImage.At(r, c) + baseImage.At(r, c + 1) +
                        scaledImage.At(2 * r + 1, 2 * c + 1) + scaledImage.At(2 * r - 1, 2 * c + 1);
                    scaledImage.At(2 * r, 2 * c + 1, 0.25 * sum);
                }
                sum = baseImage.At(lr, c) + baseImage.At(lr - 1, c) +
                    scaledImage.At(2 * lr + 1, 2 * c + 1) + scaledImage.At(2 * lr + 1, 2 * c - 1);
                scaledImage.At(2 * lr + 1, 2 * c, 0.25 * sum);

                sum = baseImage.At(lr, c) + baseImage.At(lr, c + 1) +
                    scaledImage.At(2 * lr + 1, 2 * c + 1) + scaledImage.At(2 * lr - 1, 2 * c + 1);
                scaledImage.At(2 * lr, 2 * c + 1, 0.25 * sum);
            }

            for(int r = 0; r < lr; ++r)
            {
                sum = baseImage.At(r, lc) + baseImage.At(r + 1, lc) +
                    scaledImage.At(2 * r + 1, 2 * lc + 1) + scaledImage.At(2 * r + 1, 2 * lc - 1);
                scaledImage.At(2 * r + 1, 2 * lc, 0.25 * sum);

                sum = baseImage.At(r, lc) + baseImage.At(r, lc - 1) +
                    scaledImage.At(2 * r + 1, 2 * lc + 1) + scaledImage.At(2 * r - 1, 2 * lc + 1);
                scaledImage.At(2 * r, 2 * lc + 1, 0.25 * sum);
            }

            sum = baseImage.At(lr, lc) + baseImage.At(lr - 1, lc) +
                scaledImage.At(2 * lr + 1, 2 * lc + 1) + scaledImage.At(2 * lr + 1, 2 * lc - 1);
            scaledImage.At(2 * lr + 1, 2 * lc, 0.25 * sum);

            sum = baseImage.At(lr, lc) + baseImage.At(lr, lc - 1) +
                scaledImage.At(2 * lr + 1, 2 * lc + 1) + scaledImage.At(2 * lr - 1, 2 * lc + 1);
            scaledImage.At(2 * lr, 2 * lc + 1, 0.25 * sum);

            return scaledImage;
        }
示例#21
0
 public static Matrix Matrix_Transpose(Matrix A)
 {
     Matrix C = new DenseMatrix(A.ColumnCount, A.RowCount);
     int i, j;
     for (i = 0; i < A.RowCount; i++)
     {
         for (j = 0; j < A.ColumnCount; j++)
         {
             C.At(j, i, A.At(i, j));
         }
     }
     return C;
 }
        public override ulong Create(BitmapData image)
        {
            var data = new DenseMatrix(32, 32);

            using (var unmanaged = new UnmanagedImage(image))
            {
                using (var filtered = ExtractChannel.Apply(unmanaged))
                {
                    Filter.ApplyInPlace(filtered);

                    using (var imgdata = Resize.Apply(filtered))
                    {
                        unsafe
                        {
                            var src = (byte*)imgdata.ImageData.ToPointer();
                            var offset = imgdata.Stride - imgdata.Width;
                            var width = imgdata.Width;
                            var height = imgdata.Height;
                            for (var y = 0; y < height; y++)
                            {
                                for (var x = 0; x < width; x++, src++)
                                {
                                    data.At(y, x, (float)*src / 255);
                                }
                                src += offset;
                            }
                        }
                    }
                }
            }

            var dct = DctMatrix.FastDCT(data);

            var vals = new double[dctsize * dctsize];
            var valscount = 0;
            for (var r = 1; r <= dctsize; r++)
            {
                for (var c = 1; c <= dctsize; c++)
                {
                    vals[valscount] = dct.At(r, c);
                    ++valscount;
                }
            }

            var sorted = new double[dctsize * dctsize];
            Array.Copy(vals, sorted, vals.Length);
            Array.Sort(sorted);

            var mid = dctsize * dctsize / 2;
            var median = (sorted[mid - 1] + sorted[mid]) / 2d;

            ulong index = 1;
            ulong result = 0;
            for (var i = 0; i < dctsize * dctsize; i++)
            {
                if (vals[i] > median)
                {
                    result |= index;
                }

                index = index << 1;
            }

            return result;
        }
示例#23
0
 public static Matrix quat_multi(Matrix A, Matrix B)
 {
     Matrix C = new DenseMatrix(A.RowCount, A.ColumnCount, 0);
     if (A.RowCount != 1 | A.ColumnCount != 4) return C;
     if (B.RowCount != 1 | B.ColumnCount != 4) return C;
     C.At(0, 0, A.At(0, 0) * B.At(0, 0) - B.At(0, 1) * A.At(0, 1) - B.At(0, 2) * A.At(0, 2) - B.At(0, 3) * A.At(0, 3));
     C.At(0, 1, A.At(0, 0) * B.At(0, 1) + B.At(0, 0) * A.At(0, 1) + B.At(0, 3) * A.At(0, 2) - B.At(0, 2) * A.At(0, 3));
     C.At(0, 2, A.At(0, 0) * B.At(0, 2) + B.At(0, 0) * A.At(0, 2) - B.At(0, 3) * A.At(0, 1) + B.At(0, 1) * A.At(0, 3));
     C.At(0, 3, A.At(0, 0) * B.At(0, 3) + B.At(0, 2) * A.At(0, 1) - B.At(0, 1) * A.At(0, 2) + B.At(0, 0) * A.At(0, 3));
     return C;
 }
示例#24
0
        private double[] getCoeffs(bool includeLinear)
        {
            double[] coeffs = null;
              try
              {

            DenseMatrix X = new DenseMatrix(_calibrationData.Count, 3);
            DenseVector Y = new DenseVector(_calibrationData.Count);
            int i = 0;
            foreach (Spot _spot in _calibrationData)
            {
              X.At(i, 0, includeLinear ? _spot.s : 0);
              X.At(i, 1, _spot.s * _spot.s);
              X.At(i, 2, _spot.s * _spot.s * _spot.s);
              Y.At(i, _spot.p);
              i++;
            }
            var XT = X.Transpose();
            var A = (XT * X).Inverse() * XT * Y;
            coeffs = A.ToArray();
              }
              catch (Exception ex)
              {
            coeffs = null;
              }
              return coeffs;
        }
示例#25
0
        private Matrix<double> CameraMatrixFromParameterization(int n0)
        {
            // Parameters:
            // Full: [fx, fy, s, px, py, eaX, eaY, eaZ, Cx, Cy, Cz]
            // Center fixed: [fx, fy, s, eaX, eaY, eaZ, Cx, Cy, Cz]
            // Aspect fixed: [f, eaX, eaY, eaZ, Cx, Cy, Cz]
            //
            // Camera : M = KR[I|-C]
            double fx = ParametersVector.At(n0 + _fxIdx);
            double fy = ParametersVector.At(n0 + _fyIdx);
            double sk = ParametersVector.At(n0 + _skIdx);
            double px = ParametersVector.At(n0 + _pxIdx);
            double py = ParametersVector.At(n0 + _pyIdx);
            double eX = ParametersVector.At(n0 + _euXIdx);
            double eY = ParametersVector.At(n0 + _euYIdx);
            double eZ = ParametersVector.At(n0 + _euZIdx);
            Vector<double> euler = new DenseVector(new double[3] { eX, eY, eZ });
            double cX = ParametersVector.At(n0 + _cXIdx);
            double cY = ParametersVector.At(n0 + _cYIdx);
            double cZ = ParametersVector.At(n0 + _cZIdx);
            Vector<double> center = new DenseVector(new double[3] { -cX, -cY, -cZ });

            Matrix<double> intMat = new DenseMatrix(3, 3);
            intMat.At(0, 0, fx);
            intMat.At(0, 1, sk);
            intMat.At(0, 2, px);
            intMat.At(1, 1, fy);
            intMat.At(1, 2, py);
            intMat.At(2, 2, 1.0);

            Matrix<double> rotMat = new DenseMatrix(3, 3);
            RotationConverter.EulerToMatrix(euler, rotMat);

            Matrix<double> extMat = new DenseMatrix(3, 4);
            extMat.SetSubMatrix(0, 0, rotMat);
            extMat.SetColumn(3, rotMat * center);

            return intMat * extMat;
        }
示例#26
0
        /// <summary>
        /// Samples the distribution.
        /// </summary>
        /// <param name="rnd">The random number generator to use.</param>
        /// <param name="degreesOfFreedom">The degrees of freedom (n) for the Wishart distribution.</param>
        /// <param name="scale">The scale matrix (V) for the Wishart distribution.</param>
        /// <param name="chol">The cholesky decomposition to use.</param>
        /// <returns>a random number from the distribution.</returns>
        static Matrix<double> DoSample(System.Random rnd, double degreesOfFreedom, Matrix<double> scale, Cholesky<double> chol)
        {
            var count = scale.RowCount;

            // First generate a lower triangular matrix with Sqrt(Chi-Squares) on the diagonal
            // and normal distributed variables in the lower triangle.
            var a = new DenseMatrix(count, count);
            for (var d = 0; d < count; d++)
            {
                a.At(d, d, Math.Sqrt(Gamma.Sample(rnd, (degreesOfFreedom - d)/2.0, 0.5)));
            }

            for (var i = 1; i < count; i++)
            {
                for (var j = 0; j < i; j++)
                {
                    a.At(i, j, Normal.Sample(rnd, 0.0, 1.0));
                }
            }

            var factor = chol.Factor;
            return factor*a*a.Transpose()*factor.Transpose();
        }
        /// <summary>
        /// Create a matrix based on this vector in column form (one single column).
        /// </summary>
        /// <returns>This vector as a column matrix.</returns>
        public override Matrix<double> ToColumnMatrix()
        {
            var matrix = new DenseMatrix(_length, 1);
            for (var i = 0; i < _values.Length; i++)
            {
                matrix.At(i, 0, _values[i]);
            }

            return matrix;
        }
示例#28
0
    public static Tuple<Vector, Sensors, State> AHRS_LKF_EULER(Sensors Sense, State State, Parameters Param)
    {
        Vector Attitude = new DenseVector(6, 0);
        bool restart = false;
        // get sensor data
        Matrix m = Sense.m;
        Matrix a = Sense.a;
        Matrix w = Sense.w;

        // Correct magntometers using callibration coefficients
        Matrix B = new DenseMatrix(3,3);
        B.At(0, 0, Param.magn_coefs.At(0));
        B.At(0, 1, Param.magn_coefs.At(3));
        B.At(0, 2, Param.magn_coefs.At(4));
        B.At(1, 0, Param.magn_coefs.At(5));
        B.At(1, 1, Param.magn_coefs.At(1));
        B.At(1, 2, Param.magn_coefs.At(6));
        B.At(2, 0, Param.magn_coefs.At(7));
        B.At(2, 1, Param.magn_coefs.At(8));
        B.At(2, 2, Param.magn_coefs.At(2));
        Matrix B0 = new DenseMatrix(3, 1);
        B0.At(0, 0, Param.magn_coefs.At(9));
        B0.At(1, 0, Param.magn_coefs.At(10));
        B0.At(2, 0, Param.magn_coefs.At(11));

        m = Matrix_Transpose(Matrix_Mult(Matrix_Minus(new DiagonalMatrix(3,3,1),B),Matrix_Minus(Matrix_Transpose(m),B0)));

        // Correct accelerometers using callibration coefficients
        B.At(0, 0, Param.accl_coefs.At(0));
        B.At(0, 1, Param.accl_coefs.At(3));
        B.At(0, 2, Param.accl_coefs.At(4));
        B.At(1, 0, Param.accl_coefs.At(5));
        B.At(1, 1, Param.accl_coefs.At(1));
        B.At(1, 2, Param.accl_coefs.At(6));
        B.At(2, 0, Param.accl_coefs.At(7));
        B.At(2, 1, Param.accl_coefs.At(8));
        B.At(2, 2, Param.accl_coefs.At(2));

        B0.At(0, 0, Param.accl_coefs.At(9));
        B0.At(1, 0, Param.accl_coefs.At(10));
        B0.At(2, 0, Param.accl_coefs.At(11));

        a = Matrix_Transpose(Matrix_Mult(Matrix_Minus(new DiagonalMatrix(3, 3, 1), B), Matrix_Minus(Matrix_Transpose(a), B0)));

        // Correct gyroscopes using callibration coefficients
        B.At(0, 0, Param.gyro_coefs.At(0));
        B.At(0, 1, Param.gyro_coefs.At(3));
        B.At(0, 2, Param.gyro_coefs.At(4));
        B.At(1, 0, Param.gyro_coefs.At(5));
        B.At(1, 1, Param.gyro_coefs.At(1));
        B.At(1, 2, Param.gyro_coefs.At(6));
        B.At(2, 0, Param.gyro_coefs.At(7));
        B.At(2, 1, Param.gyro_coefs.At(8));
        B.At(2, 2, Param.gyro_coefs.At(2));

        B0.At(0, 0, Param.gyro_coefs.At(9));
        B0.At(1, 0, Param.gyro_coefs.At(10));
        B0.At(2, 0, Param.gyro_coefs.At(11));

        w = Matrix_Transpose(Matrix_Mult(Matrix_Minus(new DiagonalMatrix(3, 3, 1), B), Matrix_Minus(Matrix_Transpose(w), B0)));

        // Get State
        Matrix q = State.q;
        Matrix dB = State.dB;
        Matrix dG = State.dG;
        Matrix dw = State.dw;
        Matrix P = State.P;

        Matrix Wb = Matrix_Transpose(w);
        Matrix Ab = Matrix_Transpose(a);
        Matrix Mb = Matrix_Transpose(m);

        double dT = Param.dT;

        //Correct Gyroscopes for estimate biases and scale factor
        B.At(0, 0, dB.At(0, 0));
        B.At(0, 1, dG.At(0, 0));
        B.At(0, 2, dG.At(1, 0));
        B.At(1, 0, dG.At(2, 0));
        B.At(1, 1, dB.At(1, 0));
        B.At(1, 2, dG.At(3, 0));
        B.At(2, 0, dG.At(4, 0));
        B.At(2, 1, dG.At(5, 0));
        B.At(2, 2, dB.At(2, 0));

        Matrix Omegab_ib;
        Omegab_ib = Matrix_Minus(Matrix_Mult(Matrix_Minus(new DiagonalMatrix(3, 3, 1), B), Wb),dw);

        if (q.At(0, 0).ToString() == "NaN")
        {
            restart = true;
        }

        //Quternion calculation
        q = mrotate(q, Omegab_ib, dT);

        if (q.At(0,0).ToString() == "NaN")
        {
            restart = true;
        }

        //DCM calculation
        Matrix Cbn = quat_to_DCM(q);

        //Gyro Angles
        Matrix angles = dcm2angle(Cbn);
        double Psi = (double) angles.At(0, 0);
        double Theta = (double) angles.At(0, 1);
        double Gamma = (double) angles.At(0, 2);

        //Acceleration Angles
        double ThetaAcc = (double)Math.Atan2(Ab.At(0, 0), Math.Sqrt(Ab.At(1, 0) * Ab.At(1, 0) + Ab.At(2, 0) * Ab.At(2, 0)));
        double GammaAcc = (double)-Math.Atan2(Ab.At(1, 0), Math.Sqrt(Ab.At(0, 0) * Ab.At(0, 0) + Ab.At(2, 0) * Ab.At(2, 0)));

        //Horizontal projection of magnetic field
        angles.At(0, 0, 0);
        angles.At(0, 1, ThetaAcc);
        angles.At(0, 2, GammaAcc);
        Matrix Cbh = angle2dcm(angles);
        Matrix Mh = Matrix_Mult(Matrix_Transpose(Cbh), Mb);

        //Magnetic Heading
        double PsiMgn = (double)(-Math.Atan2(Mh.At(1,0),Mh.At(0,0)) + Param.declination);

        //System matrix
        Matrix A = new DenseMatrix (15, 15, 0);
        Matrix I = new DiagonalMatrix (15, 15, 1);

        A.At(0, 3, 1);
        A.At(1, 4, 1);
        A.At(2, 5, 1);

        A.At(0, 6, 1);
        A.At(1, 7, 1);
        A.At(2, 8, 1);

        A.At(0, 9, Omegab_ib.At(1, 0));
        A.At(0, 10, Omegab_ib.At(2, 0));
        A.At(1, 11, Omegab_ib.At(0, 0));
        A.At(1, 12, Omegab_ib.At(2, 0));
        A.At(2, 13, Omegab_ib.At(0, 0));
        A.At(2, 14, Omegab_ib.At(1, 0));

        Matrix F = Matrix_Plus(I, Matrix_Const_Mult(A,dT));

        //Measurment Matrix
        double dPsi = Psi - PsiMgn;
        if (dPsi > Math.PI) dPsi = (double)(dPsi - 2 * Math.PI);
        if (dPsi < -Math.PI) dPsi = (double)(dPsi + 2 * Math.PI);

        double dTheta = Theta - ThetaAcc;
        if (dTheta > Math.PI) dTheta = (double)(dTheta - 2 * Math.PI);
        if (dTheta < -Math.PI) dTheta = (double)(dTheta + 2 * Math.PI);

        double dGamma = Gamma - GammaAcc;
        if (dGamma > Math.PI) dGamma = (double)(dGamma - 2 * Math.PI);
        if (dGamma < -Math.PI) dGamma = (double)(dGamma + 2 * Math.PI);

        Matrix z = new DenseMatrix(3, 1, 1);

        z.At(0, 0, dGamma);
        z.At(1, 0, dTheta);
        z.At(2, 0, dPsi);

        Matrix H = new DenseMatrix(3, 15, 0);
        H.At(0, 0, 1);
        H.At(1, 1, 1);
        H.At(2, 2, 1);

        if (Math.Abs(Math.Sqrt(Ab.At(0, 0) + Ab.At(1, 0) + Ab.At(2, 0))) > Param.accl_threshold)
        {
            H.At(0, 0, 0);
            H.At(1, 1, 0);
        }

        //Kalman Filter
        Matrix Q = State.Q;
        Matrix R = State.R;

        P = Matrix_Plus(Matrix_Mult(Matrix_Mult(F, P), Matrix_Transpose(F)),Q);

        if (P.At(0, 0).ToString() == "NaN")
        {
            P = new DiagonalMatrix(15, 15, (double)Math.Pow(10, -8));

            P.At(0, 0, (double)Math.Pow(10, -1));
            P.At(1, 1, (double)Math.Pow(10, -1));
            P.At(2, 2, (double)Math.Pow(10, -1));

            P.At(3, 3, (double)Math.Pow(10, -3));
            P.At(4, 4, (double)Math.Pow(10, -3));
            P.At(5, 5, (double)Math.Pow(10, -3));
            restart = true;
        }

        Tuple<Matrix, Matrix> KF_result;
        KF_result = KF_Cholesky_update(P,z,R,H);
        Matrix xf = KF_result.Item1;
        P = KF_result.Item2;

        Matrix df_hat = new DenseMatrix(3, 1, 0);
        df_hat.At(0, 0, xf.At(0, 0));
        df_hat.At(1, 0, xf.At(1, 0));
        df_hat.At(2, 0, xf.At(2, 0));

        Matrix dw_hat = new DenseMatrix(3, 1, 0);
        dw_hat.At(0, 0, xf.At(3, 0));
        dw_hat.At(1, 0, xf.At(4, 0));
        dw_hat.At(2, 0, xf.At(5, 0));
        Matrix dB_hat = new DenseMatrix(3, 1, 0);
        dB_hat.At(0, 0, xf.At(6, 0));
        dB_hat.At(1, 0, xf.At(7, 0));
        dB_hat.At(2, 0, xf.At(8, 0));
        Matrix dG_hat = new DenseMatrix(6, 1, 0);
        dG_hat.At(0, 0, xf.At(9, 0));
        dG_hat.At(1, 0, xf.At(10, 0));
        dG_hat.At(2, 0, xf.At(11, 0));
        dG_hat.At(3, 0, xf.At(12, 0));
        dG_hat.At(4, 0, xf.At(13, 0));
        dG_hat.At(5, 0, xf.At(14, 0));

        dw = Matrix_Plus(dw, dw_hat);
        dB = Matrix_Plus(dB, dB_hat);
        dG = Matrix_Plus(dG, dG_hat);

        Matrix dCbn = new DenseMatrix(3, 3, 0);

        dCbn.At(0, 1, -df_hat.At(2, 0));
        dCbn.At(0, 2, df_hat.At(1, 0));
        dCbn.At(1, 0, df_hat.At(2, 0));
        dCbn.At(1, 2, -df_hat.At(0, 0));
        dCbn.At(2, 0, -df_hat.At(1, 0));
        dCbn.At(2, 1, df_hat.At(0, 0));

        Cbn = Matrix_Mult(Matrix_Plus(new DiagonalMatrix(3, 3, 1), dCbn), Cbn);
        if (Cbn.At(0, 0).ToString() == "NaN")
        {
            restart = true;
        }
        if (dcm2quat(Cbn).At(0, 0).ToString() == "NaN")
        {
            restart = true;
        }
        q = dcm2quat(Cbn);
        if (q.At(0, 0).ToString() == "NaN")
        {
            restart = true;
        }
        q = quat_norm(q);

        if (q.At(0, 0).ToString() == "NaN")
        {
            restart = true;
        }

        Attitude.At(0, Psi);
        Attitude.At(1, Theta);
        Attitude.At(2, Gamma);
        Attitude.At(3, PsiMgn);
        Attitude.At(4, ThetaAcc);
        Attitude.At(5, GammaAcc);

        State.q = q;
        State.dG = dG;
        State.dB = dB;
        State.dw = dw;
        State.P = P;

        Sense.w = Matrix_Transpose(Omegab_ib);
        Sense.a = a;
        Sense.m = m;

        if (restart)
        {
            Matrix Initia_quat = new DenseMatrix(1, 4, 0);
            Initia_quat.At(0, 0, 1);
            State = new Kalman_class.State(ACCLERATION_NOISE, MAGNETIC_FIELD_NOISE, ANGULAR_VELOCITY_NOISE,
                Math.Pow(10, -6), Math.Pow(10, -15), Math.Pow(10, -15), Initia_quat);
        }

        return new Tuple <Vector, Sensors, State>(Attitude, Sense, State);
    }
示例#29
0
        /// <summary>
        /// Outer product of two vectors
        /// </summary>
        /// <param name="u">First vector</param>
        /// <param name="v">Second vector</param>
        /// <returns>Matrix M[i,j] = u[i]*v[j] </returns>
        /// <exception cref="ArgumentNullException">If the u vector is <see langword="null" />.</exception>
        /// <exception cref="ArgumentNullException">If the v vector is <see langword="null" />.</exception>
        public static DenseMatrix OuterProduct(DenseVector u, DenseVector v)
        {
            if (u == null)
            {
                throw new ArgumentNullException("u");
            }

            if (v == null)
            {
                throw new ArgumentNullException("v");
            }

            var matrix = new DenseMatrix(u.Count, v.Count);
            CommonParallel.For(0, u.Count, (a, b) =>
                {
                    for (int i = a; i < b; i++)
                    {
                        for (var j = 0; j < v.Count; j++)
                        {
                            matrix.At(i, j, u._values[i]*v._values[j]);
                        }
                    }
                });
            return matrix;
        }
示例#30
0
 public static Matrix angle2dcm(Matrix angles)
 {
     Matrix DCM = new DenseMatrix(3, 3, 0);
     if (angles.RowCount != 1 | angles.ColumnCount != 3) return DCM;
     double Cos1 = (double)Math.Cos(angles.At(0, 0));
     double Cos2 = (double)Math.Cos(angles.At(0, 1));
     double Cos3 = (double)Math.Cos(angles.At(0, 2));
     double Sin1 = (double)Math.Sin(angles.At(0, 0));
     double Sin2 = (double)Math.Sin(angles.At(0, 1));
     double Sin3 = (double)Math.Sin(angles.At(0, 2));
     DCM.At(0, 0, Cos2 * Cos1);
     DCM.At(0, 1, Cos2 * Sin1);
     DCM.At(0, 2, -Sin2);
     DCM.At(1, 0, Sin3 * Sin2 * Cos1 - Cos3 * Sin1);
     DCM.At(1, 1, Sin3 * Sin2 * Sin1 + Cos3 * Cos1);
     DCM.At(1, 2, Sin3 * Cos2);
     DCM.At(2, 0, Cos3 * Sin2 * Cos1 + Sin3 * Sin1);
     DCM.At(2, 1, Cos3 * Sin2 * Sin1 - Sin3 * Cos1);
     DCM.At(2, 2, Cos3 * Cos2);
     return DCM;
 }
示例#31
0
        /// <summary>
        /// Helper method to calculate an approximation of the Jacobian.
        /// </summary>
        /// <param name="f">The function.</param>
        /// <param name="x0">The argument (initial guess).</param>
        /// <param name="y0">The result (of initial guess).</param>
        static Matrix<double> CalculateApproximateJacobian(Func<double[], double[]> f, double[] x0, double[] y0)
        {
            int dim = x0.Length;
            var B = new DenseMatrix(dim);

            var x = new double[dim];
            Array.Copy(x0, 0, x, 0, dim);

            for (int j = 0; j < dim; j++)
            {
                double h = Math.Abs(x0[j])*1.0e-4;
                if (h == 0.0)
                {
                    h = 1.0e-4;
                }

                var xj = x[j];
                x[j] = xj + h;
                double[] y = f(x);
                x[j] = xj;

                for (int i = 0; i < dim; i++)
                {
                    B.At(i, j, (y[i] - y0[i])/h);
                }
            }

            return B;
        }
示例#32
0
 public static Matrix dcm2angle(Matrix DCM)
 {
     Matrix angles = new DenseMatrix(1,3,0);
     if (DCM.RowCount != 3 | DCM.ColumnCount != 3) return angles;
     angles.At(0, 0, (double)(Math.Atan2(DCM.At(0, 1), DCM.At(0, 0))));
     angles.At(0, 1, (double)-(Math.Atan2(DCM.At(0, 2), Math.Sqrt(1 - DCM.At(0, 2) * DCM.At(0, 2)))));
     angles.At(0, 2, (double)(Math.Atan2(DCM.At(1, 2), DCM.At(2, 2))));
     return angles;
 }