-
Notifications
You must be signed in to change notification settings - Fork 429
Pinv velocity solver sigma output #359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
509aa37
2c76861
1ab74b7
554b2cc
f36ad6d
b9f06c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,7 +36,9 @@ namespace KDL | |
eps(_eps), | ||
maxiter(_maxiter), | ||
nrZeroSigmas(0), | ||
svdResult(0) | ||
svdResult(0), | ||
sigmaMin(0), | ||
Smaxtomin(nj) | ||
{ | ||
} | ||
|
||
|
@@ -52,13 +54,35 @@ namespace KDL | |
for(unsigned int i = 0 ; i < V.size(); i++) | ||
V[i].resize(nj); | ||
tmp.resize(nj); | ||
Smaxtomin.resize(nj); | ||
} | ||
|
||
ChainIkSolverVel_pinv::~ChainIkSolverVel_pinv() | ||
{ | ||
} | ||
|
||
|
||
void ChainIkSolverVel_pinv::setEps(const double eps_in) | ||
{ | ||
if (0 < eps_in) eps = eps_in; | ||
// else silently ignore | ||
} | ||
|
||
void ChainIkSolverVel_pinv::setMaxIter(const unsigned int maxiter_in) | ||
{ | ||
if (1 <= maxiter_in) maxiter = maxiter_in; | ||
craigirobot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// else silently ignore | ||
} | ||
|
||
int ChainIkSolverVel_pinv::getSigma(JntArray& Sout) | ||
{ | ||
if (Sout.rows() != Smaxtomin.rows()) | ||
return (error = E_SIZE_MISMATCH); | ||
for (unsigned int i=0;i<Sout.rows();i++) | ||
craigirobot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Sout(i)=Smaxtomin(i); | ||
return (error = E_NOERROR); | ||
} | ||
|
||
int ChainIkSolverVel_pinv::CartToJnt(const JntArray& q_in, const Twist& v_in, JntArray& qdot_out) | ||
{ | ||
if (nj != chain.getNrOfJoints()) | ||
|
@@ -75,8 +99,9 @@ namespace KDL | |
double sum; | ||
unsigned int i,j; | ||
|
||
// Initialize near zero singular value counter | ||
// Initialize (internal) return values | ||
nrZeroSigmas = 0 ; | ||
sigmaMin = 0.; | ||
|
||
//Do a singular value decomposition of "jac" with maximum | ||
//iterations "maxiter", put the results in "U", "S" and "V" | ||
|
@@ -88,6 +113,18 @@ namespace KDL | |
return (error = E_SVD_FAILED); | ||
} | ||
|
||
// Sort S in descending order (S is not sorted in SVD_HH) | ||
// copied from svd_eigen_HH.cpp | ||
craigirobot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Smaxtomin = S; | ||
SortJntArrayMaxToMin(Smaxtomin); | ||
// Minimum of six largest singular values of J is S(5) if number of joints >=6 and 0 for <6 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this behaviour comming from? As there should be the same number of singular values as the number of joints, correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the number of singular values is the same as the number of joints. However, any singular values beyond the sixth which is S(5) will be zero (assuming SVs are ordered from high to low). We are interested in whether the sixth singular value is zero because that is when the determinant of J*J^T is zero and a Cartesian degree of freedom is lost. Then the condition corresponding to fabs(S(i))<eps (line 140) must be applied in order to compute the pseudoinverse. |
||
if ( jac.columns() >= 6 ) { | ||
sigmaMin = Smaxtomin(5); | ||
} | ||
else { | ||
sigmaMin = 0.; | ||
} | ||
craigirobot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// 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 | ||
|
@@ -129,6 +166,29 @@ namespace KDL | |
} | ||
} | ||
|
||
void ChainIkSolverVel_pinv::SortJntArrayMaxToMin(JntArray& Smaxtomin) | ||
{ | ||
int n=Smaxtomin.rows(); | ||
for (int i=0; i<n; i++){ | ||
double S_max = Smaxtomin(i); | ||
int i_max = i; | ||
for (int j=i+1; j<n; j++){ | ||
double Sj = Smaxtomin(j); | ||
if (Sj > S_max){ | ||
S_max = Sj; | ||
i_max = j; | ||
} | ||
} | ||
if (i_max != i){ | ||
/* swap eigenvalues */ | ||
double tmp = Smaxtomin(i); | ||
Smaxtomin(i)=Smaxtomin(i_max); | ||
Smaxtomin(i_max)=tmp; | ||
} | ||
} | ||
return; | ||
craigirobot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
const char* ChainIkSolverVel_pinv::strError(const int error) const | ||
{ | ||
if (E_CONVERGE_PINV_SINGULAR == error) return "Converged put pseudo inverse of jacobian is singular."; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,19 +79,57 @@ namespace KDL | |
*/ | ||
virtual int CartToJnt(const JntArray& /*q_init*/, const FrameVel& /*v_in*/, JntArrayVel& /*q_out*/){return -1;}; | ||
|
||
/** | ||
* Set eps | ||
* \pre 0 < eps, otherwise eps is ignored | ||
*/ | ||
void setEps(const double eps_in); | ||
|
||
/** | ||
* Set maxIter | ||
* \pre 1 <= maxiter, otherwise maxiter is ignored | ||
*/ | ||
void setMaxIter(const unsigned int maxiter_in); | ||
|
||
/** | ||
* Retrieve the number of singular values of the jacobian that are < eps; | ||
* if the number of near zero singular values is > jac.col()-jac.row(), | ||
* then the jacobian pseudoinverse is singular | ||
*/ | ||
unsigned int getNrZeroSigmas()const {return nrZeroSigmas;}; | ||
|
||
/** | ||
* Request the minimum of the first six singular values | ||
*/ | ||
double getSigmaMin()const {return sigmaMin;}; | ||
craigirobot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Request the singular values of the Jacobian | ||
*/ | ||
int getSigma(JntArray& Sout); | ||
|
||
/** | ||
* Request the value of eps | ||
*/ | ||
double getEps()const {return eps;}; | ||
craigirobot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Get maximum number of iterations | ||
* \pre 1 <= maxiter, otherwise maxiter is ignored | ||
craigirobot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
unsigned int getMaxIter()const { return maxiter; } | ||
craigirobot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Retrieve the latest return code from the SVD algorithm | ||
* @return 0 if CartToJnt() not yet called, otherwise latest SVD result code. | ||
*/ | ||
int getSVDResult()const {return svdResult;}; | ||
|
||
/** | ||
* Sort a JntArray from maximum to minimum value | ||
*/ | ||
void SortJntArrayMaxToMin(JntArray& Smaxtomin); | ||
|
||
/// @copydoc KDL::SolverI::strError() | ||
virtual const char* strError(const int error) const; | ||
|
||
|
@@ -108,10 +146,11 @@ namespace KDL | |
std::vector<JntArray> V; | ||
JntArray tmp; | ||
double eps; | ||
int maxiter; | ||
unsigned int maxiter; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is ABI breaking change. I can't accept this for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maxiter is an int type in the constructor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, so why not also store it as an int, which is the current situation. But I can't accept ABI breaking changes. So this one needs to be reverted. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Understood. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still open issue There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see how to revert this change in this system. Note that changing maxiter to an int might break the comparison in setMaxIter() which expects an unsigned int input; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can change that too.... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolved this issue with second to last commit on the latest branch. "maxiter" was updated to int in several other places in the same commit. |
||
unsigned int nrZeroSigmas; | ||
int svdResult; | ||
|
||
double sigmaMin; | ||
JntArray Smaxtomin; | ||
}; | ||
} | ||
#endif | ||
|
Uh oh!
There was an error while loading. Please reload this page.