35 #include <gtest/gtest.h>
38 #include <geometric_shapes/shapes.h>
39 #include <geometric_shapes/shape_operations.h>
40 #include <eigen3/Eigen/Eigen>
44 using namespace Eigen;
46 using namespace std::placeholders;
50 template <
typename Type>
53 return Type(min + (max - min) *
double(rand()) /
double(RAND_MAX));
56 template <
typename Type>
60 static const GLushort FILTER_GL_TYPE = GL_ZERO;
67 static const GLushort FILTER_GL_TYPE = GL_UNSIGNED_SHORT;
68 static constexpr
double ToMetricScale = 0.001;
75 static const GLushort FILTER_GL_TYPE = GL_FLOAT;
76 static constexpr
double ToMetricScale = 1.0f;
79 template <
typename Type>
86 MeshFilterTest(
unsigned width = 500,
unsigned height = 500,
double near = 0.5,
double far = 5.0,
double shadow = 0.1,
87 double epsilon = 1e-7);
95 shapes::Mesh createMesh(
double z)
const;
96 bool transformCallback(
MeshHandle handle, Isometry3d& transform)
const;
97 void getGroundTruth(
unsigned int* labels,
float* depth)
const;
98 const unsigned int width_;
99 const unsigned int height_;
102 const double shadow_;
103 const double epsilon_;
107 vector<Type> sensor_data_;
111 template <
typename Type>
120 , sensor_parameters_(width, height, near_, far_, width >> 1, height >> 1, width >> 1, height >> 1, 0.1, 0.1)
121 , filter_([this](
mesh_filter::
MeshHandle mesh, Eigen::Isometry3d& tf) {
return transformCallback(mesh, tf); },
123 , sensor_data_(width_ * height_)
126 filter_.setShadowThreshold(shadow_);
128 filter_.setPaddingOffset(0.0);
129 filter_.setPaddingScale(0.0);
133 shapes::Mesh mesh = createMesh(0);
134 handle_ = filter_.addMesh(mesh);
140 for (
typename vector<Type>::iterator s_it = sensor_data_.begin(); s_it != sensor_data_.end(); ++s_it)
145 }
while (*s_it == t_near || *s_it == t_far);
149 template <
typename Type>
150 shapes::Mesh MeshFilterTest<Type>::createMesh(
double z)
const
152 shapes::Mesh mesh(4, 4);
153 mesh.vertices[0] = -5;
154 mesh.vertices[1] = -5;
155 mesh.vertices[2] =
z;
157 mesh.vertices[3] = -5;
158 mesh.vertices[4] = 5;
159 mesh.vertices[5] =
z;
161 mesh.vertices[6] = 5;
162 mesh.vertices[7] = 5;
163 mesh.vertices[8] =
z;
165 mesh.vertices[9] = 5;
166 mesh.vertices[10] = -5;
167 mesh.vertices[11] =
z;
169 mesh.triangles[0] = 0;
170 mesh.triangles[1] = 3;
171 mesh.triangles[2] = 2;
173 mesh.triangles[3] = 0;
174 mesh.triangles[4] = 2;
175 mesh.triangles[5] = 1;
177 mesh.triangles[6] = 0;
178 mesh.triangles[7] = 2;
179 mesh.triangles[8] = 3;
181 mesh.triangles[9] = 0;
182 mesh.triangles[10] = 1;
183 mesh.triangles[11] = 2;
185 mesh.vertex_normals[0] = 0;
186 mesh.vertex_normals[1] = 0;
187 mesh.vertex_normals[2] = 1;
189 mesh.vertex_normals[3] = 0;
190 mesh.vertex_normals[4] = 0;
191 mesh.vertex_normals[5] = 1;
193 mesh.vertex_normals[6] = 0;
194 mesh.vertex_normals[7] = 0;
195 mesh.vertex_normals[8] = 1;
197 mesh.vertex_normals[9] = 0;
198 mesh.vertex_normals[10] = 0;
199 mesh.vertex_normals[11] = 1;
204 template <
typename Type>
205 bool MeshFilterTest<Type>::transformCallback(
MeshHandle handle, Isometry3d& transform)
const
207 transform = Isometry3d::Identity();
208 if (handle == handle_)
209 transform.translation() =
Vector3d(0, 0, distance_);
213 template <
typename Type>
216 shapes::Mesh mesh = createMesh(0);
220 vector<float> gt_depth(width_ * height_);
221 vector<unsigned int> gt_labels(width_ * height_);
222 getGroundTruth(>_labels[0], >_depth[0]);
224 vector<float> filtered_depth(width_ * height_);
225 vector<unsigned int> filtered_labels(width_ * height_);
226 filter_.getFilteredDepth(&filtered_depth[0]);
227 filter_.getFilteredLabels(&filtered_labels[0]);
229 for (
unsigned idx = 0; idx < width_ * height_; ++idx)
233 if (fabs(sensor_depth - distance_ - shadow_) > epsilon_ && fabs(sensor_depth - distance_) > epsilon_)
235 ASSERT_NEAR(filtered_depth[idx], gt_depth[idx], 1e-4);
236 ASSERT_EQ(filtered_labels[idx], gt_labels[idx]);
239 filter_.removeMesh(handle);
242 template <
typename Type>
246 if (distance_ <= near_ || distance_ >= far_)
249 for (
unsigned y_idx = 0, idx = 0; y_idx < height_; ++y_idx)
251 for (
unsigned x_idx = 0; x_idx < width_; ++x_idx, ++idx)
253 depth[idx] = double(sensor_data_[idx]) * scale;
254 if (depth[idx] < near_)
255 labels[idx] = MeshFilterBase::NEAR_CLIP;
256 else if (depth[idx] >= far_)
257 labels[idx] = MeshFilterBase::FAR_CLIP;
259 labels[idx] = MeshFilterBase::BACKGROUND;
261 if (depth[idx] <= near_ || depth[idx] >= far_)
268 for (
unsigned y_idx = 0, idx = 0; y_idx < height_; ++y_idx)
270 for (
unsigned x_idx = 0; x_idx < width_; ++x_idx, ++idx)
272 depth[idx] = double(sensor_data_[idx]) * scale;
274 if (depth[idx] < near_)
276 labels[idx] = MeshFilterBase::NEAR_CLIP;
281 double diff = depth[idx] - distance_;
282 if (diff < 0 && depth[idx] < far_)
283 labels[idx] = MeshFilterBase::BACKGROUND;
284 else if (diff > shadow_)
285 labels[idx] = MeshFilterBase::SHADOW;
286 else if (depth[idx] >= far_)
287 labels[idx] = MeshFilterBase::FAR_CLIP;
290 labels[idx] = MeshFilterBase::FIRST_LABEL;
294 if (depth[idx] >= far_)
307 this->setMeshDistance(this->GetParam());
315 this->setMeshDistance(this->GetParam());
320 int main(
int argc,
char** argv)
322 testing::InitGoogleTest(&argc, argv);
323 return RUN_ALL_TESTS();
Parameters for Stereo-like devices.
void setMeshDistance(double distance)
int main(int argc, char **argv)
INSTANTIATE_TEST_CASE_P(float_test, MeshFilterTestFloat, ::testing::Range< double >(0.0f, 6.0f, 0.5f))
mesh_filter_test::MeshFilterTest< float > MeshFilterTestFloat
TEST_P(MeshFilterTestFloat, float)
mesh_filter_test::MeshFilterTest< unsigned short > MeshFilterTestUnsignedShort
Type
The types of bodies that are considered for collision.
Vec3fX< details::Vec3Data< double > > Vector3d
const Type getRandomNumber(const Type &min, const Type &max)
double distance(const urdf::Pose &transform)