00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00032 #include <humanoid_functions.h>
00033 
00034 using namespace std;
00035 
00036 humanoid::humanoid(void)
00037 {
00038   
00039   robot_dimensions.arm_length =         123.; 
00040   robot_dimensions.forearm_length =     106.; 
00041   robot_dimensions.shin_length =        139.; 
00042   robot_dimensions.thigh_length =       143.; 
00043   robot_dimensions.foot_length =        150.; 
00044   robot_dimensions.foot_width =         50.; 
00045   robot_dimensions.ankle_height =       50.; 
00046   
00047   PI=3.1415926535898;
00048   
00049   robot_servo_conversion.head_servo_offset =                            2400.;
00050   robot_servo_conversion.shoulder_flexion_servo_offset_left =           1050.;
00051   robot_servo_conversion.shoulder_flexion_servo_offset_right =          1975.;
00052   robot_servo_conversion.shoulder_abduction_servo_offset_left =         600.;
00053   robot_servo_conversion.shoulder_abduction_servo_offset_right =        2400.;
00054   robot_servo_conversion.elbow_flexion_servo_offset_left =              2400.;
00055   robot_servo_conversion.elbow_flexion_servo_offset_right =             600.;
00056   robot_servo_conversion.torso_rotation_servo_offset =                  1500.;
00057   robot_servo_conversion.torso_flexion_servo_offset =                   750.;
00058   robot_servo_conversion.torso_lateral_flexion_servo_offset =           1500.;
00059   robot_servo_conversion.knee_flexion_b_value_left =                    600.;
00060   robot_servo_conversion.knee_flexion_b_value_right =                   2400.;
00061   robot_servo_conversion.hip_flexion_b_value_left =                     900.;
00062   robot_servo_conversion.hip_flexion_b_value_right =                    1600.;
00063   
00064   robot_joint_limits.head_min_tilt =                    0.; 
00065   robot_joint_limits.head_max_tilt =                    10.; 
00066   robot_joint_limits.shoulder_min_flexion =             -45.; 
00067   robot_joint_limits.shoulder_max_flexion =             135.; 
00068   robot_joint_limits.shoulder_min_abduction =           0.; 
00069   robot_joint_limits.shoulder_max_abduction =           180.; 
00070   robot_joint_limits.elbow_min_flexion =                0.; 
00071   robot_joint_limits.elbow_max_flexion =                120.; 
00072   robot_joint_limits.torso_min_rotation =               -90.; 
00073   robot_joint_limits.torso_max_rotation =               90.; 
00074   robot_joint_limits.torso_min_flexion =                -15.;  
00075   robot_joint_limits.torso_max_flexion =                90.;  
00076   robot_joint_limits.torso_min_lateral_flexion =        -90.; 
00077   robot_joint_limits.torso_max_lateral_flexion =        90.; 
00078   robot_joint_limits.ankle_min_inversion =              -30.; 
00079   robot_joint_limits.ankle_max_inversion =              45.; 
00080   robot_joint_limits.ankle_min_flexion =                -40.; 
00081   robot_joint_limits.ankle_max_flexion =                20.; 
00082   robot_joint_limits.knee_min_flexion =                 0.; 
00083   robot_joint_limits.knee_max_flexion =                 130.; 
00084   robot_joint_limits.hip_min_abduction =                -40.; 
00085   robot_joint_limits.hip_max_abduction =                45; 
00086   robot_joint_limits.hip_min_flexion =                  -30.; 
00087   robot_joint_limits.hip_max_flexion =                  120.; 
00088   
00089   robot_element_mass.foot_mass =        0.444; 
00090   robot_element_mass.shin_mass =        0.343; 
00091   robot_element_mass.thigh_mass =       0.243; 
00092   
00093   robot_relative_COM.foot_COM << 9.06, 2.746, 31.7; 
00094   robot_relative_COM.shin_COM << 0.182, 15.861, 88.519; 
00095   robot_relative_COM.thigh_COM << -2.262, 1.418, 101.284; 
00096   
00097   return;
00098 }
00099 
00100 humanoid::~humanoid(void)
00101 {
00102   memset(&robot_dimensions, 0., sizeof(robot_dimensions));
00103   memset(&robot_servo_conversion, 0., sizeof(robot_servo_conversion));
00104   memset(&robot_joint_limits, 0., sizeof(robot_joint_limits));
00105   memset(&robot_element_mass, 0., sizeof(robot_element_mass));
00106 
00107   return;
00108 }
00109 
00110 void humanoid::Dir_Kin_3DOF_Arm(double t1, double t2, double t3, short int SIDE, double *end_pos_n_RPY)
00111 {
00112   
00113   double L1 = robot_dimensions.arm_length;
00114   double L2 = robot_dimensions.forearm_length;
00115   double X, Y, Z, ROLL, PITCH, YAW;
00116   
00117   double theta1 = t1 * PI / 180.;
00118   double theta2 = t2 * PI / 180.;
00119   double theta3 = t3 * PI / 180.;
00120   
00121   
00122   X = L1 * cos(theta2) * sin(theta1) + L2 * (cos(theta1) * sin(theta3) + cos(theta2) * cos(theta3) * sin(theta1));
00123   
00124   Y = (double)SIDE * (sin(theta2) * (L1 + L2 * cos(theta3)));
00125   
00126   Z = L2 * (sin(theta1) * sin(theta3) - cos(theta1) * cos(theta2) * cos(theta3)) - L1 * cos(theta1) * cos(theta2);
00127   
00128   PITCH = asin(cos(theta1) * cos(theta2) * cos(theta3) - sin(theta1) * sin(theta3));
00129   
00130   ROLL = asin(((double)SIDE * cos(theta3)*sin(theta2))/cos(PITCH));
00131   
00132   YAW = acos(((double)SIDE * -1. * cos(theta1) * sin(theta2)) / cos(PITCH));
00133   
00134   end_pos_n_RPY[0] = X;
00135   end_pos_n_RPY[1] = Y;
00136   end_pos_n_RPY[2] = Z;
00137   end_pos_n_RPY[3] = ROLL * 180. / PI; 
00138   end_pos_n_RPY[4] = PITCH * 180. / PI; 
00139   end_pos_n_RPY[5] = YAW * 180. / PI; 
00140 }
00141 
00142 void humanoid::Inv_Kin_3DOF_Arm(double X, double Y, double Z, double *req_angle)
00143 {
00144   
00145   double L1 = robot_dimensions.arm_length;
00146   double L2 = robot_dimensions.forearm_length;
00147   
00148   static Eigen::MatrixXd solutions(3,8);
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165   
00166   double t1_pos, t2_pos, t3_pos;
00167   double t1_neg, t2_neg, t3_neg;
00168   int i;
00169   double k1, k2 ,k3, yy, xx;
00170   
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230   
00231   
00232   
00233   t3_pos=acos((pow(X,2.)+pow(Y,2.)+pow(Z,2.)-pow(L1,2.)-pow(L2,2.))/(2.*L1*L2));
00234   if(!isnan(t3_pos))
00235   {
00236     
00237     if(fabs(t3_pos)<(double) 0.0034)
00238     {
00239       t3_pos=robot_joint_limits.elbow_min_flexion;
00240     }
00241     else if(fabs(t3_pos)<(((robot_joint_limits.elbow_max_flexion+5.)*PI/180.)+0.0034) && fabs(t3_pos)>(robot_joint_limits.elbow_max_flexion*PI/180.))
00242     {
00243       t3_pos=robot_joint_limits.elbow_max_flexion*PI/180.;
00244     }
00245     
00246     if(!((t3_pos*180./PI)>=robot_joint_limits.elbow_min_flexion && (t3_pos*180./PI)<=robot_joint_limits.elbow_max_flexion))
00247     {
00248       
00249       for(i=0;i<4;i++)
00250         solutions(0,i)=0./0.;
00251     }
00252     else
00253     {
00254       
00255       for(i=0;i<4;i++)
00256         solutions(0,i)=t3_pos;
00257     }
00258   }
00259   else
00260   {
00261     
00262     for(i=0;i<4;i++)
00263       solutions(0,i)=0./0.;
00264   }
00265   
00266   t3_neg=-1.*acos((pow(X,2.)+pow(Y,2.)+pow(Z,2.)-pow(L1,2.)-pow(L2,2.))/(2.*L1*L2));
00267   if(!isnan(t3_neg))
00268   {
00269     
00270     if(fabs(t3_neg)<(double) 0.0034)
00271     {
00272       t3_pos=robot_joint_limits.elbow_min_flexion;
00273     }
00274     else if(fabs(t3_neg)<(((robot_joint_limits.elbow_max_flexion+5.)*PI/180.)+0.0034) && fabs(t3_neg)>(robot_joint_limits.elbow_max_flexion*PI/180.))
00275     {
00276       t3_neg=robot_joint_limits.elbow_max_flexion*PI/180.;
00277     }
00278     
00279     if(!((t3_neg*180./PI)>=robot_joint_limits.elbow_min_flexion && (t3_neg*180./PI)<=robot_joint_limits.elbow_max_flexion))
00280     {
00281       
00282       for(i=4;i<8;i++)
00283         solutions(0,i)=0./0.;
00284     }
00285     else
00286     {
00287       
00288       for(i=4;i<8;i++)
00289         solutions(0,i)=t3_neg;
00290     }
00291   }
00292   else
00293   {
00294     
00295     for(i=4;i<8;i++)
00296       solutions(0,i)=0./0.;
00297   }
00298   
00299   t2_pos=asin(Y / ( L1 + L2 * cos(solutions(0,0))));
00300   if(!isnan(t2_pos))
00301   {
00302     
00303     if(fabs(t2_pos)<(double) 0.0034)
00304     {
00305       t2_pos=robot_joint_limits.shoulder_min_abduction;
00306     }
00307     else if(t2_pos<(((robot_joint_limits.shoulder_max_abduction+5.)*PI/180.)+0.0034) && t2_pos>(robot_joint_limits.shoulder_max_abduction*PI/180.))
00308     {
00309       t2_pos=robot_joint_limits.shoulder_max_abduction*PI/180.;
00310     }
00311     
00312     if(!(t2_pos>=robot_joint_limits.shoulder_min_abduction && t2_pos<=(robot_joint_limits.shoulder_max_abduction*PI/180.)))
00313     {
00314       
00315       solutions(1,0)=0./0.;
00316       solutions(1,1)=0./0.;
00317     }
00318     else
00319     {
00320       
00321       solutions(1,0)=t2_pos;
00322       solutions(1,1)=t2_pos;
00323     }
00324   }
00325   else
00326   {
00327     
00328     solutions(1,0)=0./0.;
00329     solutions(1,1)=0./0.;
00330   }
00331   
00332   t2_neg=-1. * asin(Y / ( L1 + L2 * cos(solutions(0,0))));
00333   if(!isnan(t2_neg))
00334   {
00335     
00336     if(fabs(t2_neg)<(double) 0.0034)
00337     {
00338       t2_pos=robot_joint_limits.shoulder_min_abduction;
00339     }
00340     else if(t2_neg<(((robot_joint_limits.shoulder_max_abduction+5.)*PI/180.)+0.0034) && t2_neg>(robot_joint_limits.shoulder_max_abduction*PI/180.))
00341     {
00342       t2_neg=robot_joint_limits.shoulder_max_abduction*PI/180.;
00343     }
00344     
00345     if(!(t2_neg>=robot_joint_limits.shoulder_min_abduction && t2_neg<=(robot_joint_limits.shoulder_max_abduction*PI/180.)))
00346     {
00347       
00348       solutions(1,2)=0./0.;
00349       solutions(1,3)=0./0.;
00350     }
00351     else
00352     {
00353       
00354       solutions(1,2)=t2_neg;
00355       solutions(1,3)=t2_neg;
00356     }
00357   }
00358   else
00359   {
00360     
00361     solutions(1,2)=0./0.;
00362     solutions(1,3)=0./0.;
00363   }
00364   
00365   t2_pos=asin(Y / ( L1 + L2 * cos(solutions(0,4))));
00366   if(!isnan(t2_pos))
00367   {
00368     
00369     if(fabs(t2_pos)<(double) 0.0034)
00370     {
00371       t2_pos=robot_joint_limits.shoulder_min_abduction;
00372     }
00373     else if(t2_pos<(((robot_joint_limits.shoulder_max_abduction+5.)*PI/180.)+0.0034) && t2_pos>(robot_joint_limits.shoulder_max_abduction*PI/180.))
00374     {
00375       t2_pos=robot_joint_limits.shoulder_max_abduction*PI/180.;
00376     }
00377     
00378     if(!(t2_pos>=robot_joint_limits.shoulder_min_abduction && t2_pos<=(robot_joint_limits.shoulder_max_abduction*PI/180.)))
00379     {
00380       
00381       solutions(1,4)=0./0.;
00382       solutions(1,5)=0./0.;
00383     }
00384     else
00385     {
00386       
00387       solutions(1,4)=t2_pos;
00388       solutions(1,5)=t2_pos;
00389     }
00390   }
00391   else
00392   {
00393     
00394     solutions(1,4)=0./0.;
00395     solutions(1,5)=0./0.;
00396   }
00397   
00398   t2_neg=-1. * asin(Y / ( L1 + L2 * cos(solutions(0,4))));
00399   if(!isnan(t2_neg))
00400   {
00401     
00402     if(fabs(t2_neg)<(double) 0.0034)
00403     {
00404       t2_pos=robot_joint_limits.shoulder_min_abduction;
00405     }
00406     else if(t2_neg<(((robot_joint_limits.shoulder_max_abduction+5.)*PI/180.)+0.0034) && t2_neg>(robot_joint_limits.shoulder_max_abduction*PI/180.))
00407     {
00408       t2_neg=robot_joint_limits.shoulder_max_abduction*PI/180.;
00409     }
00410     
00411     if(!(t2_neg>=robot_joint_limits.shoulder_min_abduction && t2_neg<=(robot_joint_limits.shoulder_max_abduction*PI/180.)))
00412     {
00413       
00414       solutions(1,6)=0./0.;
00415       solutions(1,7)=0./0.;
00416     }
00417     else
00418     {
00419       
00420       solutions(1,6)=t2_neg;
00421       solutions(1,7)=t2_neg;
00422     }
00423   }
00424   else
00425   {
00426     
00427     solutions(1,6)=0./0.;
00428     solutions(1,7)=0./0.;
00429   }
00430   
00431   for(i=0;i<8;i++)
00432   {
00433     k1=L2 * sin(solutions(0,i));
00434     k2=L1 * cos(solutions(1,i)) + L2 * cos(solutions(1,i)) * cos(solutions(0,i));
00435     k3=X;
00436     xx=k1 + k3;
00437     yy=k2 + sqrt(pow(k1,2.) + pow(k2,2.) - pow(k3,2.));
00438     t1_pos=2.*atan2(yy,xx);
00439     if(!isnan(t1_pos))
00440     {
00441       
00442       if(t1_pos<robot_joint_limits.shoulder_min_flexion*PI/180. && t1_pos>((robot_joint_limits.shoulder_min_flexion-5.)*PI/180.+0.0034))
00443       {
00444         t1_pos=robot_joint_limits.shoulder_min_flexion*PI/180.;
00445       }
00446       else if(t1_pos<(((robot_joint_limits.shoulder_max_flexion+5.)*PI/180.)+0.0034) && t1_pos>(robot_joint_limits.shoulder_max_flexion*PI/180.))
00447       {
00448         t1_pos=robot_joint_limits.shoulder_max_flexion*PI/180.;
00449       }
00450       
00451       if(!(t1_pos>=robot_joint_limits.shoulder_min_flexion*PI/180. && t1_pos<=robot_joint_limits.shoulder_max_flexion*PI/180.))
00452       {
00453         
00454         solutions(2,i)=0./0.;
00455       }
00456       else
00457       {
00458         
00459         solutions(2,i)=t1_pos;
00460       }
00461     }
00462     else
00463     {
00464       
00465       solutions(2,i)=0./0.;
00466     }
00467     i++;
00468   }
00469   
00470   for(i=1;i<8;i++)
00471   {
00472     k1=L2 * sin(solutions(0,i));
00473     k2=L1 * cos(solutions(1,i)) + L2 * cos(solutions(1,i)) * cos(solutions(0,i));
00474     k3=X;
00475     xx=k1 + k3;
00476     yy=k2 - sqrt(pow(k1,2.) + pow(k2,2.) - pow(k3,2.));
00477     t1_neg=2.*atan2(yy,xx);
00478     if(!isnan(t1_neg))
00479     {
00480       
00481       if(t1_neg<robot_joint_limits.shoulder_min_flexion*PI/180. && t1_neg>((robot_joint_limits.shoulder_min_flexion-5.)*PI/180.+0.0034))
00482       {
00483         t1_neg=robot_joint_limits.shoulder_min_flexion*PI/180.;
00484       }
00485       else if(t1_neg<(((robot_joint_limits.shoulder_max_flexion+5.)*PI/180.)+0.0034) && t1_neg>(robot_joint_limits.shoulder_max_flexion*PI/180.))
00486       {
00487         t1_neg=robot_joint_limits.shoulder_max_flexion*PI/180.;
00488       }
00489       
00490       if(!(t1_neg>=robot_joint_limits.shoulder_min_flexion*PI/180. && t1_neg<=robot_joint_limits.shoulder_max_flexion*PI/180.))
00491       {
00492         
00493         solutions(2,i)=0./0.;
00494       }
00495       else
00496       {
00497         
00498         solutions(2,i)=t1_neg;
00499       }
00500     }
00501     else
00502     {
00503       
00504       solutions(2,i)=0./0.;
00505     }
00506     i++;
00507   }
00508   
00509 
00510 
00511   
00512   
00513   req_angle[0] = 1000.;
00514   req_angle[1] = 1000.;
00515   req_angle[2] = 1000.;
00516   
00517   double theta1;
00518   double theta2;
00519   double theta3;
00520   
00521   
00522   if(Z<=0. && Y>=0.)
00523   {
00524     theta1=solutions(2,1);
00525     theta2=solutions(1,1);
00526     theta3=solutions(0,1);
00527     if(!isnan(theta1 * theta2 * theta3))
00528     {
00529       req_angle[0]=theta1*180./PI;
00530       req_angle[1]=theta2*180./PI;
00531       req_angle[2]=theta3*180./PI;
00532       return;
00533     }
00534   }
00535   else if(Z>=0. && Y>=0. && X>=0.)
00536   {
00537     theta1=solutions(2,0);
00538     theta2=solutions(1,0);
00539     theta3=solutions(0,0);
00540     if(!isnan(theta1 * theta2 * theta3))
00541     {
00542       req_angle[0]=theta1*180./PI;
00543       req_angle[1]=theta2*180./PI;
00544       req_angle[2]=theta3*180./PI;
00545       return;
00546     }
00547   }
00548   else
00549   {
00550     theta1=solutions(2,4);
00551     theta2=solutions(1,4);
00552     theta3=solutions(0,4);
00553     if(!isnan(theta1 * theta2 * theta3))
00554     {
00555       req_angle[0]=theta1*180./PI;
00556       req_angle[1]=theta2*180./PI;
00557       req_angle[2]=theta3*180./PI;
00558       return;
00559     }
00560 
00561 
00562   }
00563   
00564 }
00565 
00566 void humanoid::CalculateArmJacobian(double theta_1, double theta_2, double theta_3, Eigen::Matrix3d *jacobian)
00567 {
00568   
00569   double L1 = robot_dimensions.arm_length;
00570   double L2 = robot_dimensions.forearm_length;
00571   
00572   double theta1=theta_1*PI/180.;
00573   double theta2=theta_2*PI/180.;
00574   double theta3=theta_3*PI/180.;
00575   
00576   
00577   double dx_dtheta1 = cos(theta1) * (L1 * cos(theta2) + L2 * cos(theta2) * cos(theta3)) - L2 * sin(theta1) * sin(theta3);
00578   
00579   double dx_dtheta2 = -sin(theta2) * sin(theta1) * (L1 + L2 * cos(theta3));
00580   
00581   double dx_dtheta3 = L2 * (cos(theta3) * cos(theta1) - sin(theta3) * sin(theta1) * cos(theta2));
00582   
00583   double dy_dtheta1 = 0.;
00584   
00585   double dy_dtheta2 = cos(theta2) * (L1 + L2 * cos(theta3));
00586   
00587   double dy_dtheta3 = -L2 * sin(theta3) * sin(theta2);
00588   
00589   double dz_dtheta1 = L2 * cos(theta1) * sin(theta3) + sin(theta1) * cos(theta2) * (L1 + L2 * cos(theta3));
00590   
00591   double dz_dtheta2 = sin(theta2) * cos(theta1) * (L1 + L2 * cos(theta3));
00592   
00593   double dz_dtheta3 = L2 * (cos(theta3) * sin(theta1) + sin(theta3) * cos(theta1) * cos(theta2));
00594   
00595   
00596   Eigen::Matrix3d jacobian_temp;
00597   jacobian_temp << dx_dtheta1, dx_dtheta2, dx_dtheta3,
00598                    dy_dtheta1, dy_dtheta2, dy_dtheta3,
00599                    dz_dtheta1, dz_dtheta2, dz_dtheta3;
00600   
00601   memcpy(jacobian,&jacobian_temp,sizeof(jacobian_temp));
00602 }
00603 
00604 void humanoid::CalculateArmAlternateJacobian_No_Theta3_Singularity(double theta_1, double theta_2, double theta_3, Eigen::MatrixXd *jacobian)
00605 {
00606   
00607   double L1 = robot_dimensions.arm_length;
00608   double L2 = robot_dimensions.forearm_length;
00609   
00610   double theta1=theta_1*PI/180.;
00611   double theta2=theta_2*PI/180.;
00612   double theta3=theta_3*PI/180.;
00613   
00614   
00615   double dx_dtheta1 = cos(theta1) * (L1 * cos(theta2) + L2 * cos(theta2) * cos(theta3)) - L2 * sin(theta1) * sin(theta3);
00616   
00617   double dx_dtheta2 = -sin(theta2) * sin(theta1) * (L1 + L2 * cos(theta3));
00618   
00619   double dy_dtheta1 = 0.;
00620   
00621   double dy_dtheta2 = cos(theta2) * (L1 + L2 * cos(theta3));
00622   
00623   double dz_dtheta1 = L2 * cos(theta1) * sin(theta3) + sin(theta1) * cos(theta2) * (L1 + L2 * cos(theta3));
00624   
00625   double dz_dtheta2 = sin(theta2) * cos(theta1) * (L1 + L2 * cos(theta3));
00626   
00627   
00628   static Eigen::MatrixXd jacobian_temp(3,2);
00629   jacobian_temp << dx_dtheta1, dx_dtheta2,
00630                    dy_dtheta1, dy_dtheta2,
00631                    dz_dtheta1, dz_dtheta2;
00632   
00633   memcpy(jacobian,&jacobian_temp,sizeof(jacobian_temp));
00634 }
00635 
00636 void humanoid::Dir_Kin_4DOF_Detached_Leg(double t1, double t2, double t3, double t4, short int SIDE, double *end_pos_n_RPY)
00637 {
00638   
00639 
00640 
00641 
00642   
00643   double theta1 = (t1 * PI / 180.) * (double)SIDE;
00644   double theta2 = t2 * PI / 180.;
00645   double theta3 = t3 * PI / 180.;
00646   double theta4 = t4 * PI / 180.;
00647 
00648   end_pos_n_RPY[0] = sin(theta2) * ((robot_dimensions.shin_length) + (robot_dimensions.thigh_length) * cos(theta3)) -
00649                     (robot_dimensions.thigh_length) * cos(theta2) * sin(theta3); 
00650   
00651   end_pos_n_RPY[1] = (cos(theta2) * sin(theta1) * ((robot_dimensions.shin_length) + (robot_dimensions.thigh_length) * cos(theta3)) +
00652                     (robot_dimensions.thigh_length) * sin(theta1) * sin(theta2) * sin(theta3));
00653   
00654   end_pos_n_RPY[2] = (robot_dimensions.ankle_height) + cos(theta1) * cos(theta2) * ((robot_dimensions.shin_length) + (robot_dimensions.thigh_length) * cos(theta3)) +
00655                       (robot_dimensions.thigh_length) * cos(theta1) * sin(theta2) * sin(theta3); 
00656   
00657   end_pos_n_RPY[3] = asin(-(cos(theta4) * (cos(theta1) * sin(theta2) * sin(theta3) + cos(theta1) * cos(theta2) * cos(theta3)) - sin(theta1)*sin(theta4))) *
00658                                                                                                                                                             (180. / PI); 
00659                                                                                                                                                             
00660   end_pos_n_RPY[4] = atan2(cos(theta1) * sin(theta2) * cos(theta3) - cos(theta1) * cos(theta2) * cos(theta3),
00661                           cos(theta4) * sin(theta1) + sin(theta4) * (cos(theta1) * sin(theta2) * sin(theta3) + cos(theta1) * cos(theta2) * cos(theta3))) *
00662                                                                                                                                                             (180. / PI); 
00663                                                                                                                                                             
00664   end_pos_n_RPY[5] = atan2(sin(theta4) * cos(theta1) + cos(theta4) * (sin(theta1) * sin(theta2) * sin(theta3) + cos(theta2) * cos(theta3) * sin(theta1)),
00665                             -cos(theta4) * (sin(theta3) * cos(theta2) - sin(theta2) * cos(theta3))) *
00666                                                                                                       (180. / PI); 
00667 }
00668 
00669 void humanoid::Inv_Kin_3DOF_Detached_Leg(double X, double Y, double Z, double *req_angle)
00670 {
00671    
00672   double L1 = robot_dimensions.shin_length;
00673   double L2 = robot_dimensions.thigh_length;
00674   double z_clearance = robot_dimensions.ankle_height;
00675 
00676   
00677   
00678  
00679   double A,q1,q2,q3;
00680   double k1,k2,k3,kk_aux;
00681   
00682   
00683   
00684   q1 = atan2(Y,(Z - z_clearance));
00685   
00686   if((q1 > PI/4. && q1 < 3. * PI/4.) || (q1 <  - PI/4. && q1 >  - 3. * PI/4.))
00687       A = Y/sin(q1);
00688   else
00689       A =  - (Z - z_clearance)/cos(q1);
00690   
00691   
00692   k1 =  2. * L1 * X;
00693   k2 =  - 2. * L1 * A;
00694   k3 = pow(X,2.) + pow(A,2.) + pow(L1,2.) - pow(L2,2.);
00695   kk_aux = pow(k1,2.) + pow(k2,2.) - pow(k3,2.);
00696 
00697   if(kk_aux < 0.)
00698   {
00699     req_angle[0] = 1000.;
00700     req_angle[1] = 1000.;
00701     req_angle[2] = 1000.;
00702     return;
00703   }
00704   q2 = atan2(k1,k2) + atan2(sqrt(pow(k1,2.) + pow(k2,2.) - pow(k3,2.)), k3);
00705     
00706   
00707   if(q2 > PI)
00708     q2 = q2 - 2. * PI;
00709 
00710   if(q2 <  - PI)
00711     q2 = q2 + 2. * PI;
00712     
00713   
00714   k1 = 0.;
00715   k2 = 2. * L1 * L2;
00716   k3 = pow(X,2.) + pow(A,2.) - pow(L1,2.) - pow(L2,2.);
00717   kk_aux = pow(k2,2.) - pow(k3,2.);
00718 
00719   if(kk_aux < 0.)
00720   {
00721     req_angle[0] = 1000.;
00722     req_angle[1] = 1000.;
00723     req_angle[2] = 1000.;
00724     return;
00725   }
00726   q3 = atan2(sqrt(pow(k2,2.) - pow(k3,2.)), k3);
00727   
00728   
00729   
00730   if(!isnan(q1 * q2 * q3))
00731   {
00732     
00733 
00734 
00735 
00736 
00737 
00738     
00739     if(q1 >=(robot_joint_limits.ankle_min_inversion *PI/180.) && q1 <= (robot_joint_limits.ankle_max_inversion*PI/180.))
00740       req_angle[0]=q1*180./PI;
00741     else
00742       req_angle[0] = 1000.;
00743     
00744 
00745 
00746 
00747 
00748 
00749     
00750     if(q2 >=(robot_joint_limits.ankle_min_flexion *PI/180.) && q2 <= (robot_joint_limits.ankle_max_flexion*PI/180.))
00751       req_angle[1]=q2*180./PI;
00752     else
00753       req_angle[1] = 1000.;
00754     
00755 
00756 
00757 
00758 
00759 
00760     
00761     if(q3 >=robot_joint_limits.knee_min_flexion && q3 <= (robot_joint_limits.knee_max_flexion*PI/180.))
00762       req_angle[2]=q3*180./PI;
00763     else
00764       req_angle[2] = 1000.;
00765     
00766     
00767 
00768 
00769 
00770     
00771 
00772 
00773     return;
00774   }
00775   else
00776   {
00777     req_angle[0] = 1000.;
00778     req_angle[1] = 1000.;
00779     req_angle[2] = 1000.;
00780     return;
00781   }
00782 }
00783 
00784 void humanoid::Calculate_Detached_Leg_3DOF_Jacobian(double theta_1, double theta_2, double theta_3, Eigen::Matrix3d *jacobian)
00785 {
00786    
00787   double L1 = robot_dimensions.shin_length;
00788   double L2 = robot_dimensions.thigh_length;
00789   
00790   double theta1=theta_1*PI/180.;
00791   double theta2=theta_2*PI/180.;
00792   double theta3=theta_3*PI/180.;
00793   
00794   
00795   Eigen::Matrix3d jacobian_temp;
00796   
00797   jacobian_temp << 0., L1*cos(theta2)+L2*cos(theta2+theta3), L2*cos(theta2+theta3),
00798   
00799                    -L1*cos(theta1)*cos(theta2)-L2*cos(theta1)*cos(theta2+theta3), L1*sin(theta1)*sin(theta2)+L2*sin(theta1)*sin(theta2+theta3), L2*sin(theta1)*sin(theta2+theta3),
00800                    
00801                    -L1*sin(theta1)*cos(theta2)-L2*sin(theta1)*cos(theta2+theta3), -L1*cos(theta1)*sin(theta2)-L2*cos(theta1)*sin(theta2+theta3), -L2*cos(theta1)*sin(theta2+theta3);
00802                    
00803   
00804   memcpy(jacobian,&jacobian_temp,sizeof(jacobian_temp));
00805 }
00806 
00807 void humanoid::Calculate_Detached_Leg_3DOF_COG(double theta_1, double theta_2, double theta_3, int SIDE, Eigen::Vector3d *COG)
00808 {
00809   static Eigen::Vector3d COM_shin;
00810   static Eigen::Vector3d COM_thigh;
00811   static Eigen::Vector3d leg_COG;
00812   static double cog_x;
00813   static double cog_y;
00814   static double cog_z;
00815   
00816   
00817   double L1 = robot_dimensions.shin_length;
00818   double theta1 = theta_1*PI/180.;
00819   double theta2 = theta_2*PI/180.;
00820   double theta3 = theta_3*PI/180.;
00821   
00822   
00823   if(SIDE == LEFT)
00824   {
00825     
00826     cog_x = robot_relative_COM.shin_COM[0];
00827     cog_y = robot_relative_COM.shin_COM[1];
00828     cog_z = robot_relative_COM.shin_COM[2];
00829     
00830     COM_shin = Eigen::Vector3d(cog_x*cos(theta2) + cog_z*sin(theta2),
00831                               cog_x*sin(theta1)*sin(theta2) + cog_y*cos(theta1) - cog_z*sin(theta1)*cos(theta2),
00832                               -cog_x*cos(theta1)*sin(theta2) + cog_y*sin(theta1) + cog_z*cos(theta1)*cos(theta2) + robot_dimensions.ankle_height);
00833     
00834     
00835     cog_x = robot_relative_COM.thigh_COM[0];
00836     cog_y = robot_relative_COM.thigh_COM[1];
00837     cog_z = robot_relative_COM.thigh_COM[2];
00838     
00839     COM_thigh = Eigen::Vector3d(cog_x*(cos(theta2)*cos(theta3)+sin(theta2)*sin(theta3)) - cog_z*(cos(theta2)*sin(theta3) - sin(theta2)*cos(theta3)) + L1*sin(theta2),
00840                                               
00841                                 cog_x*sin(theta1)*(cos(theta2)*sin(theta3) - sin(theta2)*cos(theta3)) + cog_y*cos(theta1) + (cog_z*(cos(theta2)*cos(theta3) + sin(theta2)*sin(theta3)) + L1*cos(theta2))*sin(theta1),
00842                                               
00843                                 cog_x*cos(theta1)*(cos(theta2)*sin(theta3) - sin(theta2)*cos(theta3)) - cog_y*sin(theta1) + cog_z*cos(theta1)*(cos(theta2)*cos(theta3) + sin(theta2)*sin(theta3)) + L1*cos(theta1)*cos(theta2) + robot_dimensions.ankle_height);
00844     
00845     
00846     leg_COG = (1./(robot_element_mass.foot_mass + robot_element_mass.shin_mass + robot_element_mass.thigh_mass)) *
00847               ((robot_element_mass.foot_mass)*robot_relative_COM.foot_COM + (robot_element_mass.shin_mass)*COM_shin + (robot_element_mass.thigh_mass)*COM_thigh);
00848     
00849     
00850     memcpy( COG, &leg_COG, sizeof(leg_COG));
00851     return;
00852   }
00853   else if(SIDE == RIGHT)
00854   {
00855     
00856     Eigen::Vector3d COM_foot = Eigen::Vector3d(robot_relative_COM.foot_COM[0],robot_relative_COM.foot_COM[1],robot_relative_COM.foot_COM[2]);
00857     
00858     
00859     cog_x = robot_relative_COM.shin_COM[0];
00860     cog_y = robot_relative_COM.shin_COM[1];
00861     cog_z = robot_relative_COM.shin_COM[2];
00862     
00863     COM_shin = Eigen::Vector3d(cog_x*cos(theta2) + cog_z*sin(theta2),
00864                               cog_x*sin(theta1)*sin(theta2) + cog_y*cos(theta1) - cog_z*sin(theta1)*cos(theta2),
00865                               -cog_x*cos(theta1)*sin(theta2) + cog_y*sin(theta1) + cog_z*cos(theta1)*cos(theta2) + robot_dimensions.ankle_height);
00866     
00867     
00868     cog_x = robot_relative_COM.thigh_COM[0];
00869     cog_y = robot_relative_COM.thigh_COM[1];
00870     cog_z = robot_relative_COM.thigh_COM[2];
00871     
00872     COM_thigh = Eigen::Vector3d(cog_x*(cos(theta2)*cos(theta3)+sin(theta2)*sin(theta3)) - cog_z*(cos(theta2)*sin(theta3) - sin(theta2)*cos(theta3)) + L1*sin(theta2),
00873                                               
00874                                 cog_x*sin(theta1)*(cos(theta2)*sin(theta3) - sin(theta2)*cos(theta3)) + cog_y*cos(theta1) + (cog_z*(cos(theta2)*cos(theta3) + sin(theta2)*sin(theta3)) + L1*cos(theta2))*sin(theta1),
00875                                               
00876                                 cog_x*cos(theta1)*(cos(theta2)*sin(theta3) - sin(theta2)*cos(theta3)) - cog_y*sin(theta1) + cog_z*cos(theta1)*(cos(theta2)*cos(theta3) + sin(theta2)*sin(theta3)) + L1*cos(theta1)*cos(theta2) + robot_dimensions.ankle_height);
00877 
00878     
00879     leg_COG = (1./(robot_element_mass.foot_mass + robot_element_mass.shin_mass + robot_element_mass.thigh_mass)) *
00880               ((robot_element_mass.foot_mass)*COM_foot + (robot_element_mass.shin_mass)*COM_shin + (robot_element_mass.thigh_mass)*COM_thigh);
00881     
00882     
00883     memcpy( COG, &leg_COG, sizeof(leg_COG));
00884     return;
00885   }
00886   else
00887   {
00888     return;
00889   }
00890 }
00891 
00892 short unsigned int humanoid::Head_Pan_Tilt_Conversion(double joint_angle)
00893 {
00894   
00895   
00896   
00897   
00898   if(joint_angle<robot_joint_limits.head_min_tilt || joint_angle>robot_joint_limits.head_max_tilt)
00899   {
00900     return 0;
00901   }
00902   
00903   
00904   return (robot_servo_conversion.head_servo_offset-(joint_angle*10.));
00905 }
00906 
00907 short unsigned int humanoid::Shoulder_Flexion_Extension_Conversion(short int SIDE, double joint_angle)
00908 {
00909   
00910   if(joint_angle<robot_joint_limits.shoulder_min_flexion || joint_angle>robot_joint_limits.shoulder_max_flexion)
00911   {
00912     return 0;
00913   }
00914   
00915   double offset;
00916   double sign;
00917   if(SIDE==LEFT)
00918   {
00919     
00920     
00921     
00922     offset=robot_servo_conversion.shoulder_flexion_servo_offset_left;
00923     sign=(double) LEFT;
00924   }
00925   else if(SIDE==RIGHT)
00926   {
00927     
00928     
00929     
00930     offset=robot_servo_conversion.shoulder_flexion_servo_offset_right;
00931     sign=(double) RIGHT;
00932   }
00933   else
00934   {
00935     return 0;
00936   }
00937   
00938   
00939   return (offset+sign*joint_angle*10.);
00940 }
00941 
00942 short unsigned int humanoid::Shoulder_Abduction_Adduction_Conversion(short int SIDE, double joint_angle)
00943 {
00944   double offset;
00945   double sign;
00946   if(SIDE==LEFT)
00947   {
00948     
00949     
00950     
00951     offset=robot_servo_conversion.shoulder_abduction_servo_offset_left;
00952     sign=(double) LEFT;
00953   }
00954   else if(SIDE==RIGHT)
00955   {
00956     
00957     
00958     
00959     offset=robot_servo_conversion.shoulder_abduction_servo_offset_right;
00960     sign=(double) RIGHT;
00961   }
00962   else
00963   {
00964     return 0;
00965   }
00966 
00967     
00968   if(joint_angle<robot_joint_limits.shoulder_min_abduction || joint_angle>robot_joint_limits.shoulder_max_abduction)
00969   {
00970     return 0;
00971   }
00972   
00973   
00974   return (offset+sign*joint_angle*10.);
00975 }
00976 
00977 short unsigned int humanoid::Elbow_Flexion_Extension_Conversion(short int SIDE, double joint_angle)
00978 {
00979   double offset;
00980   double sign;
00981   if(SIDE==LEFT)
00982   {
00983     
00984     
00985     
00986     offset=robot_servo_conversion.elbow_flexion_servo_offset_left;
00987     sign=(double) RIGHT; 
00988   }
00989   else if(SIDE==RIGHT)
00990   {
00991     
00992     
00993     
00994     offset=robot_servo_conversion.elbow_flexion_servo_offset_right;
00995     sign=(double) LEFT; 
00996   }
00997   else
00998   {
00999     return 0;
01000   }
01001     
01002     
01003   if(joint_angle<robot_joint_limits.elbow_min_flexion || joint_angle>robot_joint_limits.elbow_max_flexion)
01004   {
01005     return 0;
01006   }
01007   
01008   
01009   return (offset+sign*joint_angle*10.);
01010 }
01011 
01012 short unsigned int humanoid::Torso_Rotation_Conversion(double joint_angle)
01013 {
01014   
01015   
01016   
01017     
01018   if(joint_angle<robot_joint_limits.torso_min_rotation || joint_angle>robot_joint_limits.torso_max_rotation)
01019     return 0;
01020   
01021   
01022   return (robot_servo_conversion.torso_rotation_servo_offset+joint_angle*10.);
01023 }
01024 
01025 short unsigned int humanoid::Torso_Flexion_Extension_Conversion(double joint_angle)
01026 {
01027   
01028   
01029   
01030     
01031   if(joint_angle<robot_joint_limits.torso_min_flexion || joint_angle>robot_joint_limits.torso_max_flexion)
01032     return 0;
01033   
01034   
01035   return (robot_servo_conversion.torso_flexion_servo_offset+joint_angle*10.);
01036 }
01037 
01038 
01039 short unsigned int humanoid::Torso_Lateral_Flexion_Extension_Conversion(double joint_angle)
01040 {
01041   
01042   
01043   
01044     
01045   if(joint_angle<robot_joint_limits.torso_min_lateral_flexion || joint_angle>robot_joint_limits.torso_max_lateral_flexion)
01046     return 0;
01047   
01048   
01049   return (robot_servo_conversion.torso_lateral_flexion_servo_offset+joint_angle*10.);
01050 }
01051         
01052 short unsigned int humanoid::Ankle_Inversion_Eversion_Conversion(short int SIDE, double joint_angle)
01053 {
01054   
01055   
01056   if(joint_angle<robot_joint_limits.ankle_min_inversion || joint_angle>robot_joint_limits.ankle_max_inversion)
01057     return 0;
01058   
01059   double sign;
01060   if(SIDE==LEFT)
01061   {
01062     
01063     
01064     sign=(double) LEFT;
01065   }
01066   else if(SIDE==RIGHT)
01067   {
01068     
01069     
01070     sign=(double) RIGHT;
01071   }
01072   else
01073   {
01074     return 0;
01075   }
01076   
01077   double b=1500.;
01078   
01079   if(joint_angle==0)
01080     return 1500;
01081   else if(joint_angle<0)
01082   {
01083     double m=(1500.-600.)/(-robot_joint_limits.ankle_min_inversion);
01084     return round(sign*(m*joint_angle)+b);
01085   }
01086   else
01087   {
01088     double m=(2400.-1500.)/(robot_joint_limits.ankle_max_inversion);
01089     return round(sign*(m*joint_angle)+b);
01090   }
01091 }
01092 
01093 short unsigned int humanoid::Ankle_Flexion_Conversion(short int SIDE, double joint_angle)
01094 {
01095   
01096   if(joint_angle<robot_joint_limits.ankle_min_flexion || joint_angle>robot_joint_limits.ankle_max_flexion)
01097     return 0;
01098   
01099   double sign;
01100   if(SIDE==LEFT)
01101   {
01102     
01103     
01104     
01105     sign=(double) LEFT;
01106   }
01107   else if(SIDE==RIGHT)
01108   {
01109     
01110     
01111     
01112     sign=(double) RIGHT;
01113   }
01114   else
01115     return 0;
01116   
01117   double b=1500.;
01118   if(joint_angle==0)
01119     return 1500;
01120   else if(joint_angle<0)
01121   {
01122     
01123     double m=(1500.-600.)/(-robot_joint_limits.ankle_min_flexion);
01124     return round(sign*(m*joint_angle)+b);
01125   }
01126   else
01127   {
01128     
01129     double m=(2400.-1500.)/(robot_joint_limits.ankle_max_flexion);
01130     return round(sign*(m*joint_angle)+b);
01131   }
01132 }
01133 
01134 short unsigned int humanoid::Knee_Conversion(short int SIDE, double joint_angle)
01135 {
01136   
01137   if(joint_angle<robot_joint_limits.knee_min_flexion || joint_angle>robot_joint_limits.knee_max_flexion)
01138     return 0;
01139   
01140 
01141 
01142 
01143   
01144   double sign;
01145   double b;
01146   if(SIDE==LEFT)
01147   {
01148     
01149     
01150     
01151     b=robot_servo_conversion.knee_flexion_b_value_left;
01152     sign=(double) LEFT;
01153   }
01154   else if(SIDE==RIGHT)
01155   {
01156     
01157     
01158     
01159     b=robot_servo_conversion.knee_flexion_b_value_right;
01160     sign=(double) RIGHT;
01161   }
01162   else
01163     return 0;
01164   
01165   
01166   double m=sign*(2400.-600.)/(robot_joint_limits.knee_max_flexion-robot_joint_limits.knee_min_flexion);
01167   return round((m*joint_angle)+b);
01168 }
01169 
01170 short unsigned int humanoid::Hip_Abduction_Hiperabduction_Conversion(short int SIDE, double joint_angle)
01171 {
01172   
01173   
01174   
01175   
01176   if(joint_angle<robot_joint_limits.hip_min_abduction || joint_angle>robot_joint_limits.hip_max_abduction)
01177     return 0;
01178   
01179   double sign;
01180   if(SIDE==LEFT)
01181   {
01182     
01183     
01184     
01185     sign=(double) RIGHT;
01186   }
01187   else if(SIDE==RIGHT)
01188   {
01189     
01190     
01191     
01192     sign=(double) LEFT;
01193   }
01194   else
01195     return 0;
01196   
01197   double b=1500.;
01198   
01199   if(joint_angle==0)
01200     return 1500;
01201   else if(joint_angle<0)
01202   {
01203     double m=900./(-robot_joint_limits.hip_min_abduction);
01204     return round(sign*(m*joint_angle)+b);
01205   }
01206   else
01207   {
01208     double m=900./(robot_joint_limits.hip_max_abduction);
01209     return round(sign*(m*joint_angle)+b);
01210   }
01211 }
01212 
01213 short unsigned int humanoid::Hip_Flexion_Conversion(short int SIDE, double joint_angle)
01214 {
01215   
01216   
01217   
01218   
01219   if(joint_angle<robot_joint_limits.hip_min_flexion || joint_angle>robot_joint_limits.hip_max_flexion)
01220     return 0;
01221   
01222   double sign;
01223   double offset;
01224   if(SIDE==LEFT)
01225   {
01226     
01227     
01228     
01229     offset=robot_servo_conversion.hip_flexion_b_value_left;
01230     sign=(double) LEFT;
01231   }
01232   else if(SIDE==RIGHT)
01233   {
01234     
01235     
01236     
01237     offset=robot_servo_conversion.hip_flexion_b_value_right;
01238     sign=(double) RIGHT;
01239   }
01240   else
01241     return 0;
01242   
01243   
01244   return offset+sign*joint_angle*10.;
01245 }
01246 
01247 double humanoid::Head_Pan_Tilt_ServoValue_Conversion(short unsigned int servo_value)
01248 {
01249   
01250   
01251   
01252   
01253     if(servo_value<2306 || servo_value>2406)
01254   {
01255     return 0xFFFF;
01256   }
01257   
01258   
01259   return (2400.-(double)servo_value)/10.;
01260 }
01261 
01262 double humanoid::Shoulder_Flexion_Extension_ServoValue_Conversion(short int SIDE, short unsigned int servo_value)
01263 {
01264   if(servo_value<595 || servo_value>2405)
01265   {
01266     return 0xFFFF;
01267   }
01268   double offset;
01269   double sign;
01270   if(SIDE==LEFT)
01271   {
01272     
01273     
01274     
01275       
01276     offset=robot_servo_conversion.shoulder_flexion_servo_offset_left;
01277     sign=(double) LEFT;
01278   }
01279   else if(SIDE==RIGHT)
01280   {
01281     
01282     
01283     
01284     offset=robot_servo_conversion.shoulder_flexion_servo_offset_right;
01285     sign=(double) RIGHT;
01286   }
01287   else
01288   {
01289     return 0xFFFF;
01290   }
01291   
01292   
01293   return sign*((double)servo_value-offset)/10.;
01294 }
01295 
01296 double humanoid::Shoulder_Abduction_Adduction_ServoValue_Conversion(short int SIDE, short unsigned int servo_value)
01297 {
01298   if(servo_value<595 || servo_value>2405)
01299   {
01300     return 0xFFFF;
01301   } 
01302   double offset;
01303   double sign;
01304   if(SIDE==LEFT)
01305   {
01306     
01307     
01308     
01309     offset=robot_servo_conversion.shoulder_abduction_servo_offset_left;
01310     sign=(double) LEFT;
01311   }
01312   else if(SIDE==RIGHT)
01313   {
01314     
01315     
01316     
01317     offset=robot_servo_conversion.shoulder_abduction_servo_offset_right;
01318     sign=(double) RIGHT;
01319   }
01320   else
01321   {
01322     return 0xFFFF;
01323   }
01324   
01325   
01326   return sign*((double)servo_value-offset)/10.;
01327 }
01328 
01329 double humanoid::Elbow_Flexion_Extension_ServoValue_Conversion(short int SIDE, short unsigned int servo_value)
01330 {
01331   if(servo_value<595 || servo_value>2405)
01332   {
01333     return 0xFFFF;
01334   }
01335   double offset;
01336   double sign;
01337   if(SIDE==LEFT)
01338   {
01339     
01340     
01341     
01342     offset=robot_servo_conversion.elbow_flexion_servo_offset_left;
01343     sign=(double) RIGHT; 
01344   }
01345   else if(SIDE==RIGHT)
01346   {
01347     
01348     
01349     
01350     offset=robot_servo_conversion.elbow_flexion_servo_offset_right;
01351     sign=(double) LEFT; 
01352   }
01353   else
01354   {
01355     return 0xFFFF;
01356   }
01357   
01358   
01359   return sign*((double)servo_value-offset)/10.;
01360 }
01361 
01362 double humanoid::Torso_Rotation_ServoValue_Conversion(short unsigned int servo_value)
01363 {
01364   if(servo_value<595 || servo_value>2405)
01365   {
01366     return 0xFFFF;
01367   }
01368   
01369   
01370   
01371   
01372   return ((double)servo_value-robot_servo_conversion.torso_rotation_servo_offset)/10.;
01373 }
01374 
01375 double humanoid::Torso_Flexion_Extension_ServoValue_Conversion(short unsigned int servo_value)
01376 {
01377   if(servo_value<595 || servo_value>2405)
01378   {
01379     return 0xFFFF;
01380   }
01381   
01382   
01383   
01384   
01385   return ((double)servo_value-robot_servo_conversion.torso_flexion_servo_offset)/10.;
01386 }
01387 
01388 double humanoid::Torso_Lateral_Flexion_Extension_ServoValue_Conversion(short unsigned int servo_value)
01389 {
01390   if(servo_value<595 || servo_value>2405)
01391   {
01392     return 0xFFFF;
01393   }
01394   
01395   
01396   
01397   
01398   return ((double)servo_value-robot_servo_conversion.torso_lateral_flexion_servo_offset)/10.;
01399 }
01400 
01401 double humanoid::Ankle_Inversion_Eversion_ServoValue_Conversion(short int SIDE, short unsigned int servo_value)
01402 {
01403   
01404     if(servo_value<595 || servo_value>2405)
01405   {
01406     return 0xFFFF;
01407   }
01408   
01409   
01410   if(servo_value==1500)
01411     return 0.;
01412   
01413   if(SIDE==RIGHT)
01414   {
01415     
01416     
01417     if(servo_value<1500)
01418     {
01419       return servo_value*(robot_joint_limits.ankle_max_inversion/-900.)-(robot_joint_limits.ankle_max_inversion/-900.)*1500.;
01420     }
01421     else
01422     {
01423       return servo_value*(robot_joint_limits.ankle_min_inversion/900.)-(robot_joint_limits.ankle_min_inversion/900.)*1500.;
01424     }
01425   }
01426   else if(SIDE==LEFT)
01427   {
01428     if(servo_value<1500)
01429     {
01430       return servo_value*(robot_joint_limits.ankle_min_inversion/-900.)-(robot_joint_limits.ankle_min_inversion/-900.)*1500.;
01431     }
01432     else
01433     {
01434       return servo_value*(robot_joint_limits.ankle_max_inversion/900.)-(robot_joint_limits.ankle_max_inversion/900.)*1500.;
01435     }
01436   }
01437   else
01438   {
01439     return 0xFFFF;
01440   }
01441 }
01442     
01443 double humanoid::Ankle_Flexion_ServoValue_Conversion(short int SIDE, short unsigned int servo_value)
01444 {
01445   
01446     if(servo_value<595 || servo_value>2405)
01447   {
01448     return 0xFFFF;
01449   }
01450   
01451   
01452   if(servo_value==1500)
01453     return 0.;
01454   
01455   if(SIDE==RIGHT)
01456   {
01457     
01458     
01459     if(servo_value<1500)
01460     {
01461       return (double)servo_value*(robot_joint_limits.ankle_max_flexion/-900.)-(robot_joint_limits.ankle_max_flexion/-900.)*1500.;
01462     }
01463     else
01464     {
01465       return (double)servo_value*(robot_joint_limits.ankle_min_flexion/900.)-(robot_joint_limits.ankle_min_flexion/900.)*1500.;
01466     }
01467   }
01468   else if(SIDE==LEFT)
01469   {
01470     if(servo_value<1500)
01471     {
01472       return (double)servo_value*(robot_joint_limits.ankle_min_flexion/-900.)-(robot_joint_limits.ankle_min_flexion/-900.)*1500.;
01473     }
01474     else
01475     {
01476       return (double)servo_value*(robot_joint_limits.ankle_max_flexion/900.)-(robot_joint_limits.ankle_max_flexion/900.)*1500.;
01477     }
01478   }
01479   else
01480   {
01481     return 0xFFFF;
01482   }
01483 }
01484 
01485 double humanoid::Knee_Flexion_ServoValue_Conversion(short int SIDE, short unsigned int servo_value)
01486 {
01487   
01488     if(servo_value<595 || servo_value>2405)
01489   {
01490     return 0xFFFF;
01491   }
01492   
01493   double sign;
01494   if(SIDE==LEFT)
01495   {
01496     
01497     
01498     
01499     sign=(double) LEFT;
01500     return ((double)servo_value-robot_servo_conversion.knee_flexion_b_value_left)/(sign*(2400.-600.)/(robot_joint_limits.knee_max_flexion-robot_joint_limits.knee_min_flexion));
01501   }
01502   else if(SIDE==RIGHT)
01503   {
01504     
01505     
01506     
01507     sign=(double) RIGHT;
01508     return ((double)servo_value-robot_servo_conversion.knee_flexion_b_value_right)/(sign*(2400.-600.)/(robot_joint_limits.knee_max_flexion-robot_joint_limits.knee_min_flexion));
01509   }
01510   else
01511     return 0xFFFF;
01512 }
01513 
01514 double humanoid::Hip_Abduction_Hiperabduction_ServoValue_Conversion(short int SIDE, short unsigned int servo_value)
01515 {
01516   
01517   if(servo_value<595 || servo_value>2405)
01518   {
01519     return 0xFFFF;
01520   }
01521   
01522   if(servo_value==1500)
01523     return 0.;
01524   
01525   double sign;
01526   if(SIDE==LEFT)
01527   {
01528     
01529     
01530     
01531     sign=(double) RIGHT;
01532     if(servo_value<1500)
01533     {
01534       double m=900./(-robot_joint_limits.hip_min_abduction);
01535       return ((double)servo_value-1500.)/(sign*m);
01536     }
01537     else
01538     {
01539       double m=900./(robot_joint_limits.hip_max_abduction);
01540       return ((double)servo_value-1500.)/(sign*m);
01541     }
01542   }
01543   else if(SIDE==RIGHT)
01544   {
01545     
01546     
01547     
01548     sign=(double) LEFT;
01549     if(servo_value<1500)
01550     {
01551       double m=900./(-robot_joint_limits.hip_min_abduction);
01552       return ((double)servo_value-1500.)/(sign*m);
01553     }
01554     else
01555     {
01556       double m=900./(robot_joint_limits.hip_max_abduction);
01557       return ((double)servo_value-1500.)/(sign*m);
01558     }
01559   }
01560   else
01561     return 0xFFFF;
01562 }
01563     
01564 double humanoid::Hip_Flexion_ServoValue_Conversion(short int SIDE, short unsigned int servo_value)
01565 {
01566   
01567   if(servo_value<595 || servo_value>2405)
01568   {
01569     return 0xFFFF;
01570   }
01571   
01572   double sign;
01573   double offset;
01574   if(SIDE==LEFT)
01575   {
01576     
01577     
01578     
01579     offset=robot_servo_conversion.hip_flexion_b_value_left;
01580     sign=(double) LEFT;
01581     if(servo_value==offset)
01582       return 0.;
01583   }
01584   else if(SIDE==RIGHT)
01585   {
01586     
01587     
01588     
01589     offset=robot_servo_conversion.hip_flexion_b_value_right;
01590     sign=(double) RIGHT;
01591     if(servo_value==offset)
01592       return 0.;
01593   }
01594   else
01595     return 0xFFFF;
01596   
01597   
01598   return sign*((double)servo_value-offset)/10.;
01599 }
01600 
01601 
01602 
01603 
01604 double humanoid::GetRobotDimension(int dimension)
01605 {
01606   switch (dimension)
01607   {
01608     case ARM_LENGTH:
01609       return robot_dimensions.arm_length;
01610     case FOREARM_LENGTH:
01611       return robot_dimensions.forearm_length;
01612     case LEG_LENGTH:
01613       return robot_dimensions.shin_length;
01614     case THIGH_LENGTH:
01615       return robot_dimensions.thigh_length;
01616     case FOOT_LENGTH:
01617       return robot_dimensions.foot_length;
01618     case ANKLE_HEIGHT:
01619       return robot_dimensions.ankle_height;
01620     case FOOT_WIDTH:
01621       return robot_dimensions.foot_width;
01622     default:
01623       return FP_NAN;
01624   }
01625 }
01626 
01627 
01628 
01629