00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "chainiksolvervel_pinv_nso.hpp"
00023 #include "utilities/svd_eigen_HH.hpp"
00024
00025 namespace KDL
00026 {
00027 ChainIkSolverVel_pinv_nso::ChainIkSolverVel_pinv_nso(const Chain& _chain, const JntArray& _opt_pos, const JntArray& _weights, double _eps, int _maxiter, double _alpha):
00028 chain(_chain),
00029 jnt2jac(chain),
00030 nj(chain.getNrOfJoints()),
00031 jac(nj),
00032 U(MatrixXd::Zero(6,nj)),
00033 S(VectorXd::Zero(nj)),
00034 Sinv(VectorXd::Zero(nj)),
00035 V(MatrixXd::Zero(nj,nj)),
00036 tmp(VectorXd::Zero(nj)),
00037 tmp2(VectorXd::Zero(nj)),
00038 eps(_eps),
00039 maxiter(_maxiter),
00040 svdResult(0),
00041 alpha(_alpha),
00042 weights(_weights),
00043 opt_pos(_opt_pos)
00044 {
00045 }
00046
00047 ChainIkSolverVel_pinv_nso::ChainIkSolverVel_pinv_nso(const Chain& _chain, double _eps, int _maxiter, double _alpha):
00048 chain(_chain),
00049 jnt2jac(chain),
00050 nj(chain.getNrOfJoints()),
00051 jac(nj),
00052 U(MatrixXd::Zero(6,nj)),
00053 S(VectorXd::Zero(nj)),
00054 Sinv(VectorXd::Zero(nj)),
00055 V(MatrixXd::Zero(nj,nj)),
00056 tmp(VectorXd::Zero(nj)),
00057 tmp2(VectorXd::Zero(nj)),
00058 eps(_eps),
00059 maxiter(_maxiter),
00060 svdResult(0),
00061 alpha(_alpha)
00062 {
00063 }
00064
00065 void ChainIkSolverVel_pinv_nso::updateInternalDataStructures() {
00066 jnt2jac.updateInternalDataStructures();
00067 nj = chain.getNrOfJoints();
00068 jac.resize(nj);
00069 U.conservativeResizeLike(MatrixXd::Zero(6,nj));
00070 S.conservativeResizeLike(VectorXd::Zero(nj));
00071 Sinv.conservativeResizeLike(VectorXd::Zero(nj));
00072 V.conservativeResizeLike(MatrixXd::Zero(nj,nj));
00073 tmp.conservativeResizeLike(VectorXd::Zero(nj));
00074 tmp2.conservativeResizeLike(VectorXd::Zero(nj));
00075 opt_pos.data.conservativeResizeLike(VectorXd::Zero(nj));
00076 weights.data.conservativeResizeLike(VectorXd::Ones(nj));
00077 }
00078
00079 ChainIkSolverVel_pinv_nso::~ChainIkSolverVel_pinv_nso()
00080 {
00081 }
00082
00083
00084 int ChainIkSolverVel_pinv_nso::CartToJnt(const JntArray& q_in, const Twist& v_in, JntArray& qdot_out)
00085 {
00086 if (nj != chain.getNrOfJoints())
00087 return (error = E_NOT_UP_TO_DATE);
00088
00089 if (nj != q_in.rows() || nj != qdot_out.rows() || nj != opt_pos.rows() || nj != weights.rows())
00090 return (error = E_SIZE_MISMATCH);
00091
00092
00093 error = jnt2jac.JntToJac(q_in,jac);
00094 if (error < E_NOERROR) return error;
00095
00096
00097
00098
00099 svdResult = svd_eigen_HH(jac.data,U,S,V,tmp,maxiter);
00100 if (0 != svdResult)
00101 {
00102 qdot_out.data.setZero() ;
00103 return error = E_SVD_FAILED;
00104 }
00105
00106 unsigned int i;
00107
00108
00109
00110
00111
00112
00113 for (i = 0; i < nj; ++i) {
00114 Sinv(i) = fabs(S(i))<eps ? 0.0 : 1.0/S(i);
00115 }
00116 for (i = 0; i < 6; ++i) {
00117 tmp(i) = v_in(i);
00118 }
00119
00120 qdot_out.data = V * Sinv.asDiagonal() * U.transpose() * tmp.head(6);
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 double g = 0;
00141 double A = 0;
00142 for (i = 0; i < nj; ++i) {
00143 double qd = q_in(i) - opt_pos(i);
00144 g += 0.5 * qd*qd * weights(i);
00145 A += qd*qd * weights(i)*weights(i);
00146 }
00147
00148 if (A > 1e-9) {
00149
00150 for (i = 0; i < nj; ++i) {
00151 tmp(i) = weights(i)*(q_in(i) - opt_pos(i)) / A;
00152 }
00153
00154
00155 tmp2 = V * Sinv.asDiagonal() * U.transpose() * U * S.asDiagonal() * V.transpose() * tmp;
00156
00157 for (i = 0; i < nj; ++i) {
00158
00159 qdot_out(i) += -2*alpha*g * (tmp(i) - tmp2(i));
00160 }
00161 }
00162
00163 return (error = E_NOERROR);
00164 }
00165
00166 int ChainIkSolverVel_pinv_nso::setWeights(const JntArray & _weights)
00167 {
00168 if (nj != _weights.rows())
00169 return (error = E_SIZE_MISMATCH);
00170 weights = _weights;
00171 return (error = E_NOERROR);
00172 }
00173
00174 int ChainIkSolverVel_pinv_nso::setOptPos(const JntArray & _opt_pos)
00175 {
00176 if (nj != _opt_pos.rows())
00177 return (error = E_SIZE_MISMATCH);
00178 opt_pos = _opt_pos;
00179 return (error = E_NOERROR);
00180 }
00181
00182 int ChainIkSolverVel_pinv_nso::setAlpha(const double _alpha)
00183 {
00184 alpha = _alpha;
00185 return 0;
00186 }
00187
00188
00189 }