Example #1
0
/*! Given a vector of pointers to dynamic bodies, and the number of bodies in
	the vector, this routine will move those bodies in the direction of their
	current velocity for the length of the timestep, \a h. It uses the 
	pre-computed velocities and accelerations computed by iterateDynamics and
	stored for each body. 
*/
int
moveBodies(int numBodies,std::vector<DynamicBody *> bodyVec,double h)
{
  static double V[42];
  static double tmp12[12];
  static double B[12];
  static double R_N_B[9];
  static double newPos[7];
  static mat3 Rot;
  int bn;
  double currq[7];
  double currv[6];
  int errCode=SUCCESS;
  
  for (bn=0;bn<numBodies;bn++) {
    memcpy(currq,bodyVec[bn]->getPos(),7*sizeof(double));
    memcpy(currv,bodyVec[bn]->getVelocity(),6*sizeof(double));;
    
    Quaternion tmpQuat(currq[3],currq[4],currq[5],currq[6]);
    tmpQuat.ToRotationMatrix(Rot);   
    
    // The rotation matrix returned by ToRotationMatrix is expressed as
    // a graphics style rot matrix (new axes are in rows), the R_N_B matrix
    // is a robotics style rot matrix (new axes in columns)
    
    R_N_B[0] = Rot[0];  R_N_B[3] = Rot[1];  R_N_B[6] = Rot[2];
    R_N_B[1] = Rot[3];  R_N_B[4] = Rot[4];  R_N_B[7] = Rot[5];
    R_N_B[2] = Rot[6];  R_N_B[5] = Rot[7];  R_N_B[8] = Rot[8];
    
    // B relates the angular velocity of the body (expressed in
    // the body frame) to the time derivative of the Euler parameters
    B[0] = -currq[4];  B[4] = -currq[5];  B[8] = -currq[6];
    B[1] =  currq[3];  B[5] = -currq[6];  B[9] =  currq[5];
    B[2] =  currq[6];  B[6] =  currq[3];  B[10]= -currq[4];
    B[3] = -currq[5];  B[7] =  currq[4];  B[11]=  currq[3];
    dscal(12,0.5,B,1);
    
    // V is a list of matrices.  Each matrix (V_bn) can be multiplied by
    // body bn's 6x1 velocity vector to get the 7x1 time derivative 
    // of the body's position.
    // V_bn = [ eye(3,3)  zeros(3,3);
    //         zeros(4,3)  B*R_N_B'  ];
    // This list of matrices will be used at the end to compute the new
    // position from the new velocity
    dgemm("N","T",4,3,3,1.0,B,4,R_N_B,3,0.0,tmp12,4);
    V[0] = 1.0;
    V[8] = 1.0;
    V[16]= 1.0;
    fillMatrixBlock(tmp12,4,3,3,6,5,V,7);
    
    dcopy(7,currq,1,newPos,1);
    
    dgemv("N",7,6,h,V,7,currv,1,1.0,newPos,1);
    
#ifdef GRASPITDBG
    fprintf(stdout,"object %s new velocity: \n", bodyVec[bn]->getName().latin1());
    for (int i=0;i<6;i++) fprintf(stdout,"%le   ",currv[i]);
    printf("\n");
    fprintf(stdout,"object %s new position: \n", bodyVec[bn]->getName().latin1());
    disp_mat(stdout,newPos,1,7,0);
#endif
    
    //should we bother to check if the object has moved? (for optimization)
    if (!bodyVec[bn]->setPos(newPos)) {
      DBGP("requested position is out of bounds for this object!");
      errCode = FAILURE;
    }
  }
  return errCode;
}
Example #2
0
int
iterateDynamics(std::vector<Robot *> robotVec,
		std::vector<DynamicBody *> bodyVec,
		DynamicParameters *dp)		
{
  double h = dp->timeStep;
  bool useContactEps = dp->useContactEps;
  static double Jcg_tmp[9],Jcg_B[9],Jcg_N[9],Jcg_N_inv[9],R_N_B[9];
  static double db0=0.0,tmp3[3];
  static mat3 Rot;
  static int info;
  World *myWorld;
  KinematicChain *chain;
  int numBodies = bodyVec.size(),errCode = 0;
  int numRobots = robotVec.size();
  int numJoints=0;
  int numDOF=0;
  int bn,cn,i,j;
  int Mrows,Dcols,Arows,Hrows,Hcols,Nurows,Nucols;
  int numDOFLimits=0;

  std::list<Contact *> contactList;
  std::list<Contact *> objContactList;
  std::list<Contact *>::iterator cp;

  //  unsigned long dmark = dmalloc_mark();

  double *ql = new double[7*numBodies];
  double *qnew = new double[7*numBodies];
  double *vl = new double[6*numBodies];
  double *vlnew = new double[6*numBodies];
  double *M = new double[(6*numBodies)*(6*numBodies)];
  double *M_i = new double[(6*numBodies)*(6*numBodies)];
  double *fext = new double[6*numBodies];

  // LCP matrix
  double *A;

  // LCP vectors
  double *g,*lambda;
  double *predLambda = NULL; //used for debugging the prediction of LCP basis

  // main matrices for contact constraints
  double *H;

  // main matrices for joint constraints
  double *Nu;

  // main vector for contact constraints
  double *k;
  
  // main vectors for joint constraints
  double *eps;

  // intermediate matrices for contact constraints
  double *HtM_i,*v1;

  // intermediate matrices for contact constraints
  double *v2;

  // intermediate matrices for case of both joint and contact constraints
  double *NutM_i,*NutM_iNu,*INVNutM_iNu,*INVNutM_iNuNut;
  double *INVNutM_iNuNutM_i,*INVNutM_iNuNutM_iH;

  // intermediate vectors for case of both joint and contact constraints
  double *NutM_ikminuseps,*INVNutM_iNuNutM_ikminuseps;

  double *currq,*currM;

  Mrows = 6*numBodies;

  myWorld = bodyVec[0]->getWorld();

  std::map<Body*, int> islandIndices;
  for (i=0;i<myWorld->getNumBodies();i++) {
	islandIndices.insert( std::pair<Body*, int>(myWorld->getBody(i), -1) );
  }
  for (i=0;i<numBodies;i++) {
	islandIndices[ bodyVec[i] ] = i;
  }

  // count the joints and DOF, and the joint coupling constraints
  int numCouplingConstraints = 0;
  for (i=0;i<numRobots;i++) {
    numDOF += robotVec[i]->getNumDOF();
    for (j=0;j<robotVec[i]->getNumChains();j++) {
      chain = robotVec[i]->getChain(j);
      numJoints += chain->getNumJoints();
    }
	for (j=0;j<robotVec[i]->getNumDOF();j++) {
	  numCouplingConstraints += robotVec[i]->getDOF(j)->getNumCouplingConstraints();
	  numDOFLimits += robotVec[i]->getDOF(j)->getNumLimitConstraints();
	}
  }

  DBGP("Dynamics time step: " << h);
  DBGP("numJoints: " << numJoints);

  // count the total number of joints and contacts
  int numContacts = 0;
  int numTotalFrictionEdges = 0;
  int numDynJointConstraints=0;
  for (bn=0;bn<numBodies;bn++) {
    //count joints
    if (bodyVec[bn]->getDynJoint()) {
	  int numCon = bodyVec[bn]->getDynJoint()->getNumConstraints();
	  numDynJointConstraints += numCon;
	  DBGP(bodyVec[bn]->getName().latin1() << ": " << numCon << " constraints");
    }
	//count contacts
    objContactList = bodyVec[bn]->getContacts();
    for (cp=objContactList.begin();cp!=objContactList.end();cp++) {
      // check if the mate of this contact is already in the contact list
      if (std::find(contactList.begin(),contactList.end(),(*cp)->getMate()) == contactList.end()) {
		numContacts++;
		numTotalFrictionEdges += (*cp)->numFrictionEdges;
		contactList.push_back(*cp);
      }
	}
  }

  DBGP("Num contacts: " << numContacts);
  DBGP("Num friction edges: " << numTotalFrictionEdges);
  DBGP("Num dynjoint: " << numDynJointConstraints);

  // zero out matrices
  dcopy(Mrows*Mrows,&db0,0,M,1);
  dcopy(Mrows*Mrows,&db0,0,M_i,1);
  dcopy(Mrows,&db0,0,fext,1);

  //allocate the joint constraint matrices
  if (numJoints) {
    Nurows = Mrows;
    Nucols = numDynJointConstraints + numCouplingConstraints;
    DBGP("Nucols: " << Nucols);

    Nu = new double[Nurows * Nucols];
    dcopy(Nurows*Nucols,&db0,0,Nu,1);

    eps = new double[Nucols];
    dcopy(Nucols,&db0,0,eps,1);
    Arows = Mrows+Nucols;
  }
    
  // allocate the LCP matrix
  if (numContacts || numDOFLimits) {
	Dcols = numTotalFrictionEdges;

    DBGP("numContacts " << numContacts);	
    DBGP("Dcols " << Dcols);
    DBGP("numDOFLimits " << numDOFLimits);

    Hrows = Mrows;
    Hcols = Dcols + 2*numContacts + numDOFLimits;
    H = new double[Hrows * Hcols];

    dcopy(Hrows*Hcols,&db0,0,H,1);

    v1 = new double[Hrows * Hcols];
    v2 = new double[Hrows];
    dcopy(Hrows*Hcols,&db0,0,v1,1);
    dcopy(Hrows,&db0,0,v2,1);

    k = new double[Mrows]; //holds mass*previous velocity and external impulses
    Arows = Hcols;
    lambda = new double[Arows];  // the LCP solution    
  } else {
    Dcols = 0;
  }

  // allocate the constraint matrix
  if (numJoints || numContacts) {    
    A = new double[Arows*Arows];
    g = new double[Arows];

    dcopy(Arows*Arows,&db0,0,A,1); 
    dcopy(Arows,&db0,0,g,1); 
  }

  // compute mass matrix and external forces
  for (bn=0;bn<numBodies;bn++) {
	memcpy(vl+6*bn,bodyVec[bn]->getVelocity(),6*sizeof(double));
	memcpy(vlnew+6*bn,bodyVec[bn]->getVelocity(),6*sizeof(double));

    memcpy(ql+7*bn,bodyVec[bn]->getPos(),7*sizeof(double));    
    memcpy(qnew+7*bn,bodyVec[bn]->getPos(),7*sizeof(double));

    currq = qnew + 7*bn;    
    Quaternion tmpQuat(currq[3],currq[4],currq[5],currq[6]);
    tmpQuat.ToRotationMatrix(Rot);   

    // The rotation matrix returned by ToRotationMatrix is expressed as
    // a graphics style rot matrix (new axes are in rows), the R_N_B matrix
    // is a robotics style rot matrix (new axes in columns)
    
    R_N_B[0] = Rot[0];  R_N_B[3] = Rot[1];  R_N_B[6] = Rot[2];
    R_N_B[1] = Rot[3];  R_N_B[4] = Rot[4];  R_N_B[7] = Rot[5];
    R_N_B[2] = Rot[6];  R_N_B[5] = Rot[7];  R_N_B[8] = Rot[8];

    // Jcg_N = R_N_B * Jcg_B * R_N_B'; 
    // where Jcg_B is inertia matrix in body coords
    //       Jcg_N is inertia matrix in world coords ?
    memcpy(Jcg_B,bodyVec[bn]->getInertia(),9*sizeof(double));
	//multiply by mass
	dscal(9, bodyVec[bn]->getMass(), Jcg_B, 1);
    dgemm("N","N",3,3,3,1.0,R_N_B,3,Jcg_B,3,0.0,Jcg_tmp,3);
    dgemm("N","T",3,3,3,1.0,Jcg_tmp,3,R_N_B,3,0.0,Jcg_N,3);

	if ((info = invertMatrix(3,Jcg_N,Jcg_N_inv))) {
      printf("In iterateDynamics, inertia matrix inversion failed (info is %d)\n",info);
	  fprintf(stderr,"%f %f %f\n",Jcg_B[0], Jcg_B[1], Jcg_B[2]);
	  fprintf(stderr,"%f %f %f\n",Jcg_B[3], Jcg_B[4], Jcg_B[5]);
	  fprintf(stderr,"%f %f %f\n",Jcg_B[6], Jcg_B[7], Jcg_B[8]);
	  fprintf(stderr,"Body is %s\n",bodyVec[bn]->getName().latin1());
	}
    
    currM = M+((6*bn)*Mrows + bn*6);  //point to the correct block of M
    
    currM[0]              = bodyVec[bn]->getMass();
    currM[6*numBodies+1]  = bodyVec[bn]->getMass();
    currM[12*numBodies+2] = bodyVec[bn]->getMass();
    fillMatrixBlock(Jcg_N,3,3,3,5,5,currM,Mrows);
  
    currM = M_i+((6*bn)*Mrows + bn*6);//point to correct block of M_i

    currM[0]         = 1.0/bodyVec[bn]->getMass();
    currM[Mrows+1]   = 1.0/bodyVec[bn]->getMass();
    currM[2*Mrows+2] = 1.0/bodyVec[bn]->getMass();
    fillMatrixBlock(Jcg_N_inv,3,3,3,5,5,currM,Mrows);

    // compute external wrench
    // fext = [ 0 0 -9810.0*mass -[ang_vel_N x (Jcg_N * ang_vel_N)] ]
	//based on this, it would appear that graspit force units are N*1.0e6
	fext[6*bn+2] = -9810.0 * bodyVec[bn]->getMass() * dp->gravityMultiplier;  // force of gravity
	// fext[6*bn+2] = 0;  // NO force of gravity

    dgemv("N",3,3,1.0,Jcg_N,3,&vl[6*bn+3],1,0.0,tmp3,1);  // inertial moments
    fext[6*bn+3] = - (vl[6*bn+4]*tmp3[2] - vl[6*bn+5]*tmp3[1]);
    fext[6*bn+4] = - (vl[6*bn+5]*tmp3[0] - vl[6*bn+3]*tmp3[2]);
    fext[6*bn+5] = - (vl[6*bn+3]*tmp3[1] - vl[6*bn+4]*tmp3[0]);

    double ForcesToBodyFrame[36];
    transf invBody = bodyVec[bn]->getTran().inverse();
    vec3 invBodyTransl = invBody.translation();
    buildForceTransform(invBody,invBodyTransl,ForcesToBodyFrame);
	DBGP("fext initial: ");
    DBGST( disp_mat(stdout,&fext[6*bn],1,6,0) );

    // add any other wrenches that have accumulated on the body
    daxpy(6,1.0,bodyVec[bn]->getExtWrenchAcc(),1,&fext[6*bn],1);
	DBGP("fext with accumulated wrench: ");
    DBGST( disp_mat(stdout,&fext[6*bn],1,6,0) );

	if (numContacts||numDOFLimits) {
      // k = Mv_l + hfext
      currM = M+((6*bn)*Mrows + bn*6);  //point to the correct block of M
      dgemv("N",6,6,1.0,currM,Mrows,vl+6*bn,1,0.0,k+6*bn,1);
    }
  }

  if (numJoints) {
    int ncn = 0;
	int hcn = 0;
	for (i=0;i<numBodies;i++) {
	  if (bodyVec[i]->getDynJoint())
		bodyVec[i]->getDynJoint()-> buildConstraints(Nu,eps,numBodies,islandIndices,ncn);
	}
	for (i=0;i<numRobots;i++) {
      robotVec[i]->buildDOFLimitConstraints(islandIndices,numBodies,H,g,hcn);
      robotVec[i]->buildDOFCouplingConstraints(islandIndices,numBodies,Nu,eps,ncn);
	}
	for (i=0;i<Nucols;i++) {
	  eps[i] *= ERP/h;
	}
	for (i=0; i<hcn; i++) {
		g[i] *= ERP/h;
	}
  }

  // add contacts to the LCP
  if (!contactList.empty()) {
    DBGP("processing contacts");
    double Ftform_N_C[36];
    
    // A is square
    double *Wn = &H[numDOFLimits*Hrows];
    double *D  = &H[(numDOFLimits+numContacts)*Hrows];
    
    double *E =		&A[(numDOFLimits+numContacts+Dcols)*Arows + numDOFLimits+numContacts];
    double *negET = &A[(numDOFLimits+numContacts)*Arows + numDOFLimits+numContacts+Dcols]; 
    double *MU    = &A[numDOFLimits*Arows + numDOFLimits+numContacts+Dcols];
    double *contactEps = &g[numDOFLimits];

	int frictionEdgesCount = 0;
    for (cp=contactList.begin(),cn=0; cp!=contactList.end(); cp++,cn++){

      //DBGP("contact " << cn);
      transf cf  = (*cp)->getContactFrame() *  (*cp)->getBody1Tran();
      transf cf2 = (*cp)->getMate()->getContactFrame() * (*cp)->getBody2Tran();

      DBGP("CONTACT DISTANCE: " << (cf.translation() - cf2.translation()).len());
      if (useContactEps) {
            contactEps[cn] = MIN(0.0,-ERP/h *
      			(Contact::THRESHOLD/2.0 - (cf.translation() - cf2.translation()).len()));
	  }
      DBGP(" EPS: " << contactEps[cn]);
      vec3 normal(cf.affine().element(2,0), cf.affine().element(2,1), cf.affine().element(2,2));
        
      // find which body is this contact from
      for (bn=0;bn<numBodies;bn++)
	    if ((*cp)->getBody1() == bodyVec[bn]) break;
      if (bn<numBodies) {
		//????? this doesn't seem correct
       	vec3 radius = cf.translation() - ( bodyVec[bn]->getCoG() * (*cp)->getBody1Tran() - position::ORIGIN );

	    //	radius = radius / 1000.0;  // convert to meters

		vec3 RcrossN = radius * normal;
		DBGP("body1 normal: " << normal);
		DBGP("body1 radius: " << radius);

		Wn[cn*Hrows+6*bn]   = normal.x();
		Wn[cn*Hrows+6*bn+1] = normal.y();
		Wn[cn*Hrows+6*bn+2] = normal.z();
		Wn[cn*Hrows+6*bn+3] = RcrossN.x();
		Wn[cn*Hrows+6*bn+4] = RcrossN.y();
		Wn[cn*Hrows+6*bn+5] = RcrossN.z();
	
		vec3 bodyOrigin = bodyVec[bn]->getCoG() * (*cp)->getBody1Tran() - position::ORIGIN;
		buildForceTransform(cf,bodyOrigin,Ftform_N_C);

		/* dgemm("N","N", 6,Contact::numFrictionEdges,6, 1.0,Ftform_N_C,6, Contact::frictionEdges,6,
			    0.0,&D[Contact::numFrictionEdges*cn*Hrows+6*bn],Hrows); */
				
		dgemm("N","N",
				6,(*cp)->numFrictionEdges,6,  //m, n, k
				1.0,Ftform_N_C,6,			 //alfa, A, lda
				(*cp)->frictionEdges,6,		//B, ldb
			    0.0,&D[ frictionEdgesCount*Hrows+6*bn],Hrows);	//beta, C, ldc
	  }

      //find the other body
      for(bn=0;bn<numBodies;bn++)
		if ((*cp)->getBody2() == bodyVec[bn]) break;
      if (bn<numBodies) {

        //normal = vec3(cf2.affine().element(2,0), cf2.affine().element(2,1),cf2.affine().element(2,2));
		normal = -normal;

		//vec3 radius = cf2.translation() - (bodyVec[bn]->getCoG() * (*cp)->getBody2Tran() - position::ORIGIN);
		vec3 radius = cf.translation() - (bodyVec[bn]->getCoG() * (*cp)->getBody2Tran() - position::ORIGIN);
		vec3 RcrossN = radius * normal;
		DBGP("body2 normal: " << normal);
		DBGP("body2 radius: " << radius);

		Wn[cn*Hrows+6*bn]   = normal.x();
		Wn[cn*Hrows+6*bn+1] = normal.y();
		Wn[cn*Hrows+6*bn+2] = normal.z();
		Wn[cn*Hrows+6*bn+3] = RcrossN.x();
		Wn[cn*Hrows+6*bn+4] = RcrossN.y();
		Wn[cn*Hrows+6*bn+5] = RcrossN.z();
	
		vec3 bodyOrigin = bodyVec[bn]->getCoG()*(*cp)->getBody2Tran() - position::ORIGIN;
		buildForceTransform(cf,bodyOrigin,Ftform_N_C);
		//buildForceTransform(cf2,bodyOrigin,Ftform_N_C);

/*		dgemm("N","N",6,Contact::numFrictionEdges,6,-1.0,Ftform_N_C,6, Contact::frictionEdges,6,
			  0.0,&D[Contact::numFrictionEdges*cn*Hrows+6*bn],Hrows);*/
		//original graspit had a -1.0 here in front of Ftform_N_C
		dgemm("N","N",
				6,(*cp)->numFrictionEdges,6,
				-1.0,Ftform_N_C,6,
				(*cp)->frictionEdges,6,
				0.0,&D[ frictionEdgesCount*Hrows+6*bn ],Hrows);
      }

      //for (i=cn*Contact::numFrictionEdges; i<(cn+1)*Contact::numFrictionEdges; i++) {
	  for (i=frictionEdgesCount; i<frictionEdgesCount+(*cp)->numFrictionEdges; i++) {
		E[cn*Arows+i] = 1.0;
		negET[i*Arows+cn] = -1.0;
      }      
      MU[cn*Arows + cn] = (*cp)->getCof();
	  frictionEdgesCount += (*cp)->numFrictionEdges;
    }
  }
  
  if (numContacts || numDOFLimits)
    daxpy(Mrows,h,fext,1,k,1);

  if (numJoints && (numContacts || numDOFLimits)) {
    // Cnu1 = INV(Nu'M_iNu)Nu'M_iH
    // Cnu2 = INV(Nu'M_iNu)(Nu'M_ik-eps)
    // v1 = -NuCnu1
    // v2 = -NuCnu2
    
    NutM_i = new double[Nucols*Mrows];
    NutM_iNu = new double[Nucols*Nucols];
    INVNutM_iNu = new double[Nucols*Nucols];
    INVNutM_iNuNut = new double[Nucols*Nurows];
    INVNutM_iNuNutM_i = new double[Nucols*Mrows];
    INVNutM_iNuNutM_iH = new double[Nucols*Hcols];
    

    NutM_ikminuseps = new double[Nucols];
    INVNutM_iNuNutM_ikminuseps = new double[Nucols];
    
    dgemm("T","N",Nucols,Mrows,Mrows,1.0,Nu,Nurows,M_i,Mrows, 0.0,NutM_i,Nucols);
    dgemm("N","N",Nucols,Nucols,Mrows,1.0,NutM_i,Nucols,Nu,Nurows, 0.0,NutM_iNu,Nucols);
    if ((info = invertMatrix(Nucols,NutM_iNu,INVNutM_iNu)))
      printf("In iterateDynamics, NutM_iNu matrix inversion failed (info is %d)\n",info);
    
    dgemm("N","T",Nucols,Nurows,Nucols,1.0,INVNutM_iNu,Nucols,Nu,Nurows,
	  0.0,INVNutM_iNuNut,Nucols);
    dgemm("N","N",Nucols,Mrows,Mrows,1.0,INVNutM_iNuNut,Nucols,M_i,Mrows,
	  0.0,INVNutM_iNuNutM_i,Nucols);
    dgemm("N","N",Nucols,Hcols,Mrows,1.0,INVNutM_iNuNutM_i,Nucols,H,Hrows,
	  0.0,INVNutM_iNuNutM_iH,Nucols);
    dgemm("N","N",Nurows,Hcols,Nucols,-1.0,Nu,Nurows,INVNutM_iNuNutM_iH,Nucols,
	  0.0,v1,Nurows);

    dgemv("N",Nucols,Mrows,1.0,NutM_i,Nucols,k,1,0.0,NutM_ikminuseps,1);
    daxpy(Nucols,-1.0,eps,1,NutM_ikminuseps,1);

    dgemv("N",Nucols,Nucols,1.0,INVNutM_iNu,Nucols,NutM_ikminuseps,1,
	  0.0,INVNutM_iNuNutM_ikminuseps,1);

    dgemv("N",Nurows,Nucols,-1.0,Nu,Nurows,INVNutM_iNuNutM_ikminuseps,1,
	  0.0,v2,1);
  }

  if (numContacts || numDOFLimits) {
    // in the simple case without joint constraints
    // A = H'M_iv1 + N
    // g = H'M_iv2
    // where N is already stored in A
    // v1 is the first term of v_(l+1) and v2 is the second term
    // v_l+1 = M_i(v1 lambda + v2) = M_i(H lambda + k)
    // k is (Mv_l + hfext)

    //add H to v1
    //add k to v2
    DBGP("k:");
    DBGST( disp_mat(stdout,k,1,Mrows,0) );
    DBGP("first g:");
    DBGST( disp_mat(stdout,g,1,Arows,0) );

	daxpy(Mrows*Hcols,1.0,H,1,v1,1);
    daxpy(Mrows,1.0,k,1,v2,1);

    // build A and g
    HtM_i = new double[Hcols*Mrows];
    dgemm("T","N",Hcols,Mrows,Hrows,1.0,H,Hrows,M_i,Mrows,0.0,HtM_i,Hcols);

    dgemm("N","N",Hcols,Hcols,Mrows,1.0,HtM_i,Hcols,v1,Mrows,1.0,A,Arows);
    //    dgemv("N",Hcols,Mrows,1.0,HtM_i,Hcols,v2,1,0.0,g,1);
    dgemv("N",Hcols,Mrows,1.0,HtM_i,Hcols,v2,1,1.0,g,1);
  }

	int frictionEdgesCount;
	//debug information; can be removed

	if (numContacts || numDOFLimits) {
		bool lemkePredict = false;
		if (lemkePredict) {
			//try to use information from previous time steps to guess a good starting basis for Lemke's algorithm
			assembleLCPPrediction(lambda, Arows, numDOFLimits, &contactList);
	        predLambda = new double[Arows];  // keep a copy of the prediction so we can check it later
			dcopy(Arows, lambda, 1, predLambda, 1);
//			fprintf(stderr,"Prediction: \n");
//			printLCPBasis(predLambda, Arows, numDOFLimits, numContacts);
		}

	    //    double startTime;   
	    //    startTime = getTime();
   
		DBGP("g:");
		DBGST( for (i=0;i<Arows;i++) printf("%le ",g[i]); );
Example #3
0
int main(int argc, char** argv)
{
    
    CvMat* M = cvCreateMat(3, 3, CV_64FC1);

    cvSetIdentity(M);

    CvMat* L = MT_CreateCholeskyResult(M);

    MT_Cholesky(M, L);

    disp_mat(M, "M");
    disp_mat(L, "L = chol(M)");

    cvmSet(M, 1, 1, 4.0);
    cvmSet(M, 2, 2, 9.0);

    MT_Cholesky(M, L);

    disp_mat(M, "M");
    disp_mat(L, "L = chol(M)");

    cvmSet(M, 0, 1, 0.1);
    cvmSet(M, 0, 2, 0.1);
    cvmSet(M, 1, 0, 0.1);
    cvmSet(M, 1, 2, 0.1);
    cvmSet(M, 2, 0, 0.1);
    cvmSet(M, 2, 1, 0.1);

    MT_Cholesky(M, L);

    disp_mat(M, "M");
    disp_mat(L, "L = chol(M)");

    cvReleaseMat(&M);
    cvReleaseMat(&L);

    M = cvCreateMat(5, 5, CV_64FC1);
    cvSet(M, cvScalar(0.1));

    for(unsigned int i = 0; i < 5; i++)
    {
        cvmSet(M, i, i, (double) (i+1));
    }

    L = MT_CreateCholeskyResult(M);

    MT_Cholesky(M, L);

    disp_mat(M, "M");
    disp_mat(L, "L = chol(M)");

    cvReleaseMat(&M);
    cvReleaseMat(&L);


    CvMat* C = cvCreateMat(4, 4, CV_64FC1);
    CvMat* A = cvCreateMatHeader(2, 2, CV_64FC1);
    CvMat* B = cvCreateMatHeader(2, 2, CV_64FC1);

    cvGetSubRect(C, A, cvRect(0, 0, 2, 2));
    cvGetSubRect(C, B, cvRect(2, 2, 2, 2));

    cvSet(C, cvScalar(0));
    cvSet(A, cvScalar(1));
    cvSet(B, cvScalar(2));

    cvReleaseMat(&A);
    cvReleaseMat(&B);

    disp_mat(C, "C (composited)");

    cvReleaseMat(&C);    
        
}