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