Add matrix inverse computation in BussIK.

This commit is contained in:
yunfeibai
2016-09-29 15:45:57 -07:00
parent 67c49fa701
commit 0ee12475af
5 changed files with 79 additions and 3 deletions

View File

@@ -129,7 +129,8 @@ bool IKTrajectoryHelper::computeIK(const double endEffectorTargetPosition[3],
case IK2_DLS: case IK2_DLS:
case IK2_VEL_DLS: case IK2_VEL_DLS:
case IK2_VEL_DLS_WITH_ORIENTATION: case IK2_VEL_DLS_WITH_ORIENTATION:
m_data->m_ikJacobian->CalcDeltaThetasDLS(); // Damped least squares method //m_data->m_ikJacobian->CalcDeltaThetasDLS(); // Damped least squares method
m_data->m_ikJacobian->CalcDeltaThetasDLSwithNullspace();
break; break;
case IK2_DLS_SVD: case IK2_DLS_SVD:
m_data->m_ikJacobian->CalcDeltaThetasDLSwithSVD(); m_data->m_ikJacobian->CalcDeltaThetasDLSwithSVD();

View File

@@ -320,7 +320,7 @@ void Jacobian::CalcDeltaThetasPseudoinverse()
} }
void Jacobian::CalcDeltaThetasDLS() void Jacobian::CalcDeltaThetasDLSwithNullspace()
{ {
const MatrixRmn& J = ActiveJacobian(); const MatrixRmn& J = ActiveJacobian();
@@ -336,6 +336,25 @@ void Jacobian::CalcDeltaThetasDLS()
// Use these two lines for the traditional DLS method // Use these two lines for the traditional DLS method
U.Solve( dS, &dT1 ); U.Solve( dS, &dT1 );
J.MultiplyTranspose( dT1, dTheta ); J.MultiplyTranspose( dT1, dTheta );
VectorRn nullV(7);
nullV.SetZero();
nullV.Set(1, 2.0);
MatrixRmn I(U.GetNumRows(),U.GetNumColumns());
I.SetIdentity();
MatrixRmn UInv(U.GetNumRows(),U.GetNumColumns());
U.ComputeInverse(UInv);
MatrixRmn Res(U.GetNumRows(),U.GetNumColumns());
MatrixRmn::Multiply(U, UInv, Res);
for (int i = 0; i < Res.GetNumRows(); ++i)
{
for (int j = 0; j < Res.GetNumColumns(); ++j)
{
printf("i%d j%d: %f\n", i, j, Res.Get(i, j));
}
}
// Scale back to not exceed maximum angle changes // Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs(); double maxChange = dTheta.MaxAbs();
@@ -344,6 +363,30 @@ void Jacobian::CalcDeltaThetasDLS()
} }
} }
void Jacobian::CalcDeltaThetasDLS()
{
const MatrixRmn& J = ActiveJacobian();
MatrixRmn::MultiplyTranspose(J, J, U); // U = J * (J^T)
U.AddToDiagonal( DampingLambdaSq );
// Use the next four lines instead of the succeeding two lines for the DLS method with clamped error vector e.
// CalcdTClampedFromdS();
// VectorRn dTextra(3*m_nEffector);
// U.Solve( dT, &dTextra );
// J.MultiplyTranspose( dTextra, dTheta );
// Use these two lines for the traditional DLS method
U.Solve( dS, &dT1 );
J.MultiplyTranspose( dT1, dTheta );
// Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs();
if ( maxChange>MaxAngleDLS ) {
dTheta *= MaxAngleDLS/maxChange;
}
}
void Jacobian::CalcDeltaThetasDLSwithSVD() void Jacobian::CalcDeltaThetasDLSwithSVD()
{ {
const MatrixRmn& J = ActiveJacobian(); const MatrixRmn& J = ActiveJacobian();

View File

@@ -70,7 +70,7 @@ public:
void CalcDeltaThetasDLS(); void CalcDeltaThetasDLS();
void CalcDeltaThetasDLSwithSVD(); void CalcDeltaThetasDLSwithSVD();
void CalcDeltaThetasSDLS(); void CalcDeltaThetasSDLS();
void CalcDeltaThetasDLSwithNullspace();
void UpdateThetas(); void UpdateThetas();
void UpdateThetaDot(); void UpdateThetaDot();

View File

@@ -513,6 +513,36 @@ void MatrixRmn::ComputeSVD( MatrixRmn& U, VectorRn& w, MatrixRmn& V ) const
} }
void MatrixRmn::ComputeInverse( MatrixRmn& R) const
{
assert ( this->NumRows==this->NumCols );
MatrixRmn U(this->NumRows, this->NumCols);
VectorRn w(this->NumRows);
MatrixRmn V(this->NumRows, this->NumCols);
this->ComputeSVD(U, w, V);
assert(this->DebugCheckSVD(U, w , V));
double PseudoInverseThresholdFactor = 0.01;
double pseudoInverseThreshold = PseudoInverseThresholdFactor*w.MaxAbs();
MatrixRmn VD(this->NumRows, this->NumCols);
MatrixRmn D(this->NumRows, this->NumCols);
D.SetZero();
long diagLength = w.GetLength();
double* wPtr = w.GetPtr();
for ( long i = 0; i < diagLength; ++i ) {
double alpha = *(wPtr++);
if ( fabs(alpha)>pseudoInverseThreshold ) {
D.Set(i, i, 1.0/alpha);
}
}
Multiply(V,D,VD);
MultiplyTranspose(VD,U,R);
}
// ************************************************ CalcBidiagonal ************************** // ************************************************ CalcBidiagonal **************************
// Helper routine for SVD computation // Helper routine for SVD computation
// U is a matrix to be bidiagonalized. // U is a matrix to be bidiagonalized.

View File

@@ -129,6 +129,8 @@ public:
void ComputeSVD( MatrixRmn& U, VectorRn& w, MatrixRmn& V ) const; void ComputeSVD( MatrixRmn& U, VectorRn& w, MatrixRmn& V ) const;
// Good for debugging SVD computations (I recommend this be used for any new application to check for bugs/instability). // Good for debugging SVD computations (I recommend this be used for any new application to check for bugs/instability).
bool DebugCheckSVD( const MatrixRmn& U, const VectorRn& w, const MatrixRmn& V ) const; bool DebugCheckSVD( const MatrixRmn& U, const VectorRn& w, const MatrixRmn& V ) const;
// Compute inverse of a matrix, the result is written in R
void ComputeInverse( MatrixRmn& R) const;
// Some useful routines for experts who understand the inner workings of these classes. // Some useful routines for experts who understand the inner workings of these classes.
inline static double DotArray( long length, const double* ptrA, long strideA, const double* ptrB, long strideB ); inline static double DotArray( long length, const double* ptrA, long strideA, const double* ptrB, long strideB );