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
00137
00138
00139
00140
00141
00142
00143 PlaceProfile profile1()
00144 {
00145 PlaceProfile profile;
00146 profile.polygon.points.push_back(Point32());
00147 return profile;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
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
00171
00172
00173
00174
00175
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
00191
00192
00193
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
00212
00213
00214
00215
00216
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
00231
00232
00233
00234
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
00388 std::ofstream ofs("/tmp/normalizable.txt", std::ios_base::out);
00389 ofs << "count_plus: " << count_plus << "; count_minus: " << count_minus << std::endl;
00390 ofs.close();
00391
00392 return false;
00393 }
00394 }
00395 return true;
00396 }
00397
00398
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);
00407 scan.ranges.push_back(3.8);
00408 scan.ranges.push_back(4.2);
00409 scan.ranges.push_back(3.7);
00410 return scan;
00411 }
00412
00413
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);
00422 scan.ranges.push_back(3.7);
00423 scan.ranges.push_back(4.2);
00424 scan.ranges.push_back(3.8);
00425 return scan;
00426 }
00427
00428
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);
00437 scan.ranges.push_back(3);
00438 scan.ranges.push_back(3);
00439 scan.ranges.push_back(4.1);
00440 scan.ranges.push_back(4.1);
00441 scan.ranges.push_back(3.9);
00442 scan.ranges.push_back(3);
00443 scan.ranges.push_back(3);
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
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
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
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
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
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
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
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
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
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
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
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
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 }
00986
00987 int main(int argc, char** argv)
00988 {
00989 testing::InitGoogleTest(&argc, argv);
00990 return RUN_ALL_TESTS();
00991 }
00992