00001
00002
00003 #include "kuka_ikac.h"
00004 using namespace Eigen;
00005 using namespace std;
00006
00007 KukaIKAC::KukaIKAC() {
00008
00009
00010
00011 this->currentjoints_.resize(7);
00012
00013
00014 std::string port_name;
00015
00016
00017 port_name = ros::names::append(ros::this_node::getName(), "ikjoints");
00018 this->ik_joints_publisher_ = this->nh_.advertise<sensor_msgs::JointState>(port_name, 5);
00019 this->ik_joints_msg.position.resize(7);
00020
00021
00022 port_name = ros::names::append(ros::this_node::getName(), "joint_states");
00023 this->joint_states_subscriber = this->nh_.subscribe(port_name, 5, &KukaIKAC::joint_states_callback, this);
00024
00025
00026 port_name = ros::names::append(ros::this_node::getName(), "wamik");
00027 this->kukaik_server = this->nh_.advertiseService(port_name, &KukaIKAC::kukaikCallback, this);
00028
00029 port_name = ros::names::append(ros::this_node::getName(), "wamik_from_pose");
00030 this->kukaik_server_fromPose = this->nh_.advertiseService(port_name, &KukaIKAC::kukaikCallbackFromPose, this);
00031
00032
00033 port_name = ros::names::append(ros::this_node::getName(), "joints_move");
00034 joint_move_client = this->nh_.serviceClient<iri_wam_common_msgs::joints_move>(port_name);
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 double PI=3.14159265;
00046
00047 d1=0.3100;
00048 d3=0.4000;
00049 d5=0.3900;
00050 d7=0.0785;
00051
00052
00053 checksol_=1;
00054
00055
00056 DHparam_.resize(7,3);
00057 DHparam_ << 0.0, PI/2.0, d1,
00058 0.0, -PI/2.0, 0.0,
00059 0.0, -PI/2.0, d3,
00060 0.0, PI/2.0, 0.0,
00061 0.0, PI/2.0, d5,
00062 0.0, -PI/2.0, 0.0,
00063 0.0, 0.0, d7;
00064
00065
00066 Qlim_.resize(7,2);
00067 Qlim_ << -2.97, 2.97,
00068 -0.47, 3.49,
00069 -2.97, 2.97,
00070 -2.09, 2.09,
00071 -2.97, 2.97,
00072 -2.09, 2.09,
00073 -2.97, 2.97;
00074
00075
00076 step_ = 0.0005;
00077
00078
00079
00080 IMAX_ = 100;
00081
00082 }
00083
00084 void KukaIKAC::ikPub(void)
00085 {
00086 for (int i=0;i<7;i++){
00087 this->ik_joints_msg.position[i]=joints_(i);
00088 }
00089 this->ik_joints_publisher_.publish(this->ik_joints_msg);
00090 }
00091
00092
00093 void KukaIKAC::joint_states_callback(const sensor_msgs::JointState::ConstPtr& msg) {
00094
00095 for(int i=0;i<7;i++)
00096 currentjoints_[i] = msg->position[i];
00097
00098 }
00099
00100
00101 bool KukaIKAC::kukaikCallbackFromPose(iri_wam_common_msgs::wamInverseKinematicsFromPose::Request &req, iri_wam_common_msgs::wamInverseKinematicsFromPose::Response &res){
00102
00103 ROS_INFO("[KukaIKAC] User Given Current Joints %s (j1, j2, j3, j4, j5, j6, j7): [ %f, %f, %f, %f, %f, %f, %f ]",
00104 req.current_joints.header.frame_id.c_str(),
00105 req.current_joints.position[0],
00106 req.current_joints.position[1],
00107 req.current_joints.position[2],
00108 req.current_joints.position[3],
00109 req.current_joints.position[4],
00110 req.current_joints.position[5],
00111 req.current_joints.position[6]);
00112
00113 ROS_INFO("[KukaIKAC] Received Pose from frame_id %s (x, y, z, qx, qy, qz, qw): [ %f, %f, %f, %f, %f, %f, %f ]",
00114 req.desired_pose.header.frame_id.c_str(),
00115 req.desired_pose.pose.position.x,
00116 req.desired_pose.pose.position.y,
00117 req.desired_pose.pose.position.z,
00118 req.desired_pose.pose.orientation.x,
00119 req.desired_pose.pose.orientation.y,
00120 req.desired_pose.pose.orientation.z,
00121 req.desired_pose.pose.orientation.w);
00122
00123
00124 std::vector<double> currentjoints;
00125 for(int ii=0; ii<7; ii++)
00126 currentjoints[ii] = req.current_joints.position[ii];
00127
00128 Quaternion<float> quat( req.desired_pose.pose.orientation.w, req.desired_pose.pose.orientation.x, req.desired_pose.pose.orientation.y, req.desired_pose.pose.orientation.z);
00129 Matrix3f mat = quat.toRotationMatrix();
00130
00131 std::vector <double> desired_pose(16,0);
00132 std::vector <double> desired_joints(7,0);
00133
00134
00135 desired_pose[3] = req.desired_pose.pose.position.x;
00136 desired_pose[7] = req.desired_pose.pose.position.y;
00137 desired_pose[11] = req.desired_pose.pose.position.z;
00138 desired_pose[15] = 1;
00139 for(int i=0; i<12; i++){
00140 if(i%4 != 3){
00141 desired_pose[i] = mat(i/4,i%4);
00142 }
00143 }
00144 ROS_INFO("[KukaIKAC] Received HRt:\n [ \t%f %f %f %f\n\t %f %f %f %f\n\t %f %f %f %f\n\t %f %f %f %f\n",
00145 desired_pose[0], desired_pose[1], desired_pose[2], desired_pose[3],
00146 desired_pose[4], desired_pose[5], desired_pose[6], desired_pose[7],
00147 desired_pose[8], desired_pose[9], desired_pose[10], desired_pose[11],
00148 desired_pose[12], desired_pose[13], desired_pose[14], desired_pose[15]);
00149
00150 if(!KukaIKAC::ik(desired_pose, currentjoints, desired_joints)){
00151 ROS_ERROR("[KukaIKAC] IK solution not found. Is pose out of configuration space?");
00152 return false;
00153 }else{
00154
00155 ROS_INFO("[KukaIKAC] Service computed joints:\n %f %f %f %f %f %f %f\n", desired_joints.at(0), desired_joints.at(1), desired_joints.at(2), desired_joints.at(3), desired_joints.at(4), desired_joints.at(5), desired_joints.at(6));
00156
00157 res.desired_joints.position.resize(7);
00158 joints_.resize(7);
00159 for(int i=0; i<7; i++){
00160 res.desired_joints.position[i] = desired_joints.at(i);
00161 joints_(i) = desired_joints.at(i);
00162 }
00163 }
00164 return true;
00165 }
00166
00167 bool KukaIKAC::kukaikCallback(iri_wam_common_msgs::wamInverseKinematics::Request &req, iri_wam_common_msgs::wamInverseKinematics::Response &res){
00168
00169 ROS_INFO("[KukaIKAC] Received Pose from frame_id %s (x, y, z, qx, qy, qz, qw): [ %f, %f, %f, %f, %f, %f, %f ]",
00170 req.pose.header.frame_id.c_str(),
00171 req.pose.pose.position.x,
00172 req.pose.pose.position.y,
00173 req.pose.pose.position.z,
00174 req.pose.pose.orientation.x,
00175 req.pose.pose.orientation.y,
00176 req.pose.pose.orientation.z,
00177 req.pose.pose.orientation.w);
00178
00179 Quaternion<float> quat( req.pose.pose.orientation.w, req.pose.pose.orientation.x, req.pose.pose.orientation.y, req.pose.pose.orientation.z);
00180 Matrix3f mat = quat.toRotationMatrix();
00181
00182 std::vector <double> pose(16,0);
00183 std::vector <double> joints(7,0);
00184
00185 pose[3] = req.pose.pose.position.x;
00186 pose[7] = req.pose.pose.position.y;
00187 pose[11] = req.pose.pose.position.z;
00188 pose[15] = 1;
00189 for(int i=0; i<12; i++){
00190 if(i%4 != 3){
00191 pose[i] = mat(i/4,i%4);
00192 }
00193 }
00194 ROS_INFO("[KukaIKAC] Received HRt:\n [ \t%f %f %f %f\n\t %f %f %f %f\n\t %f %f %f %f\n\t %f %f %f %f\n",
00195 pose[0],pose[1],pose[2],pose[3],
00196 pose[4],pose[5],pose[6],pose[7],
00197 pose[8],pose[9],pose[10],pose[11],
00198 pose[12],pose[13],pose[14],pose[15]);
00199
00200 if(!KukaIKAC::ik(pose, currentjoints_, joints)){
00201 ROS_ERROR("[KukaIKAC] IK solution not found. Is pose out of configuration space?");
00202 return false;
00203 }else{
00204
00205 ROS_INFO("[KukaIKAC] Service computed joints:\n %f %f %f %f %f %f %f\n", joints.at(0), joints.at(1), joints.at(2), joints.at(3), joints.at(4), joints.at(5), joints.at(6));
00206
00207 res.joints.position.resize(7);
00208 joints_.resize(7);
00209 for(int i=0;i<7;i++){
00210 res.joints.position[i] = joints.at(i);
00211 joints_(i)=joints.at(i);
00212 }
00213 res.joints.position[1] = joints.at(1)+1.57079;
00214 joints_(1) = joints.at(1)+1.57079;
00215 }
00216 return true;
00217 }
00218
00219
00220
00221
00222
00223
00224 bool KukaIKAC::ik(vector<double> pose, vector<double> currentjoints, vector<double>& joints){
00225
00226
00227
00228
00229
00230 MatrixXd T0(4,4);
00231 VectorXd cjoints(7), nextangles(7), qoptim(7);
00232 for(int i=0;i<16;i++)
00233 T0(i/4,i%4) = pose.at(i);
00234
00235 for(int i=0;i<7;i++)
00236 cjoints(i) = currentjoints.at(i);
00237
00238 joints.resize(7);
00239 MatrixXd A(4,4);
00240
00241 double i=0;
00242 bool initfound=false;
00243 bool breakloop=false;
00244
00245 MatrixXd qsol(8,7);
00246 VectorXd sol(8);
00247 qsol.fill(0.0);
00248 sol.fill(0.0);
00249 double q10=cjoints(0);
00250 MatrixXd qaux;
00251 Vector3f Xw;
00252
00253 double potq=100000.;
00254
00255 printf("Solution found is that which minimizes a weighted norm of the joints variation, to insert another criterion, modify the function KukaIKAC::potentialfunction \n");
00256 printf("Variation on q0 at each step for obtaining first solution : %e", step_);
00257 printf(" \n Initial joints:\n %f %f %f %f %f %f %f\n", currentjoints.at(0), currentjoints.at(1), currentjoints.at(2), currentjoints.at(3), currentjoints.at(4), currentjoints.at(5), currentjoints.at(6));
00258
00259
00260
00261 while (!initfound & !breakloop){
00262
00263 KukaIKAC::getq1(cjoints,i,q10);
00264
00265 if (q10<Qlim_(0,1) && q10>Qlim_(0,0)){
00266
00267
00268 KukaIKAC::exactikine(T0,q10,cjoints,qsol,sol);
00269
00270 KukaIKAC::filtersols(qsol,sol);
00271 if (sol.sum()!=0.){
00272
00273 KukaIKAC::basicsols(qsol,qaux,sol);
00274 initfound=true;
00275 }
00276 }else{
00277 if (i*step_+cjoints(0)>Qlim_(0,1) && -i*step_+cjoints(0)<Qlim_(0,0)){
00278 breakloop=true;
00279 printf("LOOP BREAK,q1 steps OUT OF RANGE \n");
00280 }
00281 }
00282 i=i+1.;
00283 }
00284
00285
00286
00287 if (initfound){
00288
00289
00290 KukaIKAC::optimizesol(qaux,T0,qoptim,potq,cjoints);
00291 joints.clear();
00292 joints.resize(7);
00293 for(int i=0;i<7;i++)
00294 joints[i] = qoptim(i);
00295
00296 std::cout<<"\n best solution is: \n"<<qoptim.transpose();
00297
00298
00299 if (checksol_==1){
00300 MatrixXd T01,T12,T23,T34,T45,T56,T67,T07;
00301 KukaIKAC::DHmatrix(DHparam_(0,1),DHparam_(0,0),DHparam_(0,2),qoptim(0),T01),
00302 KukaIKAC::DHmatrix(DHparam_(1,1),DHparam_(1,0),DHparam_(1,2),qoptim(1),T12),
00303 KukaIKAC::DHmatrix(DHparam_(2,1),DHparam_(2,0),DHparam_(2,2),qoptim(2),T23),
00304 KukaIKAC::DHmatrix(DHparam_(3,1),DHparam_(3,0),DHparam_(3,2),qoptim(3),T34);
00305 KukaIKAC::DHmatrix(DHparam_(4,1),DHparam_(4,0),DHparam_(4,2),qoptim(4),T45);
00306 KukaIKAC::DHmatrix(DHparam_(5,1),DHparam_(5,0),DHparam_(5,2),qoptim(5),T56);
00307 KukaIKAC::DHmatrix(DHparam_(6,1),DHparam_(6,0),DHparam_(6,2),qoptim(6),T67);
00308 T07=T01*T12*T23*T34*T45*T56*T67;
00309 std::cout<<"\n Result matrix error T0-Tout= \n"<<T0-T07<<std::endl;
00310 }
00311
00312
00313 return true;
00314 } else{
00315 for(int i=0;i<7;i++)
00316 joints[i] = cjoints(i);
00317 printf("SOLUTION NOT FOUND, robot not moving \n ");
00318 return false;
00319 }
00320
00321
00322 }
00323
00324
00325
00326
00327
00328 void KukaIKAC::filtersols(MatrixXd qsol,VectorXd& sol){
00329
00330
00331 sol.resize(qsol.rows());
00332 sol.fill(1.0);
00333 for (int i=0;i<qsol.rows();i++){
00334 for (int j=0;j<7;j++){
00335 if ((qsol(i,j)<Qlim_(j,0))|(qsol(i,j)>Qlim_(j,1))){
00336 sol(i)=0.0;
00337 }
00338 }
00339 }
00340 }
00341
00342 void KukaIKAC::DHmatrix(double alpha, double a, double d,double& theta, MatrixXd& T){
00343
00344
00345 T.resize(4,4);
00346 T.fill(0.0);
00347 T(0,0)= cos(theta);
00348 T(0,1)=-sin(theta)*cos(alpha);
00349 T(0,2)=sin(theta)*sin(alpha);
00350 T(0,3)=a*cos(theta);
00351 T(1,0)=sin(theta);
00352 T(1,1)=cos(theta)*cos(alpha);
00353 T(1,2)=-cos(theta)*sin(alpha);
00354 T(1,3)=a*sin(theta);
00355 T(2,1)=sin(alpha);
00356 T(2,2)=cos(alpha);
00357 T(2,3)=d;
00358 T(3,3)=1;
00359
00360 }
00361
00362
00363
00364 void KukaIKAC::exactikine(MatrixXd T0, double q10, VectorXd cjoints, MatrixXd& qsol,VectorXd&sol){
00365
00366
00367
00368
00369
00370
00371
00372 double q30=cjoints(2);
00373 double c4,aux1,aux2,aux3,signq4;
00374 double PI=3.14159265;
00375 qsol.resize(8,7);
00376 MatrixXd q4sol4(2,2);
00377 MatrixXd q2sol2(2,2);
00378 MatrixXd Pw(4,1),Pwaux(3,1);
00379 MatrixXd T12,T23,T34,T01,T04;
00380 VectorXd q3(2);
00381 Vector2d q5;
00382 Vector2d q6;
00383 Vector2d q7;
00384
00385 MatrixXd qout(8,7);
00386 qout.fill(0.0);
00387 int k;
00388
00389
00390 Pw=T0.block<4,1>(0,3)-d7*T0.block<4,1>(0,2);
00391 Pwaux=Pw.block<3,1>(0,0);
00392 Pwaux(2,0)=Pw(2,0)-d1;
00393
00394
00395 c4=(Pwaux.squaredNorm()-pow(d3,2.0)-pow(d5,2.0))/(2*d3*d5);
00396 if (abs(c4)<=1.0){
00397 q4sol4(0,1)=1.0;
00398 q4sol4(1,1)=1.0;
00399 q4sol4(0,0)=acos(c4);
00400 q4sol4(1,0)=-acos(c4);
00401 }else{
00402 q4sol4.fill(0.0);
00403 q4sol4(0,0)=-99.9999;
00404 q4sol4(1,0)=-99.9999;
00405 }
00406
00407 KukaIKAC::DHmatrix(DHparam_(0,1),DHparam_(0,0),DHparam_(0,2),q10,T01);
00408 for (int i4=0;i4<2;i4++){
00409
00410
00411 aux1=c4*d5+d3;
00412 aux2=-cos(q10)*Pw(0,0)-sin(q10)*Pw(1,0);
00413 aux3=Pw(2,0)-d1;
00414 KukaIKAC::soltrig(aux1, aux2, aux3, q2sol2);
00415 KukaIKAC::DHmatrix(DHparam_(3,1),DHparam_(3,0),DHparam_(3,2),q4sol4(i4,0),T34);
00416 signq4=q4sol4(i4,0)/abs(q4sol4(i4,0));
00417 for(int i2=0;i2<2;i2++){
00418 if (abs(cos(q4sol4(i4,0))-1.0)>0.000001){
00419 q3(i2)=pi2pi(0.5*PI*(-signq4+1.0)+atan2(-sin(q10)*Pw(0,0)+cos(q10)*Pw(1,0),sin(q10)*cos(q2sol2(i2,0))*Pw(1,0)+cos(q10)*cos(q2sol2(i2,0))*Pw(0,0)+sin(q2sol2(i2,0))*(Pw(2,0)-d1)));
00420 }else{
00421 q3(i2)=q30;
00422 }
00423 KukaIKAC::DHmatrix(DHparam_(1,1),DHparam_(1,0),DHparam_(1,2),q2sol2(i2,0),T12);
00424 KukaIKAC::DHmatrix(DHparam_(2,1),DHparam_(2,0),DHparam_(2,2),q3(i2),T23);
00425 T04=T01*T12*T23*T34;
00426 KukaIKAC::sphericalikine(T0,T04,cjoints,q5,q6,q7);
00427
00428 for (int i5=0;i5<2;i5++){
00429 k=i4*4+i2*2+i5;
00430 qsol(k,0)=q10;
00431 qsol(k,1)=q2sol2(i2,0);
00432 qsol(k,2)=q3(i2);
00433 qsol(k,3)=q4sol4(i4,0);
00434 qsol(k,4)=q5(i5);
00435 qsol(k,5)=q6(i5);
00436 qsol(k,6)=q7(i5);
00437 sol(k)=q4sol4(i4,1)*q2sol2(i2,1);
00438 }
00439 }
00440 }
00441 }
00442
00443
00444
00445 void KukaIKAC::basicsols(MatrixXd qsol,MatrixXd& qaux,VectorXd sol){
00446
00447
00448
00449
00450
00451
00452
00453 MatrixXd qauxiliar2;
00454 qauxiliar2.resize(4,7);
00455 qauxiliar2.fill(-99.9999);
00456 int nbasics=0;
00457 for (int i=0;i<qsol.rows()/2;i++){
00458 if (sol(2*i)>0.0){
00459 qauxiliar2.row(nbasics)=qsol.row(2*i);
00460 nbasics=nbasics+1;
00461
00462 }else if (sol(2*i+1)>0.0){
00463 qauxiliar2.row(nbasics)=qsol.row(2*i+1);
00464 nbasics=nbasics+1;
00465 }
00466 }
00467 qaux.resize(nbasics,7);
00468
00469 for (int j=0;j<nbasics;j++){
00470 qaux.row(j)=qauxiliar2.row(j);
00471 }
00472 }
00473
00474
00475
00476
00477
00478 void KukaIKAC::optimizesol(MatrixXd q, MatrixXd T0, VectorXd& qoutput,double& potact,VectorXd qref){
00479
00480
00481
00482
00483
00484 VectorXd PJa,qelbows;
00485 MatrixXd PJ(3,q.rows());
00486
00487 printf("Rotations for each solution: %d",IMAX_);
00488
00489 for (int ia=0;ia<q.rows();ia++){
00490 qelbows=q.row(ia);
00491 KukaIKAC::initialelbows(qelbows,T0,PJa);
00492 PJ.col(ia)=PJa;
00493 }
00494
00495 double L=d7;
00496 MatrixXd T04;
00497 Matrix3d Mrot,Rn,I3;
00498 double phi,qn4,qn3,qn2,qn1,eps1,eps3,potq;
00499 Vector2d qn5,qn6,qn7;
00500 double PI=3.14159265;
00501 Vector3d v,CJ;
00502 VectorXd qn4b,sol,qbest;
00503 MatrixXd Pw,Pw2,Paux,T01,T12,T23,T34,Qaux;
00504 MatrixXd Qglobal(4*q.rows(),7);
00505 qoutput=q.row(0);
00506 VectorXd offshoulder(3,1);
00507 offshoulder << 0.0,0.0,d1;
00508 Pw=T0.block<3,1>(0,3)-L*T0.block<3,1>(0,2);
00509 Pw2=T0.block<3,1>(0,3)-L*T0.block<3,1>(0,2)-offshoulder;
00510 double aux0=Pw2.norm();
00511 v=Pw2/aux0;
00512
00513 KukaIKAC::skewop(Mrot,v);
00514 I3.setIdentity();
00515 double signq4;
00516
00517 for (int i=0;i<IMAX_;i++){
00518 phi=2*PI*double(i)/double(IMAX_)*pow(-1,double(i));
00519 Rn=I3+sin(phi)*Mrot+(1-cos(phi))*Mrot*Mrot;
00520
00521 Qglobal.fill(-9.9);
00522 for (int nconfig=0;nconfig<q.rows();nconfig++){
00523 qn4=q(nconfig,3);
00524 Paux=PJ.block<3,1>(0,nconfig);
00525 Paux(2)=Paux(2)-d1;
00526 CJ=Rn*Paux;
00527 CJ(2)=CJ(2)+d1;
00528 Qaux.resize(4,7);
00529 Qaux.fill(-9.9);
00530
00531
00532 qn2=atan2(CJ(2)-d1,sqrt(pow(CJ(0),2.0)+pow(CJ(1),2.0)))-PI/2;
00533
00534 qn1=atan2(CJ(1),CJ(0));
00535
00536 signq4=qn4/abs(qn4);
00537 qn3=pi2pi(0.5*PI*(-signq4+1.0)+atan2(-sin(qn1)*Pw(0,0)+cos(qn1)*Pw(1,0),sin(qn1)*cos(qn2)*Pw(1,0)+cos(qn1)*cos(qn2)*Pw(0,0)+sin(qn2)*(Pw(2,0)-d1)));
00538 KukaIKAC::DHmatrix(DHparam_(0,1),DHparam_(0,0),DHparam_(0,2),qn1,T01);
00539 KukaIKAC::DHmatrix(DHparam_(1,1),DHparam_(1,0),DHparam_(1,2),qn2,T12);
00540 KukaIKAC::DHmatrix(DHparam_(2,1),DHparam_(2,0),DHparam_(2,2),qn3,T23);
00541 KukaIKAC::DHmatrix(DHparam_(3,1),DHparam_(3,0),DHparam_(3,2),qn4,T34);
00542 T04=T01*T12*T23*T34;
00543
00544 KukaIKAC::sphericalikine(T0,T04,qref,qn5,qn6,qn7);
00545 eps1 = copysign(1.0, qn1);
00546 eps3 = copysign(1.0, qn3);
00547 Qaux<<qn1,qn2,qn3,qn4,qn5(0),qn6(0),qn7(0),
00548 qn1,qn2,qn3,qn4,qn5(1),qn6(1),qn7(1),
00549 qn1-eps1*PI,-qn2,qn3-eps3*PI,qn4,qn5(0),qn6(0),qn7(0),
00550 qn1-eps1*PI,-qn2,qn3-eps3*PI,qn4,qn5(1),qn6(1),qn7(1);
00551
00552
00553 Qglobal.row(4*nconfig)=Qaux.row(0);
00554 Qglobal.row(4*nconfig+1)=Qaux.row(1);
00555 Qglobal.row(4*nconfig+2)=Qaux.row(2);
00556 Qglobal.row(4*nconfig+3)=Qaux.row(3);
00557 }
00558
00559 KukaIKAC::filtersols(Qglobal,sol);
00560
00561 KukaIKAC::bestsol(Qglobal,sol,qref,qbest,potq);
00562
00563
00564 if (potq<potact){
00565 qoutput=qbest;
00566 potact=potq;
00567
00568 }
00569 }
00570 }
00571
00572
00573
00574
00575 void KukaIKAC::skewop(Matrix3d& M,Vector3d v){
00576 M.fill(0.0);
00577 M(0,1)=-v(2);
00578 M(1,0)=v(2);
00579 M(0,2)=v(1);
00580 M(2,0)=-v(1);
00581 M(1,2)=-v(0);
00582 M(2,1)=v(0);
00583 }
00584
00585 void KukaIKAC::getq1(VectorXd cjoints,float i,double& q10){
00586 q10=cjoints(0)+i*step_*pow(-1,i);
00587 }
00588
00589 double KukaIKAC::pi2pi(double x){
00590 double PI=3.14159265;
00591 while (x>PI || x<-PI){
00592 if (x>PI){
00593 x=x-2*PI;
00594 }
00595 if (x<-PI){
00596 x=x+2*PI;
00597 }
00598 }
00599 return x;
00600 }
00601
00602
00603
00604 void KukaIKAC::bestsol(MatrixXd qsol,VectorXd sol,VectorXd qref,VectorXd& q,double& potbest){
00605
00606 potbest=100000;
00607 double potq;
00608 VectorXd qact;
00609 for(int i=1;i<qsol.rows();i++){
00610 if (sol(i)!=0.0){
00611 qact=qsol.block<1,7>(i,0);
00612 KukaIKAC::potentialfunction(qref,qact,potq);
00613 if (potq<potbest){
00614 q=qact;
00615 potbest=potq;
00616 }
00617 }
00618 }
00619 }
00620
00621
00622
00623
00624 void KukaIKAC::potentialfunction(VectorXd qref,VectorXd& q, double& potq){
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 MatrixXd W(7,7);
00636 W.fill(0.0);
00637 W(0,0)=2.5;
00638 W(1,1)=2.0;
00639 W(2,2)=2.0;
00640 W(3,3)=1.5;
00641 W(4,4)=1.0;
00642 W(5,5)=1.0;
00643 W(6,6)=1.0;
00644
00645 VectorXd qdif(7);
00646
00647 qdif=q-qref;
00648 potq=qdif.transpose()*W*qdif;
00649
00650 }
00651
00652
00653
00654
00655
00656 void KukaIKAC::sphericalikine(MatrixXd T0,MatrixXd T4, VectorXd cjoints, Vector2d& q5,Vector2d& q6,Vector2d& q7){
00657
00658
00659 MatrixXd Taux;
00660 Taux=T4.inverse()*T0;
00661
00662 double c6,s6,q57;
00663 c6=Taux(2,2);
00664 double pi=3.14159265;
00665 if (abs(c6)<0.99999){
00666 q7(0)=atan2(-Taux(2,1),Taux(2,0));
00667 q5(0)=atan2(-Taux(1,2),-Taux(0,2));
00668 s6=Taux(0,3)/(-cos(q5(0))*d7);
00669 q6(0)=atan2(s6,c6);
00670 q5(1)=pi2pi(q5(0)+pi);
00671 q6(1)=-q6(0);
00672 q7(1)=pi2pi(q7(0)+pi);
00673 }else if(abs(c6<1.0) && abs(c6)>0.99999){
00674
00675 q57=atan2(Taux(1,0),Taux(0,0));
00676 q5(0)=cjoints(4);
00677 q7(0)=q57-q5(0);
00678 q6(0)=0.0;
00679 q5(1)=pi2pi(q5(0)+pi);
00680 q6(1)=0.0;
00681 q7(1)=pi2pi(q7(0)+pi);
00682 }else{
00683 q5(0)=-99.9999;
00684 q5(1)=-99.9999;
00685 q6(0)=-99.9999;
00686 q6(1)=-99.9999;
00687 q7(0)=-99.9999;
00688 q7(1)=-99.9999;
00689 std::cout<<"\n no solution spherical---------------------\n";
00690 }
00691
00692 }
00693
00694
00695
00696 void KukaIKAC::initialelbows(VectorXd q,MatrixXd T0,VectorXd& PJ){
00697 MatrixXd T01,T12,T23,T02,T03;
00698 KukaIKAC::DHmatrix(DHparam_(0,1),DHparam_(0,0),DHparam_(0,2),q(0),T01);
00699 KukaIKAC::DHmatrix(DHparam_(1,1),DHparam_(1,0),DHparam_(1,2),q(1),T12);
00700 KukaIKAC::DHmatrix(DHparam_(2,1),DHparam_(2,0),DHparam_(2,2),q(2),T23);
00701 T02=T01*T12;
00702 T03=T02*T23;
00703 VectorXd aux(4),PLaux(4);
00704 aux(0)=0.0;
00705 aux(1)=0.0;
00706 aux(2)=d3;
00707 aux(3)=1.0;
00708 PLaux=T02*aux;
00709 PJ=PLaux.block<3,1>(0,0);
00710
00711 }
00712
00713
00714
00715 void KukaIKAC::soltrig(double a, double b, double c, MatrixXd& q2sol2){
00716
00717
00718 if (abs(b)<0.00000001 && abs(a/c)<1.0){
00719 q2sol2(0,1)=1.;
00720 q2sol2(1,1)=1.;
00721 q2sol2(0,0)=acos(a/c);
00722 q2sol2(1,0)=-acos(a/c);
00723
00724
00725 }else if (pow(c,2.)*pow(b,2)-pow(b,2.)*pow(a,2.)+pow(b,4.)<=0.00000001){
00726
00727 q2sol2(0,1)=0.;
00728 q2sol2(1,1)=0.;
00729 q2sol2(0,0)=-99.9999;
00730 q2sol2(1,0)=-99.9999;
00731
00732
00733 }else{
00734
00735 q2sol2(0,1)=1.;
00736 q2sol2(1,1)=1.;
00737 q2sol2(0,0)=atan2(-(-a+c*(a*c+sqrt(pow(c,2.)*pow(b,2.)-pow(b,2.)*pow(a,2.)+pow(b,4.)))/(pow(c,2.)+pow(b,2.)))/b,(a*c+sqrt(pow(c,2.)*pow(b,2.)-pow(b,2.)*pow(a,2.)+pow(b,4.)))/(pow(c,2.)+pow(b,2.)));
00738 q2sol2(1,0)=atan2(-(-a-c*(-a*c+sqrt(pow(c,2.)*pow(b,2.)-pow(b,2.)*pow(a,2.)+pow(b,4.)))/(pow(c,2.)+pow(b,2.)))/b,-(-a*c+sqrt(pow(c,2.)*pow(b,2.)-pow(b,2.)*pow(a,2.)+pow(b,4.)))/(pow(c,2.)+pow(b,2.)));
00739 }
00740 }
00741
00742
00743 int main(int argc, char** argv) {
00744 ros::init(argc, argv, "wam_ik");
00745 KukaIKAC kuka_ikac;
00746 ros::Rate loop_rate(10);
00747 while(ros::ok()){
00748 ros::spinOnce();
00749 loop_rate.sleep();
00750 }
00751
00752 }