test_polygon.cpp
Go to the documentation of this file.
00001 
00063 #include <gtest/gtest.h>
00064 #include <cob_3d_mapping_common/polygon.h>
00065 #include <cob_3d_mapping_common/ros_msg_conversions.h>
00066 #include <pcl/common/eigen.h>
00067 
00068 
00069 struct PolygonData
00070 {
00071   PolygonData(unsigned int id,
00072               std::vector<float> color,
00073               Eigen::Vector3f normal,
00074               Eigen::Vector3f x_axis,
00075               Eigen::Vector3f origin,
00076               std::vector<std::vector<Eigen::Vector2f> > contours,
00077               std::vector<bool> holes)
00078   {
00079     id_ = id;
00080     color_ = color;
00081     normal_ = normal.normalized();
00082     origin_ = origin;
00083     d_ = origin_.dot(normal_);
00084     if (d_ > 0) {
00085       normal_ = -normal_;
00086       d_ = -d_;
00087     }
00088     contours_2d_ = contours;
00089     holes_ = holes;
00090     Eigen::Affine3f t;
00091     pcl::getTransformationFromTwoUnitVectorsAndOrigin(normal_.cross(x_axis), normal_, origin_, t);
00092     pose_ = t.inverse();
00093     for(unsigned int i = 0; i < contours_2d_.size(); i++)
00094     {
00095       std::vector<Eigen::Vector3f> c_3d;
00096       for(unsigned int j = 0; j < contours_2d_[i].size(); j++)
00097       {
00098         Eigen::Vector3f p_3d = pose_ * Eigen::Vector3f(contours_2d_[i][j](0), contours_2d_[i][j](1), 0);
00099         c_3d.push_back(p_3d);
00100       }
00101       contours_3d_.push_back(c_3d);
00102     }
00103   }
00104 
00105   unsigned int id_;
00106   std::vector<float> color_;
00107   Eigen::Vector3f normal_;
00108   double d_;
00109   Eigen::Vector3f origin_;
00110   std::vector<std::vector<Eigen::Vector2f> > contours_2d_;
00111   std::vector<std::vector<Eigen::Vector3f> > contours_3d_;
00112   std::vector<bool> holes_;
00113   Eigen::Affine3f pose_;
00114   std::vector<unsigned int> merge_candidates_;
00115 };
00116 
00117 class PolygonTest : public ::testing::Test
00118 {
00119 protected:
00120   virtual void
00121   SetUp ()
00122   {
00123     // Init pd1
00124     std::vector<std::vector<Eigen::Vector2f> > contours;
00125     Eigen::Vector2f p1(0,0), p2(0,1), p3(1,1), p4(1,0);
00126     std::vector<Eigen::Vector2f> c;
00127     c.push_back(p1);
00128     c.push_back(p2);
00129     c.push_back(p3);
00130     c.push_back(p4);
00131     contours.push_back(c);
00132     std::vector<bool> holes;
00133     holes.push_back(false);
00134     PolygonData* pd1 = new PolygonData(0, std::vector<float>(4,1), Eigen::Vector3f(0,0,-1), Eigen::Vector3f(1,0,0), Eigen::Vector3f(-1,-1,1), contours, holes);
00135     pd_.push_back(pd1);
00136 
00137     // Init pd2
00138     contours.clear();
00139     Eigen::Vector2f p5(0.5,0.5);
00140     c.push_back(p5);
00141     contours.push_back(c);
00142     //holes.clear();
00143     //holes.push_back(false);
00144     Eigen::Vector3f normal(0,0.1,-1);
00145     normal.normalize();
00146     PolygonData* pd2 = new PolygonData(1, std::vector<float>(4,1), normal, Eigen::Vector3f(1,0,0), Eigen::Vector3f(-0.5,-1,1), contours, holes);
00147     pd_.push_back(pd2);
00148 
00149     // Init pd3
00150     Eigen::Vector2f p6(0.8, 0.8), p7(0.8, 0.6), p8(0.6, 0.8);
00151     std::vector<Eigen::Vector2f> c_hole;
00152     c_hole.push_back(p6);
00153     c_hole.push_back(p7);
00154     c_hole.push_back(p8);
00155     contours.push_back(c_hole);
00156     holes.push_back(true);
00157     PolygonData* pd3 = new PolygonData(2, std::vector<float>(4,1), normal, Eigen::Vector3f(1,0,0), Eigen::Vector3f(-0.5,-1,1), contours, holes);
00158     pd_.push_back(pd3);
00159 
00160     pd_[0]->merge_candidates_.push_back(0);
00161     pd_[0]->merge_candidates_.push_back(1);
00162     pd_[0]->merge_candidates_.push_back(2);
00163     pd_[1]->merge_candidates_.push_back(0);
00164     pd_[1]->merge_candidates_.push_back(1);
00165     pd_[1]->merge_candidates_.push_back(2);
00166     pd_[2]->merge_candidates_.push_back(0);
00167     pd_[2]->merge_candidates_.push_back(1);
00168     pd_[2]->merge_candidates_.push_back(2);
00169   }
00170 
00171   std::vector<PolygonData*> pd_;
00172 
00173 };
00174 
00175 TEST_F(PolygonTest, creationWorks)
00176 {
00177   for(unsigned int i = 0; i < pd_.size(); i++)
00178   {
00179     cob_3d_mapping::Polygon p(pd_[i]->id_, pd_[i]->normal_, pd_[i]->origin_, pd_[i]->contours_3d_, pd_[i]->holes_, pd_[i]->color_);
00180     EXPECT_NEAR(pd_[i]->normal_.dot(p.normal_), 1.0, 0.001);
00181     EXPECT_NEAR(pd_[i]->d_, p.d_, 0.001);
00182     EXPECT_NEAR((p.pose_.rotation() * Eigen::Vector3f(0,0,1)).dot(pd_[i]->normal_), 1.0, 0.001);
00183     EXPECT_NEAR((p.pose_.translation() - pd_[i]->origin_).norm(), 0, 0.001);
00184     std::vector<std::vector<Eigen::Vector3f> > c_3d = p.getContours3D();
00185     //std::cout << "c of p " << i << ":" << std::endl;
00186     for(unsigned int j = 0; j < c_3d.size(); j++)
00187     {
00188       for(unsigned int k = 0; k < c_3d[j].size(); k++)
00189       {
00190         EXPECT_NEAR((pd_[i]->contours_3d_[j][k] - c_3d[j][k]).norm(), 0, 0.001);
00191         //std::cout << c_3d[j][k](0) << "," << c_3d[j][k](1) << "," << c_3d[j][k](2) << std::endl;
00192         //std::cout << pd_[i]->contours_3d_[j][k](0) << "," << pd_[i]->contours_3d_[j][k](1) << "," << pd_[i]->contours_3d_[j][k](2) << std::endl;
00193       }
00194     }
00195   }
00196 }
00197 
00198 TEST_F(PolygonTest, mergeUnion)
00199 {
00200   cob_3d_mapping::Polygon::Ptr p0(new cob_3d_mapping::Polygon(pd_[0]->id_, pd_[0]->normal_, pd_[0]->origin_, pd_[0]->contours_3d_, pd_[0]->holes_, pd_[0]->color_));
00201   std::vector<cob_3d_mapping::Polygon::Ptr> p_vec;
00202   cob_3d_mapping::Polygon::Ptr p1(new cob_3d_mapping::Polygon(pd_[1]->id_, pd_[1]->normal_, pd_[1]->origin_, pd_[1]->contours_3d_, pd_[1]->holes_, pd_[1]->color_));
00203   p_vec.push_back(p1);
00204 
00205   p0->merge(p_vec);
00206   EXPECT_EQ(p0->merged_, 2);
00207   EXPECT_NEAR(p0->normal_.dot((0.5 * (pd_[0]->normal_ + pd_[1]->normal_)).normalized()), 1, 0.001);
00208 
00209   /*std::vector<std::vector<Eigen::Vector3f> > c_3d = p0->getContours3D();
00210   std::cout << p0->contours_.size() << std::endl;
00211   for(unsigned int i = 0; i < c_3d[0].size(); i++)
00212   {
00213     std::cout << c_3d[0][i](0) << "," << c_3d[0][i](1) << "," << c_3d[0][i](2) << std::endl;
00214   }*/
00215 }
00216 
00217 TEST_F(PolygonTest, mergingWorks)
00218 {
00219   std::vector<cob_3d_mapping::Polygon::Ptr> p_vec;
00220   for(unsigned int i = 0; i < pd_.size(); i++)
00221   {
00222     cob_3d_mapping::Polygon::Ptr p(new cob_3d_mapping::Polygon(pd_[i]->id_, pd_[i]->normal_, pd_[i]->origin_, pd_[i]->contours_3d_, pd_[i]->holes_, pd_[i]->color_));
00223     p_vec.push_back(p);
00224   }
00225   //std::cout << pd_[0]->normal_.dot(pd_[1]->normal_);
00226   //std::cout << p_vec.size() << std::endl;
00227   std::vector<int> intersections;
00228   p_vec[0]->getMergeCandidates(p_vec, intersections);
00229   //for(unsigned int i=0; i<intersections.size(); i++) std::cout << "\t" << intersections[i] << std::endl;
00230   EXPECT_EQ(intersections.size(), pd_[0]->merge_candidates_.size());
00231   std::vector<cob_3d_mapping::Polygon::Ptr> merge_candidates;
00232   double sum_area = 0;
00233   for(unsigned int i = 0; i < intersections.size(); i++)
00234   {
00235     merge_candidates.push_back(p_vec[i]);
00236     sum_area += p_vec[i]->computeArea3d();
00237   }
00238   p_vec[0]->merge(merge_candidates);
00239   EXPECT_EQ(p_vec[0]->merged_, pd_[0]->merge_candidates_.size()+1);
00240   EXPECT_LE(p_vec[0]->computeArea3d(), sum_area);
00241 
00242   /*intersections.clear();
00243   p_vec[2]->getMergeCandidates(p_vec, intersections);
00244   EXPECT_EQ(intersections.size(), pd_[2]->merge_candidates_.size());
00245   merge_candidates.clear();
00246   for(unsigned int i = 0; i < intersections.size(); i++)
00247   {
00248     merge_candidates.push_back(p_vec[intersections[i]]);
00249   }
00250   p_vec[2]->merge(merge_candidates);
00251   EXPECT_EQ(p_vec[2]->merged_, pd_[2]->merge_candidates_.size()+1);
00252   std::cout << p_vec[2]->contours_.size() << std::endl;*/
00253   /*std::cout << p_vec[1]->contours_.size() << std::endl;
00254   for(unsigned int i = 0; i < p_vec[1]->contours_[0].size(); i++)
00255   {
00256     std::cout << p_vec[1]->contours_[0][i](0) << p_vec[1]->contours_[0][i](1) << std::endl;
00257   }*/
00258 }
00259 
00260 TEST_F(PolygonTest, transformWorks)
00261 {
00262   Eigen::Affine3f t(Eigen::Affine3f::Identity());
00263   t.translate(Eigen::Vector3f(-1,1,2));
00264   t.rotate(Eigen::AngleAxisf(0.5, Eigen::Vector3f(1,1,1)));
00265   for(unsigned int i = 0; i < pd_.size(); i++)
00266   {
00267     cob_3d_mapping::Polygon::Ptr p(new cob_3d_mapping::Polygon(pd_[i]->id_, pd_[i]->normal_, pd_[i]->origin_, pd_[i]->contours_3d_, pd_[i]->holes_, pd_[i]->color_));
00268     Eigen::Affine3f p0 = p->pose_;
00269     p->transform(t);
00270     p->transform(t.inverse());
00271     EXPECT_NEAR(p->normal_.dot(pd_[i]->normal_), 1, 0.001);
00272     EXPECT_NEAR(p->d_, pd_[i]->d_, 0.001);
00273     Eigen::Affine3f dt = p->pose_*p0.inverse();
00274     /*std::cout << p->pose_.matrix() << std::endl;
00275     std::cout << p0.matrix() << std::endl;
00276     std::cout << p->pose_.isApprox(p0) << std::endl;*/
00277     EXPECT_TRUE(p->pose_.isApprox(p0));
00278     /*EXPECT_NEAR(dt(0,0), 1, 0.001);
00279     EXPECT_NEAR(dt(1,1), 1, 0.001);
00280     EXPECT_NEAR(dt(2,2), 1, 0.001);
00281     EXPECT_NEAR(dt(0,1), 0, 0.001);
00282     EXPECT_NEAR(dt(0,2), 0, 0.001);
00283     EXPECT_NEAR(dt(0,3), 0, 0.001);
00284     EXPECT_NEAR(dt(1,0), 0, 0.001);
00285     EXPECT_NEAR(dt(1,2), 0, 0.001);
00286     EXPECT_NEAR(dt(1,3), 0, 0.001);
00287     EXPECT_NEAR(dt(2,0), 0, 0.001);
00288     EXPECT_NEAR(dt(2,1), 0, 0.001);
00289     EXPECT_NEAR(dt(2,3), 0, 0.001);*/
00290   }
00291 }
00292 
00293 TEST_F(PolygonTest, msgConversionWorks)
00294 {
00295   for(unsigned int i = 0; i < pd_.size(); i++)
00296   {
00297     cob_3d_mapping::Polygon::Ptr p(new cob_3d_mapping::Polygon(pd_[i]->id_, pd_[i]->normal_, pd_[i]->origin_, pd_[i]->contours_3d_, pd_[i]->holes_, pd_[i]->color_));
00298     cob_3d_mapping_msgs::Shape s;
00299     cob_3d_mapping::toROSMsg(*p, s);
00300     cob_3d_mapping::Polygon p1;
00301     cob_3d_mapping::fromROSMsg(s, p1);
00302 
00303     EXPECT_EQ(p->id_, p1.id_);
00304     EXPECT_EQ(p->contours_.size(), p1.contours_.size());
00305     EXPECT_EQ(p->holes_.size(), p1.holes_.size());
00306     EXPECT_NEAR(p->d_, p1.d_, 0.00001);
00307     EXPECT_NEAR((p->normal_ - p1.normal_).norm(), 0, 0.001);
00308     EXPECT_TRUE(p->pose_.isApprox(p1.pose_));
00309     EXPECT_NEAR(p->merge_weight_, p1.merge_weight_, 0.00001);
00310     EXPECT_NEAR((p->color_[0] - p1.color_[0]), 0, 0.001);
00311     EXPECT_NEAR((p->color_[1] - p1.color_[1]), 0, 0.001);
00312     EXPECT_NEAR((p->color_[2] - p1.color_[2]), 0, 0.001);
00313     EXPECT_NEAR((p->color_[3] - p1.color_[3]), 0, 0.001);
00314     for(unsigned int j = 0; j < p->contours_.size(); j++)
00315     {
00316       for(unsigned int k = 0; k < p->contours_[j].size(); k++)
00317       {
00318         EXPECT_NEAR((p->contours_[j][k] - p1.contours_[j][k]).norm(), 0, 0.001);
00319       }
00320       EXPECT_EQ(p->holes_[j], p1.holes_[j]);
00321     }
00322   }
00323 }
00324 
00325 
00326 
00327 
00328 int main(int argc, char **argv)
00329 {
00330   testing::InitGoogleTest(&argc, argv);
00331   return RUN_ALL_TESTS();
00332 }


cob_3d_mapping_common
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:02:19