test_geometry.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include <iostream>
  2. #include <sophus/geometry.hpp>
  3. #include <sophus/test_macros.hpp>
  4. #include "tests.hpp"
  5. namespace Sophus {
  6. namespace {
  7. template <class T>
  8. bool test2dGeometry() {
  9. bool passed = true;
  10. T const eps = Constants<T>::epsilon();
  11. for (int i = 0; i < 20; ++i) {
  12. // Roundtrip test:
  13. Vector2<T> normal_foo = Vector2<T>::Random().normalized();
  14. Sophus::SO2<T> R_foo_plane = SO2FromNormal(normal_foo);
  15. Vector2<T> resultNormal_foo = normalFromSO2(R_foo_plane);
  16. SOPHUS_TEST_APPROX(passed, normal_foo, resultNormal_foo, eps);
  17. }
  18. for (int i = 0; i < 20; ++i) {
  19. // Roundtrip test:
  20. Line2<T> line_foo = makeHyperplaneUnique(
  21. Line2<T>(Vector2<T>::Random().normalized(), Vector2<T>::Random()));
  22. Sophus::SE2<T> T_foo_plane = SE2FromLine(line_foo);
  23. Line2<T> resultPlane_foo = lineFromSE2(T_foo_plane);
  24. SOPHUS_TEST_APPROX(passed, line_foo.normal().eval(),
  25. resultPlane_foo.normal().eval(), eps);
  26. SOPHUS_TEST_APPROX(passed, line_foo.offset(), resultPlane_foo.offset(),
  27. eps);
  28. }
  29. std::vector<SE2<T>, Eigen::aligned_allocator<SE2<T>>> Ts_foo_line =
  30. getTestSE2s<T>();
  31. for (SE2<T> const& T_foo_line : Ts_foo_line) {
  32. Line2<T> line_foo = lineFromSE2(T_foo_line);
  33. SE2<T> T2_foo_line = SE2FromLine(line_foo);
  34. Line2<T> line2_foo = lineFromSE2(T2_foo_line);
  35. SOPHUS_TEST_APPROX(passed, line_foo.normal().eval(),
  36. line2_foo.normal().eval(), eps);
  37. SOPHUS_TEST_APPROX(passed, line_foo.offset(), line2_foo.offset(), eps);
  38. }
  39. return passed;
  40. }
  41. template <class T>
  42. bool test3dGeometry() {
  43. bool passed = true;
  44. T const eps = Constants<T>::epsilon();
  45. Vector3<T> normal_foo = Vector3<T>(1, 2, 0).normalized();
  46. Matrix3<T> R_foo_plane = rotationFromNormal(normal_foo);
  47. SOPHUS_TEST_APPROX(passed, normal_foo, R_foo_plane.col(2).eval(), eps);
  48. // Just testing that the function normalizes the input normal and hint
  49. // direction correctly:
  50. Matrix3<T> R2_foo_plane = rotationFromNormal((T(0.9) * normal_foo).eval());
  51. SOPHUS_TEST_APPROX(passed, normal_foo, R2_foo_plane.col(2).eval(), eps);
  52. Matrix3<T> R3_foo_plane =
  53. rotationFromNormal(normal_foo, Vector3<T>(T(0.9), T(0), T(0)),
  54. Vector3<T>(T(0), T(1.1), T(0)));
  55. SOPHUS_TEST_APPROX(passed, normal_foo, R3_foo_plane.col(2).eval(), eps);
  56. normal_foo = Vector3<T>(1, 0, 0);
  57. R_foo_plane = rotationFromNormal(normal_foo);
  58. SOPHUS_TEST_APPROX(passed, normal_foo, R_foo_plane.col(2).eval(), eps);
  59. SOPHUS_TEST_APPROX(passed, Vector3<T>(0, 1, 0), R_foo_plane.col(1).eval(),
  60. eps);
  61. normal_foo = Vector3<T>(0, 1, 0);
  62. R_foo_plane = rotationFromNormal(normal_foo);
  63. SOPHUS_TEST_APPROX(passed, normal_foo, R_foo_plane.col(2).eval(), eps);
  64. SOPHUS_TEST_APPROX(passed, Vector3<T>(1, 0, 0), R_foo_plane.col(0).eval(),
  65. eps);
  66. for (int i = 0; i < 20; ++i) {
  67. // Roundtrip test:
  68. Vector3<T> normal_foo = Vector3<T>::Random().normalized();
  69. Sophus::SO3<T> R_foo_plane = SO3FromNormal(normal_foo);
  70. Vector3<T> resultNormal_foo = normalFromSO3(R_foo_plane);
  71. SOPHUS_TEST_APPROX(passed, normal_foo, resultNormal_foo, eps);
  72. }
  73. for (int i = 0; i < 20; ++i) {
  74. // Roundtrip test:
  75. Plane3<T> plane_foo = makeHyperplaneUnique(
  76. Plane3<T>(Vector3<T>::Random().normalized(), Vector3<T>::Random()));
  77. Sophus::SE3<T> T_foo_plane = SE3FromPlane(plane_foo);
  78. Plane3<T> resultPlane_foo = planeFromSE3(T_foo_plane);
  79. SOPHUS_TEST_APPROX(passed, plane_foo.normal().eval(),
  80. resultPlane_foo.normal().eval(), eps);
  81. SOPHUS_TEST_APPROX(passed, plane_foo.offset(), resultPlane_foo.offset(),
  82. eps);
  83. }
  84. std::vector<SE3<T>, Eigen::aligned_allocator<SE3<T>>> Ts_foo_plane =
  85. getTestSE3s<T>();
  86. for (SE3<T> const& T_foo_plane : Ts_foo_plane) {
  87. Plane3<T> plane_foo = planeFromSE3(T_foo_plane);
  88. SE3<T> T2_foo_plane = SE3FromPlane(plane_foo);
  89. Plane3<T> plane2_foo = planeFromSE3(T2_foo_plane);
  90. SOPHUS_TEST_APPROX(passed, plane_foo.normal().eval(),
  91. plane2_foo.normal().eval(), eps);
  92. SOPHUS_TEST_APPROX(passed, plane_foo.offset(), plane2_foo.offset(), eps);
  93. }
  94. return passed;
  95. }
  96. void runAll() {
  97. std::cerr << "Geometry (Lines/Planes) tests:" << std::endl;
  98. std::cerr << "Double tests: " << std::endl;
  99. bool passed = test2dGeometry<double>();
  100. passed = test3dGeometry<double>();
  101. processTestResult(passed);
  102. std::cerr << "Float tests: " << std::endl;
  103. passed = test2dGeometry<float>();
  104. passed = test3dGeometry<float>();
  105. processTestResult(passed);
  106. }
  107. } // namespace
  108. } // namespace Sophus
  109. int main() { Sophus::runAll(); }