コード例 #1
0
  int ChainIkSolverVel_wdls::CartToJnt(const JntArray& q_in, const Twist& v_in, JntArray& qdot_out)
  {
      jnt2jac.JntToJac(q_in,jac);
      
      double sum;
      unsigned int i,j;
      
      /*
      for (i=0;i<jac.rows();i++) {
          for (j=0;j<jac.columns();j++)
              tmp_jac(i,j) = jac(i,j);
      }
      */
      
      // Create the Weighted jacobian
      tmp_jac_weight1 = jac.data.lazyProduct(weight_js);
      tmp_jac_weight2 = weight_ts.lazyProduct(tmp_jac_weight1);
 
      // Compute the SVD of the weighted jacobian
      int ret = svd_eigen_HH(tmp_jac_weight2,U,S,V,tmp,maxiter);
              
      //Pre-multiply U and V by the task space and joint space weighting matrix respectively
      tmp_ts = weight_ts.lazyProduct(U.topLeftCorner(6,6));
      tmp_js = weight_js.lazyProduct(V);
      
      // tmp = (Si*U'*Ly*y), 
      for (i=0;i<jac.columns();i++) {
          sum = 0.0;
          for (j=0;j<jac.rows();j++) {
              if(i<6)
                  sum+= tmp_ts(j,i)*v_in(j);
              else
                  sum+=0.0;
          }
          if(S(i)==0||S(i)<eps)
              tmp(i) = sum*((S(i)/(S(i)*S(i)+lambda*lambda)));   
          else
              tmp(i) = sum/S(i);
      }
      /*
      // x = Lx^-1*V*tmp + x
      for (i=0;i<jac.columns();i++) {
          sum = 0.0;
          for (j=0;j<jac.columns();j++) {
              sum+=tmp_js(i,j)*tmp(j);
          }
          qdot_out(i)=sum;
      }
      */
      qdot_out.data=tmp_js.lazyProduct(tmp);
      return ret;
  }
コード例 #2
0
    int ChainIkSolverVel_pinv_nso::CartToJnt(const JntArray& q_in, const Twist& v_in, JntArray& qdot_out)
    {
        if (nj != chain.getNrOfJoints())
            return (error = E_NOT_UP_TO_DATE);

        if (nj != q_in.rows() || nj != qdot_out.rows() || nj != opt_pos.rows() || nj != weights.rows())
            return (error = E_SIZE_MISMATCH);
        //Let the ChainJntToJacSolver calculate the jacobian "jac" for
        //the current joint positions "q_in" 
        error = jnt2jac.JntToJac(q_in,jac);
        if (error < E_NOERROR) return error;

        //Do a singular value decomposition of "jac" with maximum
        //iterations "maxiter", put the results in "U", "S" and "V"
        //jac = U*S*Vt
        svdResult = svd_eigen_HH(jac.data,U,S,V,tmp,maxiter);
        if (0 != svdResult)
        {
            qdot_out.data.setZero() ;
            return error = E_SVD_FAILED;
        }

        unsigned int i;

        // We have to calculate qdot_out = jac_pinv*v_in
        // Using the svd decomposition this becomes(jac_pinv=V*S_pinv*Ut):
        // qdot_out = V*S_pinv*Ut*v_in

        // S^-1
        for (i = 0; i < nj; ++i) {
            Sinv(i) = fabs(S(i))<eps ? 0.0 : 1.0/S(i);
        }
        for (i = 0; i < 6; ++i) {
            tmp(i) = v_in(i);
        }

        qdot_out.data = V * Sinv.asDiagonal() * U.transpose() * tmp.head(6);

        // Now onto NULL space
        // Given the cost function g, and the current joints q, desired joints qd, and weights w:
        // t = g(q) = 1/2 * Sum( w_i * (q_i - qd_i)^2 )
        //
        // The jacobian Jc is:
        //  t_dot = Jc(q) * q_dot
        //  Jc = dt/dq = w_j * (q_i - qd_i) [1 x nj vector]
        //
        // The pseudo inverse (^-1) is
        // Jc^-1 = w_j * (q_i - qd_i) / A [nj x 1 vector]
        // A = Sum( w_i^2 * (q_i - qd_i)^2 )
        //
        // We can set the change as the step needed to remove the error times a value alpha:
        // t_dot = -2 * alpha * t
        //
        // When we put it together and project into the nullspace, the final result is
        // q'_out += (I_n - J^-1 * J) * Jc^-1 * (-2 * alpha * g(q))

        double g = 0; // g(q)
        double A = 0; // normalizing term
        for (i = 0; i < nj; ++i) {
            double qd = q_in(i) - opt_pos(i);
            g += 0.5 * qd*qd * weights(i);
            A += qd*qd * weights(i)*weights(i);
        }

        if (A > 1e-9) {
          // Calculate inverse Jacobian Jc^-1
          for (i = 0; i < nj; ++i) {
              tmp(i) = weights(i)*(q_in(i) - opt_pos(i)) / A;
          }

          // Calculate J^-1 * J * Jc^-1 = V*S^-1*U' * U*S*V' * tmp
          tmp2 = V * Sinv.asDiagonal() * U.transpose() * U * S.asDiagonal() * V.transpose() * tmp;

          for (i = 0; i < nj; ++i) {
              //std::cerr << i <<": "<< qdot_out(i) <<", "<< -2*alpha*g * (tmp(i) - tmp2(i)) << std::endl;
              qdot_out(i) += -2*alpha*g * (tmp(i) - tmp2(i));
          }
        }
        //return the return value of the svd decomposition
        return (error = E_NOERROR);
    }
