コード例 #1
0
ファイル: test_sine_task.c プロジェクト: Riba7/hoap-sl
void
test_constraint(void)
{
  int i,j,n,m;
  static Matrix Jbig;
  static Matrix dJbigdt;
  static Vector dsbigdt;
  static Matrix JbigMinvJbigt;
  static Matrix JbigMinvJbigtinv;
  static Matrix Minv;
  static Matrix MinvJbigt;
  static Matrix Jbigt;
  static Vector dJbigdtdsbigdt;
  static Matrix Jbart;
  static Matrix Jbar;
  static Vector lv;
  static Vector lambda;
  static Vector f;
  static Matrix R;
  static Vector v;
  static int firsttime = TRUE;
  int    debug_print = TRUE;

  if (firsttime) {
    firsttime = FALSE;
    Jbig             = my_matrix(1,N_ENDEFFS*6,1,N_DOFS+6);
    Jbigt            = my_matrix(1,N_DOFS+6,1,N_ENDEFFS*6);
    dJbigdt          = my_matrix(1,N_ENDEFFS*6,1,N_DOFS+6);
    JbigMinvJbigt    = my_matrix(1,N_ENDEFFS*6,1,N_ENDEFFS*6);
    JbigMinvJbigtinv = my_matrix(1,N_ENDEFFS*6,1,N_ENDEFFS*6);
    Minv             = my_matrix(1,N_DOFS+6,1,N_DOFS+6);
    MinvJbigt        = my_matrix(1,N_DOFS+6,1,N_ENDEFFS*6);
    dsbigdt          = my_vector(1,N_DOFS+6);
    dJbigdtdsbigdt   = my_vector(1,N_ENDEFFS*6);
    Jbar             = my_matrix(1,N_DOFS+6,1,N_ENDEFFS*6);
    Jbart            = my_matrix(1,N_ENDEFFS*6,1,N_DOFS+6);
    lv               = my_vector(1,N_ENDEFFS*6);
    lambda           = my_vector(1,N_ENDEFFS*6);
    f                = my_vector(1,N_DOFS+6);
    R                = my_matrix(1,N_CART,1,N_CART);
    v                = my_vector(1,N_CART);

    // the base part of Jbig is just the identity matrix for both constraints
    for (i=1; i<=6; ++i)
      Jbig[i][N_DOFS+i] = 1.0;

    for (i=1; i<=6; ++i)
      Jbig[i+6][N_DOFS+i] = 1.0;

  }

  // build the Jacobian including the base -- just copy J into Jbig
  mat_equal_size(J,N_ENDEFFS*6,N_DOFS,Jbig);
  mat_trans(Jbig,Jbigt);

  // build the Jacobian derivative
  mat_equal_size(dJdt,N_ENDEFFS*6,N_DOFS,dJbigdt);

  // build the augmented state derivate vector
  for (i=1; i<=N_DOFS; ++i)
    dsbigdt[i] = joint_state[i].thd;

  for (i=1; i<=N_CART; ++i)
    dsbigdt[N_DOFS+i] = base_state.xd[i];

  for (i=1; i<=N_CART; ++i)
    dsbigdt[N_DOFS+N_CART+i] = base_orient.ad[i];


  // compute J-bar transpose
  my_inv_ludcmp(rbdInertiaMatrix,N_DOFS+6, Minv);
  mat_mult(Minv,Jbigt,MinvJbigt);
  mat_mult(Jbig,MinvJbigt,JbigMinvJbigt);
  my_inv_ludcmp(JbigMinvJbigt,N_ENDEFFS*6,JbigMinvJbigtinv);
  mat_mult(MinvJbigt,JbigMinvJbigtinv,Jbar);
  mat_trans(Jbar,Jbart);

  // compute C+G-u
  for (i=1; i<=N_DOFS; ++i)
    f[i] = -joint_state[i].u;
  
  for (i=1; i<=6; ++i)
    f[N_DOFS+i] = 0.0;

  vec_add(f,rbdCplusGVector,f);

  // compute first part of lambda
  mat_vec_mult(Jbart,f,lambda);

  // compute second part of lambda
  mat_vec_mult(dJbigdt,dsbigdt,dJbigdtdsbigdt);
  mat_vec_mult(JbigMinvJbigtinv,dJbigdtdsbigdt,lv);

  // compute final lambda
  vec_sub(lambda,lv,lambda);

  // ----------------------------------------------------------------------
  // express lambda in the same coordinate at the foot sensors

  /* rotation matrix from world to L_AAA coordinates:
     we can borrow this matrix from the toes, which have the same
     rotation, but just a different offset vector, which is not
     needed here */

  mat_trans_size(Alink[L_IN_HEEL],N_CART,N_CART,R);

  // transform forces
  for (i=1; i<=N_CART; ++i)
    v[i] = lambda[N_CART*2+i];
  mat_vec_mult(R,v,v);

  if (debug_print) {
    printf("LEFT Force: lx=% 7.5f   sx=% 7.5f\n",v[1],misc_sim_sensor[L_CFx]);
    printf("LEFT Force: ly=% 7.5f   sy=% 7.5f\n",v[2],misc_sim_sensor[L_CFy]);
    printf("LEFT Force: lz=% 7.5f   sz=% 7.5f\n",v[3],misc_sim_sensor[L_CFz]);
  }

  misc_sensor[L_CFx] = v[1];
  misc_sensor[L_CFy] = v[2];
  misc_sensor[L_CFz] = v[3];

  // transform torques
  for (i=1; i<=N_CART; ++i)
    v[i] = lambda[N_CART*2+N_CART+i];
  mat_vec_mult(R,v,v);

  if (debug_print) {
    printf("LEFT Torque: lx=% 7.5f   sx=% 7.5f\n",v[1],misc_sim_sensor[L_CTa]);
    printf("LEFT Torque: ly=% 7.5f   sy=% 7.5f\n",v[2],misc_sim_sensor[L_CTb]);
    printf("LEFT Torque: lz=% 7.5f   sz=% 7.5f\n",v[3],misc_sim_sensor[L_CTg]);
  }

  misc_sensor[L_CTa] = v[1];
  misc_sensor[L_CTb] = v[2];
  misc_sensor[L_CTg] = v[3];

  /* rotation matrix from world to R_AAA coordinates :
     we can borrow this matrix from the toes, which have the same
     rotation, but just a different offset vector, which is not
     needed here */
  mat_trans_size(Alink[R_IN_HEEL],N_CART,N_CART,R);

  // transform forces
  for (i=1; i<=N_CART; ++i)
    v[i] = lambda[i];
  mat_vec_mult(R,v,v);

  if (debug_print) {
    printf("RIGHT Force: lx=% 7.5f   sx=% 7.5f\n",v[1],misc_sim_sensor[R_CFx]);
    printf("RIGHT Force: ly=% 7.5f   sy=% 7.5f\n",v[2],misc_sim_sensor[R_CFy]);
    printf("RIGHT Force: lz=% 7.5f   sz=% 7.5f\n",v[3],misc_sim_sensor[R_CFz]);
  }
    
  misc_sensor[R_CFx] = v[1];
  misc_sensor[R_CFy] = v[2];
  misc_sensor[R_CFz] = v[3];

  // transform torques
  for (i=1; i<=N_CART; ++i)
    v[i] = lambda[N_CART+i];
  mat_vec_mult(R,v,v);

  if (debug_print) {
    printf("RIGHT Torque: lx=% 7.5f   sx=% 7.5f\n",v[1],misc_sim_sensor[R_CTa]);
    printf("RIGHT Torque: ly=% 7.5f   sy=% 7.5f\n",v[2],misc_sim_sensor[R_CTb]);
    printf("RIGHT Torque: lz=% 7.5f   sz=% 7.5f\n",v[3],misc_sim_sensor[R_CTg]);
  }

  misc_sensor[R_CTa] = v[1];
  misc_sensor[R_CTb] = v[2];
  misc_sensor[R_CTg] = v[3];

  if (debug_print)
    getchar();
  
}
コード例 #2
0
ファイル: mat_util.c プロジェクト: RobotLearning/SL
void expm(Matrix A, Matrix B, double h) {

	static int firsttime = TRUE;
	static Matrix M;
	static Matrix M2;
	static Matrix M3;
	static Matrix D;
	static Matrix N;

	if (firsttime) {
		firsttime = FALSE;
		M = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
		M2 = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
		M3 = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
		D = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
		N = my_matrix(1,3*N_DOFS,1,3*N_DOFS);
	}

	int norm = 0;
	double c = 0.5;
	int q = 6; // uneven p-q order for Pade approx.
	int p = 1;
	int i,j,k;

	// Form the big matrix
	mat_mult_scalar(A, h, A);
	mat_equal_size(A, 2*N_DOFS, 2*N_DOFS, M);
	for (i = 1; i <= 2*N_DOFS; ++i) {
		for (j = 1; j <= N_DOFS; ++j) {
			M[i][2*N_DOFS + j] = h * B[i][j];
	    }
	}
	//print_mat("M is:\n", M);

	// scale M by power of 2 so that its norm < 1/2
	norm = (int)(log2(inf_norm(M))) + 2;
	//printf("Inf norm of M: %f \n", inf_norm(M));
	if (norm < 0)
		norm = 0;

	mat_mult_scalar(M, 1/pow(2,(double)norm), M);
	//printf("Norm of M logged, floored and 2 added is: %d\n", norm);
	//print_mat("M after scaling is:\n", M);

	for (i = 1; i <= 3*N_DOFS; i++) {
		for (j = 1; j <= 3*N_DOFS; j++) {
			N[i][j] = c * M[i][j];
			D[i][j] = -c * M[i][j];
		}
		N[i][i] = N[i][i] + 1.0;
		D[i][i] = D[i][i] + 1.0;
	}

	// set M2 equal to M
	mat_equal(M, M2);

	// start pade approximation

	for (k = 2; k <= q; k++) {
		c = c * (q - k + 1) / (double)(k * (2*q - k + 1));
		mat_mult(M,M2,M2);
		mat_mult_scalar(M2,c,M3);
		mat_add(N,M3,N);
		if (p == 1)
			mat_add(D,M3,D);
		else
			mat_sub(D,M3,D);
		p = -1 * p;
	}

	// multiply denominator with nominator i.e. D\E
	my_inv_ludcmp(D, 3*N_DOFS, D);
	mat_mult(D,N,N);

	// undo scaling by repeated squaring
	for (k = 1; k <= norm; k++)
		mat_mult(N,N,N);

	// get the matrices out
	// read off the entries
	for (i = 1; i <= 2*N_DOFS; i++) {
		for (j = 1; j <= 2*N_DOFS; j++) {
			A[i][j] = N[i][j];
		}
		for (j = 1; j <= N_DOFS; j++) {
			B[i][j] = N[i][2*N_DOFS + j];
		}
	}
}