Esempio n. 1
0
C4X4Matrix C7Vector::getMatrix() const
{
	return(C4X4Matrix(Q.getMatrix(),X));
}
Esempio n. 2
0
C4X4Matrix C4X4Matrix::operator* (const CMatrix& m) const
{
    C4X4Matrix retM((*this)*C4X4Matrix(m));
    return(retM);
}
Esempio n. 3
0
CIKChain::CIKChain(CIKDummy* tip,float interpolFact,int jointNbToExclude)
{
	tooltip=tip;
	chainIsValid=true;
	// interpolFact is the interpolation factor we use to compute the target pose:
	// interpolPose=tooltipPose*(1-interpolFact)+targetPose*interpolFact
	// We get the jacobian and the rowJointIDs:
	C4X4Matrix oldMatr;
	int theConstraints=tip->constraints;
	tip->baseReorient.setIdentity();
	CMatrix* Ja=NULL;

	if (tip->loopClosureDummy)
	{
		// The purpose of the following code is to have tip and target dummies reoriented
		// and the appropriate constraints calculated automatically (only for loop closure dummies!)
		tip->constraints=0;
		int posDimensions=0;
		int orDimensions=0;
		C3Vector firstJointZAxis(0.0f,0.0f,1.0f);
		C4X4Matrix firstJointCumul;
		// here we reorient tip and targetCumulativeMatrix
		// 1. We find the first revolute joint:
		CIKObject* iterat=tip->parent;
		while (iterat!=NULL)
		{
			if ( (iterat->objectType==IK_JOINT_TYPE)&&((CIKJoint*)iterat)->revolute&&((CIKJoint*)iterat)->active )
				break;
			iterat=iterat->parent;
		}
		if (iterat!=NULL)
		{ // We have the first revolute joint from tip
			orDimensions=1;
			CIKObject* firstJoint=iterat;
			firstJointCumul=C4X4Matrix(firstJoint->getCumulativeTransformationPart1(true).getMatrix());
			firstJointZAxis=firstJointCumul.M.axis[2];
			C3Vector normalVect;
			// We search for a second revolute joint which is not aligned with the first one:
			iterat=iterat->parent;
			while (iterat!=NULL)
			{
				if ( (iterat->objectType==IK_JOINT_TYPE)&&((CIKJoint*)iterat)->revolute&&((CIKJoint*)iterat)->active )
				{
					C4X4Matrix secondJointCumul(iterat->getCumulativeTransformationPart1(true).getMatrix());
					C3Vector secondJointZAxis(secondJointCumul.M.axis[2]);
					if (fabs(firstJointZAxis*secondJointZAxis)<0.999999f) // Approx. 0.08 degrees
					{
						normalVect=(firstJointZAxis^secondJointZAxis).getNormalized();
						if (firstJointZAxis*secondJointZAxis<0.0f)
							secondJointZAxis=secondJointZAxis*-1.0f;
						firstJointZAxis=((firstJointZAxis+secondJointZAxis)/2.0f).getNormalized();
						break;
					}
				}
				iterat=iterat->parent;
			}
			if (iterat!=NULL)
			{
				orDimensions=2;
				// We search for a third revolute joint which is not orthogonal with normalVect:
				iterat=iterat->parent;
				while (iterat!=NULL)
				{
					if ( (iterat->objectType==IK_JOINT_TYPE)&&((CIKJoint*)iterat)->revolute&&((CIKJoint*)iterat)->active )
					{
						C4X4Matrix thirdJointCumul(iterat->getCumulativeTransformationPart1(true).getMatrix());
						C3Vector thirdJointZAxis(thirdJointCumul.M.axis[2]);
						if (fabs(normalVect*thirdJointZAxis)>0.0001f) // Approx. 0.005 degrees
						{
							orDimensions=3;
							break;
						}
					}
					iterat=iterat->parent;
				}
			}
		}			
		if ( (orDimensions==1)||(orDimensions==2) )
		{
			// We align the tip dummy's z axis with the joint axis 
			// (and do the same transformation to targetCumulativeMatrix)

			C4Vector rot(C4X4Matrix(firstJointZAxis).M.getQuaternion());
			C4Vector tipParentInverse(tip->getParentCumulativeTransformation(true).Q.getInverse());
			C4Vector tipNewLocal(tipParentInverse*rot);
			C4Vector postTr(tip->getLocalTransformation(true).Q.getInverse()*tipNewLocal);
			tip->transformation.Q=tipNewLocal;
			C7Vector postTr2;
			postTr2.setIdentity();
			postTr2.Q=postTr;
			tip->targetCumulativeTransformation=tip->targetCumulativeTransformation*postTr2;
		}
		Ja=getJacobian(tip,oldMatr,rowJoints,jointNbToExclude);
		C3Vector posV;
		for (int i=0;i<Ja->cols;i++)
		{
			// 1. Position space:
			C3Vector vc((*Ja)(0,i),(*Ja)(1,i),(*Ja)(2,i));
			float l=vc.getLength();
			if (l>0.0001f) // 0.1 mm
			{
				vc=vc/l;
				if (posDimensions==0)
				{
					posV=vc;
					posDimensions++;
				}
				else if (posDimensions==1)
				{
					if (fabs(posV*vc)<0.999999f) // Approx. 0.08 degrees
					{
						posV=(posV^vc).getNormalized();
						posDimensions++;
					}
				}
				else if (posDimensions==2)
				{
					if (fabs(posV*vc)>0.0001f) // Approx. 0.005 degrees
						posDimensions++;
				}
			}
		}
		if (posDimensions!=3)
		{
			if (posDimensions!=0)
			{
				C4X4Matrix aligned(posV);
				tip->baseReorient=aligned.getInverse().getTransformation();
				for (int i=0;i<Ja->cols;i++)
				{
					posV(0)=(*Ja)(0,i);
					posV(1)=(*Ja)(1,i);
					posV(2)=(*Ja)(2,i);
					posV=tip->baseReorient.Q*posV; // baseReorient.X is 0 anyway...
					(*Ja)(0,i)=posV(0);
					(*Ja)(1,i)=posV(1);
					(*Ja)(2,i)=posV(2);
				}
				oldMatr=tip->baseReorient.getMatrix()*oldMatr;
			
				if (posDimensions==1)
					tip->constraints+=IK_Z_CONSTRAINT;
				else
					tip->constraints+=(IK_X_CONSTRAINT+IK_Y_CONSTRAINT);
			}
		}
		else
			tip->constraints+=(IK_X_CONSTRAINT+IK_Y_CONSTRAINT+IK_Z_CONSTRAINT);

		int doF=Ja->cols;
		if (orDimensions==1)
		{
			if (doF-posDimensions>=1)
				tip->constraints+=IK_GAMMA_CONSTRAINT;
		}
		else if (orDimensions==2)
		{
			if (doF-posDimensions>=1) // Is this correct?
				tip->constraints+=IK_GAMMA_CONSTRAINT;
		}
		else if (orDimensions==3)
		{
			if (doF-posDimensions>=3)
				tip->constraints+=(IK_ALPHA_BETA_CONSTRAINT|IK_GAMMA_CONSTRAINT);
		}
		
		theConstraints=tip->constraints;
	}
	else
		Ja=getJacobian(tip,oldMatr,rowJoints,jointNbToExclude);

	if (Ja==NULL)
	{ // Error or not enough joints (effJoint=joints-jointNbToExclude) to get a Jacobian
		delete Ja;
		// We create dummy objects (so that we don't get an error when destroyed)
		matrix=new CMatrix(0,0);
		errorVector=new CMatrix(0,1);
		chainIsValid=false;
		return;
	}
	// oldMatr now contains the cumulative transf. matr. of tooltip relative to base
	C4X4Matrix oldMatrInv(oldMatr.getInverse());
	int doF=Ja->cols;
	int equationNumber=0;

	C4X4Matrix m;
	C4X4Matrix targetCumulativeMatrix((tip->baseReorient*tip->targetCumulativeTransformation).getMatrix());
	m.buildInterpolation(oldMatr,targetCumulativeMatrix,interpolFact);
	// We prepare matrix and errorVector and their respective sizes:
	if (theConstraints&IK_X_CONSTRAINT)
		equationNumber++;
	if (theConstraints&IK_Y_CONSTRAINT)
		equationNumber++;
	if (theConstraints&IK_Z_CONSTRAINT)
		equationNumber++;
	if (theConstraints&IK_ALPHA_BETA_CONSTRAINT)
		equationNumber=equationNumber+2;
	if (theConstraints&IK_GAMMA_CONSTRAINT)
		equationNumber++;
	matrix=new CMatrix(equationNumber,doF);
	errorVector=new CMatrix(equationNumber,1);
	// We set up the position/orientation errorVector and the matrix:
	
	float positionWeight=1.0f;
	float orientationWeight=1.0f;
	int pos=0;
	if (theConstraints&IK_X_CONSTRAINT)
	{
		for (int i=0;i<doF;i++)
			(*matrix)(pos,i)=(*Ja)(0,i);
		(*errorVector)(pos,0)=(m.X(0)-oldMatr.X(0))*positionWeight;
		pos++;
	}
	if (theConstraints&IK_Y_CONSTRAINT)
	{
		for (int i=0;i<doF;i++)
			(*matrix)(pos,i)=(*Ja)(1,i);
		(*errorVector)(pos,0)=(m.X(1)-oldMatr.X(1))*positionWeight;
		pos++;
	}
	if (theConstraints&IK_Z_CONSTRAINT)
	{
		for (int i=0;i<doF;i++)
			(*matrix)(pos,i)=(*Ja)(2,i);
		(*errorVector)(pos,0)=(m.X(2)-oldMatr.X(2))*positionWeight;
		pos++;
	}

	if (theConstraints&IK_ALPHA_BETA_CONSTRAINT)
	{
		for (int i=0;i<doF;i++)
		{
			(*matrix)(pos,i)=(*Ja)(3,i);
			(*matrix)(pos+1,i)=(*Ja)(4,i);
		}
		C4X4Matrix diff(oldMatrInv*m);
		C3Vector euler(diff.M.getEulerAngles());
		(*errorVector)(pos,0)=euler(0)*orientationWeight/IK_DIVISION_FACTOR;
		(*errorVector)(pos+1,0)=euler(1)*orientationWeight/IK_DIVISION_FACTOR;
		pos=pos+2;
	}
	if (theConstraints&IK_GAMMA_CONSTRAINT)
	{
		for (int i=0;i<doF;i++)
			(*matrix)(pos,i)=(*Ja)(5,i);
		C4X4Matrix diff(oldMatrInv*m);
		C3Vector euler(diff.M.getEulerAngles());
		(*errorVector)(pos,0)=euler(2)*orientationWeight/IK_DIVISION_FACTOR;
		pos++;
	}

	delete Ja; // We delete the jacobian!
}