コード例 #3
0
    int ChainIkSolverVel_wdls::CartToJnt(const JntArray& q_in, const Twist& v_in, JntArray& qdot_out)
    {
        if(nj != chain.getNrOfJoints())
            return (error = E_NOT_UP_TO_DATE);

        if(nj != q_in.rows() || nj != qdot_out.rows())
            return (error = E_SIZE_MISMATCH);
        error = jnt2jac.JntToJac(q_in,jac);
        if ( error < E_NOERROR) return error;
        
        double sum;
        unsigned int i,j;
        
        // Initialize (internal) return values
        nrZeroSigmas = 0 ;
        sigmaMin = 0.;
        lambda_scaled = 0.;

        /*
        for (i=0;i<jac.rows();i++) {
            for (j=0;j<jac.columns();j++)
                tmp_jac(i,j) = jac(i,j);
        }
        */
        
        // Create the Weighted jacobian
        tmp_jac_weight1 = jac.data.lazyProduct(weight_js);
        tmp_jac_weight2 = weight_ts.lazyProduct(tmp_jac_weight1);
   
        // Compute the SVD of the weighted jacobian
        svdResult = svd_eigen_HH(tmp_jac_weight2,U,S,V,tmp,maxiter);
        if (0 != svdResult)
        {
            qdot_out.data.setZero() ;
            return (error = E_SVD_FAILED);
        }

        //Pre-multiply U and V by the task space and joint space weighting matrix respectively
        tmp_ts = weight_ts.lazyProduct(U.topLeftCorner(6,6));
        tmp_js = weight_js.lazyProduct(V);

        // Minimum of six largest singular values of J is S(5) if number of joints >=6 and 0 for <6
        if ( jac.columns() >= 6 ) {
            sigmaMin = S(5);
        }
        else {
            sigmaMin = 0.;
        }

        // tmp = (Si*U'*Ly*y),
        for (i=0;i<jac.columns();i++) {
            sum = 0.0;
            for (j=0;j<jac.rows();j++) {
                if(i<6)
                    sum+= tmp_ts(j,i)*v_in(j);
                else
                    sum+=0.0;
            }
            // If sigmaMin > eps, then wdls is not active and lambda_scaled = 0 (default value)
            // If sigmaMin < eps, then wdls is active and lambda_scaled is scaled from 0 to lambda
            // Note:  singular values are always positive so sigmaMin >=0
            if ( sigmaMin < eps )
            {
			    lambda_scaled = sqrt(1.0-(sigmaMin/eps)*(sigmaMin/eps))*lambda ;
            }
			if(fabs(S(i))<eps) {
				if (i<6) {
					// Scale lambda to size of singular value sigmaMin
					tmp(i) = sum*((S(i)/(S(i)*S(i)+lambda_scaled*lambda_scaled)));
				}
				else {
					tmp(i)=0.0;  // S(i)=0 for i>=6 due to cols>rows
				}
				//  Count number of singular values near zero
				++nrZeroSigmas ;
			}
			else {
                tmp(i) = sum/S(i);
			}
        }

        /*
        // x = Lx^-1*V*tmp + x
        for (i=0;i<jac.columns();i++) {
            sum = 0.0;
            for (j=0;j<jac.columns();j++) {
                sum+=tmp_js(i,j)*tmp(j);
            }
            qdot_out(i)=sum;
        }
        */
        qdot_out.data=tmp_js.lazyProduct(tmp);

        // If number of near zero singular values is greater than the full rank
        // of jac, then wdls is active
        if ( nrZeroSigmas > (jac.columns()-jac.rows()) )	{
            return (error = E_CONVERGE_PINV_SINGULAR);  // converged but pinv singular
        } else {
            return (error = E_NOERROR);                 // have converged
        }
    }