Example #1
0
void FindConfiguration () {
/* **************************************************************************************************************************** */
	MDFloat	 Err;
	MDFloat	 ErrVectP[4];
	MDFloat	 ErrVectO[4];
	int		 NoOfIter;
/* **************************************************************************************************************************** */
	NoOfIter	 = 0;
/* **************************************************************************************************************************** */
	// Calcul de l'erreur
	// .. 
		VectSub(PNew, PnIter , ErrVectP);
		VectSub(ONew, OnIter, ErrVectO);
		Err = sqrt ( ScalProd(ErrVectP,ErrVectP) + ScalProd(ErrVectO,ErrVectO) );

	while ( (Err > _OUTER_EPSILON_) && (NoOfIter<_MAX_OUTER_ITER_) ) {
	// .. 
		InnerIterate();
		VectSub(PNew, PnIter , ErrVectP);
		VectSub(ONew, OnIter, ErrVectO);
		Err = sqrt ( ScalProd(ErrVectP,ErrVectP) + ScalProd(ErrVectO,ErrVectO) );

		NoOfIter++;
	}
/* **************************************************************************************************************************** */
#ifdef _DEBUG
	fprintf(stderr, "OUTER loop: %d\n", NoOfIter);
#endif
/* **************************************************************************************************************************** */
}
Example #2
0
void InnerIterate() {
/* **************************************************************************************************************************** */
	int	i;
	int	NoOfIter;

	MDFloat	 dX[_JAC_N_];			// Vecteur d'entrée (position & orientation désirées) 
	MDFloat	 dTheta[_JAC_M_];		// Vecteur de sortie (DDL : oX1,oY1,oZ1,oX2,oY2,oZ2,etc.)
	MDFloat	 (*ZTN)[4];

	MDFloat	 TempJt[_JAC_N_][_JAC_M_];	
		
	MDFloat	 JdThetaP[4];			// Vecteurs d'erreur
	MDFloat	 JdThetaO[4];

	MDFloat	 ErrVectP[4];			 
	MDFloat	 ErrVectO[4];

	MDFloat	 Pn[4];				// Position actuelle de l'effecteur 
	MDFloat	 dXPn[4];			// Variation désirée en position : dXPn = PNew - Pn
	MDFloat	 On[4];				// Orientation actuelle de l'effecteur
	MDFloat	 dXOn[4];			// Variation désirée en orientation : dXOn = ONew - On

	MDFloat	 Err; 				// Erreur

	CLink	 BackUpSkelet[_NO_OF_LINKS_];
/* **************************************************************************************************************************** */
	NoOfIter	 = 0;
	// Sauvegarde du squelette **
	memcpy(BackUpSkelet, Skelet, _NO_OF_LINKS_*sizeof(CLink));
/* **************************************************************************************************************************** */

	/////////////////////////////
	// Calcul du vecteur d'entrée
	/////////////////////////////

	// Intilisation du vecteur d'entrée
	// .. 
	for(i = 0; i<_JAC_N_;i++)dX[i] = 0.0;
	// Calcul de la variation de position "dXPn" du vecteur d'entrée "dX"
	// .. 

	ZTN = (MDFloat(*)[4])Skelet[_NO_OF_LINKS_-1].Get_ZTi();
	Pn[0] = ZTN[0][3];
	Pn[1] = ZTN[1][3];
	Pn[2] = ZTN[2][3];
	Pn[3] = 1.0;

	VectSub(PNew,Pn,dXPn);

	// Calcul de la variation en orientation "dXOn" du vecteur d'entrée "dX"
	// .. 

	GetEulerAngles(ZTN, On);

	On[3] = 1.0;

	VectSub(ONew, On, dXOn);

	dX[0] = dXPn[0]*0.5;
	dX[1] = dXPn[1]*0.5;
	dX[2] = dXPn[2]*0.5;
	dX[3] = dXOn[0]*0.5;
	dX[4] = dXOn[1]*0.5;
	dX[5] = dXOn[2]*0.5;

/* **************************************************************************************************************************** */

	///////////////////////////////////////
	// Calcul du vecteur de sortie "dTheta"
	///////////////////////////////////////

	do {	// Améliore la convergence de l'algorithme **
		memcpy(Skelet, BackUpSkelet, _NO_OF_LINKS_*sizeof(CLink));

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

		// Calcul de la Jacobienne
		// .. 
		MakeJacobian(Skelet,J);
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

		// Calcul de la Jacobienne transposée
		// .. 
		TransposeJacobian(J, Jt);
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

		// Incorporation d'une raideur à la Jacobienne : poids forts aux articulations éloignée de l'effecteur.
		// .. 
		memcpy(TempJt, Jt, _JAC_N_*_JAC_M_*sizeof(MDFloat));
		MultKJacobianT(K , TempJt , Jt);
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */


		// Calcul du vecteur de sortie : dTheta = Jt * dX
		// .. 
		MultJacobianT(Jt, dX, dTheta );
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

		// Ajout de dTheta aux angles et mise-à-jour des matrices de transformation locales "m1Ti" du squelette
		// .. 
		for (i=0; i<_NO_OF_LINKS_; i++)
		Skelet[i].Updateim1Ti(dTheta[i*3+0], dTheta[i*3+1], dTheta[i*3+2]);
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

		// Estimation de l'erreur : Err² = (ErrVectP)² + (ErrVectO)²
		// .. 
		UpdateZTiMatrices(Skelet);
		GetEEPosition(Skelet, PnIter, OnIter);

		VectSub(PnIter , Pn , JdThetaP);
		VectSub(JdThetaP, dX , ErrVectP);

		VectSub(OnIter , On , JdThetaO);
		VectSub(JdThetaO, &dX[3], ErrVectO);		

		Err = sqrt ( ScalProd(ErrVectP,ErrVectP) + ScalProd(ErrVectO,ErrVectO) );
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

		//Calcul du nouveau vecteur d'entrée : division par deux pour fluidifier le mouvement **
		// ..
		dX[0] *=0.5;
		dX[1] *=0.5;
		dX[2] *=0.5;
		dX[3] *=0.5;
		dX[4] *=0.5; 
		dX[5] *=0.5;
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
		NoOfIter++;
	} while ( (Err > _INNER_EPSILON_) && (NoOfIter < _MAX_INNER_ITER_) );
#ifdef _DEBUG
	fprintf(stderr, "INNER loop: %d\n", NoOfIter);
#endif
	
/* **************************************************************************************************************************** */
}
Example #3
0
// Vissage MatTrans2screw(Mat33 rotmatrix, Coord3D t0, Coord3D t1)
Screw MatTrans2screw(const Matrix& mat)
{

    Coord3D trans;
    Mat33 rotmatrix;

    trans.x = mat(0,3);
    trans.y = mat(1,3);
    trans.z = mat(2,3);


//     Coord3D trans = t0-t1;


    for(int i=0; i<3; i++)
      for(int j=0; j<3; j++)
          rotmatrix[i][j]=mat(i,j);

//     std::cout << trans.toString();

    Screw screw;
    Coord3D eigenvect;

    Coord3D x,y,z;
    x.x = rotmatrix[0][0] ; x.y = rotmatrix[1][0]; x.z=rotmatrix[2][0];
    y.x = rotmatrix[0][1] ; y.y = rotmatrix[1][1]; y.z=rotmatrix[2][1];
    z.x = rotmatrix[0][2] ; z.y = rotmatrix[1][2]; z.z=rotmatrix[2][2];

    Coord3D pt ; //un point de l'axe de rotation


    double a = rotmatrix[0][0] ; // Xx
    double b = rotmatrix[1][1] ; // Yy
    double c = rotmatrix[2][2] ; // Zz

    if (fabs(1+a-b-c) > EPSILON)
    {
        eigenvect.x = x.x + 1 - b - c ;
        eigenvect.y = x.y + y.x ;
        eigenvect.z = x.z + z.x ;
        screw.unitVector = eigenvect / Norm(eigenvect);
        screw.normtranslation = ScalProd(screw.unitVector,trans);

        Coord3D s = trans - screw.normtranslation*screw.unitVector ;
        screw.point.x = 0 ;
        screw.point.y = s.z*z.y + s.y*(1-z.z) ;
        screw.point.z = s.y*y.z+s.z*(1-y.y);
        screw.point = screw.point/(1+x.x-y.y-z.z) ;


    }
    else if (fabs(1-a+b-c)> EPSILON)
    {
        eigenvect.x = y.x + x.y;
        eigenvect.y = y.y + 1 - x.x - z.z ;
        eigenvect.z = y.z + z.y ;

        screw.unitVector = eigenvect / Norm(eigenvect);
        screw.normtranslation = ScalProd(screw.unitVector,trans);

        Coord3D s = trans - screw.normtranslation*screw.unitVector ;
        screw.point.x =  s.z*z.x + s.x*(1-z.z);
        screw.point.y =  0 ;
        screw.point.z =  s.x*x.z + s.z*(1-x.x);
        screw.point = screw.point/(1-x.x+y.y-z.z) ;
    }
    else if (fabs(1-a-b+c)>EPSILON)
    {
        eigenvect.x = z.x + x.z ;
        eigenvect.y = z.y + y.z ;
        eigenvect.z = z.z + 1 - x.x - y.y ;

        screw.unitVector = eigenvect / Norm(eigenvect);
        screw.normtranslation = ScalProd(screw.unitVector,trans);

        Coord3D s = trans - screw.normtranslation*screw.unitVector ;
        screw.point.x = s.y*y.x + s.x*(1-y.y) ;
        screw.point.y = s.x*x.y + s.y*(1-x.x) ;
        screw.point.z =  0 ;
        screw.point = screw.point/(1-x.x-y.y+z.z) ;

    }
    else     // angle=0
      { 
            screw.point = Coord3D(0,0,0);
            if(Norm(trans)!=0)
            {
            screw.unitVector=trans /Norm(trans);
            }
            else {  screw.unitVector =  Coord3D(0,0,1); /*axe arbitraire*/ }
            screw.normtranslation=Norm(trans);
            screw.angle=0;
            return screw;


    }

    //creation d'un vecteur non aligne avec screw.unitVector:
    Coord3D v (1,0,0);
    if (fabs(Angle(screw.unitVector,v)) < 0.1) v= Coord3D(0,0,1); //v et axe colin�aires: on change v


    Coord3D u = v - ScalProd(v,screw.unitVector)*screw.unitVector ;
    u = u/Norm(u);

    Coord3D uprime;
    Mat33xcoord3D(rotmatrix,u,uprime);

    double cost = ScalProd(u,uprime);

    Coord3D usec;
    VectProd(screw.unitVector,u,usec);
    double sint = ScalProd(usec,uprime);

    
    if (cost < -1 ) cost=-1;
    if (cost >1 ) cost= 1 ; 
    screw.angle = acos(cost);
    if (sint < 0) screw.angle = -screw.angle ;

    screw.angle *= -1;
    return screw ;
}