/*!***************************************************************************** ******************************************************************************* \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; }