Exemple #1
0
/*!*****************************************************************************
 *******************************************************************************
 \note  run_user_task
 \date  Nov. 2007
 
 \remarks 
 
 this function is clocked out of the task servo
 
 *******************************************************************************
 Function Parameters: [in]=input,[out]=output

 none 

 ******************************************************************************/
int
run_user_task(void)

{
  
  int i,j;
  MY_MATRIX(M,1,N_CART,1,N_CART);
  MY_VECTOR(v,1,N_CART);

  // compute the contact forces in world coordinates at the feet from the
  // force 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 */

  // transform forces
  v[_X_] = misc_sensor[L_CFx];
  v[_Y_] = misc_sensor[L_CFy];
  v[_Z_] = misc_sensor[L_CFz];
  mat_vec_mult_size(Alink[L_IN_HEEL],N_CART,N_CART,v,N_CART,endeff[LEFT_FOOT].cf);

  // transform torques
  v[_A_] = misc_sensor[L_CTa];
  v[_B_] = misc_sensor[L_CTb];
  v[_G_] = misc_sensor[L_CTg];
  mat_vec_mult_size(Alink[L_IN_HEEL],N_CART,N_CART,v,N_CART,endeff[LEFT_FOOT].ct);

  /* 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 */

  // transform forces
  // transform forces
  v[_X_] = misc_sensor[R_CFx];
  v[_Y_] = misc_sensor[R_CFy];
  v[_Z_] = misc_sensor[R_CFz];
  mat_vec_mult_size(Alink[R_IN_HEEL],N_CART,N_CART,v,N_CART,endeff[RIGHT_FOOT].cf);

  // transform torques
  v[_A_] = misc_sensor[R_CTa];
  v[_B_] = misc_sensor[R_CTb];
  v[_G_] = misc_sensor[R_CTg];
  mat_vec_mult_size(Alink[R_IN_HEEL],N_CART,N_CART,v,N_CART,endeff[RIGHT_FOOT].ct);

  // use the simulated base state if required
  if (use_simulated_base_state)
    read_simulated_base();

  /*//sending
  char buf[BUFLEN];

  sprintf(buf, 'to je paket %d\n', 5);
  mainSend(buf);
  printf("send\n");*/
  return TRUE;
}
/*!*****************************************************************************
 *******************************************************************************
\note  baseToWorldAcc
\date  April 2006
   
\remarks 

        converts a 3D acceleration in base coordinates to world coordinates

 *******************************************************************************
 Function Parameters: [in]=input,[out]=output


 \param[in]     xl     : the vector in local coordinates
 \param[in]     cbase  : the base position
 \param[in]     obase  : the base orientation
 \param[out]    xw     : the vector in world coordinates


 ******************************************************************************/
void
baseToWorldAcc(double *xl, SL_Cstate *cbase, SL_quat *obase, double *xw)
{

  int           i,j;
  static int    firsttime=TRUE;
  double tmp[N_CART+1];

  MY_MATRIX(R,1,N_CART,1,N_CART);
  
  quatToRotMatInv(obase,R);
  mat_vec_mult_size(R,N_CART,N_CART,xl,N_CART,tmp);

  for (i=1; i<=N_CART; ++i)
    xw[i] = tmp[i];

}
/*!*****************************************************************************
 *******************************************************************************
\note  worldToBaseAcc
\date  April 2006
   
\remarks 

        converts a 3D acceleration in world coordinates to base coordinates

 *******************************************************************************
 Function Parameters: [in]=input,[out]=output


 \param[in]     xw     : the vector in world coordinates
 \param[in]     cbase  : the base position
 \param[in]     obase  : the base orientation
 \param[out]    xl     : the vector in local coordinates


 ******************************************************************************/
void
worldToBaseAcc(double *xw, SL_Cstate *cbase, SL_quat *obase, double *xl)
{

  int           i,j;
  static int    firsttime=TRUE;
  double        temp[N_CART+1];

  MY_MATRIX(R,1,N_CART,1,N_CART);

  for (i=1; i<=N_CART; ++i)
    temp[i] = xw[i];

  quatToRotMat(obase,R);
  mat_vec_mult_size(R,N_CART,N_CART,temp,N_CART,xl);

}
/*!*****************************************************************************
 *******************************************************************************
\note  compute_inertial
\date  Oct 2005
   
\remarks 

      This functions computes simulated inertial signals, i.e., body 
      quaternion, angular velocity, and linear acceleration, and 
      linear acceleration at the feet

 *******************************************************************************
 Function Parameters: [in]=input,[out]=output

     All results can be computed based on global variables. Results are
     assigned to the misc_sensor structures.


 ******************************************************************************/
