00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "wam_ikj.h"
00013 using namespace Eigen;
00014 using namespace std;
00015
00016 WamIKJ::WamIKJ() {
00017
00018
00019
00020 this->currentjoints.resize(7);
00021
00022
00023 std::string port_name;
00024
00025
00026 port_name = ros::names::append(ros::this_node::getName(), "ikjoints");
00027 this->ik_joints_publisher_ = this->nh_.advertise<sensor_msgs::JointState>(port_name, 5);
00028 this->ik_joints_msg.position.resize(7);
00029
00030
00031 port_name = ros::names::append(ros::this_node::getName(), "joint_states");
00032 this->joint_states_subscriber = this->nh_.subscribe(port_name, 5, &WamIKJ::joint_states_callback, this);
00033
00034
00035 port_name = ros::names::append(ros::this_node::getName(), "pose_move");
00036 this->pose_move_server = this->nh_.advertiseService(port_name, &WamIKJ::pose_moveCallback, this);
00037 port_name = ros::names::append(ros::this_node::getName(), "wamik");
00038 this->wamik_server = this->nh_.advertiseService(port_name, &WamIKJ::wamikCallback, this);
00039
00040
00041 port_name = ros::names::append(ros::this_node::getName(), "joints_move");
00042 joint_move_client = this->nh_.serviceClient<iri_wam_common_msgs::joints_move>(port_name);
00043
00044
00045
00046
00047
00048 }
00049
00050 void WamIKJ::ikPub(void)
00051 {
00052 for (int i=0;i<7;i++){
00053 this->ik_joints_msg.position[i]=joints_(i);
00054 }
00055 this->ik_joints_publisher_.publish(this->ik_joints_msg);
00056 }
00057
00058
00059 void WamIKJ::joint_states_callback(const sensor_msgs::JointState::ConstPtr& msg) {
00060
00061 for(int i=0;i<7;i++)
00062 currentjoints[i] = msg->position[i];
00063
00064 }
00065
00066
00067 bool WamIKJ::pose_moveCallback(iri_wam_common_msgs::pose_move::Request &req, iri_wam_common_msgs::pose_move::Response &res)
00068 {
00069
00070 bool result;
00071 Quaternion<float> quat( req.pose.orientation.w, req.pose.orientation.x, req.pose.orientation.y, req.pose.orientation.z);
00072 Matrix3f mat = quat.toRotationMatrix();
00073 ROS_INFO("Received Quat: %f %f %f %f %f %f %f\n",
00074 req.pose.position.x, req.pose.position.y, req.pose.position.z,
00075 req.pose.orientation.x, req.pose.orientation.y, req.pose.orientation.z, req.pose.orientation.w);
00076
00077 std::vector <double> pose(16,0);
00078 std::vector <double> joints(7,0);
00079
00080 pose[3] = req.pose.position.x;
00081 pose[7] = req.pose.position.y;
00082 pose[11] = req.pose.position.z;
00083 pose[15] = 1;
00084 for(int i=0; i<12; i++){
00085 if(i%4 != 3){
00086 pose[i] = mat(i/4,i%4);
00087 }
00088 }
00089 ROS_INFO("wamik Service Received Pose:\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n",
00090 pose[0],pose[1],pose[2],pose[3],
00091 pose[4],pose[5],pose[6],pose[7],
00092 pose[8],pose[9],pose[10],pose[11],
00093 pose[12],pose[13],pose[14],pose[15]);
00094
00095 if(!WamIKJ::ik(pose, currentjoints, joints)){
00096 ROS_ERROR("IK solution not found. Requested pose:\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n",
00097 pose[0],pose[1],pose[2],pose[3],
00098 pose[4],pose[5],pose[6],pose[7],
00099 pose[8],pose[9],pose[10],pose[11],
00100 pose[12],pose[13],pose[14],pose[15]);
00101 joints_<<-99.9,-99.9,-99.9,-99.9,-99.9,-99.9,-99.9;
00102 result = false;
00103 }else{
00104
00105 ROS_INFO("wamik 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));
00106 joints_.resize(7);
00107
00108 joint_move_srv.request.joints.resize(7);
00109 for(int i=0;i<7;i++){
00110 joint_move_srv.request.joints[i] = joints.at(i);
00111 joints_(i)=joints.at(i);
00112 }
00113 ikPub();
00114
00115
00116 if (this->joint_move_client.call(joint_move_srv))
00117 {
00118 ROS_INFO(" %d\n",joint_move_srv.response.success);
00119 result = true;
00120 }
00121 else
00122 {
00123 ROS_ERROR("Failed to call service joint_move");
00124 result = false;
00125 }
00126 }
00127 res.success = result;
00128 return result;
00129 }
00130
00131 bool WamIKJ::wamikCallback(iri_wam_common_msgs::wamInverseKinematics::Request &req, iri_wam_common_msgs::wamInverseKinematics::Response &res){
00132 bool result;
00133 Quaternion<float> quat(req.pose.orientation.x, req.pose.orientation.y, req.pose.orientation.z, req.pose.orientation.w);
00134 Matrix3f mat = quat.toRotationMatrix();
00135
00136 std::vector <double> pose(16,0);
00137 std::vector <double> joints(7,0);
00138
00139 pose[3] = req.pose.position.x;
00140 pose[7] = req.pose.position.y;
00141 pose[11] = req.pose.position.z;
00142 pose[15] = 1;
00143 for(int i=0; i<12; i++){
00144 if(i%4 != 3){
00145 pose[i] = mat(i/4,i%4);
00146 }
00147 }
00148 ROS_INFO("wamik Service Received Pose:\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n",
00149 pose[0],pose[1],pose[2],pose[3],
00150 pose[4],pose[5],pose[6],pose[7],
00151 pose[8],pose[9],pose[10],pose[11],
00152 pose[12],pose[13],pose[14],pose[15]);
00153
00154 if(!WamIKJ::ik(pose, currentjoints, joints)){
00155 ROS_ERROR("IK solution not found");
00156 result = false;
00157 }else{
00158
00159 ROS_INFO("wamik 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));
00160
00161 res.joints.position.resize(7);
00162 joints_.resize(7);
00163 for(int i=0;i<7;i++){
00164 res.joints.position[i] = joints.at(i);
00165 joints_(i)=joints.at(i);
00166 }
00167
00168 }
00169 return result;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 bool WamIKJ::ik(vector<double> pose, vector<double> currentjoints, vector<double>& joints){
00181
00182
00183
00184
00185
00186 MatrixXd Qlim(7,2);
00187 Qlim<<-2.6,2.6,-2.0,2.0,-2.8,2.8,-0.9,3.1,-4.8,1.3,-1.6,1.6,-2.2,2.2;
00188
00189
00190 int itmax=500;
00191 double emax=0.0001,lambda=0.00001,eps=0.01;
00192
00193
00194
00195 MatrixXd T0(4,4);
00196 VectorXd cjoints(7),nextangles(7);
00197
00198 for(int i=0;i<7;i++)
00199 cjoints(i) = currentjoints.at(i);
00200
00201
00202
00203
00204 for(int i=0;i<16;i++)
00205 T0(i/4,i%4) = pose.at(i);
00206
00207
00208 int method=1;
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 MatrixXd U,V,S;
00219 int m=7;
00220 int n=6;
00221 int it=0;
00222 bool final=false;
00223 double mu=0.2,beta0=0.2,nu=10,s0=0.01,gmax=M_PI/5.0,gi,Ni,Mi,sig,lambdajl=0.2;
00224 MatrixXd Tf,J,I7(7,7);
00225 I7.setIdentity();
00226
00227
00228 VectorXd errc,aux,gradman,ejl,qnew(7),dq2(7);
00229 MatrixXd Vi(m,1),Ui(n,1),Ji(n,1);
00230
00231 VectorXd q(7),dH(7),dH0(7),difH(7),wi(7),w(7),thi,dq,dq1;
00232 MatrixXd H,Wi(7,7),J0,J1i,JP1i,JP1iaux,J1,P1,Haux(7,7),Jf(n,m),S2(n,m),Ub,Vb,Sb;
00233 Wi.fill(0.0);
00234 S2.fill(0.0);
00235
00236
00237 q=cjoints;
00238 double alpha,alpha2,man;
00239
00240 dhfunct(q,dH0);
00241
00242
00243 WamIKJ::fkine(q,Tf,J);
00244 WamIKJ::errortrans(Tf, T0,errc);
00245
00246 ROS_INFO("STARTING");
00247
00248 std::cout<<"METHOD="<<method<<std::endl;
00249
00250 while(!final){
00251 dq.fill(0.0);
00252 dq1.fill(0.0);
00253 if (method==1){
00254
00255 Ji=J.transpose();
00256 aux=J*Ji*errc;
00257 WamIKJ::dotprod(aux,errc,alpha);
00258 WamIKJ::dotprod(aux,aux,alpha2);
00259 alpha=alpha/alpha2;
00260 qnew=q+alpha*Ji*errc;
00261 }else if(method==2){
00262
00263
00264
00265 WamIKJ::pseudoinverse(J,Ji,U,V,S);
00266 qnew=q+Ji*errc;
00267 }else if(method==3){
00268
00269 WamIKJ::pseudoinverse(J,Ji,U,V,S);
00270 WamIKJ::manipgrad(q,man,gradman);
00271
00272 qnew=q+Ji*errc+mu*(I7-Ji*J)*gradman;
00273 }else if(method==4){
00274
00275 WamIKJ::Dpseudoinverse(J,Ji,lambda);
00276 qnew=q+Ji*errc;
00277 }else if(method==5){
00278
00279 WamIKJ::Fpseudoinverse(J,Ji,lambda,eps);
00280
00281 qnew=q+Ji*errc;
00282 }else if(method==6){
00283
00284 dhfunct(q,dH);
00285 difH=dH.cwiseAbs()-dH0.cwiseAbs();
00286
00287 for (int ij=1;ij<m;ij++){
00288 if (difH(ij)>0){
00289 Wi(ij,ij)=sqrt(1.0/(1.0+abs(dH(ij))));
00290 }else{
00291 Wi(ij,ij)=1.0;
00292 }
00293 }
00294 WamIKJ::pseudoinverse(J*Wi,Ji,U,V,S);
00295 qnew=q+Wi*Ji*errc;
00296
00297 dH0=dH;
00298 }else if(method==7){
00299
00300 WamIKJ::clampjoints(q,H);
00301 WamIKJ::pseudoinverse(J*H,Ji,U,V,S);
00302 qnew=WamIKJ::pi2piwam(q+H*Ji*errc);
00303
00304
00305
00306 }else if(method==8){
00307
00308 WamIKJ::HjlCONT(q,H,beta0);
00309 WamIKJ::pseudoinverse(J*H,Ji,U,V,S);
00310 qnew=q+H*Ji*errc;
00311
00312 }else if(method==9){
00313
00314 WamIKJ::CFpseudoinverse(J,Ji,nu,s0);
00315 qnew=q+Ji*errc;
00316
00317 }else if(method==10){
00318
00319 wi.resize(7);
00320 WamIKJ::svdJ(J,U,V,S);
00321 w.fill(0.0);
00322 for (int i=0;i<m;i++){
00323 if (i>n-1){
00324 wi.fill(0.0);
00325 Ni=0.0;
00326 sig=0.0;
00327 }else if (abs(S(i,i))<0.000001){
00328 wi.fill(0.0);
00329 Ni=0.0;
00330 sig=0.0;
00331 }else{
00332
00333 for (int ii=0;ii<m;ii++){
00334 Vi(ii,0)=V(ii,i);
00335 }
00336
00337 for (int ii2=0;ii2<n;ii2++){
00338 Ji(ii2,0)=J(ii2,i);
00339 Ui(ii2,0)=U(ii2,i);
00340 }
00341
00342 sig=1/S(i,i);
00343
00344 wi=sig*Vi*Ui.transpose()*errc;
00345 Ni=Ui.norm();
00346 Mi=0.0;
00347 for (int j=0;j<m;j++){
00348 Mi=Mi+sig*abs(V(j,i))*Ji.norm();
00349 }
00350
00351 gi=gmax*min(1.0,Ni/Mi);
00352 if (wi.maxCoeff()>gi){
00353 thi=gi*wi/wi.maxCoeff();
00354 }else{
00355 thi=wi;
00356 }
00357 w=w+thi;
00358 }
00359 }
00360
00361 if (w.maxCoeff()>gmax){
00362 dq=gmax*w/w.maxCoeff();
00363 }else{
00364 dq=w;
00365 }
00366
00367 qnew=q+dq;
00368
00369
00370 }else if(method==11){
00371
00372
00373 WamIKJ::HjlCONT(q,H,beta0);
00374 J0.resize(7,7);
00375 J1=I7-H;
00376 ejl=-lambdajl*q;
00377 WamIKJ::pseudoinverse(J1,J1i,U,V,S);
00378 P1=I7-J1i*J1;
00379 WamIKJ::pseudoinverse(J*P1,JP1i,U,V,S);
00380 dq=J1i*ejl+JP1i*(errc+J*J1i*ejl);
00381 qnew=q+dq;
00382
00383
00384
00385 }else if(method==12){
00386
00387
00388 WamIKJ::HjlCONT(q,Haux,beta0);
00389 J1=I7;
00390 H=I7-Haux;
00391 J0.resize(7,7);
00392 ejl=-lambdajl*q;
00393 J1i=H;
00394 P1=I7-J1i*J1;
00395 JP1iaux=WamIKJ::cpinv(J.transpose(),P1);
00396 JP1i=JP1iaux.transpose();
00397 dq1=J1i*ejl;
00398 dq=dq1+JP1i*errc-JP1i*J*dq1;
00399 qnew=pi2piwam(q+dq);
00400
00401 }else if(method==13){
00402
00403
00404 WamIKJ::svdJ(J,U,V,S);
00405 for (int i=0;i<n;i++){
00406 S2(i,i)=(2*s0+S(i,i)*(2+S(i,i)*(nu+S(i,i))))/(2+S(i,i)*(nu+S(i,i)));
00407 }
00408 Jf=U*S2*V.transpose();
00409 WamIKJ::HjlCONT(q,Haux,beta0);
00410 J1=I7;
00411 H=I7-Haux;
00412 J0.resize(7,7);
00413 ejl=-lambdajl*q;
00414
00415 J1i=H;
00416 P1=I7-J1i*J1;
00417
00418 JP1iaux=WamIKJ::cpinv(J.transpose(),P1);
00419
00420 JP1i=JP1iaux.transpose();
00421
00422
00423
00424 dq1=J1i*ejl;
00425 dq=dq1+JP1i*errc-JP1i*J*dq1;
00426
00427
00428
00429
00430
00431
00432 qnew=pi2piwam(q+dq);
00433
00434 }else if(method==14){
00435
00436
00437 WamIKJ::HjlCONT(q,Haux,beta0);
00438 J1=I7;
00439 H=I7-Haux;
00440 J0.resize(7,7);
00441 ejl=-lambdajl*q;
00442 J1i=H;
00443 P1=I7-J1i*J1;
00444
00445
00446 WamIKJ::svdJ(J,U,V,S);
00447 for (int i=0;i<n;i++){
00448 S2(i,i)=(2*s0+S(i,i)*(2+S(i,i)*(nu+S(i,i))))/(2+S(i,i)*(nu+S(i,i)));
00449 }
00450 Jf=U*S2*V.transpose();
00451
00452
00453 JP1iaux=WamIKJ::cpinv(Jf.transpose(),P1);
00454 JP1i=JP1iaux.transpose();
00455
00456
00457 WamIKJ::svdJ(JP1i,Vb,Ub,Sb);
00458
00459 wi.resize(7);
00460 w.fill(0.0);
00461
00462 for (int i=0;i<n;i++){
00463 if (abs(S(i,i))<0.000001){
00464 wi.fill(0.0);
00465 Ni=1.0;
00466 sig=0.0;
00467 }else{
00468
00469 for (int ii=0;ii<m;ii++){
00470 Vi(ii,0)=Vb(ii,i);
00471 }
00472
00473 for (int ii2=0;ii2<n;ii2++){
00474 Ji(ii2,0)=Jf(ii2,i);
00475 Ui(ii2,0)=Ub(ii2,i);
00476 }
00477
00478 sig=Sb(i,i);
00479
00480 wi=sig*Vi*Ui.transpose()*errc;
00481 Ni=Ui.norm();
00482 Mi=0.0;
00483 for (int j=0;j<m;j++){
00484 Mi=Mi+sig*abs(Vb(j,i))*Ji.norm();
00485 }
00486
00487 gi=gmax*min(1.0,Ni/Mi);
00488 if (wi.maxCoeff()>gi){
00489 thi=gi*wi/wi.maxCoeff();
00490 }else{
00491 thi=wi;
00492 }
00493 w=w+thi;
00494 }
00495 }
00496 dq1=J1i*ejl-JP1i*Jf*J1i*ejl;
00497 dq2=dq1+w;
00498 if (dq2.maxCoeff()>gmax){
00499 dq=gmax*dq2/dq2.maxCoeff();
00500 }else{
00501 dq=dq2;
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 qnew=pi2piwam(q+dq);
00515
00516 }
00517
00518
00519
00520 WamIKJ::fkine(qnew,Tf,J);
00521 WamIKJ::errortrans(Tf,T0,errc);
00522 q=pi2piwam(qnew);
00523
00524 if (std::isnan(errc.norm())){
00525 }else{
00526
00527 }
00528 it++;
00529
00530
00531 if (errc.norm()<emax || it>itmax){
00532 final=true;
00533 }
00534
00535
00536 }
00537
00538 std::cout<<"end error= "<<errc.norm()<<", iterations="<< it-1<<std::endl;
00539
00540
00541
00542
00543
00544
00545
00546 for(int i=0;i<7;i++){
00547 joints.at(i) = q(i);
00548
00549 }
00550
00551
00552
00553 return true;
00554 }
00555
00556
00557
00558
00559 MatrixXd WamIKJ::rcpinv(MatrixXd Q,MatrixXd W){
00560 MatrixXd Qu,J1,U,V,S;
00561 WamIKJ::svdJ(W,U,V,S);
00562 Qu=U.transpose()*Q;
00563
00564 J1=cpinv(Qu,S)*U.transpose();
00565
00566
00567
00568 return J1;
00569 }
00570
00571
00572 MatrixXd WamIKJ::lcpinv(MatrixXd Q,MatrixXd W){
00573 MatrixXd J1;
00574
00575 J1=rcpinv(Q.transpose(),W);
00576
00577
00578
00579 return J1.transpose();
00580 }
00581
00582
00583 MatrixXd WamIKJ::cpinv(MatrixXd J,MatrixXd H){
00584 int m=J.cols();
00585 int n=J.rows();
00586 MatrixXd U,V,S,Ji,J1(m,n),H0(7,7);
00587 J1.fill(0.0);
00588 H0.fill(0.0);
00589 int val;
00590 MatrixXd hbin(n,1),hi(n,1);
00591 double produ;
00592
00593 for (int j=0;j<n;j++){
00594 hi(j,0)=H(j,j);
00595 }
00596
00597
00598
00599 for (int i1=0;i1<pow(2,n);i1++){
00600 hbin.fill(0.0);
00601 val=i1;
00602 for (int iaux=n-1;iaux>=0;iaux--){
00603 if (val>pow(2,iaux)-1){
00604 hbin(iaux,0)=1.0;
00605 val=val-pow(2,iaux);
00606 }
00607 }
00608
00609 for (int j=0;j<n;j++){
00610 H0(j,j)=hbin(j,0);
00611 }
00612
00613 produ=1.0;
00614 for(int i2=0;i2<n;i2++){
00615 if (hbin(i2,0)==1.0){
00616 produ=produ*hi(i2,0);
00617 }else {
00618 produ=produ*(1.0-hi(i2,0));
00619 }
00620 }
00621
00622 WamIKJ::pseudoinverse(H0*J,Ji,U,V,S);
00623
00624 J1=J1+produ*Ji;
00625
00626 if (produ>0.0000001){
00627
00628 }
00629
00630
00631 }
00632
00633 return J1;
00634
00635 }
00636
00637 VectorXd WamIKJ::pi2piwam(VectorXd q){
00638 MatrixXd Qlim(7,7);
00639 VectorXd qout(7),q2(7);
00640 Qlim.resize(7,2);
00641 Qlim<<-2.6,2.6,-2.0,2.0,-2.8,2.8,-0.9,3.1,-4.8,1.3,-1.6,1.6,-2.2,2.2;
00642
00643 for (int i=0;i<7;i++){
00644 q2(i)=min(q(i),Qlim(i,1))-0.00000001;
00645 qout(i)=max(q2(i),Qlim(i,0))+0.00000001;
00646 }
00647 return qout;
00648 }
00649
00650
00651 void WamIKJ::HjlCONT(VectorXd q,MatrixXd& H,double b){
00652 MatrixXd Qlim,I7(7,7);
00653 VectorXd beta(7);
00654 Qlim.resize(7,2);
00655 Qlim<<-2.6,2.6,-2.0,2.0,-2.8,2.8,-0.9,3.1,-4.8,1.3,-1.6,1.6,-2.2,2.2;
00656 VectorXd hb(7);
00657 hb.fill(0.0);
00658 H.resize(7,7);
00659 H.fill(0.0);
00660 I7.fill(0.0);
00661 for (int i=0;i<7;i++){
00662 beta(i)=(Qlim(i,1)-Qlim(i,0))*b;
00663
00664 if ((q(i)<Qlim(i,0)) || (q(i)>Qlim(i,1)) ){
00665 hb(i)=1.0;
00666 }else if(q(i)>Qlim(i,0) && q(i)<Qlim(i,0)+beta(i)){
00667 hb(i)=fubeta(beta(i)+Qlim(i,0)-q(i),beta(i));
00668 }else if(q(i)<Qlim(i,1) && q(i)>Qlim(i,1)-beta(i)){
00669 hb(i)=fubeta(beta(i)-Qlim(i,1)+q(i),beta(i));
00670 }else{
00671 hb(i)=0.0;
00672 }
00673 H(i,i)=1.0-hb(i);
00674
00675 }
00676
00677 }
00678
00679
00680 double WamIKJ::fubeta(double x,double beta){
00681 double f;
00682 f=0.5*(1.0+tanh(1.0/(1.0-x/beta)-beta/x));
00683 return f;
00684 }
00685
00686 void WamIKJ::dhfunct(VectorXd q,VectorXd& dH){
00687 MatrixXd Qlim;
00688 Qlim.resize(7,2);
00689 Qlim<<-2.6,2.6,-2.0,2.0,-2.8,2.8,-0.9,3.1,-4.8,1.3,-1.6,1.6,-2.2,2.2;
00690 for (int i=0;i<7;i++){
00691 dH(i)=1/14*(pow((Qlim(i,1)-Qlim(i,0)),2)*(2*q(i)-Qlim(i,1)-Qlim(i,0))/(pow((Qlim(i,1)-q(i)),2.0)*pow((q(i)-Qlim(i,0)),2.0)));
00692 }
00693
00694 }
00695
00696
00697 void WamIKJ::clampjoints(VectorXd q,MatrixXd& H){
00698 MatrixXd Qlim;
00699 H.resize(7,7);
00700 H.setIdentity();
00701 Qlim.resize(7,2);
00702 Qlim<<-2.6,2.6,-2.0,2.0,-2.8,2.8,-0.9,3.1,-4.8,1.3,-1.6,1.6,-2.2,2.2;
00703 for (int i=0;i<7;i++){
00704 if ((q(i)<Qlim(i,0)) || (q(i)>Qlim(i,1)) ){
00705 H(i,i)=0;
00706 }
00707 }
00708
00709 }
00710
00711 void WamIKJ::manipulability(MatrixXd J,double& man){
00712 MatrixXd JJt;
00713 JJt=J*J.transpose();
00714 man=sqrt(JJt.determinant());
00715 }
00716
00717 void WamIKJ::manipgrad(VectorXd q,double& man,VectorXd& gradman){
00718 VectorXd qaux;
00719 MatrixXd Tfk,Jn;
00720 double man0,mani;
00721 WamIKJ::fkine(q,Tfk,Jn);
00722 WamIKJ::manipulability(Jn,man0);
00723 gradman.resize(7);
00724 gradman.fill(0);
00725 double h=0.000001;
00726 for (int i=0;i<7;i++){
00727 qaux=q;
00728 qaux(i)+=h;
00729 WamIKJ::fkine(q,Tfk,Jn);
00730 WamIKJ::manipulability(Jn,mani);
00731 gradman(i)=mani-man0;
00732
00733 }
00734
00735 }
00736
00737
00738
00739 void WamIKJ::pseudoinverse(MatrixXd J,MatrixXd& Ji,MatrixXd& U,MatrixXd& V,MatrixXd& S){
00740 int n=J.rows();
00741 int m=J.cols();
00742 MatrixXd Si(m,n);
00743 Si.fill(0.0);
00744
00745
00746 WamIKJ::svdJ(J,U,V,S);
00747
00748
00749
00750 for (int i=0;i<min(n,m);i++){
00751 if (abs(S(i,i))<0.00000001){
00752
00753
00754
00755 }else{
00756 Si(i,i)=1/S(i,i);
00757
00758
00759 }
00760
00761 }
00762
00763 Ji=V*Si*U.transpose();
00764
00765 }
00766
00767
00768 void WamIKJ::Dpseudoinverse(MatrixXd J,MatrixXd& Ji,double lambda){
00769 int n=J.rows();
00770 int m=J.cols();
00771 MatrixXd U,V,S,Si(m,n);
00772 Si.fill(0.0);
00773 WamIKJ::svdJ(J,U,V,S);
00774 for (int i=0;i<n;i++){
00775 if (abs(S(i,i))<0.00000001){
00776 Si(i,i)=0.0;
00777 }else{
00778 Si(i,i)=S(i,i)/( pow(S(i,i),2.0)+pow(lambda,2.0));
00779 }
00780 Ji=V*Si*U.transpose();
00781 }
00782 }
00783
00784
00785 void WamIKJ::CFpseudoinverse(MatrixXd J,MatrixXd& Ji,double nu,double s0){
00786 int n=J.rows();
00787 int m=J.cols();
00788 MatrixXd U,V,S,S2(n,m),Si(m,n);
00789 Si.fill(0.0);
00790 S2.fill(0.0);
00791 WamIKJ::svdJ(J,U,V,S);
00792 for (int i=0;i<n;i++){
00793 S2(i,i)=(2*s0+S(i,i)*(2+S(i,i)*(nu+S(i,i))))/(2+S(i,i)*(nu+S(i,i)));
00794 if (abs(S(i,i))>0.00000001){
00795 Si(i,i)=1/S2(i,i);
00796 }
00797 Ji=V*Si*U.transpose();
00798 }
00799 }
00800
00801 void WamIKJ::Fpseudoinverse(MatrixXd J,MatrixXd& Ji,double lambda,double eps){
00802 int n=J.rows();
00803 int m=J.cols();
00804 double lambda2;
00805 MatrixXd U,V,S,Si(m,n);
00806 Si.fill(0.0);
00807 WamIKJ::svdJ(J,U,V,S);
00808
00809
00810 if (S(n-1,n-1)<eps){
00811 lambda2=lambda*sqrt(1.0-pow(S(n-1,n-1)/eps,2.0));
00812 }else{
00813 lambda2=0.0;
00814 }
00815
00816
00817
00818 for (int i=0;i<n-1;i++){
00819 if (abs(S(i,i))<0.00000001){
00820 Si(i,i)=0.0;
00821 }else{
00822 Si(i,i)=1/S(i,i);
00823 }
00824 }
00825
00826
00827
00828
00829 if (abs(S(n-1,n-1))<0.00000001){
00830 Si(n-1,n-1)=0.0;
00831 }else{
00832 Si(n-1,n-1)=S(n-1,n-1)/(pow(S(n-1,n-1),2.0)+pow(lambda2,2.0));
00833 }
00834
00835
00836
00837 Ji=V*Si*U.transpose();
00838 }
00839
00840
00841 void WamIKJ::svdJ(MatrixXd J, MatrixXd& U,MatrixXd& V,MatrixXd& S){
00842
00843
00844
00845 int n=J.rows();
00846 int m=J.cols();
00847 U.resize(n,n);
00848 V.resize(m,m);
00849 S.resize(n,m);
00850 double maxim=J.maxCoeff();
00851 double minim=J.minCoeff();
00852 int maux=min(n,m);
00853
00854 if (abs(maxim)<0.00000001 && abs(minim)<0.00000001){
00855 U.setIdentity();
00856 V.setIdentity();
00857 S.fill(0.0);
00858 }else{
00859
00860
00861 JacobiSVD<MatrixXd> svd(J,ComputeFullU | ComputeFullV);
00862
00863
00864 VectorXd vaps;
00865 int n=J.rows();
00866 int m=J.cols();
00867 U=svd.matrixU();
00868 V=svd.matrixV();
00869 vaps=svd.singularValues();
00870 S.resize(n,m);
00871 S.fill(0.0);
00872
00873 for (int i=0;i<maux;i++){
00874
00875 S(i,i)=vaps(i);
00876 }
00877
00878 }
00879
00880
00881 }
00882
00883 void WamIKJ::fkine(VectorXd theta,MatrixXd& Tfk,MatrixXd& Jn){
00884 int n=6;
00885 int m=7;
00886 MatrixXd T_aux(4,4),T_aux2(4,4),R(3,3),J(n,m),MJ(n,n);
00887
00888 Tfk.resize(4,4);
00889 Tfk.setIdentity();
00890
00891 MatrixXd DHcoeffs(7,3);
00892 DHcoeffs<<-M_PI/2,0.,0.,M_PI/2,0.,0.,-M_PI/2,0.045,0.55,M_PI/2,-0.045,0.,-M_PI/2,0.,0.3,M_PI/2,0.,0.,0.,0.,0.06;
00893 for (int j=m-1;j>=0;j--){
00894 DHmatrix(DHcoeffs(j,0), DHcoeffs(j,1), DHcoeffs(j,2),theta(j),T_aux);
00895 T_aux2=T_aux*Tfk;
00896 Tfk = T_aux2;
00897 J(0,j)=-Tfk(0,0)*Tfk(1,3)+Tfk(1,0)*Tfk(0,3);
00898 J(1,j)=-Tfk(0,1)*Tfk(1,3)+Tfk(1,1)*Tfk(0,3);
00899 J(2,j)=-Tfk(0,2)*Tfk(1,3)+Tfk(1,2)*Tfk(0,3);
00900 J(3,j)=Tfk(2,0);
00901 J(4,j)=Tfk(2,1);
00902 J(5,j)=Tfk(2,2);
00903
00904 }
00905 R.resize(3,3);
00906 R=Tfk.block<3,3>(0,0);
00907 MJ.resize(n,n);
00908 MJ.fill(0.0);
00909 MJ.block<3,3>(0,0)=R;
00910 MJ.block<3,3>(3,3)=R;
00911 Jn=MJ*J;
00912 }
00913
00914 void WamIKJ::dotprod(MatrixXd u,MatrixXd v,double& p){
00915 p=0.0;
00916 if ((v.rows()==1 && u.rows()==1) && u.cols()==v.cols()){
00917 for(int i=0;i<u.cols();i++){
00918 p+=u(0,i)*v(0,i);
00919 }
00920 }else if((v.cols()==1 && u.cols()==1) && u.rows()==v.rows()){
00921 for(int i=0;i<u.rows();i++){
00922 p+=u(i,0)*v(i,0);
00923 }
00924 }else{
00925 std::cout<<"Error when calculating dot product"<<std::endl;
00926 }
00927 }
00928
00929
00930
00931 MatrixXd WamIKJ::crossprod(MatrixXd u,MatrixXd v){
00932
00933 MatrixXd w(3,1);
00934 w(0,0)=u(1,0)*v(2,0)-u(2,0)*v(1,0);
00935 w(1,0)=u(2,0)*v(0,0)-u(0,0)*v(2,0);
00936 w(2,0)=u(0,0)*v(1,0)-u(1,0)*v(0,0);
00937 return w;
00938 }
00939
00940
00941 void WamIKJ::errortrans(MatrixXd Tcurrent, MatrixXd Tdesired, VectorXd& errc){
00942
00943 errc.resize(6);
00944 MatrixXd d1(3,1),d2(3,1),d3(3,1),c1(3,1),c2(3,1),c3(3,1),xd(3,1),xc(3,1),aux(3,1);
00945
00946 d1=Tdesired.block<3,1>(0,0);
00947 d2=Tdesired.block<3,1>(0,1);
00948 d3=Tdesired.block<3,1>(0,2);
00949 xd=Tdesired.block<3,1>(0,3);
00950
00951 c1=Tcurrent.block<3,1>(0,0);
00952 c2=Tcurrent.block<3,1>(0,1);
00953 c3=Tcurrent.block<3,1>(0,2);
00954 xc=Tcurrent.block<3,1>(0,3);
00955
00956 errc(0)=xd(0)-xc(0);
00957 errc(1)=xd(1)-xc(1);
00958 errc(2)=xd(2)-xc(2);
00959
00960 aux=0.5*(crossprod(c1,d1)+crossprod(c2,d2)+crossprod(c3,d3));
00961
00962 errc(3)=aux(0,0);
00963 errc(4)=aux(1,0);
00964 errc(5)=aux(2,0);
00965 }
00966
00967
00968 void WamIKJ::filtersols(MatrixXd qsol,VectorXd& sol){
00969
00970
00971 MatrixXd Qlim(7,2);
00972 Qlim << -2.6, 2.6,
00973 -2.0, 2.0,
00974 -2.8, 2.8,
00975 -0.9, 3.1,
00976 -4.76,1.24,
00977 -1.6, 1.6,
00978 -2.2, 2.2;
00979 sol.resize(qsol.rows());
00980 sol.fill(1.0);
00981
00982 for (int i=0;i<qsol.rows();i++){
00983 for (int j=0;j<7;j++){
00984 if ((qsol(i,j)<Qlim(j,0))|(qsol(i,j)>Qlim(j,1))){
00985 sol(i)=0.0;
00986
00987 }
00988 }
00989
00990 }
00991
00992
00993 }
00994
00995 void WamIKJ::DHmatrix(double alpha, double a, double d,double& theta, MatrixXd& T){
00996
00997
00998 T.resize(4,4);
00999 T.fill(0.0);
01000 T(0,0)= cos(theta);
01001 T(0,1)=-sin(theta)*cos(alpha);
01002 T(0,2)=sin(theta)*sin(alpha);
01003 T(0,3)=a*cos(theta);
01004 T(1,0)=sin(theta);
01005 T(1,1)=cos(theta)*cos(alpha);
01006 T(1,2)=-cos(theta)*sin(alpha);
01007 T(1,3)=a*sin(theta);
01008 T(2,1)=sin(alpha);
01009 T(2,2)=cos(alpha);
01010 T(2,3)=d;
01011 T(3,3)=1;
01012 }
01013
01014
01015
01016 void WamIKJ::skewop(Matrix3d& M,Vector3d v){
01017 M.fill(0.0);
01018 M(0,1)=-v(2);
01019 M(1,0)=v(2);
01020 M(0,2)=v(1);
01021 M(2,0)=-v(1);
01022 M(1,2)=-v(0);
01023 M(2,1)=v(0);
01024 }
01025
01026
01027
01028 void WamIKJ::potentialfunction(VectorXd qref,VectorXd& q, double& potq){
01029
01030
01031
01032 MatrixXd W(7,7);
01033 W.fill(0.0);
01034 W(0,0)=2.5;
01035 W(1,1)=2.0;
01036 W(2,2)=2.0;
01037 W(3,3)=1.5;
01038 W(4,4)=1.0;
01039 W(5,5)=1.0;
01040 W(6,6)=1.0;
01041
01042 VectorXd qdif(7);
01043
01044 qdif=q-qref;
01045 potq=qdif.transpose()*W*qdif;
01046
01047 }
01048
01049
01050
01051
01052
01053 void WamIKJ::sphericalikine(MatrixXd T0,MatrixXd T4, Vector2d& q5,Vector2d& q6,Vector2d& q7){
01054 MatrixXd Taux;
01055 Taux=T4.inverse()*T0;
01056 q5(0)=atan(Taux(1,2)/Taux(0,2));
01057
01058 if (q5(0)>1.3-3.14159265){
01059 q5(1)=q5(0)-3.14159265;
01060 }else{
01061 q5(1)=q5(0)+3.14159265;
01062 }
01063
01064 for (int i5=0;i5<2;i5++){
01065 q6(i5)=atan2(Taux(0,2)*cos(q5(i5))+Taux(1,2)*sin(q5(i5)),Taux(2,2));
01066 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)));
01067 }
01068 }
01069
01070
01071
01072
01073 void WamIKJ::soltrig(double a, double b, double c, MatrixXd& q2sol2){
01074
01075
01076 if (abs(b)<0.00000001 && abs(a/c)<1.0){
01077 q2sol2(0,1)=1.;
01078 q2sol2(1,1)=1.;
01079 q2sol2(0,0)=acos(a/c);
01080 q2sol2(1,0)=-acos(a/c);
01081
01082
01083 }else if (pow(c,2.)*pow(b,2)-pow(b,2.)*pow(a,2.)+pow(b,4.)<=0.00000001){
01084
01085 q2sol2(0,1)=0.;
01086 q2sol2(1,1)=0.;
01087 q2sol2(0,0)=-99.9999;
01088 q2sol2(1,0)=-99.9999;
01089
01090
01091 }else{
01092
01093 q2sol2(0,1)=1.;
01094 q2sol2(1,1)=1.;
01095
01096 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.)));
01097
01098 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.)));
01099 }
01100 }
01101
01102
01103
01104
01105 int main(int argc, char** argv) {
01106 ros::init(argc, argv, "wam_ik");
01107 WamIKJ wam_ikj;
01108 ros::Rate loop_rate(10);
01109 while(ros::ok()){
01110 ros::spinOnce();
01111 loop_rate.sleep();
01112 }
01113 }