public DenseMatrix getInversedJacobiFromSVD(DenseVector angles)
    {
        DenseMatrix jacobi = this.getJacobi(angles);
        var         svd    = jacobi.Svd(true);
        var         s      = new DiagonalMatrix(jacobi.RowCount, jacobi.ColumnCount, (1 / svd.S).ToArray());
        // 疑似逆行列を計算する
        var m = svd.VT.Transpose() * s.Transpose() * svd.U.Transpose();

        return((DenseMatrix)m);
    }
Exemple #2
0
    public void Compute_Vector()
    {
        Counting++;


        DH_kinematics();

        //Debug.Log(Key_Input.purpos_x);

        /*
         * if (Mathf.Abs(Key_Input.purpos_x - Key_Input.coordinate_x) == 0.0f)
         * {
         *  move_x = 0.0f;
         * }else
         * {
         *  move_x = ((Key_Input.purpos_x - Key_Input.coordinate_x) / (Mathf.Abs(Key_Input.purpos_x - Key_Input.coordinate_x))) * step;
         * }
         *
         * if (Mathf.Abs(Key_Input.purpos_y - Key_Input.coordinate_y) == 0.0f)
         * {
         *  move_y = 0.0f;
         * }
         * else
         * {
         *  move_y =((Key_Input.purpos_y - Key_Input.coordinate_y) / (Mathf.Abs(Key_Input.purpos_y - Key_Input.coordinate_y))) * step;
         * }
         *
         *
         * if (Mathf.Abs(Key_Input.purpos_z - Key_Input.coordinate_z) == 0.0f)
         * {
         *  move_z = 0.0f;
         * }
         * else
         * {
         *  move_z = ((Key_Input.purpos_z - Key_Input.coordinate_z) / (Mathf.Abs(Key_Input.purpos_z - Key_Input.coordinate_z))) * step;
         * }
         */



        /****目標位置まで移動するベクトルを算出****/
        var move_vector = DenseMatrix.OfArray(new double[, ] {
            { Key_Input.purpos_x *step }, { Key_Input.purpos_y *step }, { Key_Input.purpos_z *step }
        });                                                                                                                                                  //DenseMatrix.OfArray(new double[,] { { move_x }, { move_y }, { move_z } });
        //Debug.Log(move_vector);
        /****ヤコビアン****/
        var jacobian = DenseMatrix.OfArray(new double[, ] {
            { Mathf.Round(L4 * Mathf.Cos(t4) * (Mathf.Cos(t1) * Mathf.Sin(t3) - Mathf.Cos(t2) * Mathf.Cos(t3) * Mathf.Sin(t1)) - L2 * Mathf.Sin(t1) - L3 * Mathf.Sin(t1) * Mathf.Sin(t2) + L4 * Mathf.Sin(t1) * Mathf.Sin(t2) * Mathf.Sin(t4)), Mathf.Round(L3 * Mathf.Cos(t1) * Mathf.Cos(t2) - L4 * Mathf.Cos(t1) * Mathf.Cos(t2) * Mathf.Sin(t4) - L4 * Mathf.Cos(t1) * Mathf.Cos(t3) * Mathf.Cos(t4) * Mathf.Sin(t2)), Mathf.Round(L4 * Mathf.Cos(t4) * (Mathf.Cos(t3) * Mathf.Sin(t1) - Mathf.Cos(t1) * Mathf.Cos(t2) * Mathf.Sin(t3))), Mathf.Round(-L4 * Mathf.Sin(t4) * (Mathf.Sin(t1) * Mathf.Sin(t3) + Mathf.Cos(t1) * Mathf.Cos(t2) * Mathf.Cos(t3)) - L4 * Mathf.Cos(t1) * Mathf.Cos(t4) * Mathf.Sin(t2)) },
            { Mathf.Round(L2 * Mathf.Cos(t1) + L4 * Mathf.Cos(t4) * (Mathf.Sin(t1) * Mathf.Sin(t3) + Mathf.Cos(t1) * Mathf.Cos(t2) * Mathf.Cos(t3)) + L3 * Mathf.Cos(t1) * Mathf.Sin(t2) - L4 * Mathf.Cos(t1) * Mathf.Sin(t2) * Mathf.Sin(t4)), Mathf.Round(L3 * Mathf.Cos(t2) * Mathf.Sin(t1) - L4 * Mathf.Cos(t2) * Mathf.Sin(t1) * Mathf.Sin(t4) - L4 * Mathf.Cos(t3) * Mathf.Cos(t4) * Mathf.Sin(t1) * Mathf.Sin(t2)), Mathf.Round(-L4 * Mathf.Cos(t4) * (Mathf.Cos(t1) * Mathf.Cos(t3) + Mathf.Cos(t2) * Mathf.Sin(t1) * Mathf.Sin(t3))), Mathf.Round(L4 * Mathf.Sin(t4) * (Mathf.Cos(t1) * Mathf.Sin(t3) - Mathf.Cos(t2) * Mathf.Cos(t3) * Mathf.Sin(t1)) - L4 * Mathf.Cos(t4) * Mathf.Sin(t1) * Mathf.Sin(t2)) },
            { 0, Mathf.Round(L3 * Mathf.Sin(t2) - L4 * Mathf.Sin(t2) * Mathf.Sin(t4) + L4 * Mathf.Cos(t2) * Mathf.Cos(t3) * Mathf.Cos(t4)), Mathf.Round(-L4 * Mathf.Cos(t4) * Mathf.Sin(t2) * Mathf.Sin(t3)), Mathf.Round(L4 * Mathf.Cos(t2) * Mathf.Cos(t4) - L4 * Mathf.Cos(t3) * Mathf.Sin(t2) * Mathf.Sin(t4)) }
        });


        //Debug.Log(jacobian);


        /****特異値分解****/
        var svd = jacobian.Svd(true);


        /****ベクトルを行列に逆数を取って代入****/
        var S = new DiagonalMatrix(jacobian.RowCount, jacobian.ColumnCount, (1 / svd.S).ToArray());

        /**0除算の例外処理**/
        for (int i = 0; i < S.RowCount; i++)
        {
            for (int j = 0; j < S.ColumnCount; j++)
            {
                if (double.IsInfinity(S[i, j]))
                {
                    S[i, j] = 0.0f;
                }
            }
        }

        /**擬似逆行列**/
        var pseudoInv = svd.VT.Transpose() * S.Transpose() * svd.U.Transpose();

        //var pseudoInv = jacobian.Transpose() * (jacobian * jacobian.Transpose()).Inverse();
        Debug.Log("psudoInv = " + pseudoInv);
        Debug.Log("move_vector = " + move_vector);


        /********Δθの算出*********/
        var delta_theta = pseudoInv * move_vector;

        Debug.Log("delta_theta = " + delta_theta);


        t1 += (float)delta_theta[0, 0];
        t2 += (float)delta_theta[1, 0];
        t3 += (float)delta_theta[2, 0];
        t4 += (float)delta_theta[3, 0];


        //Debug.Log(t1 +", "+ t2 + ", " + t3 + ", " + t4);
        DH_kinematics();

        /*if(Mathf.Abs(Key_Input.purpos_x - Key_Input.coordinate_x) > error || Mathf.Abs(Key_Input.purpos_y - Key_Input.coordinate_y) > error || Mathf.Abs(Key_Input.purpos_z - Key_Input.coordinate_z) > error)
         * {
         *  if (Counting != 30)
         *  {
         *      Compute_Vector();
         *  }
         *  else
         *  {
         *      Debug.Log("It could not Compute values of theta");
         *      Counting = 0;
         *  }
         * }*/
    }