uncalibvs_sim_alg.cpp
Go to the documentation of this file.
00001 #include "uncalibvs_sim_alg.h"
00002 
00003 // Class Constructor
00004 Uncalibvs_simAlgorithm::Uncalibvs_simAlgorithm(void) {
00005    base_rtw();
00006    initZeros();
00007 }
00008 
00009 // Class Destructor
00010 Uncalibvs_simAlgorithm::~Uncalibvs_simAlgorithm(void){
00011 }
00012 
00013 // Save Current Config
00014 void Uncalibvs_simAlgorithm::config_update(Config& new_cfg, uint32_t level){
00015   this->lock();
00016 
00017   // save the current configuration
00018   this->config_=new_cfg;
00019   
00020   this->unlock();
00021 }
00022 
00023 // Uncalibvs_simAlgorithm Public API
00024 void Uncalibvs_simAlgorithm::uncalib_vs_sim(const bool& traditional, const bool& random_points, const bool& quadrotor, const bool& arm_unina, const bool& arm_catec, const bool& output_files, const std::string& path, const double& lambda, const Eigen::MatrixXf& lambda_robot, const double& final_z,  const Eigen::Matrix4f& cTo, const double& secs, const Eigen::MatrixXf& V2, KDL::Chain& chain, Eigen::MatrixXf& QQ,  const Eigen::Matrix3f& Rquad_inertial, Eigen::MatrixXf& Vel_quad){
00025   this->lock();
00026   
00027   traditional_=traditional;
00028   random_points_=random_points;
00029   quadrotor_=quadrotor;
00030   arm_unina_=arm_unina;
00031   arm_catec_=arm_catec;
00032   output_files_=output_files;
00033   path_=path;
00034   cTo_=cTo;
00035   secs_=secs;
00036   V2_=V2;
00037   chain_=chain;
00038   QQ_=QQ;
00039   lambda_=lambda;
00040   lambda_robot_=lambda_robot;
00041   final_z_=final_z;
00042   Rquad_inertial_=Rquad_inertial;
00043   
00044   if (secs_==0) {
00045    base_rtw();
00046    initZeros();
00047   }
00048   // Desired position of the object r.t. camera (invert to see the camera r.t. object)
00049   //T0c_x_.block(0,0,3,3) << -0.995, -0.0998, 0, 0.0998, -0.995, 0, 0, 0, 1;
00050   T0c_x_.block(0,0,3,3) << -1, 0, 0, 0, -1, 0, 0, 0, 1;
00051   T0c_x_.col(3) << 0, 0.3, -final_z_, 1;
00052   T0c_x_.row(3) << 0, 0, 0, 1;
00053   //   T0c_x_.block(0,0,3,3) << -1, 0, 0, 0, -1, 0, 0, 0, 1;
00054   //   T0c_x_.col(3) << 0, 0, -1, 1;
00055   //   T0c_x_.row(3) << 0, 0, 0, 1;
00056   
00057   T0c_0_=cTo_.inverse();
00058 
00059  
00060   // if(output_files_){
00061   //   const char * outputFilename       = path_.c_str();
00062   //   std::ofstream myfile;
00063   //   myfile.open (outputFilename, std::ios::out | std::ios::app | std::ios::binary);
00064   //   myfile << cTo_;
00065   //   myfile << "\n \n";
00066   //   myfile.close();
00067   // }
00068   
00069   //camera update
00070   //T0c_new = diTj_int + T0c_0;
00071   //Tc0 = T0c_new.inverse();
00072 
00073   T0c_new_=T0c_0_;
00074 
00075   // Extracting values 
00076 
00077   Eigen::MatrixXf cam_pose(6,1);
00078   Eigen::Matrix3f Rot;
00079   cam_pose(0,0)=T0c_new_(0,3);
00080   cam_pose(1,0)=T0c_new_(1,3);
00081   cam_pose(2,0)=T0c_new_(2,3);
00082   Rot=T0c_new_.block(0,0,3,3);
00083   cam_pose.block(3,0,3,1)=Rot.eulerAngles(0,1,2);
00084 
00085   if(output_files_){
00086     const char * outputFilename  = "/home/asantamaria/Desktop/poses.txt";
00087     std::ofstream myfile;
00088     myfile.open (outputFilename, std::ios::out | std::ios::app | std::ios::binary);
00089     myfile << cam_pose;
00090     myfile << "\n \n";
00091     myfile.close();
00092 
00093   }
00094 
00095   Tc0_=cTo_;
00096   //Actual features
00097   //Features transform r.t.camera 
00098   cP_ = Tc0_ * P0_;
00099   //image_projection(f,ff,u0,v0,cP);
00100 
00101   //features_vector(cP);
00102   ccP_=cP_;
00103 
00104   features_vector();
00105   S_ = s_;
00106 
00107   //Desired features_vector
00108   Eigen::Matrix4f Tc0_x;
00109   Tc0_x=T0c_x_.inverse();
00110   cP_x_ = Tc0_x * P0_; 
00111   //image_projection(f,ff,u0,v0,cP_x);     
00112   //features_vector(cP);
00113   ccP_=cP_x_;
00114    
00115   features_vector();
00116   S_x_ = s_;
00117 
00118   //Computation of image jacobian
00119   //Object coordinates r.t. camera frame (in this case world)
00120   pj_ = Tc0_ * pn_;
00121  
00122   //image_projection(f,f,u0,v0,pj);
00123   image_projection(ff_,ff_);
00124 
00125   //noise add
00126   Eigen::MatrixXf ran(2,n_);
00127   ran.setRandom();
00128   uv_ = uv_ + noise_ * ran;
00129 
00130   //Jacobian
00131   if (traditional_){
00132     compute_jacobian_t();
00133   }
00134   else {
00135     compute_jacobian_u();  
00136   }
00137 
00138   //Diferential change of T0c under Vc
00139   K_control(); 
00140 
00141   Eigen::Matrix4f diTj;
00142   diTj=Eigen::Matrix4f::Zero();
00143   
00144   diTj = T0c_new_ * V_mod_;
00145 
00146   //Integration aproximation
00147   diTj_int_ = diTj_int_ + diTj * secs_;
00148  
00149   if (quadrotor_){ 
00150 
00151     if (this->arm_unina_ || this->arm_catec_){
00152       qa_kinematics();
00153       qa_control();
00154       //Arm positions
00155       QQ_.block(6,0,this->nj_,1) = QQ_.block(6,0,this->nj_,1)+(Velqa_.block(6,0,this->nj_,1) * secs_);
00156       QQ=QQ_;
00157       
00158     }
00159     else {
00160       q_control();
00161     }
00162   }
00163 
00164   Vel_quad=Vel_;
00165   
00166   
00167   this->unlock();
00168 }
00169 
00171 void Uncalibvs_simAlgorithm::base_rtw(){
00172 
00173   if (random_points_){  
00175     n_=9;
00176     // Points of the object
00177     pn_ = Eigen::MatrixXf::Zero(4,n_);
00178     pn_=1*pn_.setRandom();
00179     pn_.row(3) = Eigen::VectorXf::Ones(n_);
00180 
00181    
00182     cj_0_= Eigen::MatrixXf::Zero(3,3); 
00183     cj_0_(0,0)=pn_.row(0).mean();
00184     cj_0_(1,0)=pn_.row(1).mean();
00185     cj_0_(2,0)=pn_.row(2).mean();
00186 
00187     // Computing the base points
00188     Eigen::MatrixXf q(3,n_);
00189     q=pn_.block(0,0,3,n_);
00190     q.colwise()-=cj_0_.col(0);
00191 
00192     // Assemble the correlation matrix Q = q * q'
00193     Eigen::Matrix3f Q = (q * q.transpose());
00194 
00195     // Compute the Singular Value Decomposition
00196     Eigen::JacobiSVD<Eigen::Matrix3f> svd (Q, Eigen::ComputeFullU | Eigen::ComputeFullV);
00197     //Eigen::Matrix3f u = svd.matrixU ();
00198     Eigen::Matrix3f v = svd.matrixV ();
00199 
00200     cj_0_.col(1)=cj_0_.col(0)+v.col(0);
00201     //with this library the second column of v appear sign changed
00202     cj_0_.col(2)=cj_0_.col(0)-v.col(1);
00203 
00204     // check the planarity
00205     if ( svd.singularValues()(2)<0.00001){
00206       planar_=true; 
00207     }
00208     else {
00209       planar_=false; 
00210     }
00211 
00212     Eigen::MatrixXf dd1(3,1),dd2(3,1),dd3(3,1);       
00213     if (planar_){
00214       std::cout << "\n" << \
00215       "**************************************** Planar case ***************************************" \
00216       << std::endl;  
00217       P0_= Eigen::MatrixXf::Zero(4,3);  
00218       P0_.block(0,0,3,3)=cj_0_;
00219       P0_.row(3) << 1, 1, 1;  
00220    
00221       Eigen::MatrixXf D(3,2),DD(2,2);
00222     
00223       dd1=cj_0_.col(1).array()-cj_0_.col(0).array();
00224       dd2=cj_0_.col(2).array()-cj_0_.col(0).array();
00225       D.col(0)=dd1;
00226       D.col(1)=dd2;
00227       DD=D.transpose()*D;
00228     
00229       // alfas linear combination of vectors
00230       alfas_= Eigen::MatrixXf::Zero(3,n_);
00231       // alfas.resize(3,n);
00232       alfas_.block(1,0,2,4)=(DD.inverse()*D.transpose()) * q;
00233       //alfas.block(1,0,2,4)=D.inverse() * q;
00234       alfas_.row(0)=Eigen::MatrixXf::Ones(1,n_)-alfas_.block(1,0,2,n_).colwise().sum();
00235     }  
00236     else{
00237       std::cout << "\n" << \
00238       "**************************************** NON Planar case ***************************************" \
00239       << std::endl;
00240     
00241       // resizing the base points to 4
00242       Eigen::Matrix3f Temp;
00243       Temp=cj_0_;
00244       cj_0_.resize(3,4);
00245       cj_0_.block(0,0,3,3)=Temp;
00246     
00247       cj_0_.col(3)=cj_0_.col(0)+v.col(2);
00248       P0_= Eigen::MatrixXf::Zero(4,4); 
00249       // P0.resize(4,4);
00250       P0_.block(0,0,3,4)=cj_0_;
00251       P0_.row(3) << 1, 1, 1, 1;
00252 
00253       dd1=cj_0_.col(1).array()-cj_0_.col(0).array();
00254       dd2=cj_0_.col(2).array()-cj_0_.col(0).array();
00255       dd3=cj_0_.col(3).array()-cj_0_.col(0).array();
00256 
00257       Eigen::MatrixXf D(3,3),DD(2,2);
00258       D.col(0)=dd1;
00259       D.col(1)=dd2;
00260       D.col(2)=dd3;
00261       DD=D.transpose()*D;
00262       //alfas linear combination of vectors
00263       alfas_= Eigen::MatrixXf::Zero(4,n_);
00264       // alfas.resize(4,n);
00265       alfas_.block(1,0,3,n_)=(DD.inverse()*D.transpose()) * q;
00266       // alfas.block(1,0,3,4)=D.inverse() * q;
00267       alfas_.row(0)=Eigen::MatrixXf::Ones(1,n_)-alfas_.block(1,0,3,n_).colwise().sum();  
00268     }
00269   }
00270   else {
00272     n_=9;
00273   
00274     //original points
00275     pn_ = Eigen::MatrixXf::Zero(4,n_);
00276     pn_.row(0) << -0.124725, -0.431413, 0.375723, 0.658402, -0.29928, 0.314608, -0.203127, -0.0350187, -0.70468;
00277     pn_.row(1) << 0.86367, 0.477069, -0.668052, -0.339326, 0.37334, 0.717353, 0.629534, -0.56835, 0.762124;
00278     pn_.row(2) << 0.86162, 0.279958, -0.119791, -0.542064, 0.912936, -0.12088, 0.368437, 0.900505, 0.282161;
00279     pn_.row(3) << 1, 1, 1, 1, 1, 1, 1, 1, 1;
00280 
00281     cj_0_= Eigen::MatrixXf::Zero(3,4);
00282   
00283     cj_0_.row(0) << -0.0499455, -0.559669, 0.127189, 0.791961;
00284     cj_0_.row(1) << 0.249707, 0.962512, 0.884623, 0.547683;
00285     cj_0_.row(2) << 0.313654, 0.795411, -0.438347, 0.763547;
00286 
00287   
00288     //base points
00289     P0_ = Eigen::MatrixXf::Zero(4,4);
00290   
00291     P0_.row(0) << -0.0499456, -0.559669, 0.127189, 0.791961;
00292     P0_.row(1) << 0.249707, 0.962513, 0.884623, 0.547683;
00293     P0_.row(2) << 0.313654, 0.795411, -0.438347, 0.763547;
00294     P0_.row(3) << 1, 1, 1, 1;
00295 
00296     //alfas: linear combination of vectors
00297     alfas_= Eigen::MatrixXf::Zero(4,n_); 
00298     alfas_.row(0) << -0.0707542, 0.826173, 2.37142, 1.76233, 0.815866, 0.122787, 0.443096, 2.23324, 0.495841;
00299     alfas_.row(1) << 0.73974, 0.340274, -1.07997, -1.19318, 0.503927, -0.0618209, 0.375215, -0.308004, 0.683816;
00300     alfas_.row(2) << -0.0355018, 0.102124, -0.181349, 0.394987, -0.41633, 0.68826, 0.172827, -0.958066, 0.233048;
00301     alfas_.row(3) << 0.366516, -0.268571, -0.110102, 0.0358625, 0.0965375, 0.250773, 0.00886206, 0.0328262, -0.412705;
00302     
00303   //  //original points
00304   //     pn_ = Eigen::MatrixXf::Zero(4,n_);
00305   //     pn_.row(0) << 0.0970, 0.1089, 0.0919, 0.1033, 0.0829, 0.1032, 0.0997, 0.1109, 0.1008;
00306   //     pn_.row(1) << 0.1029, 0.0885, 0.0706, 0.0925, 0.0990, 0.1031, 0.0984, 0.1111, 0.0879;
00307   //     pn_.row(2) << 0.0921, 0.0893, 0.1144, 0.1137, 0.0976, 0.0914, 0.1063, 0.0914, 0.0889;
00308   //     pn_.row(3) << 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000;
00309   // 
00310   //     cj_0_= Eigen::MatrixXf::Zero(3,4);
00311   //   
00312   //     cj_0_.row(0) << 0.0100, -0.0208, 0.0801, 0.0743;
00313   //     cj_0_.row(1) << 0.0095, -0.0647, -0.0505, 0.0393;
00314   //     cj_0_.row(2) << 0.0098, 0.0694, -0.0287, 0.0804;
00315   // 
00316   //   
00317   //     //base points
00318   //     P0_ = Eigen::MatrixXf::Zero(4,4);
00319   //   
00320   //     P0_.row(0) << 0.0100, -0.0208, 0.0801, 0.0743;
00321   //     P0_.row(1) << 0.0095, -0.0647, -0.0505, 0.0393;
00322   //     P0_.row(2) << 0.0098, 0.0694, -0.0287, 0.0804;
00323   //     P0_.row(3) << 1.0000, 1.0000, 1.0000, 1.0000;
00324   // 
00325   //     //alfas: linear combination of vectors
00326   //     alfas_= Eigen::MatrixXf::Zero(4,n_); 
00327   //     alfas_.row(0) << 1.1706, 0.9225, 0.6814, 0.7986, 1.2252, 1.1152, 0.9649, 1.1180, 1.0036;
00328   //     alfas_.row(1) << -0.0879, -0.0345, 0.3005, 0.0990, 0.0174, -0.1131, 0.0219, -0.1960, -0.0072;
00329   //     alfas_.row(2) << -0.0446, 0.1363, 0.0285, -0.0207, -0.1405, 0.0009, -0.0524, 0.0073, 0.0852;
00330   //     alfas_.row(3) << -0.0381, -0.0243, -0.0104, 0.1232, -0.1020, -0.0030, 0.0656, 0.0707, -0.0816;
00331   //     
00332     
00333     planar_=false;
00334   }
00335   //   ROS_INFO_STREAM(pn_);
00336   //   ROS_INFO_STREAM(cj_0_);
00337   //   ROS_INFO_STREAM(P0_);
00338   //   ROS_INFO_STREAM(alfas_);
00339 }
00340 
00342 void Uncalibvs_simAlgorithm::initZeros(){
00343 
00344   if (planar_){
00345   //features generic
00346   s_= Eigen::MatrixXf::Zero(6,1);
00347   //actual features
00348   S_= Eigen::MatrixXf::Zero(6,1);
00349   //desired features
00350   S_x_= Eigen::MatrixXf::Zero(6,1);
00351   //Actual points camera frame
00352   cP_= Eigen::MatrixXf::Zero(4,3);
00353   //Desired points camera frame
00354   cP_x_= Eigen::MatrixXf::Zero(4,3);
00355   //Points generic camera frame
00356   ccP_= Eigen::MatrixXf::Zero(4,3);
00357   //Image Jacobian
00358   J_= Eigen::MatrixXf::Zero(6,6);
00359   diff_=Eigen::MatrixXf::Zero(6,1);
00360   }
00361   else {
00362 
00363 
00364   //features generic
00365   s_= Eigen::MatrixXf::Zero(8,1);
00366   //actual features
00367   S_= Eigen::MatrixXf::Zero(8,1);
00368   //desired features
00369   S_x_= Eigen::MatrixXf::Zero(8,1);
00370   //Actual points camera frame
00371   cP_= Eigen::MatrixXf::Zero(4,4);
00372   //Desired points camera frame
00373   cP_x_= Eigen::MatrixXf::Zero(4,4);
00374   //Points generic camera frame
00375   ccP_= Eigen::MatrixXf::Zero(4,4);
00376   //Image Jacobian
00377   J_= Eigen::MatrixXf::Zero(8,6);
00378   diff_=Eigen::MatrixXf::Zero(8,1);
00379   }
00380 
00381 
00382   //image coordinates
00383   uv_= Eigen::MatrixXf::Zero(2,n_);  
00384   //Initial integral condition
00385   diTj_int_=Eigen::Matrix4f::Zero();
00386   //Velocity commands
00387   Vel_= Eigen::MatrixXf::Zero(6,1);  
00388   //lambda=0.125;
00389   u0_=640;
00390   v0_=480;
00391   ff_=400;
00392   ff_old_=ff_;
00393   noise_=0;
00394   phi_old_=0;
00395   
00396   //Arm initial positions
00397   //q_ = Eigen::MatrixXf::Zero(11,1);
00398 }
00399 
00401 void Uncalibvs_simAlgorithm::image_projection(const float& fu, const float& fv){  
00402 
00403   //image plane projection
00404   uv_.row(0) = (pj_.row(0).array()/pj_.row(2).array()) * fu + u0_;
00405   uv_.row(1) = (pj_.row(1).array()/pj_.row(2).array()) * fv + v0_;  
00406 }
00407 
00409 void Uncalibvs_simAlgorithm::features_vector(){
00410 
00411   
00412   if (planar_){
00413     Eigen::ArrayXXf xx(1,3),yy(1,3);
00414     //features vector
00415     xx=(ccP_.row(0).array()/ccP_.row(2).array());
00416     yy=(ccP_.row(1).array()/ccP_.row(2).array());  
00417     //reshape (actually Eigen has no reshape function)
00418     s_(0,0)=xx(0,0);
00419     s_(1,0)=yy(0,0);
00420     s_(2,0)=xx(0,1);
00421     s_(3,0)=yy(0,1);
00422     s_(4,0)=xx(0,2);
00423     s_(5,0)=yy(0,2);
00424   }
00425   else {
00426     Eigen::ArrayXXf xx(1,4),yy(1,4);
00427     //features vector
00428     xx=(ccP_.row(0).array()/ccP_.row(2).array());
00429     yy=(ccP_.row(1).array()/ccP_.row(2).array());  
00430     //reshape (actually Eigen has no reshape function)
00431     s_(0,0)=xx(0,0);
00432     s_(1,0)=yy(0,0);
00433     s_(2,0)=xx(0,1);
00434     s_(3,0)=yy(0,1);
00435     s_(4,0)=xx(0,2);
00436     s_(5,0)=yy(0,2);    
00437     s_(6,0)=xx(0,3);  
00438     s_(7,0)=yy(0,3);
00439   }
00440 }
00441 
00443 void Uncalibvs_simAlgorithm::compute_jacobian_t(){
00444   if (planar_){
00445     Eigen::ArrayXXf xx(1,3),yy(1,3),zz(1,3);
00446     //features vector
00447     xx=(cP_.row(0).array()/cP_.row(2).array());
00448     yy=(cP_.row(1).array()/cP_.row(2).array());  
00449     zz=(cP_.row(2).array());
00450     //Computing Image Jacobian
00451     float xj,yj,zj;
00452     for (int i=0; i<3; ++i){
00453       xj=xx(0,i);
00454       yj=yy(0,i);
00455       zj=zz(0,i);
00456       J_.row((i*2)) << (-1.0/zj), 0.0, (xj/zj), (xj*yj), -(1.0 + (xj*xj)), yj;
00457       J_.row((i*2)+1) << 0.0, (-1.0/zj), (yj/zj), (1.0 + (yj*yj)), -(xj*yj), -xj;
00458     }
00459   }
00460   else {
00461     Eigen::ArrayXXf xx(1,4),yy(1,4),zz(1,4);
00462     //features vector
00463     xx=(cP_.row(0).array()/cP_.row(2).array());
00464     yy=(cP_.row(1).array()/cP_.row(2).array());  
00465     zz=(cP_.row(2).array());
00466     //Computing Image Jacobian
00467     float xj,yj,zj;
00468     for (int i=0; i<4; ++i){
00469       xj=xx(0,i);
00470       yj=yy(0,i);
00471       zj=zz(0,i);
00472       J_.row((i*2)) << (-1.0/zj), 0.0, (xj/zj), (xj*yj), -(1.0 + (xj*xj)), yj;
00473       J_.row((i*2)+1) << 0.0, (-1.0/zj), (yj/zj), (1.0 + (yj*yj)), -(xj*yj), -xj;
00474     }         
00475   }
00476 
00477   // Frame changes 
00478   Eigen::MatrixXf Jtemp(J_.rows(),J_.cols()); 
00479   Jtemp=J_;
00480   J_.col(0)=-Jtemp.col(1);
00481   J_.col(1)=-Jtemp.col(0);
00482   J_.col(2)=-Jtemp.col(2);
00483   J_.col(3)=Jtemp.col(5);
00484   J_.col(4)=Jtemp.col(4);
00485   J_.col(5)=Jtemp.col(3); 
00486 }
00487 
00489 void Uncalibvs_simAlgorithm::compute_jacobian_u(){
00490   if (planar_) { 
00491     Eigen::MatrixXf m;
00492     m=Eigen::MatrixXf::Zero((2*n_),9);
00493     
00494     //Generate M and check the rank
00495     for (int i=0; i<n_; ++i){
00496       for (int j=0; j<3; ++j){
00497         //u rows
00498         m((2*i),(j*3))=alfas_(j,i);
00499         m((2*i),(j*3)+2)=alfas_(j,i)*(u0_-uv_(0,i));
00500         //v rows
00501         m((2*i)+1,(j*3)+1)=alfas_(j,i);
00502         m((2*i)+1,(j*3)+2)=alfas_(j,i)*(v0_-uv_(1,i));
00503       }   
00504     }
00505     
00506     // Assemble the correlation matrix M = m' * m
00507     Eigen::MatrixXf M(9,9),UU(9,9),VV(9,9);
00508     M = (m.transpose() * m);
00509 
00510     // Compute the Singular Value Decomposition
00511     Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eigensolver(M);
00512     Eigen::VectorXf v(9,1);
00513     v =eigensolver.eigenvectors().col(0);
00514 
00515     //Distance equations
00516     int g=0;
00517     Eigen::Vector3f d,va,vb,vc,w;
00518     Eigen::Vector2f b;
00519     Eigen::MatrixXf L(3,2);
00520     L=Eigen::MatrixXf::Zero(3,2);
00521     
00522     for (int i=0; i<2; ++i){
00523       for (int j=i+1; j<3; ++j){
00524         va=v.block(i*3,0,3,1);
00525         vb=v.block(j*3,0,3,1);
00526         vc=va-vb;
00527         L(g,0)=(vc.topRows(2).transpose()*vc.topRows(2));
00528         L(g,1)= (vc(2)*vc(2));
00529         w = cj_0_.col(i)-cj_0_.col(j);
00530         d(g,0)=(w.transpose() * w);
00531         g=g+1;
00532       }
00533     }
00534   
00535     Eigen::Matrix2f LL;
00536     Eigen::MatrixXf L_inv(3,2);
00537 
00538     LL=(L.transpose()*L);
00539     L_inv=LL.inverse()*L.transpose();
00540     b(0)= L_inv.row(0) * d;
00541     b(1)= L_inv.row(1) * d;
00542 
00543     //Obtaining Beta and ff
00544 
00545     float Beta=+sqrt(fabs(b(0)));
00546     ff_=+sqrt(fabs(b(1)))/Beta;
00547 
00548     ff_old_=ff_;
00549 
00550     Eigen::VectorXf C2(9,1);
00551 
00552     C2=Beta*v;
00553 
00554     //Check the sqrt correct sign
00555     Eigen::Matrix3f check;
00556     check.col(0)=C2.block(0,0,3,1);
00557     check.col(1)=C2.block(3,0,3,1);
00558     check.col(2)=C2.block(6,0,3,1);
00559     
00560     if (check.determinant()>0){
00561       C2=-C2;  
00562     }
00563     C2(2,0)=C2(2,0)*ff_;
00564     C2(5,0)=C2(5,0)*ff_;
00565     C2(8,0)=C2(8,0)*ff_;
00566 
00567     //Computing Image Jacobian
00568     float xj,yj,zj;
00569     for (int i=0; i<3; ++i){
00570       xj=C2((i*3),0);
00571       yj=C2((i*3)+1,0);
00572       zj=C2((i*3)+2,0);
00573       J_.row((i*2)) << (-1.0/zj), 0.0, (xj/zj), (xj*yj), -(1.0 + (xj*xj)), yj;
00574       J_.row((i*2)+1) << 0.0, (-1.0/zj), (yj/zj), (1.0 + (yj*yj)), -(xj*yj), -xj;
00575     }
00576   }
00577 
00579   else {
00580     Eigen::MatrixXf m;
00581     m=Eigen::MatrixXf::Zero((2*n_),12);
00582 
00583     //Generate M and check the rank
00584     for (int i=0; i<n_; ++i){
00585       for (int j=0; j<4; ++j){
00586         //u rows
00587         m((2*i),(j*3))=alfas_(j,i);
00588         m((2*i),(j*3)+2)=alfas_(j,i)*(u0_-uv_(0,i));
00589     
00590         //v rows
00591         m((2*i)+1,(j*3)+1)=alfas_(j,i);
00592         m((2*i)+1,(j*3)+2)=alfas_(j,i)*(v0_-uv_(1,i));
00593       }   
00594     }
00595 
00596     // Assemble the correlation matrix M = m' * m
00597     Eigen::MatrixXf M(12,12),UU(12,12),VV(12,12);
00598     M = (m.transpose() * m);
00599 
00600     // Compute the Singular Value Decomposition
00601     Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eigensolver(M);
00602     Eigen::VectorXf v(12,1);
00603     v =eigensolver.eigenvectors().col(0);
00604 
00605     //Distance equations
00606     int g=0;
00607     Eigen::Vector3f va,vb,vc,w;
00608     Eigen::VectorXf d(6,1);
00609     Eigen::Vector2f b;
00610     Eigen::MatrixXf L;
00611     L=Eigen::MatrixXf::Zero(6,2);
00612     
00613     for (int i=0; i<3; ++i){
00614       for (int j=i+1; j<4; ++j){
00615         va=v.block(i*3,0,3,1);
00616         vb=v.block(j*3,0,3,1);
00617         vc=va-vb;
00618         L(g,0)=(vc.topRows(2).transpose()*vc.topRows(2));
00619         L(g,1)= (vc(2)*vc(2));
00620         w = cj_0_.col(i)-cj_0_.col(j);
00621         d(g,0)=(w.transpose() * w);
00622         g=g+1;
00623       }
00624     }
00625 
00626     Eigen::Matrix2f LL;
00627     Eigen::MatrixXf L_inv(6,2);
00628 
00629     LL=(L.transpose()*L);
00630     L_inv=LL.inverse()*L.transpose();
00631     b(0)= L_inv.row(0) * d;
00632     b(1)= L_inv.row(1) * d;
00633     
00634     //Obtaining Beta and ff
00635     float Beta=+sqrt(fabs(b(0)));
00636     ff_=+sqrt(fabs(b(1)))/Beta;
00637 
00638     ff_old_=ff_;
00639     
00640     Eigen::VectorXf C2(12,1);
00641 
00642     C2=Beta*v;
00643 
00644     //Check the sqrt correct sign
00645     Eigen::Vector3f cc1,cc2,cc3;
00646     cc1=(C2.block(3,0,3,1)-C2.block(0,0,3,1));
00647     cc2=(C2.block(6,0,3,1)-C2.block(0,0,3,1));
00648     cc3=(C2.block(9,0,3,1)-C2.block(0,0,3,1));
00649      
00650     Eigen::Vector3f ccc1,ccc2,ccc3;
00651     ccc1=cc1.cross(cc2);
00652     ccc2=cc1.cross(cc3);
00653     ccc3=cc2.cross(cc3);
00654      
00655     float oo1,oo2,oo3; 
00656     oo1=(ccc1.transpose()*cc3);
00657     oo2=(ccc2.transpose()*cc2);
00658     oo3=(ccc3.transpose()*cc1);
00659      
00660     if ((oo1 < 0) || (oo2>0) || (oo3<0)){
00661       C2=-C2;  
00662     }
00663     C2(2,0)=C2(2,0)*ff_;
00664     C2(5,0)=C2(5,0)*ff_;
00665     C2(8,0)=C2(8,0)*ff_;
00666     C2(11,0)=C2(11,0)*ff_;
00667     
00668     //Computing Image Jacobian
00669     float xj,yj,zj;
00670     for (int i=0; i<4; ++i){
00671       xj=C2((i*3),0);
00672       yj=C2((i*3)+1,0);
00673       zj=C2((i*3)+2,0);
00674       J_.row((i*2)) << (-1.0/zj), 0.0, (xj/zj), (xj*yj), -(1.0 + (xj*xj)), yj;
00675       J_.row((i*2)+1) << 0.0, (-1.0/zj), (yj/zj), (1.0 + (yj*yj)), -(xj*yj), -xj;
00676     }   
00677   }
00678 
00679   // Frame changes 
00680   Eigen::MatrixXf Jtemp(J_.rows(),J_.cols()); 
00681   Jtemp=J_;
00682   J_.col(0)=Jtemp.col(1);
00683   J_.col(1)=Jtemp.col(0);
00684   J_.col(2)=-Jtemp.col(2);
00685   J_.col(3)=Jtemp.col(5);
00686   J_.col(4)=Jtemp.col(4);
00687   J_.col(5)=Jtemp.col(3);  
00688 }
00689 
00691 void Uncalibvs_simAlgorithm::K_control(){
00692   if (planar_) {
00693     // features error
00694     diff_=S_.array()-S_x_.array();
00695     
00696     //Proportional control
00697     Eigen::MatrixXf J_pseudo(6,6);
00698     J_pseudo=Eigen::MatrixXf::Zero(6,6);
00699     J_pseudo=J_.inverse();
00700     Vel_=-lambda_*(J_pseudo*diff_);
00701   }
00702 
00703   else {
00704     // features error
00705     diff_=S_.array()-S_x_.array();
00706     
00707     Eigen::MatrixXf JJ(6,6);
00708 
00709     JJ=J_.transpose()*J_;
00710     Eigen::MatrixXf J_pseudo(8,6);
00711     J_pseudo=Eigen::MatrixXf::Zero(8,6);
00712     J_pseudo=JJ.inverse()*J_.transpose();  
00713 
00714     //Proportional control
00715     Vel_=-lambda_*(J_pseudo*diff_);
00716   }
00717   
00718   Eigen::MatrixXf v_linear(3,1),v_angular(3,1);
00719   Eigen::Matrix3f skew_v_angular;
00720     
00721   //Lineal Velocity
00722   v_linear = Vel_.block(0,0,3,1);
00723     
00724   //Angular velocity
00725   v_angular = Vel_.block(3,0,3,1);
00726 
00727   //Skew-symmetric matrix 
00728   skew_v_angular.row(0) << 0, -v_angular(2), v_angular(1);
00729   skew_v_angular.row(1) << v_angular(2), 0, -v_angular(0);
00730   skew_v_angular.row(2) << -v_angular(1), v_angular(0), 0;
00731 
00732   //Using modified velocity matrix 
00733   V_mod_.block(0,0,3,3)=skew_v_angular;
00734   V_mod_.block(0,3,3,1)=v_linear;
00735   V_mod_.row(3) << 0, 0, 0, 0; 
00736 
00737   // Extracting values 
00738   if(output_files_){
00739     const char * outputFilename  = "/home/asantamaria/Desktop/features_error.txt";
00740     std::ofstream myfile;
00741     myfile.open (outputFilename, std::ios::out | std::ios::app | std::ios::binary);
00742     myfile << diff_;
00743     myfile << "\n \n";
00744     myfile.close();
00745   }
00746 }
00747 
00749 void Uncalibvs_simAlgorithm::q_control(){
00750   // Underactuated Quadrotor /////////////////////////////////////////////        
00751   
00752   Eigen::MatrixXf J1(8,4),J2(8,2),V1(4,1);
00753       
00754   J1.col(0)=J_.col(0);
00755   J1.col(1)=J_.col(1);
00756   J1.col(2)=J_.col(2);
00757   J1.col(3)=J_.col(5);
00758 
00759   J2.col(0)=J_.col(3);
00760   J2.col(1)=J_.col(4);
00761 
00762   Eigen::MatrixXf JJ1(4,4);
00763   Eigen::MatrixXf J1_pseudo(4,8);
00764   //pseudo inverse of J1
00765   JJ1=J1.transpose()*J1;
00766   J1_pseudo=JJ1.inverse()*J1.transpose();  
00767  
00768   //V1=-J1_pseudo*((lambda*diff)+(J2*V2_));
00769   V1=-J1_pseudo*lambda_*(diff_+(J2*V2_));
00770       
00771   Eigen::MatrixXf Velq(6,1);
00772   Velq=Eigen::MatrixXf::Zero(6,1);
00773 
00774   Velq.block(0,0,3,1)=V1.block(0,0,3,1);
00775   Velq(5,0)=V1(3,0);
00776       
00777   Vel_=Velq.block(0,0,6,1);
00778 }
00779 
00781 void Uncalibvs_simAlgorithm::qa_kinematics(){
00782   //Initialize Quadrotor and Arm terms
00783   // constructs the kdl solvers in non-realtime
00784   jnt_to_pose_solver_.reset(new KDL::ChainFkSolverPos_recursive(chain_));
00785   jnt_to_jac_solver_.reset(new KDL::ChainJntToJacSolver(chain_));
00786    
00787   // Create joint array
00788   this->nj_ = chain_.getNrOfJoints();
00789   jnt_pos_ = KDL::JntArray(this->nj_);
00790   // resizes the joint state vectors in non-realtime
00791   jnt_pos_.resize(this->nj_);
00792   jacobian_.resize(this->nj_);
00793    
00794   for(unsigned int i=0; i < this->nj_; i++){
00795     jnt_pos_.data(i) = QQ_(6+i,0);
00796   }
00797 
00798   // computes Cartesian pose in realtime
00799   KDL::Frame kdlTarm;
00800   jnt_to_pose_solver_->JntToCart(jnt_pos_, kdlTarm);
00801     
00802   double ro,pit,ya;
00803   kdlTarm.M.GetEulerZYX(ya,pit,ro);
00804     
00805   Eigen::Matrix4f Tarm, Tiner;
00806   Eigen::Matrix3f Rarm;
00807   // euler convention zyx    
00808   Rarm = Eigen::AngleAxisf(ro, Eigen::Vector3f::UnitZ()) \
00809         * Eigen::AngleAxisf(pit, Eigen::Vector3f::UnitY()) \
00810         * Eigen::AngleAxisf(ya, Eigen::Vector3f::UnitX());
00811  
00812   Tarm.block(0,0,3,3)=Rarm;
00813   Tarm(0,3) = (double)kdlTarm.p.data[0];
00814   Tarm(1,3) = (double)kdlTarm.p.data[1];
00815   Tarm(2,3) = (double)kdlTarm.p.data[2];
00816   Tarm.row(3) << 0, 0, 0, 1;
00817    
00818   // Tiner=Tc0_*Tarm.inverse();
00819   Tiner=T0c_new_*Tarm.inverse();
00820     
00821   //Quadrotor linear positions
00822   QQ_.block(0,0,3,1) = Tiner.block(0,3,3,1);
00823   Eigen::Matrix3f Riner;
00824   Riner=Tiner.block(0,0,3,3);
00825   //Quadrotor angles
00826   QQ_.block(3,0,3,1) = Riner.eulerAngles(0,1,2);
00827    
00828   // compute Jacobian in realtime
00829   jnt_to_jac_solver_->JntToJac(jnt_pos_, jacobian_);
00830   
00831   Jqa_=Eigen::MatrixXf::Zero(6,6+this->nj_);
00832   
00833   // Quadrotor Jacobian
00834 
00835   //Jqa_.block(0,0,6,6)=(Eigen::MatrixXf::Identity(6,6));
00836 
00837   double psi,theta,phi;
00838   psi=QQ_(3,0);
00839   theta=QQ_(4,0);
00840   phi=QQ_(5,0);
00841   
00842   Eigen::MatrixXf Jq(6,6);
00843   Jq(0,0)=cos(psi)*cos(theta);
00844   Jq(0,1)=sin(phi)*cos(psi)*sin(theta)-cos(phi)*sin(psi);
00845   Jq(0,2)=cos(phi)*cos(psi)*sin(theta)+sin(phi)*sin(psi);
00846   Jq(1,0)=sin(psi)*cos(theta);
00847   Jq(1,1)=sin(phi)*sin(psi)*sin(theta)+cos(phi)*cos(psi);
00848 
00849   Jq(1,2)=cos(phi)*sin(psi)*sin(theta)-sin(phi)*cos(psi);
00850   Jq(2,0)=-sin(theta);
00851   Jq(2,1)=sin(phi)*cos(theta);
00852   Jq(2,2)=cos(phi)*cos(theta);
00853   Jq.block(0,3,3,3)=Eigen::MatrixXf::Zero(3,3);
00854   Jq.block(3,0,3,3)=Eigen::MatrixXf::Zero(3,3);
00855   Jq(3,3)=1;
00856   Jq(3,4)=sin(phi)*tan(theta);
00857   Jq(3,5)=cos(phi)*tan(theta);
00858   Jq(4,3)=0;
00859   Jq(4,4)=cos(phi);
00860   Jq(4,5)=-sin(phi);
00861   Jq(5,3)=0;
00862   Jq(5,4)=sin(phi)*cos(theta);
00863   Jq(5,5)=cos(phi)*cos(theta);
00864 
00865   Jqa_.block(0,0,6,6)=Jq.block(0,0,6,6);
00866   Jqa_.block(0,1,6,2)=-Jqa_.block(0,1,6,2);
00867   Jqa_.block(0,4,6,2)=-Jqa_.block(0,4,6,2);
00868   //convert from doubles to float
00869   for (int i=0; i<6; ++i){
00870     for (int j=0; j<(int)this->nj_; ++j){
00871       Jqa_(i,6+j)=(float)jacobian_.data(i,j);
00872     }
00873   }
00874   //ROS_INFO_STREAM(Jqa_);
00875 }
00876 
00878 void Uncalibvs_simAlgorithm::qa_control(){
00879   // Underactuated Quadrotor /////////////////////////////////////////////////// 
00880 
00881   Eigen::MatrixXf J1(8,4),J2(8,2),V1(4,1),Jqa1(6,4+this->nj_),Jqa2(6,2),Vtotal(4+this->nj_,1);
00882     
00883   // Computing secondary task ////////////////////////
00884   if (this->arm_unina_) v_null_space_unina();
00885   else if (this->arm_catec_) v_null_space_catec();
00886 
00887   // 9 DOF Extracting wx and wy from quadrotor //////////////////
00888 
00889   Jqa1.block(0,0,6,3)=Jqa_.block(0,0,6,3);
00890   Jqa1.block(0,3,6,1+this->nj_)=Jqa_.block(0,5,6,1+this->nj_);
00891   Jqa2=Jqa_.block(0,3,6,2);
00892   Eigen::MatrixXf eye(4+this->nj_,4+this->nj_);
00893   eye=Eigen::MatrixXf::Identity(4+this->nj_,4+this->nj_);
00894 
00895   // compute pseudo inverse /////////////
00896   Eigen::MatrixXf Jqa1_pseudo(4+this->nj_,6);
00897   Jqa1_pseudo = calcPinv(Jqa1);
00898 
00899   //ROS_INFO_STREAM(this->Vel_);
00900 
00901   // this->Vel_(0,0) = 0.1;
00902   // this->Vel_(1,0) = 0.1;
00903   // this->Vel_(2,0) = 0.1;
00904   // this->Vel_(3,0) = 0.1;
00905   // this->Vel_(4,0) = 0.1;
00906   // this->Vel_(5,0) = 0.1;
00907 
00908   // Control law ////////////////////////
00909   Vtotal = (Jqa1_pseudo * (Vel_-Jqa2*V2_)) + (eye-(Jqa1_pseudo*Jqa1))*Vqa0_; 
00910 
00911   Vtotal = this->lambda_robot_.array()*Vtotal.array();
00912 
00913   // Check a singular configuration /////
00914   if (std::isnan(Vtotal(0,0)))
00915   {
00916     Vtotal=Eigen::MatrixXf::Zero(4+this->nj_,1);
00917   } 
00918 
00919 ROS_INFO_STREAM(Vel_);
00920 
00921   // Rearranging ////////////////////////
00922   Velqa_=Eigen::MatrixXf::Zero(6+this->nj_,1);
00923   Velqa_.block(0,0,3,1)=Vtotal.block(0,0,3,1);
00924   Velqa_.block(5,0,1+this->nj_,1)=Vtotal.block(3,0,1+this->nj_,1);
00925   Velqa_.block(6,0,1,1)=-Velqa_.block(6,0,1,1);
00926   Vel_=Velqa_.block(0,0,6,1);
00927 
00928   // 11DOF Without extracting wx and wy ///////////////////////////////////////////
00929 
00930   // Eigen::MatrixXf eye2(6+this->nj_,6+this->nj_);
00931   // eye2=Eigen::MatrixXf::Identity(6+this->nj_,6+this->nj_);
00932   // Eigen::MatrixXf Vqa0_2=Eigen::MatrixXf::Zero(11,1); 
00933   // Vqa0_2.block(0,0,4+this->nj_,1)=Vqa0_;
00934 
00935   // compute pseudo inverses ///////////
00936   // Eigen::MatrixXf Jqa_pseudo(6+this->nj_,6);
00937   // Jqa_pseudo = calcPinv(Jqa_);
00938 
00939   // Control law ///////////////////////
00940   // Velqa_=Jqa_pseudo*Vel_+(eye2-(Jqa_pseudo*Jqa_))*Vqa0_2;
00941   // Vel_=Velqa_.block(0,0,6,1);
00942 
00943 
00944   // Extracting values 
00945   if(output_files_){
00946     const char * outputFilename  = path_.c_str();
00947     std::ofstream myfile;
00948     myfile.open (outputFilename, std::ios::out | std::ios::app | std::ios::binary);
00949     myfile << Vtotal;
00950     myfile << "\n \n";
00951     myfile.close();
00952   }
00953 }
00954 
00956 void Uncalibvs_simAlgorithm::v_null_space_unina(){
00957 
00958   float ndof = 4+this->nj_;
00959   Eigen::MatrixXf w(this->nj_,1);
00960   Vqa0_= Eigen::MatrixXf::Zero(ndof,1);
00961   
00962   // num of segments
00963   // unsigned int js = chain_.getNrOfSegments();
00964 
00965   // joints positions
00966   //Eigen::MatrixXf qa(this->nj_,1);
00967   //qa = this->QQ_.block(6,0,this->nj_,1);
00968 
00969   // std::vector<KDL::Segment> segment(js);
00970   // std::vector<KDL::Frame> frame(this->nj_);
00971   // std::vector<Eigen::Matrix4f> transf(this->nj_);
00972 
00973   // segment.reserve(js);
00974   // frame.reserve(this->nj_);
00975   // transf.reserve(this->nj_);
00976 
00977   // segment.push_back(chain_.getSegment(0));
00978   // frame.push_back(seg[0].pose(qa(0,0)));
00979   // transf.push_back(GetTransform(frame[0]));
00980   // ROS_INFO_STREAM(frame[0].M);
00981 
00982   // for (unsigned int i = 0; i < 1; i++)
00983   // {
00984   //   seg.push_back(chain_.getSegment(i));
00985 
00986   //   // the first link is a fixed one and we are not intereseted in it
00987   //   if (i>0)
00988   //   {
00989   //     frame.push_back(seg[i].pose(qa(i-1,0)));
00990   //     transf.push_back(GetTransform(frame[i]));
00991   //     ROS_INFO_STREAM(transf[i]);
00992   //   }    
00993   // }
00994   KDL::Segment segment0,segment1,segment2,segment3,segment4,segment5;
00995   segment0 = chain_.getSegment(0);
00996   segment1 = chain_.getSegment(1);
00997   segment2 = chain_.getSegment(2);
00998   segment3 = chain_.getSegment(3);
00999   segment4 = chain_.getSegment(4);
01000   segment5 = chain_.getSegment(5);
01001 
01002   double dq=0.01;
01003 
01004   Eigen::MatrixXf qa_old(this->nj_,1),qa_new(this->nj_,1);
01005   qa_old=this->QQ_.block(6,0,this->nj_,1);
01006   qa_new=this->QQ_.block(6,0,this->nj_,1);
01007 
01008   for (unsigned int i = 0; i < this->nj_; ++i){
01009 
01010     qa_old(i,0)=qa_old(i,0)-dq;
01011     qa_new(i,0)=qa_new(i,0)+dq;
01012 
01013     KDL::Frame pose1_old,pose2_old,pose3_old,pose4_old,pose5_old;
01014     KDL::Frame pose1_new,pose2_new,pose3_new,pose4_new,pose5_new;
01015     pose1_old=segment1.pose(qa_old(0,0));
01016     pose2_old=segment2.pose(qa_old(1,0));
01017     pose3_old=segment3.pose(qa_old(2,0));
01018     pose4_old=segment4.pose(qa_old(3,0));
01019     pose5_old=segment5.pose(qa_old(4,0));
01020     pose1_new=segment1.pose(qa_new(0,0));
01021     pose2_new=segment2.pose(qa_new(1,0));
01022     pose3_new=segment3.pose(qa_new(2,0));
01023     pose4_new=segment4.pose(qa_new(3,0));
01024     pose5_new=segment5.pose(qa_new(4,0));
01025 
01026     Eigen::Matrix4f T1_old,T2_old,T3_old,T4_old,T5_old;
01027     Eigen::Matrix4f T1_new,T2_new,T3_new,T4_new,T5_new;
01028     T1_old=GetTransform(pose1_old);
01029     T2_old=GetTransform(pose2_old);
01030     T3_old=GetTransform(pose3_old);
01031     T4_old=GetTransform(pose4_old);
01032     T5_old=GetTransform(pose5_old);
01033     T1_new=GetTransform(pose1_new);
01034     T2_new=GetTransform(pose2_new);
01035     T3_new=GetTransform(pose3_new);
01036     T4_new=GetTransform(pose4_new);
01037     T5_new=GetTransform(pose5_new);
01038 
01039     Eigen::MatrixXf pini(4,1);
01040     pini.col(0) << 0,0,0,1;
01041   
01042     //Fixed transform between base_link and arm_base
01043     Eigen::Matrix4f Tbase=Eigen::Matrix4f::Zero();
01044     Tbase(0,2)=1;
01045     Tbase(1,1)=1;
01046     Tbase(2,0)=-1;
01047     Tbase(3,3)=1;
01048 
01049     Eigen::MatrixXf joint0_old(4,1),joint1_old(4,1),joint2_old(4,1),joint3_old(4,1),joint4_old(4,1),joint5_old(4,1);
01050     Eigen::MatrixXf joint0_new(4,1),joint1_new(4,1),joint2_new(4,1),joint3_new(4,1),joint4_new(4,1),joint5_new(4,1);
01051     joint0_old=Tbase*pini;
01052     joint1_old=Tbase*T1_old*pini;
01053     joint2_old=Tbase*T1_old*T2_old*pini;
01054     joint3_old=Tbase*T1_old*T2_old*T3_old*pini;
01055     joint4_old=Tbase*T1_old*T2_old*T3_old*T4_old*pini;
01056     joint5_old=Tbase*T1_old*T2_old*T3_old*T4_old*T5_old*pini;
01057     joint0_new=Tbase*pini;
01058     joint1_new=Tbase*T1_new*pini;
01059     joint2_new=Tbase*T1_new*T2_new*pini;
01060     joint3_new=Tbase*T1_new*T2_new*T3_new*pini;
01061     joint4_new=Tbase*T1_new*T2_new*T3_new*T4_new*pini;
01062     joint5_new=Tbase*T1_new*T2_new*T3_new*T4_new*T5_new*pini;
01063 
01064     // mass of each link
01065     double m0,m1,m2,m3,m4;
01066     m0=0;
01067     m1=0;
01068     m2=50;
01069     m3=50;
01070     m4=10;
01071 
01072     // middle link distances 
01073     Eigen::MatrixXf d0_old(3,1),d1_old(3,1),d2_old(3,1),d3_old(3,1),d4_old(3,1);
01074     Eigen::MatrixXf d0_new(3,1),d1_new(3,1),d2_new(3,1),d3_new(3,1),d4_new(3,1);
01075     d0_old=(joint1_old-joint0_old)/2;
01076     d1_old=(joint2_old-joint1_old)/2;
01077     d2_old=(joint3_old-joint2_old)/2;
01078     d3_old=(joint4_old-joint3_old)/2;
01079     d4_old=(joint5_old-joint4_old)/2;
01080     d0_new=(joint1_new-joint0_new)/2;
01081     d1_new=(joint2_new-joint1_new)/2;
01082     d2_new=(joint3_new-joint2_new)/2;
01083     d3_new=(joint4_new-joint3_new)/2;
01084     d4_new=(joint5_new-joint4_new)/2;
01085 
01086     Eigen::MatrixXf cg0_old,cg1_old,cg2_old,cg3_old,cg4_old;
01087     Eigen::MatrixXf cg0_new,cg1_new,cg2_new,cg3_new,cg4_new;
01088 
01089     cg0_old=m0*(joint0_old+d0_old);
01090     cg1_old=m1*(joint1_old+d1_old);
01091     cg2_old=m2*(joint2_old+d2_old);
01092     cg3_old=m3*(joint3_old+d3_old);
01093     cg4_old=m4*(joint4_old+d4_old);
01094     cg0_new=m0*(joint0_new+d0_new);
01095     cg1_new=m1*(joint1_new+d1_new);
01096     cg2_new=m2*(joint2_new+d2_new);
01097     cg3_new=m3*(joint3_new+d3_new);
01098     cg4_new=m4*(joint4_new+d4_new); 
01099 
01100     Eigen::MatrixXf rcm_old(3,1),rcm_new(3,1);
01101     rcm_old=(cg0_old+cg1_old+cg2_old+cg3_old+cg4_old)/(m0+m1+m2+m3+m4);
01102     rcm_new=(cg0_new+cg1_new+cg2_new+cg3_new+cg4_new)/(m0+m1+m2+m3+m4);
01103 
01104     w(i,0)=-(((rcm_new(0,0)*rcm_new(0,0)+rcm_new(1,0)*rcm_new(1,0))-(rcm_old(0,0)*rcm_old(0,0)+rcm_old(1,0)*rcm_old(1,0)))/(2*dq));
01105 
01106     // ROS_INFO_STREAM(T1_old);
01107     // ROS_INFO_STREAM(T2_old);
01108     // ROS_INFO_STREAM(T3_old);
01109     // ROS_INFO_STREAM(T4_old);
01110     // ROS_INFO_STREAM(T5_old);
01111     // ROS_INFO_STREAM(joint0_old);
01112     // ROS_INFO_STREAM(joint1_old);
01113     // ROS_INFO_STREAM(joint2_old);
01114     // ROS_INFO_STREAM(joint3_old);
01115     // ROS_INFO_STREAM(joint4_old);
01116     // ROS_INFO_STREAM(joint5_old);
01117     // ROS_INFO_STREAM(rcm_old);
01118 
01119 
01120   }
01121 
01122   Vqa0_.block(4,0,5,1)=100*w;
01123   // ROS_INFO_STREAM(Vqa0_);
01124 
01125   // // Stabilize quadrotor ///////////////////////////////////////////////
01126   //float dq = 0.001;
01127 
01128   //for (unsigned int i = 0; i < this->nj_; ++i)
01129   //{
01130   //     Eigen::MatrixXf q_old(this->nj_,1),q_new(this->nj_,1);
01131   //     Eigen::Matrix4f T_old,T_new,inv_T_old,inv_T_new;
01132 
01133   //     q_old=this->QQ_.block(6,0,this->nj_,1);
01134   //     q_old(i,0)=q_old(i,0)-dq;
01135   //     q_new=this->QQ_.block(6,0,this->nj_,1);
01136   //     q_new(i,0)=q_new(i,0)+dq;
01137 
01138   //     //Arm kinematics OLD values ///////////////////////////////
01139   //     for (unsigned int j = 0; j < this->nj_; ++j)
01140   //     {
01141   //       jnt_pos_.data(j) = q_old(j,0);
01142   //     }
01143   //     // computes Cartesian pose in realtime
01144   //     KDL::Frame kdlTarm;
01145   //     jnt_to_pose_solver_->JntToCart(jnt_pos_, kdlTarm);
01146   //     double ro,pit,ya;
01147   //     kdlTarm.M.GetEulerZYX(ya,pit,ro);
01148   //     Eigen::Matrix3f Rarm;
01149   //     // euler convention zyx    
01150   //     Rarm = Eigen::AngleAxisf(ya, Eigen::Vector3f::UnitZ()) \
01151   //          * Eigen::AngleAxisf(pit, Eigen::Vector3f::UnitY()) \
01152   //          * Eigen::AngleAxisf(ro, Eigen::Vector3f::UnitX());
01153   //     T_old.block(0,0,3,3)=Rarm;
01154   //     T_old(0,3) = (double)kdlTarm.p.data[0];
01155   //     T_old(1,3) = (double)kdlTarm.p.data[1];
01156   //     T_old(2,3) = (double)kdlTarm.p.data[2];
01157   //     T_old.row(3) << 0, 0, 0, 1;
01158   //     //Arm kinematics NEW values
01159 
01160   //     for (unsigned int j = 0; j < this->nj_; ++j)
01161   //     {
01162   //       jnt_pos_.data(j) = q_new(j,0);
01163   //     }
01164   //     // computes Cartesian pose in realtime
01165   //     jnt_to_pose_solver_->JntToCart(jnt_pos_, kdlTarm);
01166   //     kdlTarm.M.GetEulerZYX(ya,pit,ro);
01167   //     // euler convention zyx    
01168   //     Rarm = Eigen::AngleAxisf(ya, Eigen::Vector3f::UnitZ()) \
01169   //          * Eigen::AngleAxisf(pit, Eigen::Vector3f::UnitY()) \
01170   //          * Eigen::AngleAxisf(ro, Eigen::Vector3f::UnitX());
01171   //     T_new.block(0,0,3,3)=Rarm;
01172   //     T_new(0,3) = (double)kdlTarm.p.data[0];
01173   //     T_new(1,3) = (double)kdlTarm.p.data[1];
01174   //     T_new(2,3) = (double)kdlTarm.p.data[2];
01175   //     T_new.row(3) << 0, 0, 0, 1;
01176   //     inv_T_old = this->T0c_new_*T_old.inverse();
01177   //     inv_T_new = this->T0c_new_*T_new.inverse();
01178 
01179   //     Eigen::MatrixXf angles_old(3,1),angles_new(3,1);
01180   //     Eigen::Matrix3f Rot_old,Rot_new;
01181   //     double psi_old,psi_new,theta_old,theta_new;
01182   //     Rot_old = inv_T_old.block(0,0,3,3);
01183   //     Rot_new = inv_T_new.block(0,0,3,3);
01184 
01185   //     angles_old=Rot_old.eulerAngles(2,1,0);
01186   //     angles_new=Rot_new.eulerAngles(2,1,0);
01187     
01188   //     psi_old=angles_old(0);
01189   //     theta_old=angles_old(1);
01190   //     psi_new=angles_new(0);
01191   //     theta_new=angles_new(1);
01192 
01193 
01194   //     // ROS_INFO("Rots");
01195   //     // Eigen::MatrixXf angles(3,1);
01196   //     // angles=this->Rquad_inertial_.eulerAngles(2,1,0);
01197   //     // ROS_INFO_STREAM(angles_old);
01198   //     // ROS_INFO_STREAM(angles);
01199 
01200 
01201   //     w(i,0)=(((psi_new*psi_new)+(theta_new*theta_new))-((psi_old*psi_old)+(theta_old*theta_old)))/dq;
01202   // }
01203 
01204   // Vqa0_.block(4,0,this->nj_,1)=0*w;
01205 
01206 
01207   // Joint Limits ////////////////////////////////////////////////////77
01208 
01209   // Vqa0_.block(4,0,this->nj_,1)=Eigen::MatrixXf::Zero(this->nj_,1);
01210 
01211   // ROS_INFO_STREAM(w);
01212   
01213   // float qxma,qxmi,qxm,qyma,qymi,qym,qzma,qzmi,qzm,qyama,qyami,qyam,a0ma,a0mi,a0m,a1ma,a1mi,a1m,a2ma,a2mi,a2m,a3ma,a3mi,a3m,a4ma,a4mi,a4m;
01214     
01215   // //DOF's
01216   // float ndof=9;
01217             
01218   // //quadrotor Limits
01219   // qxma=10;
01220   // qxmi=-10;
01221   // qxm=0.0;
01222       
01223   // qyma=10;
01224   // qymi=-10;
01225   // qym=0.0;
01226       
01227   // qzma=10;
01228   // qzmi=1.0;
01229   // qzm=4.0;
01230       
01231   // qyama=3.1416;
01232   // qyami=-3.1416;
01233   // qyam=0.0;
01234       
01235   // //arm limits
01236   // a0ma=0.548;
01237   // a0mi=-0.548;
01238   // a0m=0.0;
01239   // //a0ma=0.3;
01240   // //a0mi=-0.3;
01241   // //a0m=0.0;
01242       
01243   // a1ma=1.57;
01244   // a1mi=-1.57;
01245   // a1m=0.0;
01246   // //a1ma=1.0;
01247   // //a1mi=-1.0;
01248   // //a1m=0.0;
01249       
01250   // a2ma=5.23;
01251   // a2mi=0;
01252   // a2m=2.615;
01253   // //a2ma=5.0;
01254   // //a2mi=0.0;
01255   // //a2m=2.5;      
01256        
01257   // a3ma=5.23;
01258   // a3mi=0;
01259   // a3m=2.615;
01260   // //a3ma=5.0;
01261   // //a3mi=0.0;
01262   // //a3m=2.5;
01263       
01264   // a4ma=3.1416;
01265   // a4mi=-3.1416;
01266   // a4m=0.0;
01267   // //a4ma=6.0;
01268   // //a4mi=0.0;
01269   // //a4m=3.0;
01270           
01271   // Vqa0_(0,0)=(-0/ndof)*((QQ_(0,0)-qxm)/((qxma-qxmi)*(qxma-qxmi)));
01272   // Vqa0_(1,0)=(-0/ndof)*((QQ_(1,0)-qym)/((qyma-qymi)*(qyma-qymi)));
01273   // Vqa0_(2,0)=(-50/ndof)*((QQ_(2,0)-qzm)/((qzma-qzmi)*(qzma-qzmi)));
01274   // Vqa0_(3,0)=(-30/ndof)*((QQ_(5,0)-qyam)/((qyama-qyami)*(qyama-qyami)));
01275   // Vqa0_(4,0)=(-100/ndof)*((QQ_(6,0)-a0m)/((a0ma-a0mi)*(a0ma-a0mi)));
01276   // Vqa0_(5,0)=(-100/ndof)*((QQ_(7,0)-a1m)/((a1ma-a1mi)*(a1ma-a1mi)));
01277   // Vqa0_(6,0)=(-100/ndof)*((QQ_(8,0)-a2m)/((a2ma-a2mi)*(a2ma-a2mi)));
01278   // Vqa0_(7,0)=(-100/ndof)*((QQ_(9,0)-a3m)/((a3ma-a3mi)*(a3ma-a3mi)));
01279   // Vqa0_(8,0)=(-30/ndof)*((QQ_(10,0)-a4m)/((a4ma-a4mi)*(a4ma-a4mi)));
01280 }
01281 
01283 void Uncalibvs_simAlgorithm::v_null_space_catec(){
01284 
01285   //DOF's
01286   float ndof=4+this->nj_;
01287   Vqa0_=Eigen::MatrixXf::Zero(ndof,1);
01288   // float qxma,qxmi,qxm,qyma,qymi,qym,qzma,qzmi,qzm,qyama,qyami,qyam,a0ma,a0mi,a0m,a1ma,a1mi,a1m,a2ma,a2mi,a2m,a3ma,a3mi,a3m,a4ma,a4mi,a4m,a5ma,a5mi,a5m;
01289             
01290   // //quadrotor Limits
01291   // qxma=10;
01292   // qxmi=-10;
01293   // qxm=0.0;
01294       
01295   // qyma=10;
01296   // qymi=-10;
01297   // qym=0.0;
01298       
01299   // qzma=10;
01300   // qzmi=1.0;
01301   // qzm=4.0;
01302       
01303   // qyama=3.1416;
01304   // qyami=-3.1416;
01305   // qyam=0.0;
01306       
01307   // //arm limits
01308   // a0ma=0.8726;
01309   // a0mi=-0.8726;
01310   // a0m=0.0;
01311   // //a0ma=0.3;
01312   // //a0mi=-0.3;
01313   // //a0m=0.0;
01314   
01315       
01316   // a1ma=3.14159;
01317   // a1mi=0.0;
01318   // a1m=1.5707;
01319   // //a1ma=1.0;
01320   // //a1mi=-1.0;
01321   // //a1m=0.0;
01322       
01323   // a2ma=0.0;
01324   // a2mi=-3.14159;
01325   // a2m=-1.5707;
01326   // //a2ma=5.0;
01327   // //a2mi=0.0;
01328   // //a2m=2.5;      
01329        
01330   // a3ma=2.6179;
01331   // a3mi=-2.6179;
01332   // a3m=0;
01333   // //a3ma=5.0;
01334   // //a3mi=0.0;
01335   // //a3m=2.5;
01336       
01337   // a4ma=1.5707;
01338   // a4mi=-1.5707;
01339   // a4m=0.0;
01340   // //a4ma=6.0;
01341   // //a4mi=0.0;
01342   // //a4m=3.0;
01343 
01344   // a5ma=2.6179;
01345   // a5mi=-2.6179;
01346   // a5m=0.0;
01347   
01348   // Vqa0_(0,0)=(-0/ndof)*((QQ_(0,0)-qxm)/((qxma-qxmi)*(qxma-qxmi)));
01349   // Vqa0_(1,0)=(-0/ndof)*((QQ_(1,0)-qym)/((qyma-qymi)*(qyma-qymi)));
01350   // Vqa0_(2,0)=(-0/ndof)*((QQ_(2,0)-qzm)/((qzma-qzmi)*(qzma-qzmi)));
01351   // Vqa0_(3,0)=(-0/ndof)*((QQ_(5,0)-qyam)/((qyama-qyami)*(qyama-qyami)));
01352   // Vqa0_(4,0)=(-0/ndof)*((QQ_(6,0)-a0m)/((a0ma-a0mi)*(a0ma-a0mi)));
01353   // Vqa0_(5,0)=(-0/ndof)*((QQ_(7,0)-a1m)/((a1ma-a1mi)*(a1ma-a1mi)));
01354   // Vqa0_(6,0)=(-0/ndof)*((QQ_(8,0)-a2m)/((a2ma-a2mi)*(a2ma-a2mi)));
01355   // Vqa0_(7,0)=(-0/ndof)*((QQ_(9,0)-a3m)/((a3ma-a3mi)*(a3ma-a3mi)));
01356   // Vqa0_(8,0)=(-0/ndof)*((QQ_(10,0)-a4m)/((a4ma-a4mi)*(a4ma-a4mi)));
01357   // Vqa0_(9,0)=(-0/ndof)*((QQ_(11,0)-a5m)/((a5ma-a5mi)*(a5ma-a5mi)));
01358 }
01359 
01361 Eigen::MatrixXf Uncalibvs_simAlgorithm::calcPinv(const Eigen::MatrixXf &a){
01362 using namespace Eigen;
01363         // see : http://en.wikipedia.org/wiki/Moore-Penrose_pseudoinverse#The_general_case_and_the_SVD_method
01364         const MatrixXf* m;
01365         MatrixXf t;
01366         MatrixXf m_pinv;
01367 
01368         // transpose so SVD decomp can work...
01369         if ( a.rows()<a.cols() ){
01370                 t = a.transpose();
01371                 m = &t;
01372         } else {
01373                 m = &a;
01374         }
01375 
01376         // SVD
01377         //Eigen::JacobiSVD<MatrixXd> svd = m->jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
01378         Eigen::JacobiSVD<MatrixXf> svd = m->jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV);
01379         Eigen::MatrixXf vSingular = svd.singularValues();
01380         // Build a diagonal matrix with the Inverted Singular values
01381         // The pseudo inverted singular matrix is easy to compute :
01382         // is formed by replacing every nonzero entry by its reciprocal (inversing).
01383         Eigen::MatrixXf vPseudoInvertedSingular(svd.matrixV().cols(),1);
01384         for (int iRow =0; iRow<vSingular.rows(); iRow++) {
01385                                                          // Todo : Put epsilon in parameter
01386                 if ( fabs(vSingular(iRow))<=1e-10 ) {
01387                         vPseudoInvertedSingular(iRow,0)=0.;
01388                 }
01389                 else {
01390                         vPseudoInvertedSingular(iRow,0)=1./vSingular(iRow);
01391                 }
01392         }
01393         // A little optimization here
01394         Eigen::MatrixXf mAdjointU = svd.matrixU().adjoint().block(0,0,vSingular.rows(),svd.matrixU().adjoint().cols());
01395         // Pseudo-Inversion : V * S * U'
01396         m_pinv = (svd.matrixV() *  vPseudoInvertedSingular.asDiagonal()) * mAdjointU  ;
01397 
01398         // transpose back if necessary
01399         if ( a.rows()<a.cols() )
01400                 return m_pinv.transpose();
01401         
01402         return m_pinv;
01403 }
01404 
01406 void Uncalibvs_simAlgorithm::pseudo_inverse(const Eigen::MatrixXf& M, const Eigen::MatrixXf& Y, Eigen::MatrixXf& X){
01407  // Performs the pseudo inverse such as: m*X=y -> X=(m⁻1*y)
01408 
01409  X = M.fullPivHouseholderQr().solve(Y);
01410  assert(Y.isApprox(M*X));
01411 }
01412 
01414 Eigen::Matrix4f Uncalibvs_simAlgorithm::GetTransform(const KDL::Frame &f){
01415 
01416   double ya,pi,ro;
01417   Eigen::Matrix3f R;
01418   Eigen::Matrix4f T;
01419 
01420   f.M.GetEulerZYX(ya,pi,ro);
01421   
01422   // euler convention zyx    
01423   R = Eigen::AngleAxisf(ya, Eigen::Vector3f::UnitZ()) \
01424     * Eigen::AngleAxisf(pi, Eigen::Vector3f::UnitY()) \
01425     * Eigen::AngleAxisf(ro, Eigen::Vector3f::UnitX());
01426   T.block(0,0,3,3)=R;
01427   T(0,3) = (double)f.p.data[0];
01428   T(1,3) = (double)f.p.data[1];
01429   T(2,3) = (double)f.p.data[2];
01430   T.row(3) << 0, 0, 0, 1;
01431 
01432   return T;
01433 }


iri_uncalibvs_sim
Author(s): Àngel Sanatamaria Navarro
autogenerated on Fri Dec 6 2013 21:57:13