test_velocities.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include <iostream>
  2. #include "tests.hpp"
  3. #include <sophus/velocities.hpp>
  4. namespace Sophus {
  5. namespace experimental {
  6. template <class Scalar>
  7. bool tests_linear_velocities() {
  8. bool passed = true;
  9. std::vector<SE3<Scalar>, Eigen::aligned_allocator<SE3<Scalar>>> bar_Ts_baz;
  10. for (size_t i = 0; i < 10; ++i) {
  11. bar_Ts_baz.push_back(SE3<Scalar>::rotX(i * 0.001) *
  12. SE3<Scalar>::rotY(i * 0.001) *
  13. SE3<Scalar>::transX(0.01 * i));
  14. }
  15. SE3<Scalar> foo_T_bar =
  16. SE3<Scalar>::rotX(0.5) * SE3<Scalar>::rotZ(0.2) * SE3<Scalar>::transY(2);
  17. std::vector<SE3<Scalar>, Eigen::aligned_allocator<SE3<Scalar>>> foo_Ts_baz;
  18. for (auto const& bar_T_baz : bar_Ts_baz) {
  19. foo_Ts_baz.push_back(foo_T_bar * bar_T_baz);
  20. }
  21. auto gen_linear_vels =
  22. [](std::vector<SE3<Scalar>, Eigen::aligned_allocator<SE3<Scalar>>> const&
  23. a_Ts_b) {
  24. std::vector<Vector3<Scalar>, Eigen::aligned_allocator<Vector3<Scalar>>>
  25. linearVels_a;
  26. for (size_t i = 0; i < a_Ts_b.size() - 1; ++i) {
  27. linearVels_a.push_back(a_Ts_b[i + 1].translation() -
  28. a_Ts_b[i].translation());
  29. }
  30. return linearVels_a;
  31. };
  32. // linear velocities in frame bar
  33. std::vector<Vector3<Scalar>, Eigen::aligned_allocator<Vector3<Scalar>>>
  34. linearVels_bar = gen_linear_vels(bar_Ts_baz);
  35. // linear velocities in frame foo
  36. std::vector<Vector3<Scalar>, Eigen::aligned_allocator<Vector3<Scalar>>>
  37. linearVels_foo = gen_linear_vels(foo_Ts_baz);
  38. for (size_t i = 0; i < linearVels_bar.size(); ++i) {
  39. SOPHUS_TEST_APPROX(passed, linearVels_foo[i],
  40. transformVelocity(foo_T_bar, linearVels_bar[i]),
  41. sqrt(Constants<Scalar>::epsilon()));
  42. }
  43. return passed;
  44. }
  45. template <class Scalar>
  46. bool tests_rotational_velocities() {
  47. bool passed = true;
  48. SE3<Scalar> foo_T_bar =
  49. SE3<Scalar>::rotX(0.5) * SE3<Scalar>::rotZ(0.2) * SE3<Scalar>::transY(2);
  50. // One parameter subgroup of SE3, motion through space given time t.
  51. auto bar_T_baz = [](Scalar t) -> SE3<Scalar> {
  52. return SE3<Scalar>::rotX(t * Scalar(0.01)) *
  53. SE3<Scalar>::rotY(t * Scalar(0.0001)) *
  54. SE3<Scalar>::transX(t * Scalar(0.0001));
  55. };
  56. std::vector<Scalar> ts = {Scalar(0), Scalar(0.3), Scalar(1)};
  57. Scalar h = Constants<Scalar>::epsilon();
  58. for (Scalar t : ts) {
  59. // finite difference approximiation of instantanious velocity in frame bar
  60. Vector3<Scalar> rotVel_in_frame_bar =
  61. finiteDifferenceRotationalVelocity<Scalar>(bar_T_baz, t, h);
  62. // finite difference approximiation of instantanious velocity in frame foo
  63. Vector3<Scalar> rotVel_in_frame_foo =
  64. finiteDifferenceRotationalVelocity<Scalar>(
  65. [&foo_T_bar, bar_T_baz](Scalar t) -> SE3<Scalar> {
  66. return foo_T_bar * bar_T_baz(t);
  67. },
  68. t, h);
  69. Vector3<Scalar> rotVel_in_frame_bar2 =
  70. transformVelocity(foo_T_bar.inverse(), rotVel_in_frame_foo);
  71. SOPHUS_TEST_APPROX(
  72. passed, rotVel_in_frame_bar, rotVel_in_frame_bar2,
  73. // not too tight threshold, because of finit difference approximation
  74. std::sqrt(Constants<Scalar>::epsilon()));
  75. // The rotational velocities rotVel_in_frame_foo and rotVel_in_frame_bar
  76. // should not be equal since they are in different frames (foo != bar).
  77. SOPHUS_TEST_NOT_APPROX(passed, rotVel_in_frame_foo, rotVel_in_frame_bar,
  78. Scalar(1e-3));
  79. // Expect same result when using adjoint instead since:
  80. // vee(bar_R_foo * hat(vel_foo) * bar_R_foo^T = bar_R_foo 8 vel_foo.
  81. SOPHUS_TEST_APPROX(
  82. passed, transformVelocity(foo_T_bar.inverse(), rotVel_in_frame_foo),
  83. SO3<Scalar>::vee(foo_T_bar.so3().inverse().matrix() *
  84. SO3<Scalar>::hat(rotVel_in_frame_foo) *
  85. foo_T_bar.so3().matrix()),
  86. Constants<Scalar>::epsilon());
  87. }
  88. return passed;
  89. }
  90. int test_velocities() {
  91. using std::cerr;
  92. using std::endl;
  93. cerr << "Test Velocities" << endl << endl;
  94. cerr << "Double tests: " << endl;
  95. bool passed = tests_linear_velocities<double>();
  96. passed &= tests_rotational_velocities<double>();
  97. processTestResult(passed);
  98. cerr << "Float tests: " << endl;
  99. passed = tests_linear_velocities<float>();
  100. passed &= tests_rotational_velocities<float>();
  101. processTestResult(passed);
  102. return 0;
  103. }
  104. } // namespace experimental
  105. } // namespace Sophus
  106. int main() { return Sophus::experimental::test_velocities(); }