static void
compute_inertial(void)

{
  int i,j;
  static int firsttime = TRUE;
  static Matrix R;
  static Matrix RT;
  static Vector ad;
  static Vector xdd;
  static Vector r;
  static Vector r0;
  static Vector t1;
  static Vector t2;
  static Vector t3;
  static Vector lv;
  static Vector rv;
  static Vector lv_last;
  static Vector rv_last;
  static Vector lacc;
  static Vector racc;


  if (firsttime) {
    R   = my_matrix(1,N_CART,1,N_CART);
    RT  = my_matrix(1,N_CART,1,N_CART);
    ad  = my_vector(1,N_CART);
    xdd = my_vector(1,N_CART);
    r   = my_vector(1,N_CART);
    r0  = my_vector(1,N_CART);
    t1  = my_vector(1,N_CART);
    t2  = my_vector(1,N_CART);
    t3  = my_vector(1,N_CART);
    lv  = my_vector(1,N_CART);
    rv  = my_vector(1,N_CART);
    lacc= my_vector(1,N_CART);
    racc= my_vector(1,N_CART);
    lv_last  = my_vector(1,N_CART);
    rv_last  = my_vector(1,N_CART);
    firsttime = FALSE;
  }

  // copy quaternion from base coordinates (perfect data)
  misc_sim_sensor[B_Q0_IMU] = base_orient.q[_Q0_];
  misc_sim_sensor[B_Q1_IMU] = base_orient.q[_Q1_];
  misc_sim_sensor[B_Q2_IMU] = base_orient.q[_Q2_];
  misc_sim_sensor[B_Q3_IMU] = base_orient.q[_Q3_];


  // the angular vel. and translatory acc are first computed in world coordinates
  // and then transformed to base coordinates.

  // need the base coordinate rotatin matrix, which transforms world to base
  quatToRotMat(&base_orient,R);
  mat_trans(R,RT);

  // offset is IMU_X_OFFSET and -IMU_Y_OFFSET
  r[_X_] = IMU_X_OFFSET;
  r[_Y_] = -IMU_Y_OFFSET;
  r[_Z_] = 0.0;

  // get offset vector in global coordinates
  mat_vec_mult(RT,r,r0);

  // w x r0
  vec_mult_outer_size(base_orient.ad,r0,N_CART,t1);

  // w x (w x r0) = w x t1 (which is one term of xdd)
  vec_mult_outer_size(base_orient.ad,t1,N_CART,t2);

  // wd x r0
  vec_mult_outer_size(base_orient.add,r0,N_CART,t1);  

  // add to xdd
  vec_add(t1,t2,t1);

  // and add the base acceleration
  vec_add_size(t1,base_state.xdd,N_CART,t1);

  // add gravity to t1
  t1[_Z_] -= gravity;

  // rotate all into base coordinates
  mat_vec_mult_size(R,N_CART,N_CART,base_orient.ad,N_CART,t3);
  mat_vec_mult_size(R,N_CART,N_CART,t1,N_CART,t2);

  // and rotate this information into IMU coordinates
  // IMU_X = -Z_BASE; IMU_Y = -X_BASE; IMU_Z = Y_BASE

  t1[_A_] = -PI/2.;
  t1[_B_] = 0.0;
  t1[_G_] = PI/2.;
  eulerToRotMat(t1,R);
  mat_vec_mult(R,t2,xdd);
  mat_vec_mult(R,t3,ad);

  // the final result
  misc_sim_sensor[B_AD_A_IMU] = ad[_A_];
  misc_sim_sensor[B_AD_B_IMU] = ad[_B_];
  misc_sim_sensor[B_AD_G_IMU] = ad[_G_];

  misc_sim_sensor[B_XACC_IMU] = xdd[_X_];
  misc_sim_sensor[B_YACC_IMU] = xdd[_Y_];
  misc_sim_sensor[B_ZACC_IMU] = xdd[_Z_];


  // now get the foot accelerations in WORLD coordinate, computed at the L_FOOT position,
  // which is not exactly the same as the load cell offset, but very close.
  computeLinkVelocity(L_FOOT, link_pos_sim, joint_origin_pos_sim, 
		      joint_axis_pos_sim, joint_sim_state, lv);

  computeLinkVelocity(R_FOOT, link_pos_sim, joint_origin_pos_sim, 
		      joint_axis_pos_sim, joint_sim_state, rv);

  for (i=1; i<=N_CART; ++i) {
    lacc[i] = (lv[i]-lv_last[i])*(double)simulation_servo_rate;
    lv_last[i] = lv[i];
    racc[i] = (rv[i]-rv_last[i])*(double)simulation_servo_rate;
    rv_last[i] = rv[i];
  }

  // transform to local foot coordinates after adding gravity
  lacc[_Z_] -= gravity;
  racc[_Z_] -= gravity;

  // rotation matrix from world to L_AAA coordinates 
  mat_trans_size(Alink_sim[L_FOOT],N_CART,N_CART,R);
  mat_vec_mult(R,lacc,t1);

  // rotation matrix from world to R_AAA coordinates 
  mat_trans_size(Alink_sim[R_FOOT],N_CART,N_CART,R);
  mat_vec_mult(R,racc,t2);

#ifdef HAS_LOWER_BODY
  // the final result
  misc_sim_sensor[L_FOOT_XACC] = t1[_X_];
  misc_sim_sensor[L_FOOT_YACC] = t1[_Y_];
  misc_sim_sensor[L_FOOT_ZACC] = t1[_Z_];

  misc_sim_sensor[R_FOOT_XACC] = t2[_X_];
  misc_sim_sensor[R_FOOT_YACC] = t2[_Y_];
  misc_sim_sensor[R_FOOT_ZACC] = t2[_Z_];
#endif
}
/*!*****************************************************************************
 *******************************************************************************
 \note  run_user_task
 \date  Nov. 2007
 
 \remarks 
 
 this function is clocked out of the task servo
 
 *******************************************************************************
 Function Parameters: [in]=input,[out]=output

 none 

 ******************************************************************************/
