Go to the documentation of this file.00001
00059 template<typename INPUT>
00060 void TFLink<INPUT>::operator()(const TFLinkObj &obj, const TFLinkObj &cor_obj)
00061 {
00062 ROS_ASSERT(obj.plane_==cor_obj.plane_);
00063 ROS_ASSERT(obj.weight_R_==cor_obj.weight_R_);
00064 ROS_ASSERT(obj.weight_t_==cor_obj.weight_t_);
00065
00066 if(!obj.length_ || !obj.length_ || !pcl_isfinite( obj.weight_R_ ) || !pcl_isfinite( cor_obj.weight_R_ ) || !pcl_isfinite( obj.weight_t_ ) || !pcl_isfinite( cor_obj.weight_t_ ))
00067 return;
00068
00069 ROS_ASSERT(pcl_isfinite( obj.next_point_.sum() ));
00070 ROS_ASSERT(pcl_isfinite( cor_obj.next_point_.sum() ));
00071 ROS_ASSERT(pcl_isfinite( obj.rotation_n_.sum() ));
00072 ROS_ASSERT(pcl_isfinite( cor_obj.rotation_n_.sum() ));
00073
00074 ROS_ASSERT(pcl_isfinite( obj.weight_R_ ));
00075 ROS_ASSERT(pcl_isfinite( cor_obj.weight_R_ ));
00076 ROS_ASSERT(pcl_isfinite( obj.weight_t_ ));
00077 ROS_ASSERT(pcl_isfinite( cor_obj.weight_t_ ));
00078
00079 if(!obj.plane_) {
00080 sum_x_ += obj.weight_R_*cor_obj.next_point_;
00081 sum_y_ += obj.weight_R_*obj.next_point_;
00082 rot_sum_ += obj.weight_R_;
00083 }
00084
00085 variance_x_ += obj.weight_R_*cor_obj.rotation_n_ * cor_obj.rotation_n_.transpose() /(cor_obj.length_*cor_obj.length_);
00086 if(!obj.plane_||cor_obj.rotation_n_.dot(obj.rotation_n_)>-0.7*(cor_obj.length_*obj.length_)) {
00087 covariance_ += obj.weight_R_*cor_obj.rotation_n_ * obj.rotation_n_.transpose() /(cor_obj.length_*obj.length_);
00088 variance_y_ += obj.weight_R_*obj.rotation_n_ * obj.rotation_n_.transpose() /(obj.length_*obj.length_);
00089 }
00090 else {
00091 covariance_ -= obj.weight_R_*cor_obj.rotation_n_ * obj.rotation_n_.transpose() /(cor_obj.length_*obj.length_);
00092 variance_y_ -= obj.weight_R_*obj.rotation_n_ * obj.rotation_n_.transpose() /(obj.length_*obj.length_);
00093 }
00094 accumlated_weight_ += obj.weight_R_;
00095
00096 translation_ += obj.weight_t_*cor_obj.translation_M_;
00097 var_x_ += obj.weight_t_*cor_obj.next_point_;
00098 var_y_ += obj.weight_t_*obj.next_point_;
00099 accumlated_weight_t_ += obj.weight_t_;
00100
00101 if(obj.next_point_.squaredNorm()||cor_obj.next_point_.squaredNorm()) {
00102 corsA_.push_back(obj.next_point_);
00103 corsB_.push_back(cor_obj.next_point_);
00104 }
00105 }
00106
00107 template<typename INPUT>
00108 TFLink<INPUT> TFLink<INPUT>::operator+(const TFLink &o) const
00109 {
00110 TFLink<INPUT> r;
00111 #if 0
00112
00113
00114 std::cout<<"test1\n"<<covariance_<<"\n";
00115 std::cout<<"test2\n"<<getRotation()*variance_x_<<"\n";
00116 std::cout<<"test3\n"<<getRotation()*variance_y_<<"\n";
00117
00118 std::cout<<"test1\n"<<o.covariance_<<"\n";
00119 std::cout<<"test2\n"<<o.getRotation()*o.variance_x_<<"\n";
00120 std::cout<<"test3\n"<<o.getRotation()*o.variance_y_<<"\n";
00121
00122
00123
00124
00125
00126 Matrix t=o.covariance_;
00127 t.normalize();
00128 r.covariance_ = variance_y_ * o.getRotation().transpose();
00129 r.covariance_ = covariance_*o.covariance_;
00130 r.covariance_ = variance_x_*t.inverse().transpose()*t;
00131 r.covariance_ = o.covariance_*covariance_.transpose();
00132
00133 r.covariance_ = variance_x_.transpose()*covariance_.inverse().transpose()*o.covariance_;
00134
00135
00136
00137 r.covariance_ = o.getRotation()*covariance_;
00138
00139 std::cout<<"test\n"<<(o.getRotation()*getRotation()).inverse()<<"\n";
00140
00141 Matrix A=o.covariance_;
00142 Matrix B=covariance_;
00143 A.normalize();
00144 B.normalize();
00145 r.covariance_ = variance_y_*covariance_*variance_y_.inverse()*o.covariance_*o.variance_y_.inverse();
00146
00147 std::cout<<"V1\n"<<variance_y_<<"\n";
00148 std::cout<<"U1\n"<<variance_x_<<"\n";
00149 std::cout<<"V1\n"<<variance_y_.inverse()<<"\n";
00150 std::cout<<"V2\n"<<o.variance_y_.inverse()<<"\n";
00151 std::cout<<"COV1\n"<<covariance_<<"\n";
00152 std::cout<<"COV2\n"<<o.covariance_<<"\n";
00153 std::cout<<"COV\n"<<r.covariance_<<"\n";
00154
00155 r.covariance_ = o.getRotation()*covariance_;
00156
00157
00158 r.covariance_ = o.covariance_*getRotation();
00159
00160 #endif
00161
00162 r.covariance_ = getRotation()*o.covariance_ + covariance_*o.getRotation();
00163 r.accumlated_weight_ = std::min(accumlated_weight_,o.accumlated_weight_);
00164 r.variance_x_ = variance_x_ + getRotation()*o.variance_x_*getRotation().transpose();
00165 r.variance_y_ = o.variance_y_ + o.getRotation().transpose()*variance_y_*o.getRotation();
00166
00167
00168
00169
00170
00171
00172
00173 r.accumlated_weight_t_ = accumlated_weight_t_ + o.accumlated_weight_t_;
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 r.var_x_ = var_x_ + translation_ * getRotation() * o.getTranslation();
00194 r.var_y_ = o.getRotation().transpose()*var_y_;
00195 r.translation_ = translation_;
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 r.finish();
00211
00212
00213 r.rot_var_= rot_var_+ o.rot_var_;
00214 r.tr_var_ = tr_var_ + o.tr_var_;
00215
00216 return r;
00217 }
00218
00219 template<typename INPUT>
00220 void TFLink<INPUT>::operator+=(const TFLink &o)
00221 {
00222
00223 #ifdef DEBUG_OUTPUT_
00224 std::cout<<"+=VAR X1\n"<<var_x_<<"\n";
00225 std::cout<<"+=VAR X2\n"<<o.var_x_<<"\n";
00226 std::cout<<"+=VAR Y1\n"<<var_y_<<"\n";
00227 std::cout<<"+=VAR Y2\n"<<o.var_y_<<"\n";
00228 std::cout<<"+=VAR T1\n"<<translation_<<"\n";
00229 std::cout<<"+=VAR T2\n"<<o.translation_<<"\n";
00230 #endif
00231
00232 covariance_ += o.covariance_;
00233 variance_x_ += o.variance_x_;
00234 variance_y_ += o.variance_y_;
00235 accumlated_weight_ += o.accumlated_weight_;
00236 var_x_ += o.var_x_;
00237 var_y_ += o.var_y_;
00238 translation_ += o.translation_;
00239 accumlated_weight_t_ += o.accumlated_weight_t_;
00240
00241
00242 finish();
00243 }
00244
00245 template<typename INPUT>
00246 TFLink<INPUT> TFLink<INPUT>::transpose() const {
00247 TFLink<INPUT> r;
00248
00249 r.covariance_ = covariance_.transpose();
00250 r.variance_x_ = variance_y_;
00251 r.variance_y_ = variance_x_;
00252
00253 r.translation_ = rot_.transpose()*translation_.transpose()*rot_;
00254 r.var_x_ = var_y_;
00255 r.var_y_ = var_x_;
00256
00257 r.rot_ = rot_.transpose();
00258 r.tr_ = -r.rot_*tr_;
00259
00260 return r;
00261 }
00262
00263 template<typename INPUT>
00264 void TFLink<INPUT>::finish() {
00265
00266
00267 if(rot_sum_) {
00268 covariance_ -= (sum_x_*sum_y_.transpose())/rot_sum_;
00269 variance_x_ -= (sum_x_*sum_x_.transpose())/rot_sum_;
00270 variance_y_ -= (sum_y_*sum_y_.transpose())/rot_sum_;
00271
00272 sum_x_.fill(0);
00273 sum_y_.fill(0);
00274 rot_sum_=0;
00275 }
00276
00277
00278
00279
00280
00281 Eigen::JacobiSVD<Matrix> svd (covariance_, Eigen::ComputeFullU | Eigen::ComputeFullV);
00282 const Matrix& u = svd.matrixU(),
00283 & v = svd.matrixV();
00284
00285 Matrix s = Matrix::Identity();
00286 if (u.determinant()*v.determinant() < 0.0f)
00287 s(2,2) = -1.0f;
00288
00289 rot_ = u * s * v.transpose();
00290
00291 ROS_ASSERT(pcl_isfinite(rot_.sum()));
00292
00293 rot_var_ = std::max(
00294
00295 svd.singularValues()(1)*svd.singularValues()(1)<=0.00001f*svd.singularValues().squaredNorm() ? 100000. : 0.,
00296
00297
00298 0.
00299 );
00300
00301 #ifdef DEBUG_OUTPUT_
00302 std::cout<<"ROT\n"<<rot_<<"\n";
00303 std::cout<<"SING VALS\n"<<svd.singularValues()<<"\n";
00304 std::cout<<"ROT_DIS "<<sqrtf((variance_y_-(rot_.transpose()*variance_x_*rot_)).squaredNorm()/variance_y_.squaredNorm())<<"\n";
00305 std::cout<<"ROT1 \n"<<(variance_y_)<<"\n";
00306 std::cout<<"ROT2 \n"<<((rot_.transpose()*variance_x_*rot_))<<"\n";
00307 #endif
00308
00309
00310
00311 Vector temp = var_x_ - rot_*var_y_;
00312 tr_ = translation_.fullPivLu().solve(temp);
00313 tr_var_ = 0;
00314
00315
00316 ROS_ASSERT(pcl_isfinite(temp.sum()));
00317
00318
00319 if(!rot_var_) {
00320 for(size_t i=0; i<corsA_.size(); i++) {
00321 Eigen::Vector3f a = rot_*corsA_[i] + tr_;
00322 float f = std::abs(std::acos( a.dot(corsB_[i])/(a.norm()*corsB_[i].norm()) ));
00323 if(pcl_isfinite(f)) rot_var_+=f;
00324 }
00325 rot_var_ /= corsA_.size();
00326 }
00327
00328 if(!pcl_isfinite(rot_var_))
00329 rot_var_ = 100000;
00330
00331 #ifdef DEBUG_OUTPUT_
00332 std::cout<<"rot_var. "<<rot_var_<<"\n";
00333 std::cout<<"TRANSLATION MATRIX\n"<<translation_<<"\n";
00334 std::cout<<"TRANSLATION VECTOR1\n"<<temp<<"\n";
00335 std::cout<<"TRANSLATION VECTOR2\n"<<translation_*tr_<<"\n";
00336 std::cout<<"det. "<<translation_.determinant()<<"\n";
00337 std::cout<<"should det. "<<(0.2*accumlated_weight_*accumlated_weight_)<<"\n";
00338 #endif
00339
00340 if(translation_.determinant()<(TYPE)0.04*accumlated_weight_*accumlated_weight_)
00341 tr_var_ += 10000;
00342
00343 if(!tr_var_) {
00344 for(size_t i=0; i<corsA_.size(); i++) {
00345 Eigen::Vector3f a = rot_*corsA_[i] + tr_;
00346 tr_var_+=std::abs( a.norm()-corsB_[i].norm() );
00347 }
00348 tr_var_ /= corsA_.size();
00349 }
00350
00351 if(!pcl_isfinite(tr_var_) || !pcl_isfinite(tr_.sum()))
00352 tr_var_ = 100000;
00353 if(!pcl_isfinite(tr_.sum())
00354 #ifndef ATOM_TESTING_
00355 ||tr_var_>=1000
00356 #endif
00357 )
00358 tr_.fill(0);
00359
00360 }
00361
00362 template<typename INPUT>
00363 void TFLink<INPUT>::check() const {
00364 Matrix R = getRotation();
00365
00366 #ifdef DEBUG_OUTPUT_
00367 std::cout<<"V1\n"<<variance_y_<<"\n";
00368 std::cout<<"U1\n"<<variance_x_<<"\n";
00369
00370 std::cout<<"V2\n"<<R.transpose()*variance_x_*R<<"\n";
00371 std::cout<<"U2\n"<<R*variance_y_*R.transpose()<<"\n";
00372
00373 std::cout<<"C\n"<<(variance_y_-(R.transpose()*variance_x_*R)).norm()<<"\n";
00374 std::cout<<"C\n"<<(variance_x_-(R*variance_y_*R.transpose())).norm()<<"\n";
00375 #endif
00376
00377 }
00378
00379 template<typename INPUT>
00380 typename TFLink<INPUT>::Matrix4 TFLink<INPUT>::getTransformation() const {
00381 Matrix rot = getRotation();
00382
00383
00384
00385
00386 Matrix4 r=Matrix4::Identity();
00387 for(int i=0; i<3; i++) {
00388 for(int j=0; j<3; j++)
00389 r(i,j) = rot(i,j);
00390 r.col(3)(i)= getTranslation()(i);
00391 }
00392
00393 return r;
00394 }