Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "chainiksolvervel_wdls.hpp"
00023 #include "utilities/svd_eigen_HH.hpp"
00024
00025 namespace KDL
00026 {
00027
00028 ChainIkSolverVel_wdls::ChainIkSolverVel_wdls(const Chain& _chain,double _eps,int _maxiter):
00029 chain(_chain),
00030 jnt2jac(chain),
00031 nj(chain.getNrOfJoints()),
00032 jac(nj),
00033 U(MatrixXd::Zero(6,nj)),
00034 S(VectorXd::Zero(nj)),
00035 V(MatrixXd::Zero(nj,nj)),
00036 eps(_eps),
00037 maxiter(_maxiter),
00038 tmp(VectorXd::Zero(nj)),
00039 tmp_jac(MatrixXd::Zero(6,nj)),
00040 tmp_jac_weight1(MatrixXd::Zero(6,nj)),
00041 tmp_jac_weight2(MatrixXd::Zero(6,nj)),
00042 tmp_ts(MatrixXd::Zero(6,6)),
00043 tmp_js(MatrixXd::Zero(nj,nj)),
00044 weight_ts(MatrixXd::Identity(6,6)),
00045 weight_js(MatrixXd::Identity(nj,nj)),
00046 lambda(0.0),
00047 lambda_scaled(0.0),
00048 nrZeroSigmas(0),
00049 svdResult(0),
00050 sigmaMin(0)
00051 {
00052 }
00053
00054
00055 ChainIkSolverVel_wdls::~ChainIkSolverVel_wdls()
00056 {
00057 }
00058
00059 int ChainIkSolverVel_wdls::setWeightJS(const MatrixXd& Mq){
00060 if (Mq.size() != weight_js.size())
00061 return (error = E_SIZE_MISMATCH);
00062 weight_js = Mq;
00063 return (error = E_NOERROR);
00064 }
00065
00066 int ChainIkSolverVel_wdls::setWeightTS(const MatrixXd& Mx){
00067 if (Mx.size() != weight_ts.size())
00068 return (error = E_SIZE_MISMATCH);
00069 weight_ts = Mx;
00070 return (error = E_NOERROR);
00071 }
00072
00073 void ChainIkSolverVel_wdls::setLambda(const double lambda_in)
00074 {
00075 lambda=lambda_in;
00076 }
00077
00078 void ChainIkSolverVel_wdls::setEps(const double eps_in)
00079 {
00080 eps=eps_in;
00081 }
00082
00083 void ChainIkSolverVel_wdls::setMaxIter(const int maxiter_in)
00084 {
00085 maxiter=maxiter_in;
00086 }
00087
00088 int ChainIkSolverVel_wdls::CartToJnt(const JntArray& q_in, const Twist& v_in, JntArray& qdot_out)
00089 {
00090 if(nj != q_in.rows() || nj != qdot_out.rows())
00091 return (error = E_SIZE_MISMATCH);
00092 error = jnt2jac.JntToJac(q_in,jac);
00093 if ( error < E_NOERROR) return error;
00094
00095 double sum;
00096 unsigned int i,j;
00097
00098
00099 nrZeroSigmas = 0 ;
00100 sigmaMin = 0.;
00101 lambda_scaled = 0.;
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 tmp_jac_weight1 = jac.data.lazyProduct(weight_js);
00112 tmp_jac_weight2 = weight_ts.lazyProduct(tmp_jac_weight1);
00113
00114
00115 svdResult = svd_eigen_HH(tmp_jac_weight2,U,S,V,tmp,maxiter);
00116 if (0 != svdResult)
00117 {
00118 qdot_out.data.setZero() ;
00119 return (error = E_SVD_FAILED);
00120 }
00121
00122
00123 tmp_ts = weight_ts.lazyProduct(U.topLeftCorner(6,6));
00124 tmp_js = weight_js.lazyProduct(V);
00125
00126
00127 if ( jac.columns() >= 6 ) {
00128 sigmaMin = S(5);
00129 }
00130 else {
00131 sigmaMin = 0.;
00132 }
00133
00134
00135 for (i=0;i<jac.columns();i++) {
00136 sum = 0.0;
00137 for (j=0;j<jac.rows();j++) {
00138 if(i<6)
00139 sum+= tmp_ts(j,i)*v_in(j);
00140 else
00141 sum+=0.0;
00142 }
00143
00144
00145
00146 if ( sigmaMin < eps )
00147 {
00148 lambda_scaled = sqrt(1.0-(sigmaMin/eps)*(sigmaMin/eps))*lambda ;
00149 }
00150 if(fabs(S(i))<eps) {
00151 if (i<6) {
00152
00153 tmp(i) = sum*((S(i)/(S(i)*S(i)+lambda_scaled*lambda_scaled)));
00154 }
00155 else {
00156 tmp(i)=0.0;
00157 }
00158
00159 ++nrZeroSigmas ;
00160 }
00161 else {
00162 tmp(i) = sum/S(i);
00163 }
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 qdot_out.data=tmp_js.lazyProduct(tmp);
00177
00178
00179
00180 if ( nrZeroSigmas > (jac.columns()-jac.rows()) ) {
00181 return (error = E_CONVERGE_PINV_SINGULAR);
00182 } else {
00183 return (error = E_NOERROR);
00184 }
00185 }
00186
00187 const char* ChainIkSolverVel_wdls::strError(const int error) const
00188 {
00189 if (E_CONVERGE_PINV_SINGULAR == error) return "Converged put pseudo inverse of jacobian is singular.";
00190 else return SolverI::strError(error);
00191 }
00192
00193 }