示例#1
0
CMatrix CMatrix::operator* (const C4X4Matrix& m) const
{
	CMatrix retM(rows,4);
	for (int i=0;i<rows;i++)
	{
		for (int j=0;j<3;j++)
		{
			retM(i,j)=0.0f;
			for (int k=0;k<3;k++)
				retM(i,j)+=( (*this)(i,k)*m.M.axis[j](k) );
		}
		retM(i,3)=(*this)(i,3);
		for (int k=0;k<3;k++)
			retM(i,3)+=( (*this)(i,k)*m.X(k) );
	}
	return(retM);
}
示例#2
0
void CikEl::prepareIkEquations(extIkReal interpolFact)
{	// Before calling this function, make sure that joint's temp. param. are initialized!
	// Make also sure the tooltip is built on a joint before 'base' and that base
	// is parent of 'tooltip'.
	// interpolFact is the interpolation factor we use to compute the target pose:
	// interpolPose=tooltipPose*(1-interpolFact)+targetPose*interpolFact

	// We first take care of dummies linked to path objects in a "sliding" manner (not fixed but assigned to the path):
	// Case 1. Target is the free sliding dummy:
	CDummy* dummyObj=Ct::ct->objCont->getDummy(getTarget());
	CDummy* tipObj=Ct::ct->objCont->getDummy(tooltip);

	// We get the jacobian and the rowJointIDs:
	rowJointIDs=new std::vector<int>;
	rowJointStages=new std::vector<int>;
	C4X4Matrix oldMatr;
	CMatrix* Ja=CIkRoutine::getJacobian(this,oldMatr,rowJointIDs,rowJointStages);

	// oldMatr now contains the cumulative transf. matr. of tooltip relative to base
	C4X4Matrix oldMatrInv(oldMatr.getInverse());
	int doF=Ja->cols;
	int equationNumber=0;

	C4X4Matrix dummyCumul;
	C4X4Matrix m;
	if (dummyObj!=NULL)
	{
		C3DObject* baseObj=Ct::ct->objCont->getObject(base);
		C4X4Matrix baseCumul;
		baseCumul.setIdentity();
		if (baseObj!=NULL)
			baseCumul=baseObj->getCumulativeTransformation(true).getMatrix();

		baseObj=Ct::ct->objCont->getObject(alternativeBaseForConstraints);
		if (baseObj!=NULL)
			baseCumul=baseObj->getCumulativeTransformation(true).getMatrix();

		baseCumul.inverse();

		dummyCumul=dummyObj->getCumulativeTransformationPart1(true).getMatrix();
		dummyCumul=baseCumul*dummyCumul; // target is relative to the base (or the alternative base)!
		C7Vector tr;
		tr.buildInterpolation(oldMatr.getTransformation(),dummyCumul.getTransformation(),interpolFact);
		m=tr;

		// We prepare matrix and errorVector and their respective sizes:
		if (constraints&sim_ik_x_constraint)
			equationNumber++;
		if (constraints&sim_ik_y_constraint)
			equationNumber++;
		if (constraints&sim_ik_z_constraint)
			equationNumber++;
		if (constraints&sim_ik_alpha_beta_constraint)
			equationNumber+=2;
		if (constraints&sim_ik_gamma_constraint)
			equationNumber++;
	}

	matrix=new CMatrix(equationNumber,doF);
	matrix_correctJacobian=new CMatrix(equationNumber,doF);
	errorVector=new CMatrix(equationNumber,1);
	if (dummyObj!=NULL)
	{
		// We set up the position/orientation errorVector and the matrix:
		int pos=0;
		if (constraints&sim_ik_x_constraint)
		{
			for (int i=0;i<doF;i++)
			{
				(*matrix)(pos,i)=(*Ja)(0,i);
				(*matrix_correctJacobian)(pos,i)=(*Ja)(0,i);
			}
			(*errorVector)(pos,0)=(m.X(0)-oldMatr.X(0))*positionWeight;
			pos++;
		}
		if (constraints&sim_ik_y_constraint)
		{
			for (int i=0;i<doF;i++)
			{
				(*matrix)(pos,i)=(*Ja)(1,i);
				(*matrix_correctJacobian)(pos,i)=(*Ja)(1,i);
			}
			(*errorVector)(pos,0)=(m.X(1)-oldMatr.X(1))*positionWeight;
			pos++;
		}
		if (constraints&sim_ik_z_constraint)
		{
			for (int i=0;i<doF;i++)
			{
				(*matrix)(pos,i)=(*Ja)(2,i);
				(*matrix_correctJacobian)(pos,i)=(*Ja)(2,i);
			}
			(*errorVector)(pos,0)=(m.X(2)-oldMatr.X(2))*positionWeight;
			pos++;
		}
		if ( (constraints&sim_ik_alpha_beta_constraint)&&(constraints&sim_ik_gamma_constraint) )
		{
			for (int i=0;i<doF;i++)
			{
				(*matrix)(pos,i)=(*Ja)(3,i);
				(*matrix)(pos+1,i)=(*Ja)(4,i);
				(*matrix)(pos+2,i)=(*Ja)(5,i);
				(*matrix_correctJacobian)(pos,i)=(*Ja)(3,i)*IK_DIVISION_FACTOR;
				(*matrix_correctJacobian)(pos+1,i)=(*Ja)(4,i)*IK_DIVISION_FACTOR;
				(*matrix_correctJacobian)(pos+2,i)=(*Ja)(5,i)*IK_DIVISION_FACTOR;
			}
			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;
			(*errorVector)(pos+2,0)=euler(2)*orientationWeight/IK_DIVISION_FACTOR;
			pos=pos+3;
		}
		else
		{
			if (constraints&sim_ik_alpha_beta_constraint)
			{
				for (int i=0;i<doF;i++)
				{
					(*matrix)(pos,i)=(*Ja)(3,i);
					(*matrix)(pos+1,i)=(*Ja)(4,i);
					(*matrix_correctJacobian)(pos,i)=(*Ja)(3,i)*IK_DIVISION_FACTOR;
					(*matrix_correctJacobian)(pos+1,i)=(*Ja)(4,i)*IK_DIVISION_FACTOR;
				}
				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 (constraints&sim_ik_gamma_constraint)
			{ // sim_gamma_constraint can't exist without sim_alpha_beta_constraint!
				for (int i=0;i<doF;i++)
				{
					(*matrix)(pos,i)=(*Ja)(5,i);
					(*matrix_correctJacobian)(pos,i)=(*Ja)(5,i)*IK_DIVISION_FACTOR;
				}
				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!
}
示例#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!
}