Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "tabletop_object_detector/model_fitter.h"
00038
00039 #include "distance_field/propagation_distance_field.h"
00040 #include "tabletop_object_detector/iterative_distance_fitter.h"
00041
00042 namespace tabletop_object_detector {
00043
00044 DistanceFieldFitter::DistanceFieldFitter() : distance_voxel_grid_(NULL)
00045 {
00046 truncate_value_ = 0.05;
00047 distance_field_resolution_ = 0.002;
00048 }
00049
00050 DistanceFieldFitter::~DistanceFieldFitter()
00051 {
00052 delete distance_voxel_grid_;
00053 }
00054
00055 void DistanceFieldFitter::initializeFromBtVectors(const std::vector<tf::Vector3> &points)
00056 {
00057 delete distance_voxel_grid_;
00058 distance_voxel_grid_ = NULL;
00059
00060 if (points.size() == 0) {
00061 return;
00062 }
00063
00064 tf::Vector3 min = points[0], max = points[0];
00065 for (size_t i=0; i<points.size(); ++i)
00066 {
00067 for (size_t j=0; j<3; ++j)
00068 {
00069 if (min[j] > points[i][j])
00070 {
00071 min[j] = points[i][j];
00072 }
00073 if (max[j] < points[i][j])
00074 {
00075 max[j] = points[i][j];
00076 }
00077 }
00078 }
00079
00080 ROS_DEBUG("Size: (%g,%g,%g, %g, %g, %g)",min[0], min[1], min[2], max[0], max[1], max[2]);
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 double table_padding = 2.5 * distance_field_resolution_;
00091 distance_voxel_grid_ = new distance_field::PropagationDistanceField(max[0]-min[0] + 2*truncate_value_,
00092 max[1]-min[1] + 2*truncate_value_,
00093 max[2]-min[2] + truncate_value_ + table_padding,
00094 distance_field_resolution_,
00095 min[0] - truncate_value_,
00096 min[1] - truncate_value_,
00097 min[2] - table_padding,
00098 2 * truncate_value_ );
00099 distance_voxel_grid_->reset();
00100 distance_voxel_grid_->addPointsToField(points);
00101 }
00102
00103 double dist(const tf::Vector3 &v0, const tf::Vector3 &v1)
00104 {
00105 return sqrt( (v1.x()-v0.x())*(v1.x()-v0.x()) +
00106 (v1.y()-v0.y())*(v1.y()-v0.y()) +
00107 (v1.z()-v0.z())*(v1.z()-v0.z()) );
00108 }
00109
00119 std::vector<tf::Vector3> interpolateTriangle(tf::Vector3 v0,
00120 tf::Vector3 v1,
00121 tf::Vector3 v2, double min_res)
00122 {
00123 std::vector<tf::Vector3> vectors;
00124
00125
00126
00127 double d01 = dist(v0, v1);
00128 double d02 = dist(v0, v2);
00129 double res_0 = min_res / std::max(d01, d02);
00130
00131
00132
00133 double t0=res_0;
00134 bool done = false;
00135 while (!done)
00136 {
00137 if (t0 >= 1.0)
00138 {
00139 t0 = 1.0;
00140 done = true;
00141 }
00142
00143 tf::Vector3 p1 = t0*v0 + (1-t0) * v1;
00144 tf::Vector3 p2 = t0*v0 + (1-t0) * v2;
00145 double d12 = dist(p1, p2);
00146 double res_12 = min_res / d12;
00147
00148
00149 double t12 = 0;
00150 bool done12 = false;
00151 while (!done12)
00152 {
00153 if (t12 >= 1.0)
00154 {
00155 t12 = 1.0;
00156 done12 = true;
00157 }
00158
00159
00160 if (t0!=1.0 || (t12!=0.0 && t12!=1.0))
00161 {
00162 vectors.push_back( t12*p1 + (1.0 - t12)*p2 );
00163 }
00164 t12 += res_12;
00165 }
00166
00167 t0 += res_0;
00168 }
00169 return vectors;
00170 }
00171
00172 void ModelToCloudFitter::sampleMesh(const shape_msgs::Mesh &mesh,
00173 std::vector<tf::Vector3> &btVectors,
00174 double resolution)
00175 {
00176 btVectors.reserve(mesh.vertices.size());
00177
00178
00179 typedef std::vector<geometry_msgs::Point>::const_iterator I;
00180 for (I i=mesh.vertices.begin(); i!=mesh.vertices.end(); i++)
00181 {
00182 btVectors.push_back(tf::Vector3(i->x,i->y,i->z));
00183 }
00184
00185
00186
00187 for (size_t i=0; i<mesh.triangles.size(); i++)
00188 {
00189 tf::Vector3 v0( mesh.vertices.at( mesh.triangles.at(i).vertex_indices.at(0) ).x,
00190 mesh.vertices.at( mesh.triangles.at(i).vertex_indices.at(0) ).y,
00191 mesh.vertices.at( mesh.triangles.at(i).vertex_indices.at(0) ).z);
00192 tf::Vector3 v1( mesh.vertices.at( mesh.triangles.at(i).vertex_indices.at(1) ).x,
00193 mesh.vertices.at( mesh.triangles.at(i).vertex_indices.at(1) ).y,
00194 mesh.vertices.at( mesh.triangles.at(i).vertex_indices.at(1) ).z);
00195 tf::Vector3 v2( mesh.vertices.at( mesh.triangles.at(i).vertex_indices.at(2) ).x,
00196 mesh.vertices.at( mesh.triangles.at(i).vertex_indices.at(2) ).y,
00197 mesh.vertices.at( mesh.triangles.at(i).vertex_indices.at(2) ).z);
00198 std::vector<tf::Vector3> triangleVectors = interpolateTriangle(v0, v1, v2, resolution);
00199 btVectors.insert(btVectors.begin(), triangleVectors.begin(), triangleVectors.end());
00200 }
00201 }
00202
00203
00204 void DistanceFieldFitter::initializeFromMesh(const shape_msgs::Mesh &mesh)
00205 {
00206 std::vector<tf::Vector3> btVectors;
00207
00208
00209 sampleMesh(mesh, btVectors, 1.5 * distance_field_resolution_ );
00210 initializeFromBtVectors(btVectors);
00211 }
00212
00213
00214 }