00001 #include "uncalibvs_sim_alg.h"
00002
00003
00004 Uncalibvs_simAlgorithm::Uncalibvs_simAlgorithm(void) {
00005 base_rtw();
00006 initZeros();
00007 }
00008
00009
00010 Uncalibvs_simAlgorithm::~Uncalibvs_simAlgorithm(void){
00011 }
00012
00013
00014 void Uncalibvs_simAlgorithm::config_update(Config& new_cfg, uint32_t level){
00015 this->lock();
00016
00017
00018 this->config_=new_cfg;
00019
00020 this->unlock();
00021 }
00022
00023
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
00049
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
00054
00055
00056
00057 T0c_0_=cTo_.inverse();
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 T0c_new_=T0c_0_;
00074
00075
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
00097
00098 cP_ = Tc0_ * P0_;
00099
00100
00101
00102 ccP_=cP_;
00103
00104 features_vector();
00105 S_ = s_;
00106
00107
00108 Eigen::Matrix4f Tc0_x;
00109 Tc0_x=T0c_x_.inverse();
00110 cP_x_ = Tc0_x * P0_;
00111
00112
00113 ccP_=cP_x_;
00114
00115 features_vector();
00116 S_x_ = s_;
00117
00118
00119
00120 pj_ = Tc0_ * pn_;
00121
00122
00123 image_projection(ff_,ff_);
00124
00125
00126 Eigen::MatrixXf ran(2,n_);
00127 ran.setRandom();
00128 uv_ = uv_ + noise_ * ran;
00129
00130
00131 if (traditional_){
00132 compute_jacobian_t();
00133 }
00134 else {
00135 compute_jacobian_u();
00136 }
00137
00138
00139 K_control();
00140
00141 Eigen::Matrix4f diTj;
00142 diTj=Eigen::Matrix4f::Zero();
00143
00144 diTj = T0c_new_ * V_mod_;
00145
00146
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
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
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
00188 Eigen::MatrixXf q(3,n_);
00189 q=pn_.block(0,0,3,n_);
00190 q.colwise()-=cj_0_.col(0);
00191
00192
00193 Eigen::Matrix3f Q = (q * q.transpose());
00194
00195
00196 Eigen::JacobiSVD<Eigen::Matrix3f> svd (Q, Eigen::ComputeFullU | Eigen::ComputeFullV);
00197
00198 Eigen::Matrix3f v = svd.matrixV ();
00199
00200 cj_0_.col(1)=cj_0_.col(0)+v.col(0);
00201
00202 cj_0_.col(2)=cj_0_.col(0)-v.col(1);
00203
00204
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
00230 alfas_= Eigen::MatrixXf::Zero(3,n_);
00231
00232 alfas_.block(1,0,2,4)=(DD.inverse()*D.transpose()) * q;
00233
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
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
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
00263 alfas_= Eigen::MatrixXf::Zero(4,n_);
00264
00265 alfas_.block(1,0,3,n_)=(DD.inverse()*D.transpose()) * q;
00266
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
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
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
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
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 planar_=false;
00334 }
00335
00336
00337
00338
00339 }
00340
00342 void Uncalibvs_simAlgorithm::initZeros(){
00343
00344 if (planar_){
00345
00346 s_= Eigen::MatrixXf::Zero(6,1);
00347
00348 S_= Eigen::MatrixXf::Zero(6,1);
00349
00350 S_x_= Eigen::MatrixXf::Zero(6,1);
00351
00352 cP_= Eigen::MatrixXf::Zero(4,3);
00353
00354 cP_x_= Eigen::MatrixXf::Zero(4,3);
00355
00356 ccP_= Eigen::MatrixXf::Zero(4,3);
00357
00358 J_= Eigen::MatrixXf::Zero(6,6);
00359 diff_=Eigen::MatrixXf::Zero(6,1);
00360 }
00361 else {
00362
00363
00364
00365 s_= Eigen::MatrixXf::Zero(8,1);
00366
00367 S_= Eigen::MatrixXf::Zero(8,1);
00368
00369 S_x_= Eigen::MatrixXf::Zero(8,1);
00370
00371 cP_= Eigen::MatrixXf::Zero(4,4);
00372
00373 cP_x_= Eigen::MatrixXf::Zero(4,4);
00374
00375 ccP_= Eigen::MatrixXf::Zero(4,4);
00376
00377 J_= Eigen::MatrixXf::Zero(8,6);
00378 diff_=Eigen::MatrixXf::Zero(8,1);
00379 }
00380
00381
00382
00383 uv_= Eigen::MatrixXf::Zero(2,n_);
00384
00385 diTj_int_=Eigen::Matrix4f::Zero();
00386
00387 Vel_= Eigen::MatrixXf::Zero(6,1);
00388
00389 u0_=640;
00390 v0_=480;
00391 ff_=400;
00392 ff_old_=ff_;
00393 noise_=0;
00394 phi_old_=0;
00395
00396
00397
00398 }
00399
00401 void Uncalibvs_simAlgorithm::image_projection(const float& fu, const float& fv){
00402
00403
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
00415 xx=(ccP_.row(0).array()/ccP_.row(2).array());
00416 yy=(ccP_.row(1).array()/ccP_.row(2).array());
00417
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
00428 xx=(ccP_.row(0).array()/ccP_.row(2).array());
00429 yy=(ccP_.row(1).array()/ccP_.row(2).array());
00430
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
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
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
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
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
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
00495 for (int i=0; i<n_; ++i){
00496 for (int j=0; j<3; ++j){
00497
00498 m((2*i),(j*3))=alfas_(j,i);
00499 m((2*i),(j*3)+2)=alfas_(j,i)*(u0_-uv_(0,i));
00500
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
00507 Eigen::MatrixXf M(9,9),UU(9,9),VV(9,9);
00508 M = (m.transpose() * m);
00509
00510
00511 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eigensolver(M);
00512 Eigen::VectorXf v(9,1);
00513 v =eigensolver.eigenvectors().col(0);
00514
00515
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
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
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
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
00584 for (int i=0; i<n_; ++i){
00585 for (int j=0; j<4; ++j){
00586
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
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
00597 Eigen::MatrixXf M(12,12),UU(12,12),VV(12,12);
00598 M = (m.transpose() * m);
00599
00600
00601 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eigensolver(M);
00602 Eigen::VectorXf v(12,1);
00603 v =eigensolver.eigenvectors().col(0);
00604
00605
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
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
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
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
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
00694 diff_=S_.array()-S_x_.array();
00695
00696
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
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
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
00722 v_linear = Vel_.block(0,0,3,1);
00723
00724
00725 v_angular = Vel_.block(3,0,3,1);
00726
00727
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
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
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
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
00765 JJ1=J1.transpose()*J1;
00766 J1_pseudo=JJ1.inverse()*J1.transpose();
00767
00768
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
00783
00784 jnt_to_pose_solver_.reset(new KDL::ChainFkSolverPos_recursive(chain_));
00785 jnt_to_jac_solver_.reset(new KDL::ChainJntToJacSolver(chain_));
00786
00787
00788 this->nj_ = chain_.getNrOfJoints();
00789 jnt_pos_ = KDL::JntArray(this->nj_);
00790
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
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
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
00819 Tiner=T0c_new_*Tarm.inverse();
00820
00821
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
00826 QQ_.block(3,0,3,1) = Riner.eulerAngles(0,1,2);
00827
00828
00829 jnt_to_jac_solver_->JntToJac(jnt_pos_, jacobian_);
00830
00831 Jqa_=Eigen::MatrixXf::Zero(6,6+this->nj_);
00832
00833
00834
00835
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
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
00875 }
00876
00878 void Uncalibvs_simAlgorithm::qa_control(){
00879
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
00884 if (this->arm_unina_) v_null_space_unina();
00885 else if (this->arm_catec_) v_null_space_catec();
00886
00887
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
00896 Eigen::MatrixXf Jqa1_pseudo(4+this->nj_,6);
00897 Jqa1_pseudo = calcPinv(Jqa1);
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 Vtotal = (Jqa1_pseudo * (Vel_-Jqa2*V2_)) + (eye-(Jqa1_pseudo*Jqa1))*Vqa0_;
00910
00911 Vtotal = this->lambda_robot_.array()*Vtotal.array();
00912
00913
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
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
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
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
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
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
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
01065 double m0,m1,m2,m3,m4;
01066 m0=0;
01067 m1=0;
01068 m2=50;
01069 m3=50;
01070 m4=10;
01071
01072
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
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120 }
01121
01122 Vqa0_.block(4,0,5,1)=100*w;
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280 }
01281
01283 void Uncalibvs_simAlgorithm::v_null_space_catec(){
01284
01285
01286 float ndof=4+this->nj_;
01287 Vqa0_=Eigen::MatrixXf::Zero(ndof,1);
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358 }
01359
01361 Eigen::MatrixXf Uncalibvs_simAlgorithm::calcPinv(const Eigen::MatrixXf &a){
01362 using namespace Eigen;
01363
01364 const MatrixXf* m;
01365 MatrixXf t;
01366 MatrixXf m_pinv;
01367
01368
01369 if ( a.rows()<a.cols() ){
01370 t = a.transpose();
01371 m = &t;
01372 } else {
01373 m = &a;
01374 }
01375
01376
01377
01378 Eigen::JacobiSVD<MatrixXf> svd = m->jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV);
01379 Eigen::MatrixXf vSingular = svd.singularValues();
01380
01381
01382
01383 Eigen::MatrixXf vPseudoInvertedSingular(svd.matrixV().cols(),1);
01384 for (int iRow =0; iRow<vSingular.rows(); iRow++) {
01385
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
01394 Eigen::MatrixXf mAdjointU = svd.matrixU().adjoint().block(0,0,vSingular.rows(),svd.matrixU().adjoint().cols());
01395
01396 m_pinv = (svd.matrixV() * vPseudoInvertedSingular.asDiagonal()) * mAdjointU ;
01397
01398
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
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
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 }