Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #ifndef FEATURE_H_
00009 #define FEATURE_H_
00010
00011
00013 namespace DOF6
00014 {
00015
00016 struct S_FEATURE
00017 {
00018 enum TYPE {POINT, NORMAL, DIRECTION};
00019
00020 int ID_;
00021 TYPE type_;
00022 Eigen::Vector3f v_, v_org_, n_;
00023 float var_, weight_;
00024
00025 S_FEATURE(const cob_3d_mapping_msgs::feature &ft, const Eigen::Vector3f &n):var_(0.2f), weight_(1.f), n_(n)
00026 {
00027 ID_ = ft.ID;
00028 v_(0) = ft.x;
00029 v_(1) = ft.y;
00030 v_(2) = ft.z;
00031 v_org_=v_;
00032 switch(ft.ID)
00033 {
00034 case 2:
00035 case 4:
00036 case 5:
00037 v_.normalize();
00038 type_ = DIRECTION;
00039 break;
00040 case 3:
00041 type_ = POINT;
00042 break;
00043 default:
00044 ROS_ASSERT(0);
00045 break;
00046 }
00047 n_.normalize();
00048 }
00049
00050 S_FEATURE(const Eigen::Vector3f &v, const Eigen::Vector3f &n, const bool bPlane):
00051 v_(v), var_(0.2f), weight_(1.f), n_(n)
00052 {
00053 type_ = bPlane?NORMAL:POINT;
00054 ID_ = 1;
00055 n_.normalize();
00056 }
00057
00058 S_FEATURE(const Eigen::Vector3f &v, const Eigen::Vector3f &n, const float w):
00059 v_(v), var_(0.2f), weight_(w), n_(n)
00060 {
00061 type_ = POINT;
00062 ID_ = -1;
00063 n_.normalize();
00064 }
00065
00066 void transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr, const float var_R, const float var_T)
00067 {
00068 switch(type_)
00069 {
00070 case POINT:
00071 var_ += v_.norm()*var_R+var_T;
00072 v_ = rot*v_ + tr;
00073 break;
00074 case NORMAL:
00075 var_ += v_.norm()*var_R+var_T;
00076 v_ = rot*v_;
00077 if(tr.squaredNorm())
00078 v_ += v_*(tr.dot(v_))/(v_.squaredNorm());
00079 break;
00080 case DIRECTION:
00081 v_ = rot*v_;
00082 var_ += var_R;
00083 break;
00084 default:
00085 ROS_ASSERT(0);
00086 break;
00087 }
00088 n_ = rot*n_;
00089 }
00090
00091 bool isReachable(const S_FEATURE &o, const float thr_tr, const float thr_rot) const
00092 {
00093 if(type_ != o.type_)
00094 {
00095 ROS_INFO("cannot check features of differnt type");
00096 return false;
00097 }
00098
00099 Eigen::Vector3f z;
00100 z(0)=z(1)=0;z(2)=1;
00101 switch(type_)
00102 {
00103 case POINT:
00104 {
00105 if(std::abs(o.v_.norm()-v_.norm())> thr_tr)
00106 return false;
00107 const float d = (o.v_-v_).norm();
00108 if(d>thr_tr && 2*std::asin( (d - thr_tr)/(2*v_.norm()) )>thr_rot)
00109 return false;
00110 if( std::acos( n_.dot(o.n_))>thr_rot + (n_.dot(z)+o.n_.dot(z))/12 )
00111 return false;
00112 }
00113 break;
00114 case NORMAL:
00115 if(std::abs(o.v_.norm()-v_.norm())> thr_tr)
00116 return false;
00117 if(2*std::asin( ((o.v_-v_).norm())/(2*v_.norm()) )>thr_rot)
00118 return false;
00119 break;
00120 case DIRECTION:
00121 if(2*std::asin( ((o.v_-v_).norm())/(2*v_.norm()) )>thr_rot)
00122 return false;
00123 break;
00124
00125 default:
00126 ROS_ASSERT(0);
00127 break;
00128 }
00129 return true;
00130 }
00131
00132 void merge(const S_FEATURE &o, const float weight, const float oweight)
00133 {
00134 ROS_ASSERT(var_>0);
00135 ROS_ASSERT(o.var_>0);
00136 if(type_ != o.type_)
00137 {
00138 ROS_INFO("cannot merge features of differnt type");
00139 return;
00140 }
00141
00142 if(!pcl_isfinite(o.v_.sum())||!pcl_isfinite(o.var_))
00143 return;
00144
00145 if(!pcl_isfinite(v_.sum())||!pcl_isfinite(var_))
00146 {
00147 v_ = o.v_;
00148 var_ = o.var_;
00149 }
00150 else
00151 {
00152 switch(type_)
00153 {
00154 case POINT:
00155 case NORMAL:
00156
00157
00158
00159 v_ = v_ + (var_)/((var_+o.var_))*(o.v_-v_);
00160 n_ = n_ + o.n_;
00161 n_.normalize();
00162
00163
00164 break;
00165 case DIRECTION:
00166
00167 v_ = v_ + (var_)/((var_+o.var_))*(o.v_-v_);
00168 v_.normalize();
00169 break;
00170
00171 default:
00172 ROS_ASSERT(0);
00173 break;
00174 }
00175
00176 var_ = var_ - var_*var_/(var_+o.var_);
00177
00178 }
00179
00180
00181 }
00182
00183 };
00184 }
00185
00186 #endif