int
run_user_task(void)

{
  
  int i,j;
  MY_MATRIX(M,1,N_CART,1,N_CART);
  MY_VECTOR(v,1,N_CART);

  // compute the contact forces in world coordinates at the feet from the
  // force 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 */

#ifdef HAS_LOWER_BODY
  // transform forces
  v[_X_] = misc_sensor[L_CFx];
  v[_Y_] = misc_sensor[L_CFy];
  v[_Z_] = misc_sensor[L_CFz];
  mat_vec_mult_size(Alink[L_IN_HEEL],N_CART,N_CART,v,N_CART,endeff[LEFT_FOOT].cf);

  // transform torques
  v[_A_] = misc_sensor[L_CTa];
  v[_B_] = misc_sensor[L_CTb];
  v[_G_] = misc_sensor[L_CTg];
  mat_vec_mult_size(Alink[L_IN_HEEL],N_CART,N_CART,v,N_CART,endeff[LEFT_FOOT].ct);

  /* 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 */

  // transform forces
  // transform forces
  v[_X_] = misc_sensor[R_CFx];
  v[_Y_] = misc_sensor[R_CFy];
  v[_Z_] = misc_sensor[R_CFz];
  mat_vec_mult_size(Alink[R_IN_HEEL],N_CART,N_CART,v,N_CART,endeff[RIGHT_FOOT].cf);

  // transform torques
  v[_A_] = misc_sensor[R_CTa];
  v[_B_] = misc_sensor[R_CTb];
  v[_G_] = misc_sensor[R_CTg];
  mat_vec_mult_size(Alink[R_IN_HEEL],N_CART,N_CART,v,N_CART,endeff[RIGHT_FOOT].ct);
#endif

  differentiate_cog(&cog);  
  test_fall(&cog);

  // use the simulated base state if required
  if (use_simulated_base_state)
    read_simulated_base();
  else
  {
	
	  // do base state estimation
//	  update_base_state_estimation(&base_orient, &base_state);

	  // run_state_est_lin_task();
	  // getPelv(&base_orient, &base_state);

	  // base state
	  if (semTake(sm_base_state_sem,ns2ticks(NO_WAIT)) == ERROR)
	  {
	    //printf("sm_base_state_sem take error\n");
	    return TRUE;
	  }

	  cSL_Cstate((&base_state)-1, sm_base_state_data, 1, DOUBLE2FLOAT);

	  sm_base_state->state[1] = sm_base_state_data[1];

	  semGive(sm_base_state_sem);


	  // base orient
	  if (semTake(sm_base_orient_sem,ns2ticks(NO_WAIT)) == ERROR)
	  {
	    //printf("sm_base_orien_sem take error\n");
	    return TRUE;

	  }
	  cSL_quat(&base_orient-1, sm_base_orient_data, 1, DOUBLE2FLOAT);

	  sm_base_orient->orient[1] = sm_base_orient_data[1];

	  semGive(sm_base_orient_sem);
  }


  return TRUE;

}