utest.cpp
Go to the documentation of this file.
00001 #include <string>
00002 #include <fstream>
00003 #include <algorithm>
00004 #include <cmath>
00005 #include <iostream>
00006 #include <vector>
00007 
00008 #include <gtest/gtest.h>
00009 #include <geometry_msgs/Point32.h>
00010 #include <geometry_msgs/Polygon.h>
00011 #include <geometry_msgs/Pose.h>
00012 
00013 #include <lama_common/angular_point.h>
00014 #include <lama_common/place_profile_utils.h>
00015 #include <lama_common/place_profile_conversions.h>
00016 #include <lama_common/polygon_utils.h>
00017 
00018 #define SAVE_FILES 0
00019 
00020 namespace lama_common
00021 {
00022 
00023 using std::vector;
00024 using sensor_msgs::LaserScan;
00025 using lama_msgs::PlaceProfile;
00026 using geometry_msgs::Point32;
00027 
00028 testing::AssertionResult pointEqual(const Point32& a, const Point32& b)
00029 {
00030   if (a.x == b.x && a.y == b.y)
00031   {
00032     return testing::AssertionSuccess();
00033   }
00034   else
00035   {
00036     return testing::AssertionFailure() << "(" << a.x << ", " << a.y <<
00037       ") is not (" << b.x << ", " << b.y << ")";
00038   }
00039 }
00040 
00041 testing::AssertionResult pointsEqual(const vector<Point32>& a, const vector<Point32>& b)
00042 {
00043   if (a.size() != b.size())
00044   {
00045     return testing::AssertionFailure() << "a.size() == " << a.size() <<
00046       " != b.size() == " << b.size();
00047   }
00048   for (size_t i = 0; i < a.size(); ++i)
00049   {
00050     if (a[i].x != b[i].x || a[i].y != b[i].y)
00051     {
00052       return testing::AssertionFailure() << "Point " << i << ": (" << a[i].x << ", " << a[i].y <<
00053       ") is not (" << b[i].x << ", " << b[i].y << ")";
00054     }
00055   }
00056   return testing::AssertionSuccess();
00057 }
00058 
00059 testing::AssertionResult polygonEqual(const geometry_msgs::Polygon& a, const geometry_msgs::Polygon& b)
00060 {
00061   return pointsEqual(a.points, b.points);
00062 }
00063 
00064 testing::AssertionResult pointClose(const Point32& a, const Point32& b, double tolerance)
00065 {
00066   if ((std::abs(a.x - b.x) < tolerance) && (std::abs(a.y - b.y) < tolerance))
00067   {
00068     return testing::AssertionSuccess();
00069   }
00070   else
00071   {
00072     return testing::AssertionFailure() << "(" << a.x << ", " << a.y <<
00073       ") is not close to (" << b.x << ", " << b.y << "): delta is (" <<
00074       std::abs(a.x - b.x) << ", " << std::abs(a.y - b.y) << ")";
00075   }
00076 }
00077 
00078 testing::AssertionResult pointsClose(const vector<Point32>& a, const vector<Point32>& b, double tolerance)
00079 {
00080   if (a.size() != b.size())
00081   {
00082     return testing::AssertionFailure() << "a.size() == " << a.size() <<
00083       " != b.size() == " << b.size();
00084   }
00085   for (size_t i = 0; i < a.size(); ++i)
00086   {
00087     testing::AssertionResult res = pointClose(a[i], b[i], tolerance);
00088     if (!res)
00089     {
00090       return testing::AssertionFailure() << "Point " << i << ": (" << a[i].x << ", " << a[i].y <<
00091         ") is not close to (" << b[i].x << ", " << b[i].y << "): delta is (" <<
00092         std::abs(a[i].x - b[i].x) << ", " << std::abs(a[i].y - b[i].y) << ")";
00093     }
00094   }
00095   return testing::AssertionSuccess();
00096 }
00097 
00098 testing::AssertionResult polygonClose(const geometry_msgs::Polygon& a, const geometry_msgs::Polygon& b, double tolerance)
00099 {
00100   return pointsClose(a.points, b.points, tolerance);
00101 }
00102 
00103 testing::AssertionResult profileIsClosed(const PlaceProfile& profile, double max_frontier_width)
00104 {
00105   if (isClosed(profile, max_frontier_width))
00106   {
00107     return testing::AssertionSuccess();
00108   }
00109   return testing::AssertionFailure() << "Profile is not closed";
00110 }
00111 
00114 PlaceProfile shift_profile_index(const PlaceProfile& profile, size_t shift)
00115 {
00116   const size_t n = profile.polygon.points.size();
00117   PlaceProfile new_profile;
00118   new_profile.polygon.points.reserve(n);
00119   for (size_t i = 0; i < n; ++i)
00120   {
00121     new_profile.polygon.points.push_back(profile.polygon.points[(i + shift) % n]);
00122   }
00123   return new_profile;
00124 }
00125 
00126 void translate_profile(PlaceProfile& profile, double dx, double dy)
00127 {
00128   vector<Point32>::iterator pt = profile.polygon.points.begin();
00129   for (; pt != profile.polygon.points.end(); ++pt)
00130   {
00131     pt->x += dx;
00132     pt->y += dy;
00133   }
00134 }
00135 
00136 /* 1 point
00137  *
00138  * no exclude segment
00139  *
00140  * exclude:
00141  * include: 0 -
00142  */
00143 PlaceProfile profile1()
00144 {
00145   PlaceProfile profile;
00146   profile.polygon.points.push_back(Point32());
00147   return profile;
00148 }
00149 
00150 
00151 /* 2 points
00152  *
00153  * no exclude segment
00154  *
00155  * exclude:
00156  * include: 0 - 1 -
00157  */
00158 PlaceProfile profile2()
00159 {
00160   PlaceProfile profile;
00161   for (size_t i = 0; i < 2; ++i)
00162   {
00163     Point32 point;
00164     point.x = i;
00165     profile.polygon.points.push_back(point);
00166   }
00167   return profile;
00168 }
00169 
00170 /* 3 points
00171  *
00172  * 1 exclude segment
00173  *
00174  * exclude:        -
00175  * include: 0 - 1 / \ 2 -
00176  */
00177 PlaceProfile profile3()
00178 {
00179   PlaceProfile profile;
00180   for (size_t i = 0; i < 3; ++i)
00181   {
00182     Point32 point;
00183     point.x = i;
00184     profile.polygon.points.push_back(point);
00185   }
00186   profile.exclude_segments.push_back(1);
00187   return profile;
00188 }
00189 
00190 /* 6 points
00191  *
00192  * exclude:       2 - 3
00193  * include: 0 - 1 /    \ 4 - 5 -
00194  *
00195  */
00196 PlaceProfile profile6()
00197 {
00198   PlaceProfile profile;
00199   for (size_t i = 0; i < 6; ++i)
00200   {
00201     Point32 point;
00202     point.x = i;
00203     profile.polygon.points.push_back(point);
00204   }
00205   profile.exclude_segments.push_back(1);
00206   profile.exclude_segments.push_back(2);
00207   profile.exclude_segments.push_back(3);
00208   return profile;
00209 }
00210 
00211 /* 7 points
00212  *
00213  * Same as profile6, with one added point.
00214  *
00215  * exclude       2 - 3        6
00216  * include 0 - 1 /    \4 - 5 / \
00217  *
00218  */
00219 PlaceProfile profile7()
00220 {
00221   PlaceProfile profile = profile6();
00222   Point32 point;
00223   point.x = 6;
00224   profile.polygon.points.push_back(point);
00225   profile.exclude_segments.push_back(5);
00226   profile.exclude_segments.push_back(6);
00227   return profile;
00228 }
00229 
00230 /* 10 points
00231  *
00232  * exclude                       -
00233  * irrelevant                           6 - 7 -      
00234  * include    0 - 1 - 2 - 3 - 4     5 -         8 - 9 -
00235  *
00236  */
00237 PlaceProfile profile10()
00238 {
00239   PlaceProfile profile;
00240   for (size_t i = 0; i < 10; ++i)
00241   {
00242     Point32 point;
00243     point.x = i;
00244     profile.polygon.points.push_back(point);
00245   }
00246   profile.polygon.points[0].y = 1;
00247   profile.polygon.points[1].y = 1.9;
00248   profile.polygon.points[2].y = 0.6;
00249   profile.polygon.points[3].y = 0;
00250   profile.polygon.points[4].y = 0.8;
00251   profile.polygon.points[5].y = 1;
00252   profile.polygon.points[6].y = 1;
00253   profile.polygon.points[7].y = 1;
00254   profile.polygon.points[8].y = 1;
00255   profile.polygon.points[9].y = 1.9;
00256   profile.exclude_segments.push_back(4);
00257   return profile;
00258 }
00259 
00260 PlaceProfile profile_circle_ccw()
00261 {
00262   PlaceProfile profile;
00263   const double radius = 5;
00264   const size_t point_count = 40;
00265   const double start_angle = -M_PI + 1e-5;
00266   for (size_t i = 0; i < point_count; ++i)
00267   {
00268     Point32 point;
00269     point.x = radius * std::cos(start_angle + ((double)i) / point_count * 2 * M_PI);
00270     point.y = radius * std::sin(start_angle + ((double)i) / point_count * 2 * M_PI);
00271     profile.polygon.points.push_back(point);
00272   }
00273   return profile;
00274 }
00275 
00278 PlaceProfile profile_circle_cw()
00279 {
00280   PlaceProfile profile = profile_circle_ccw();
00281   PlaceProfile new_profile;
00282   vector<Point32>::const_reverse_iterator pt = profile.polygon.points.rbegin();
00283   for (; pt != profile.polygon.points.rend(); ++pt)
00284   {
00285     new_profile.polygon.points.push_back(*pt);
00286   }
00287   return new_profile;
00288 }
00289 
00290 PlaceProfile profile_circle_growing()
00291 {
00292   PlaceProfile profile;
00293   double angle;
00294   double radius;
00295   Point32 point;
00296 
00297   angle = -3 * M_PI_4;
00298   radius = 3;
00299   point.x = radius * std::cos(angle);
00300   point.y = radius * std::sin(angle);
00301   profile.polygon.points.push_back(point);
00302 
00303   angle = -M_PI_4;
00304   radius = 4;
00305   point.x = radius * std::cos(angle);
00306   point.y = radius * std::sin(angle);
00307   profile.polygon.points.push_back(point);
00308 
00309   angle = M_PI_4;
00310   radius = 5;
00311   point.x = radius * std::cos(angle);
00312   point.y = radius * std::sin(angle);
00313   profile.polygon.points.push_back(point);
00314 
00315   angle = 3 * M_PI_4;
00316   radius = 5;
00317   point.x = radius * std::cos(angle);
00318   point.y = radius * std::sin(angle);
00319   profile.polygon.points.push_back(point);
00320 
00321   return profile;
00322 }
00323 
00324 PlaceProfile loadFromFile(const std::string& filename)
00325 {
00326   PlaceProfile profile;
00327   std::ifstream fin(filename.c_str());
00328   if (!fin.is_open())
00329   {
00330     std::cerr << "\"" << filename << "\" not found.";
00331     return PlaceProfile();
00332   }
00333   do
00334   {
00335     Point32 point;
00336     fin >> point.x >> point.y;
00337     if (!fin.eof())
00338     {
00339       profile.polygon.points.push_back(point);
00340     }
00341   } while (!fin.eof() && !fin.fail());
00342   return profile;
00343 }
00344 
00345 #if SAVE_FILES
00346 
00347 void saveToFile(const std::string& filename, const PlaceProfile& profile)
00348 {
00349   std::ofstream fout(filename.c_str());
00350   if (!fout.is_open())
00351   {
00352     std::cerr << "\"" << filename << "\" cannot be opened for writing";
00353     return;
00354   }
00355   vector<Point32>::const_iterator it = profile.polygon.points.begin();
00356   for (; it < profile.polygon.points.end(); ++it)
00357   {
00358     fout << it->x << " " << it->y << "\n";
00359   }
00360 }
00361 #endif
00362 
00365 static bool normalizablePolygon(const vector<AngularPoint>& angular_points)
00366 {
00367   unsigned int count_plus = 0;
00368   unsigned int count_minus = 0;
00369   for (size_t i = 0; i < angular_points.size(); ++i)
00370   {
00371     const double this_angle = angular_points[i].angle;
00372     const double next_angle = angular_points[(i + 1) % angular_points.size()].angle;
00373     if (this_angle == next_angle)
00374     {
00375       return false;
00376     }
00377     if (this_angle < next_angle)
00378     {
00379       count_plus++;
00380     }
00381     else
00382     {
00383       count_minus++;
00384     }
00385     if (count_plus > 1 && count_minus > 1)
00386     {
00387       /* DEBUG */
00388       std::ofstream ofs("/tmp/normalizable.txt", std::ios_base::out);
00389       ofs << "count_plus: " << count_plus << "; count_minus: " << count_minus << std::endl; // DEBUG
00390       ofs.close();
00391       /* DEBUG */
00392       return false;
00393     }
00394   }
00395   return true;
00396 }
00397 
00398 /* LaserScan with 4 points starting from 0, CCW
00399  */
00400 LaserScan scan4ccw()
00401 {
00402   LaserScan scan;
00403   scan.angle_min = 0 + 1e-5;
00404   scan.angle_max = scan.angle_min + 3 * M_PI_2;
00405   scan.angle_increment = M_PI_2;
00406   scan.ranges.push_back(3.5);  // 0
00407   scan.ranges.push_back(3.8);  // M_PI_2
00408   scan.ranges.push_back(4.2);  // M_PI
00409   scan.ranges.push_back(3.7);  // 3 * M_PI_2
00410   return scan;
00411 }
00412 
00413 /* LaserScan with 4 points starting from 0, CW
00414  */
00415 LaserScan scan4cw()
00416 {
00417   LaserScan scan;
00418   scan.angle_min = 0 + 1e-5;
00419   scan.angle_max = scan.angle_min - 3 * M_PI_2;
00420   scan.angle_increment = -M_PI_2;
00421   scan.ranges.push_back(3.5);  // 0
00422   scan.ranges.push_back(3.7);  // 3 * M_PI_2
00423   scan.ranges.push_back(4.2);  // M_PI
00424   scan.ranges.push_back(3.8);  // M_PI_2
00425   return scan;
00426 }
00427 
00428 /* LaserScan with 8 points starting from M_PI_2, CW
00429  */
00430 LaserScan scan8cw()
00431 {
00432   LaserScan scan;
00433   scan.angle_min = M_PI_2 + 1e-5;
00434   scan.angle_increment = M_PI_4;
00435   scan.angle_max = scan.angle_min + 2 * M_PI - scan.angle_increment;
00436   scan.ranges.push_back(3);  // pi / 2
00437   scan.ranges.push_back(3);  // 3 * pi / 4
00438   scan.ranges.push_back(3);  // pi
00439   scan.ranges.push_back(4.1);  // -3 * pi / 4
00440   scan.ranges.push_back(4.1);  // -pi / 2
00441   scan.ranges.push_back(3.9);  // -pi / 4
00442   scan.ranges.push_back(3);  // 0
00443   scan.ranges.push_back(3);  // pi / 4
00444   return scan;
00445 }
00446 
00447 inline double distance(Point32 point)
00448 {
00449   return std::sqrt(point.x * point.x + point.y * point.y);
00450 }
00451 
00452 TEST(TestSuite, testCenterPolygon)
00453 {
00454   geometry_msgs::Polygon poly;
00455   const double side = 1.0;
00456   // poly must be centered about its center of mass.
00457   Point32 point;
00458   point.x = side;
00459   point.y = side;
00460   poly.points.push_back(point);
00461   point.x = -side;
00462   point.y = side;
00463   poly.points.push_back(point);
00464   point.x = -side;
00465   point.y = -side;
00466   poly.points.push_back(point);
00467   point.x = side;
00468   point.y = -side;
00469   poly.points.push_back(point);
00470   geometry_msgs::Polygon mod_poly = poly;
00471 
00472   const double dx = 6.0;
00473   const double dy = 7.0;
00474   vector<geometry_msgs::Point32>::iterator pt;
00475   for (pt = mod_poly.points.begin(); pt != mod_poly.points.end(); ++pt)
00476   {
00477     pt->x += dx;
00478     pt->y += dy;
00479   }
00480 
00481   centerPolygon(mod_poly);
00482   EXPECT_TRUE(polygonClose(poly, mod_poly, 1e-6));
00483 }
00484 
00485 TEST(TestSuite, testNormalizePlaceProfile)
00486 {
00487   PlaceProfile profile;
00488   PlaceProfile mod_profile;
00489 
00490   // From CW to CCW.
00491   profile = profile_circle_ccw();
00492   mod_profile = profile_circle_cw();
00493   normalizePlaceProfile(mod_profile);
00494 
00495   ASSERT_EQ(profile.exclude_segments.size(), mod_profile.exclude_segments.size());
00496   EXPECT_TRUE(polygonEqual(profile.polygon, mod_profile.polygon));
00497 
00498   // exclude_segments minimization and sorting.
00499   mod_profile = profile;
00500   mod_profile.exclude_segments.push_back(10);
00501   mod_profile.exclude_segments.push_back(12);
00502   mod_profile.exclude_segments.push_back(11);
00503   mod_profile.exclude_segments.push_back(12);
00504   normalizePlaceProfile(mod_profile);
00505   ASSERT_EQ(profile.polygon.points.size(), mod_profile.polygon.points.size());
00506   EXPECT_TRUE(pointEqual(profile.polygon.points[10], mod_profile.polygon.points[10]));
00507   EXPECT_TRUE(pointEqual(profile.polygon.points[11], mod_profile.polygon.points[11]));
00508   EXPECT_TRUE(pointEqual(profile.polygon.points[12], mod_profile.polygon.points[12]));
00509   EXPECT_TRUE(pointEqual(profile.polygon.points[13], mod_profile.polygon.points[13]));
00510   ASSERT_EQ(3, mod_profile.exclude_segments.size());
00511   EXPECT_EQ(10, mod_profile.exclude_segments[0]);
00512   EXPECT_EQ(11, mod_profile.exclude_segments[1]);
00513   EXPECT_EQ(12, mod_profile.exclude_segments[2]);
00514 
00515   // From CW to CCW with 1 excluded segment.
00516   mod_profile = profile_circle_cw();
00517   mod_profile.exclude_segments.push_back(1);
00518   normalizePlaceProfile(mod_profile);
00519   ASSERT_EQ(profile.polygon.points.size(), mod_profile.polygon.points.size());
00520   EXPECT_TRUE(pointEqual(profile.polygon.points[37], mod_profile.polygon.points[37]));
00521   EXPECT_TRUE(pointEqual(profile.polygon.points[38], mod_profile.polygon.points[38]));
00522   ASSERT_EQ(1, mod_profile.exclude_segments.size());
00523   EXPECT_EQ(37, mod_profile.exclude_segments[0]);
00524 
00525   // From CW to CCW with 3 excluded segments (one twice).
00526   mod_profile = profile_circle_cw();
00527   mod_profile.exclude_segments.push_back(1);
00528   mod_profile.exclude_segments.push_back(1);
00529   mod_profile.exclude_segments.push_back(2);
00530   normalizePlaceProfile(mod_profile);
00531   ASSERT_EQ(profile.polygon.points.size(), mod_profile.polygon.points.size());
00532   EXPECT_TRUE(pointEqual(profile.polygon.points[36], mod_profile.polygon.points[36]));
00533   EXPECT_TRUE(pointEqual(profile.polygon.points[37], mod_profile.polygon.points[37]));
00534   EXPECT_TRUE(pointEqual(profile.polygon.points[38], mod_profile.polygon.points[38]));
00535   ASSERT_EQ(2, mod_profile.exclude_segments.size());
00536   EXPECT_EQ(36, mod_profile.exclude_segments[0]);
00537   EXPECT_EQ(37, mod_profile.exclude_segments[1]);
00538 
00539   // Rotated profile.
00540   const size_t shift = 5;
00541   profile = profile_circle_ccw();
00542   profile.polygon.points[0].x *= 2;
00543   profile.polygon.points[0].y *= 2;
00544   mod_profile = shift_profile_index(profile, shift);
00545   normalizePlaceProfile(mod_profile);
00546   EXPECT_TRUE(polygonEqual(profile.polygon, mod_profile.polygon));
00547 }
00548 
00549 TEST(TestSuite, testNormalizablePolygon)
00550 {
00551   PlaceProfile profile;
00552   vector<AngularPoint> angular_points;
00553 
00554   profile = profile_circle_ccw();
00555   angular_points = toAngularPoints(profile);
00556   EXPECT_TRUE(normalizablePolygon(angular_points));
00557 
00558   profile = profile_circle_ccw();
00559   translate_profile(profile, 0.5, 0.6);
00560   angular_points = toAngularPoints(profile);
00561   EXPECT_TRUE(normalizablePolygon(angular_points));
00562 
00563   profile = profile_circle_ccw();
00564   translate_profile(profile, 5.0, 6.0);
00565   angular_points = toAngularPoints(profile);
00566   EXPECT_FALSE(normalizablePolygon(angular_points));
00567 }
00568 
00569 TEST(TestSuite, testNormalizePolygon)
00570 {
00571   PlaceProfile profile;
00572   PlaceProfile mod_profile;
00573 
00574   // From CW to CCW.
00575   profile = profile_circle_ccw();
00576   mod_profile = profile_circle_cw();
00577   normalizePolygon(mod_profile.polygon);
00578 
00579   EXPECT_TRUE(polygonEqual(profile.polygon, mod_profile.polygon));
00580 
00581   // Rotated profile.
00582   const size_t shift = 5;
00583   profile = profile_circle_ccw();
00584   profile.polygon.points[0].x *= 2;
00585   profile.polygon.points[0].y *= 2;
00586   mod_profile = shift_profile_index(profile, shift);
00587   normalizePolygon(mod_profile.polygon);
00588   EXPECT_TRUE(polygonEqual(profile.polygon, mod_profile.polygon));
00589 }
00590 
00591 TEST(TestSuite, testClosePlaceProfile)
00592 {
00593   PlaceProfile profile;
00594 
00595   profile = profile_circle_ccw();
00596   PlaceProfile old_profile = profile;
00597 
00598 #if SAVE_FILES
00599   saveToFile("open_profile.txt", profile);
00600 #endif
00601 
00602   closePlaceProfile(profile, 0.05);
00603 
00604 #if SAVE_FILES
00605   saveToFile("closed_profile.txt", profile);
00606 #endif
00607 
00608   EXPECT_TRUE(profileIsClosed(profile, 0.06));
00609   EXPECT_FALSE(profileIsClosed(profile, 0.04));
00610   EXPECT_GE(profile.polygon.points.size(), old_profile.polygon.points.size());
00611 }
00612 
00613 TEST(TestSuite, testClosedPlaceProfile)
00614 {
00615   PlaceProfile old_profile;
00616 
00617   old_profile = profile_circle_ccw();
00618   PlaceProfile profile = closedPlaceProfile(old_profile, 0.05);
00619 
00620 #if SAVE_FILES
00621   saveToFile("open_profile.txt", old_profile);
00622   saveToFile("closed_profile.txt", profile);
00623 #endif 
00624 
00625   EXPECT_TRUE(profileIsClosed(profile, 0.06));
00626   EXPECT_FALSE(profileIsClosed(profile, 0.04));
00627   EXPECT_GE(profile.polygon.points.size(), old_profile.polygon.points.size());
00628 }
00629 
00630 TEST(TestSuite, testSimplifyPath)
00631 {
00632   // Note: simplifyPath does not know about excluded segments.
00633   
00634   PlaceProfile profile;
00635   vector<Point32> filtered_points;
00636 
00637   profile = profile1();
00638   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00639   EXPECT_EQ(1, filtered_points.size());
00640   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00641 
00642   profile = profile2();
00643   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00644   EXPECT_EQ(2, filtered_points.size());
00645   EXPECT_TRUE(pointsEqual(profile.polygon.points, filtered_points));
00646 
00647   profile = profile3();
00648   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00649   EXPECT_EQ(2, filtered_points.size());
00650   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00651   EXPECT_TRUE(pointEqual(profile.polygon.points[2], filtered_points[1]));
00652 
00653   profile = profile6();
00654   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00655   EXPECT_EQ(2, filtered_points.size());
00656   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00657   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[1]));
00658 
00659   profile = profile6();
00660   filtered_points = simplifyPath(profile.polygon.points, 0, 2, 0.01);
00661   EXPECT_EQ(2, filtered_points.size());
00662   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00663   EXPECT_TRUE(pointEqual(profile.polygon.points[1], filtered_points[1]));
00664 
00665   profile = profile6();
00666   filtered_points = simplifyPath(profile.polygon.points, 0, 3, 0.01);
00667   EXPECT_EQ(2, filtered_points.size());
00668   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00669   EXPECT_TRUE(pointEqual(profile.polygon.points[2], filtered_points[1]));
00670 
00671   profile = profile6();
00672   filtered_points = simplifyPath(profile.polygon.points, 4, 6, 0.01);
00673   EXPECT_EQ(2, filtered_points.size());
00674   EXPECT_TRUE(pointEqual(profile.polygon.points[4], filtered_points[0]));
00675   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[1]));
00676 
00677   profile = profile6();
00678   profile.polygon.points[1].y = 1;
00679   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00680   EXPECT_EQ(4, filtered_points.size());
00681   // std::copy(filtered_points.begin(), filtered_points.end(), std::ostream_iterator<Point32>(std::cout, "\n"));
00682   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00683   EXPECT_TRUE(pointEqual(profile.polygon.points[1], filtered_points[1]));
00684   EXPECT_TRUE(pointEqual(profile.polygon.points[2], filtered_points[2]));
00685   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[3]));
00686 
00687   profile = profile6();
00688   profile.polygon.points[1].y = 1;
00689   filtered_points = simplifyPath(profile.polygon.points, 0, 3, 0.01);
00690   EXPECT_EQ(3, filtered_points.size());
00691   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00692   EXPECT_TRUE(pointEqual(profile.polygon.points[1], filtered_points[1]));
00693   EXPECT_TRUE(pointEqual(profile.polygon.points[2], filtered_points[2]));
00694 
00695   profile = profile6();
00696   profile.polygon.points[2].y = 1;
00697   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00698   EXPECT_EQ(5, filtered_points.size());
00699   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00700   EXPECT_TRUE(pointEqual(profile.polygon.points[1], filtered_points[1]));
00701   EXPECT_TRUE(pointEqual(profile.polygon.points[2], filtered_points[2]));
00702   EXPECT_TRUE(pointEqual(profile.polygon.points[3], filtered_points[3]));
00703   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[4]));
00704 
00705   profile = profile6();
00706   profile.polygon.points[3].y = 1;
00707   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00708   EXPECT_EQ(5, filtered_points.size());
00709   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00710   EXPECT_TRUE(pointEqual(profile.polygon.points[2], filtered_points[1]));
00711   EXPECT_TRUE(pointEqual(profile.polygon.points[3], filtered_points[2]));
00712   EXPECT_TRUE(pointEqual(profile.polygon.points[4], filtered_points[3]));
00713   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[4]));
00714 
00715   profile = profile6();
00716   profile.polygon.points[4].y = 1;
00717   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00718   EXPECT_EQ(4, filtered_points.size());
00719   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00720   EXPECT_TRUE(pointEqual(profile.polygon.points[3], filtered_points[1]));
00721   EXPECT_TRUE(pointEqual(profile.polygon.points[4], filtered_points[2]));
00722   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[3]));
00723 
00724   profile = profile6();
00725   profile.polygon.points[1].y = 1;
00726   profile.polygon.points[4].y = 1;
00727   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00728   EXPECT_TRUE(pointsEqual(profile.polygon.points, filtered_points));
00729 
00730   profile = profile6();
00731   profile.polygon.points[1].y = 1;
00732   profile.polygon.points[2].y = 1;
00733   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00734   EXPECT_EQ(5, filtered_points.size());
00735   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00736   EXPECT_TRUE(pointEqual(profile.polygon.points[1], filtered_points[1]));
00737   EXPECT_TRUE(pointEqual(profile.polygon.points[2], filtered_points[2]));
00738   EXPECT_TRUE(pointEqual(profile.polygon.points[3], filtered_points[3]));
00739   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[4]));
00740 
00741   profile = profile6();
00742   profile.polygon.points[3].y = 1;
00743   profile.polygon.points[4].y = 1;
00744   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00745   EXPECT_EQ(5, filtered_points.size());
00746   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00747   EXPECT_TRUE(pointEqual(profile.polygon.points[2], filtered_points[1]));
00748   EXPECT_TRUE(pointEqual(profile.polygon.points[3], filtered_points[2]));
00749   EXPECT_TRUE(pointEqual(profile.polygon.points[4], filtered_points[3]));
00750   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[4]));
00751 
00752   profile = profile6();
00753   profile.polygon.points[2].y = 1;
00754   profile.polygon.points[3].y = 1;
00755   profile.polygon.points[4].y = 1;
00756   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00757   EXPECT_EQ(5, filtered_points.size());
00758   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00759   EXPECT_TRUE(pointEqual(profile.polygon.points[1], filtered_points[1]));
00760   EXPECT_TRUE(pointEqual(profile.polygon.points[2], filtered_points[2]));
00761   EXPECT_TRUE(pointEqual(profile.polygon.points[4], filtered_points[3]));
00762   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[4]));
00763 
00764   profile = profile6();
00765   profile.polygon.points[1].y = 1;
00766   profile.polygon.points[2].y = 1;
00767   profile.polygon.points[3].y = 1;
00768   profile.polygon.points[4].y = 1;
00769   filtered_points = simplifyPath(profile.polygon.points, 0, profile.polygon.points.size(), 0.01);
00770   EXPECT_EQ(4, filtered_points.size());
00771   EXPECT_TRUE(pointEqual(profile.polygon.points[0], filtered_points[0]));
00772   EXPECT_TRUE(pointEqual(profile.polygon.points[1], filtered_points[1]));
00773   EXPECT_TRUE(pointEqual(profile.polygon.points[4], filtered_points[2]));
00774   EXPECT_TRUE(pointEqual(profile.polygon.points[5], filtered_points[3]));
00775 }
00776 
00777 TEST(TestSuite, testSimplifyPlaceProfile)
00778 {
00779   PlaceProfile profile;
00780   PlaceProfile old_profile;
00781 
00782   profile = profile1();
00783   old_profile = profile;
00784   simplifyPlaceProfile(profile, 0.01);
00785   EXPECT_TRUE(pointsEqual(old_profile.polygon.points, profile.polygon.points));
00786 
00787   profile = profile2();
00788   old_profile = profile;
00789   simplifyPlaceProfile(profile, 0.01);
00790   EXPECT_TRUE(pointsEqual(old_profile.polygon.points, profile.polygon.points));
00791 
00792   profile = profile3();
00793   old_profile = profile;
00794   simplifyPlaceProfile(profile, 0.01);
00795   //std::copy(profile.polygon.points.begin(), profile.polygon.points.end(), std::ostream_iterator<Point32>(std::cout, "\n"));
00796   EXPECT_TRUE(pointsEqual(old_profile.polygon.points, profile.polygon.points));
00797   EXPECT_EQ(old_profile.exclude_segments, profile.exclude_segments);
00798 
00799   profile = profile6();
00800   old_profile = profile;
00801   simplifyPlaceProfile(profile, 0.01);
00802   EXPECT_TRUE(pointsEqual(old_profile.polygon.points, profile.polygon.points));
00803   ASSERT_EQ(3, profile.exclude_segments.size());
00804   EXPECT_EQ(1, profile.exclude_segments[0]);
00805   EXPECT_EQ(2, profile.exclude_segments[1]);
00806   EXPECT_EQ(3, profile.exclude_segments[2]);
00807 
00808   profile = profile7();
00809   old_profile = profile;
00810   simplifyPlaceProfile(profile, 0.01);
00811   EXPECT_TRUE(pointsEqual(old_profile.polygon.points, profile.polygon.points));
00812   EXPECT_EQ(old_profile.exclude_segments, profile.exclude_segments);
00813 
00814   profile = profile10();
00815   old_profile = profile;
00816   simplifyPlaceProfile(profile, 0.01);
00817   ASSERT_EQ(8, profile.polygon.points.size());
00818   EXPECT_TRUE(pointEqual(old_profile.polygon.points[0], profile.polygon.points[0]));
00819   EXPECT_TRUE(pointEqual(old_profile.polygon.points[1], profile.polygon.points[1]));
00820   EXPECT_TRUE(pointEqual(old_profile.polygon.points[2], profile.polygon.points[2]));
00821   EXPECT_TRUE(pointEqual(old_profile.polygon.points[3], profile.polygon.points[3]));
00822   EXPECT_TRUE(pointEqual(old_profile.polygon.points[4], profile.polygon.points[4]));
00823   EXPECT_TRUE(pointEqual(old_profile.polygon.points[5], profile.polygon.points[5]));
00824   EXPECT_TRUE(pointEqual(old_profile.polygon.points[8], profile.polygon.points[6]));
00825   EXPECT_TRUE(pointEqual(old_profile.polygon.points[9], profile.polygon.points[7]));
00826   EXPECT_EQ(old_profile.exclude_segments, profile.exclude_segments);
00827 
00828   // profile10 + segment 6 excluded.
00829   profile = profile10();
00830   profile.exclude_segments.push_back(6);
00831   old_profile = profile;
00832   simplifyPlaceProfile(profile, 0.01);
00833   EXPECT_TRUE(pointsEqual(old_profile.polygon.points, profile.polygon.points));
00834   EXPECT_EQ(old_profile.exclude_segments, profile.exclude_segments);
00835 }
00836 
00837 TEST(TestSuite, testRealDataSimplify)
00838 {
00839   PlaceProfile profile;
00840   PlaceProfile out_profile_1;
00841   PlaceProfile out_profile_2;
00842 
00843   profile = loadFromFile("corridor130a-1.txt");
00844   out_profile_1 = profile;
00845   EXPECT_EQ(362, profile.polygon.points.size());
00846   out_profile_2 = simplifiedPlaceProfile(profile, 0.01);
00847   EXPECT_GE(out_profile_1.polygon.points.size(), out_profile_2.polygon.points.size());
00848 
00849 #if SAVE_FILES
00850   saveToFile("corridor130a-1-0.01.txt", out_profile_2);
00851 #endif
00852 
00853   out_profile_1 = out_profile_2;
00854   out_profile_2 = simplifiedPlaceProfile(profile, 0.1);
00855   EXPECT_GE(out_profile_1.polygon.points.size(), out_profile_2.polygon.points.size());
00856 
00857 #if SAVE_FILES
00858   saveToFile("corridor130a-1-0.1.txt", out_profile_2);
00859 #endif
00860 }
00861 
00862 TEST(TestSuite, testCurtailPlaceProfile)
00863 {
00864   PlaceProfile profile = profile_circle_growing();
00865   PlaceProfile mod_profile;
00866 
00867   mod_profile = profile;
00868   curtailPlaceProfile(mod_profile, 2.5);
00869   EXPECT_EQ(0, mod_profile.polygon.points.size());
00870   EXPECT_EQ(0, mod_profile.exclude_segments.size());
00871 
00872   mod_profile = profile;
00873   curtailPlaceProfile(mod_profile, 3.5);
00874   ASSERT_EQ(1, mod_profile.polygon.points.size());
00875   EXPECT_EQ(0, mod_profile.exclude_segments.size());
00876   EXPECT_TRUE(pointEqual(profile.polygon.points[0], mod_profile.polygon.points[0]));
00877 
00878   mod_profile = profile;
00879   curtailPlaceProfile(mod_profile, 4.5);
00880   ASSERT_EQ(2, mod_profile.polygon.points.size());
00881   EXPECT_EQ(0, mod_profile.exclude_segments.size());
00882   EXPECT_TRUE(pointEqual(profile.polygon.points[0], mod_profile.polygon.points[0]));
00883   EXPECT_TRUE(pointEqual(profile.polygon.points[1], mod_profile.polygon.points[1]));
00884 
00885   mod_profile = profile;
00886   curtailPlaceProfile(mod_profile, 5.5);
00887   ASSERT_EQ(4, mod_profile.polygon.points.size());
00888   EXPECT_EQ(0, mod_profile.exclude_segments.size());
00889   EXPECT_TRUE(pointEqual(profile.polygon.points[0], mod_profile.polygon.points[0]));
00890   EXPECT_TRUE(pointEqual(profile.polygon.points[1], mod_profile.polygon.points[1]));
00891   EXPECT_TRUE(pointEqual(profile.polygon.points[2], mod_profile.polygon.points[2]));
00892   EXPECT_TRUE(pointEqual(profile.polygon.points[3], mod_profile.polygon.points[3]));
00893 
00894   profile = profile_circle_ccw();
00895   mod_profile = profile;
00896   mod_profile.polygon.points[5].x *= 2;
00897   mod_profile.polygon.points[5].y *= 2;
00898   curtailPlaceProfile(mod_profile, 6);
00899   ASSERT_EQ(profile.polygon.points.size() - 1, mod_profile.polygon.points.size());
00900   EXPECT_TRUE(pointEqual(profile.polygon.points[4], mod_profile.polygon.points[4]));
00901   EXPECT_TRUE(pointEqual(profile.polygon.points[6], mod_profile.polygon.points[5]));
00902   ASSERT_EQ(1, mod_profile.exclude_segments.size());
00903   EXPECT_EQ(4, mod_profile.exclude_segments[0]);
00904 
00905   mod_profile = profile;
00906   mod_profile.polygon.points[5].x *= 2;
00907   mod_profile.polygon.points[5].y *= 2;
00908   mod_profile.polygon.points[7].x *= 2;
00909   mod_profile.polygon.points[7].y *= 2;
00910   curtailPlaceProfile(mod_profile, 6);
00911   ASSERT_EQ(profile.polygon.points.size() - 2, mod_profile.polygon.points.size());
00912   EXPECT_TRUE(pointEqual(profile.polygon.points[4], mod_profile.polygon.points[4]));
00913   EXPECT_TRUE(pointEqual(profile.polygon.points[6], mod_profile.polygon.points[5]));
00914   EXPECT_TRUE(pointEqual(profile.polygon.points[8], mod_profile.polygon.points[6]));
00915   ASSERT_EQ(2, mod_profile.exclude_segments.size());
00916   EXPECT_EQ(4, mod_profile.exclude_segments[0]);
00917   EXPECT_EQ(5, mod_profile.exclude_segments[1]);
00918 }
00919 
00920 TEST(TestSuite, testLaserScanToPlaceProfile)
00921 {
00922   LaserScan scan;
00923   PlaceProfile profile;
00924 
00925   scan = scan4ccw();
00926   profile = laserScanToPlaceProfile(scan, 5);
00927   ASSERT_EQ(4, profile.polygon.points.size());
00928   EXPECT_EQ(0, profile.exclude_segments.size());
00929   EXPECT_FLOAT_EQ(scan.ranges[2], distance(profile.polygon.points[0]));
00930   EXPECT_FLOAT_EQ(scan.ranges[3], distance(profile.polygon.points[1]));
00931   EXPECT_FLOAT_EQ(scan.ranges[0], distance(profile.polygon.points[2]));
00932   EXPECT_FLOAT_EQ(scan.ranges[1], distance(profile.polygon.points[3]));
00933 
00934   scan = scan4ccw();
00935   profile = laserScanToPlaceProfile(scan, 4);
00936   ASSERT_EQ(3, profile.polygon.points.size());
00937   ASSERT_EQ(1, profile.exclude_segments.size());
00938   EXPECT_FLOAT_EQ(scan.ranges[3], distance(profile.polygon.points[0]));
00939   EXPECT_FLOAT_EQ(scan.ranges[0], distance(profile.polygon.points[1]));
00940   EXPECT_FLOAT_EQ(scan.ranges[1], distance(profile.polygon.points[2]));
00941   EXPECT_EQ(2, profile.exclude_segments[0]);
00942 
00943   scan = scan4cw();
00944   profile = laserScanToPlaceProfile(scan, 5);
00945   ASSERT_EQ(4, profile.polygon.points.size());
00946   EXPECT_EQ(0, profile.exclude_segments.size());
00947   EXPECT_FLOAT_EQ(scan.ranges[2], distance(profile.polygon.points[0]));
00948   EXPECT_FLOAT_EQ(scan.ranges[1], distance(profile.polygon.points[1]));
00949   EXPECT_FLOAT_EQ(scan.ranges[0], distance(profile.polygon.points[2]));
00950   EXPECT_FLOAT_EQ(scan.ranges[3], distance(profile.polygon.points[3]));
00951 
00952   scan = scan4cw();
00953   profile = laserScanToPlaceProfile(scan, 4);
00954   ASSERT_EQ(3, profile.polygon.points.size());
00955   ASSERT_EQ(1, profile.exclude_segments.size());
00956   EXPECT_FLOAT_EQ(scan.ranges[1], distance(profile.polygon.points[0]));
00957   EXPECT_FLOAT_EQ(scan.ranges[0], distance(profile.polygon.points[1]));
00958   EXPECT_FLOAT_EQ(scan.ranges[3], distance(profile.polygon.points[2]));
00959   EXPECT_EQ(2, profile.exclude_segments[0]);
00960 
00961   scan = scan8cw();
00962   profile = laserScanToPlaceProfile(scan, 4);
00963   ASSERT_EQ(6, profile.polygon.points.size());
00964   ASSERT_EQ(1, profile.exclude_segments.size());
00965   EXPECT_FLOAT_EQ(scan.ranges[2], distance(profile.polygon.points[0]));
00966   EXPECT_FLOAT_EQ(scan.ranges[5], distance(profile.polygon.points[1]));
00967   EXPECT_FLOAT_EQ(scan.ranges[6], distance(profile.polygon.points[2]));
00968   EXPECT_FLOAT_EQ(scan.ranges[7], distance(profile.polygon.points[3]));
00969   EXPECT_FLOAT_EQ(scan.ranges[0], distance(profile.polygon.points[4]));
00970   EXPECT_FLOAT_EQ(scan.ranges[1], distance(profile.polygon.points[5]));
00971   EXPECT_EQ(0, profile.exclude_segments[0]);
00972 
00973   scan = scan8cw();
00974   profile = laserScanToPlaceProfile(scan, 3.5);
00975   ASSERT_EQ(5, profile.polygon.points.size());
00976   ASSERT_EQ(1, profile.exclude_segments.size());
00977   EXPECT_FLOAT_EQ(scan.ranges[2], distance(profile.polygon.points[0]));
00978   EXPECT_FLOAT_EQ(scan.ranges[6], distance(profile.polygon.points[1]));
00979   EXPECT_FLOAT_EQ(scan.ranges[7], distance(profile.polygon.points[2]));
00980   EXPECT_FLOAT_EQ(scan.ranges[0], distance(profile.polygon.points[3]));
00981   EXPECT_FLOAT_EQ(scan.ranges[1], distance(profile.polygon.points[4]));
00982   EXPECT_EQ(0, profile.exclude_segments[0]);
00983 }
00984 
00985 } // namespace lama_common
00986 
00987 int main(int argc, char** argv)
00988 {
00989   testing::InitGoogleTest(&argc, argv);
00990   return RUN_ALL_TESTS();
00991 }
00992 


lama_common
Author(s): Gaël Ecorchard , Karel Košnar , Vojtěch Vonásek
autogenerated on Thu Jun 6 2019 22:02:03