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
00027
00028
00029
00030 #include <xpp_hyq/hyqleg_inverse_kinematics.h>
00031
00032 #include <cmath>
00033 #include <map>
00034
00035 #include <xpp_states/cartesian_declarations.h>
00036
00037
00038 namespace xpp {
00039
00040
00041 HyqlegInverseKinematics::Vector3d
00042 HyqlegInverseKinematics::GetJointAngles (const Vector3d& ee_pos_B, KneeBend bend) const
00043 {
00044 double q_HAA_bf, q_HAA_br, q_HFE_br;
00045 double q_HFE_bf, q_KFE_br, q_KFE_bf;
00046
00047 Eigen::Vector3d xr;
00048 Eigen::Matrix3d R;
00049
00050
00051
00052
00053 xr = ee_pos_B;
00054
00055
00056 q_HAA_bf = q_HAA_br = -atan2(xr[Y],-xr[Z]);
00057
00058
00059 R << 1.0, 0.0, 0.0, 0.0, cos(q_HAA_bf), -sin(q_HAA_bf), 0.0, sin(q_HAA_bf), cos(q_HAA_bf);
00060
00061 xr = (R * xr).eval();
00062
00063
00064 xr += hfe_to_haa_z;
00065
00066
00067 double tmp1 = pow(xr[X],2)+pow(xr[Z],2);
00068
00069
00070
00071 double lu = length_thigh;
00072 double ll = length_shank;
00073 double alpha = atan2(-xr[Z],xr[X]) - 0.5*M_PI;
00074
00075
00076 double some_random_value_for_beta = (pow(lu,2)+tmp1-pow(ll,2))/(2.*lu*sqrt(tmp1));
00077 if (some_random_value_for_beta > 1) {
00078 some_random_value_for_beta = 1;
00079 }
00080 if (some_random_value_for_beta < -1) {
00081 some_random_value_for_beta = -1;
00082 }
00083 double beta = acos(some_random_value_for_beta);
00084
00085
00086 q_HFE_bf = q_HFE_br = alpha + beta;
00087
00088
00089 double some_random_value_for_gamma = (pow(ll,2)+pow(lu,2)-tmp1)/(2.*ll*lu);
00090
00091 if (some_random_value_for_gamma > 1) {
00092 some_random_value_for_gamma = 1;
00093 }
00094 if (some_random_value_for_gamma < -1) {
00095 some_random_value_for_gamma = -1;
00096 }
00097 double gamma = acos(some_random_value_for_gamma);
00098
00099
00100 q_KFE_bf = q_KFE_br = gamma - M_PI;
00101
00102
00103 EnforceLimits(q_HAA_bf, HAA);
00104 EnforceLimits(q_HFE_bf, HFE);
00105 EnforceLimits(q_KFE_bf, KFE);
00106
00107
00108 EnforceLimits(q_HAA_br, HAA);
00109 EnforceLimits(q_HFE_br, HFE);
00110 EnforceLimits(q_KFE_br, KFE);
00111
00112 if (bend==Forward)
00113 return Vector3d(q_HAA_bf, q_HFE_bf, q_KFE_bf);
00114 else
00115 return Vector3d(q_HAA_br, -q_HFE_br, -q_KFE_br);
00116 }
00117
00118 void
00119 HyqlegInverseKinematics::EnforceLimits (double& val, HyqJointID joint) const
00120 {
00121
00122 const static double haa_min = -180;
00123 const static double haa_max = 90;
00124
00125 const static double hfe_min = -90;
00126 const static double hfe_max = 90;
00127
00128 const static double kfe_min = -180;
00129 const static double kfe_max = 0;
00130
00131
00132 static const std::map<HyqJointID, double> max_range {
00133 {HAA, haa_max/180.0*M_PI},
00134 {HFE, hfe_max/180.0*M_PI},
00135 {KFE, kfe_max/180.0*M_PI}
00136 };
00137
00138
00139 static const std::map<HyqJointID, double> min_range {
00140 {HAA, haa_min/180.0*M_PI},
00141 {HFE, hfe_min/180.0*M_PI},
00142 {KFE, kfe_min/180.0*M_PI}
00143 };
00144
00145 double max = max_range.at(joint);
00146 val = val>max? max : val;
00147
00148 double min = min_range.at(joint);
00149 val = val<min? min : val;
00150 }
00151
00152 }