tests.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. #ifndef SOPUHS_TESTS_HPP
  2. #define SOPUHS_TESTS_HPP
  3. #include <array>
  4. #include <Eigen/StdVector>
  5. #include <unsupported/Eigen/MatrixFunctions>
  6. #include <sophus/average.hpp>
  7. #include <sophus/interpolate.hpp>
  8. #include <sophus/num_diff.hpp>
  9. #include <sophus/test_macros.hpp>
  10. #ifdef SOPHUS_CERES
  11. #include <ceres/jet.h>
  12. #endif
  13. namespace Sophus {
  14. template <class LieGroup_>
  15. class LieGroupTests {
  16. public:
  17. using LieGroup = LieGroup_;
  18. using Scalar = typename LieGroup::Scalar;
  19. using Transformation = typename LieGroup::Transformation;
  20. using Tangent = typename LieGroup::Tangent;
  21. using Point = typename LieGroup::Point;
  22. using HomogeneousPoint = typename LieGroup::HomogeneousPoint;
  23. using ConstPointMap = Eigen::Map<const Point>;
  24. using Line = typename LieGroup::Line;
  25. using Adjoint = typename LieGroup::Adjoint;
  26. static int constexpr N = LieGroup::N;
  27. static int constexpr DoF = LieGroup::DoF;
  28. static int constexpr num_parameters = LieGroup::num_parameters;
  29. LieGroupTests(
  30. std::vector<LieGroup, Eigen::aligned_allocator<LieGroup>> const&
  31. group_vec,
  32. std::vector<Tangent, Eigen::aligned_allocator<Tangent>> const&
  33. tangent_vec,
  34. std::vector<Point, Eigen::aligned_allocator<Point>> const& point_vec)
  35. : group_vec_(group_vec),
  36. tangent_vec_(tangent_vec),
  37. point_vec_(point_vec) {}
  38. bool adjointTest() {
  39. bool passed = true;
  40. for (size_t i = 0; i < group_vec_.size(); ++i) {
  41. Transformation T = group_vec_[i].matrix();
  42. Adjoint Ad = group_vec_[i].Adj();
  43. for (size_t j = 0; j < tangent_vec_.size(); ++j) {
  44. Tangent x = tangent_vec_[j];
  45. Transformation I;
  46. I.setIdentity();
  47. Tangent ad1 = Ad * x;
  48. Tangent ad2 = LieGroup::vee(T * LieGroup::hat(x) *
  49. group_vec_[i].inverse().matrix());
  50. SOPHUS_TEST_APPROX(passed, ad1, ad2, Scalar(10) * kSmallEps,
  51. "Adjoint case %, %", i, j);
  52. }
  53. }
  54. return passed;
  55. }
  56. bool contructorAndAssignmentTest() {
  57. bool passed = true;
  58. for (LieGroup foo_T_bar : group_vec_) {
  59. LieGroup foo_T2_bar = foo_T_bar;
  60. SOPHUS_TEST_APPROX(passed, foo_T_bar.matrix(), foo_T2_bar.matrix(),
  61. kSmallEps, "Copy constructor: %\nvs\n %",
  62. transpose(foo_T_bar.matrix()),
  63. transpose(foo_T2_bar.matrix()));
  64. LieGroup foo_T3_bar;
  65. foo_T3_bar = foo_T_bar;
  66. SOPHUS_TEST_APPROX(passed, foo_T_bar.matrix(), foo_T3_bar.matrix(),
  67. kSmallEps, "Copy assignment: %\nvs\n %",
  68. transpose(foo_T_bar.matrix()),
  69. transpose(foo_T3_bar.matrix()));
  70. LieGroup foo_T4_bar(foo_T_bar.matrix());
  71. SOPHUS_TEST_APPROX(
  72. passed, foo_T_bar.matrix(), foo_T4_bar.matrix(), kSmallEps,
  73. "Constructor from homogeneous matrix: %\nvs\n %",
  74. transpose(foo_T_bar.matrix()), transpose(foo_T4_bar.matrix()));
  75. Eigen::Map<LieGroup> foo_Tmap_bar(foo_T_bar.data());
  76. LieGroup foo_T5_bar = foo_Tmap_bar;
  77. SOPHUS_TEST_APPROX(
  78. passed, foo_T_bar.matrix(), foo_T5_bar.matrix(), kSmallEps,
  79. "Assignment from Eigen::Map type: %\nvs\n %",
  80. transpose(foo_T_bar.matrix()), transpose(foo_T5_bar.matrix()));
  81. Eigen::Map<LieGroup const> foo_Tcmap_bar(foo_T_bar.data());
  82. LieGroup foo_T6_bar;
  83. foo_T6_bar = foo_Tcmap_bar;
  84. SOPHUS_TEST_APPROX(
  85. passed, foo_T_bar.matrix(), foo_T5_bar.matrix(), kSmallEps,
  86. "Assignment from Eigen::Map type: %\nvs\n %",
  87. transpose(foo_T_bar.matrix()), transpose(foo_T5_bar.matrix()));
  88. LieGroup I;
  89. Eigen::Map<LieGroup> foo_Tmap2_bar(I.data());
  90. foo_Tmap2_bar = foo_T_bar;
  91. SOPHUS_TEST_APPROX(passed, foo_Tmap2_bar.matrix(), foo_T_bar.matrix(),
  92. kSmallEps, "Assignment to Eigen::Map type: %\nvs\n %",
  93. transpose(foo_Tmap2_bar.matrix()),
  94. transpose(foo_T_bar.matrix()));
  95. }
  96. return passed;
  97. }
  98. bool derivativeTest() {
  99. bool passed = true;
  100. LieGroup g;
  101. for (int i = 0; i < DoF; ++i) {
  102. Transformation Gi = g.Dxi_exp_x_matrix_at_0(i);
  103. Transformation Gi2 = curveNumDiff(
  104. [i](Scalar xi) -> Transformation {
  105. Tangent x;
  106. setToZero(x);
  107. setElementAt(x, xi, i);
  108. return LieGroup::exp(x).matrix();
  109. },
  110. Scalar(0));
  111. SOPHUS_TEST_APPROX(passed, Gi, Gi2, kSmallEpsSqrt,
  112. "Dxi_exp_x_matrix_at_ case %", i);
  113. }
  114. return passed;
  115. }
  116. template <class G = LieGroup>
  117. enable_if_t<std::is_same<G, Sophus::SO2<Scalar>>::value ||
  118. std::is_same<G, Sophus::SO3<Scalar>>::value ||
  119. std::is_same<G, Sophus::SE2<Scalar>>::value ||
  120. std::is_same<G, Sophus::SE3<Scalar>>::value,
  121. bool>
  122. additionalDerivativeTest() {
  123. bool passed = true;
  124. for (size_t j = 0; j < tangent_vec_.size(); ++j) {
  125. Tangent a = tangent_vec_[j];
  126. Eigen::Matrix<Scalar, num_parameters, DoF> J = LieGroup::Dx_exp_x(a);
  127. Eigen::Matrix<Scalar, num_parameters, DoF> J_num =
  128. vectorFieldNumDiff<Scalar, num_parameters, DoF>(
  129. [](Tangent const& x) -> Sophus::Vector<Scalar, num_parameters> {
  130. return LieGroup::exp(x).params();
  131. },
  132. a);
  133. SOPHUS_TEST_APPROX(passed, J, J_num, 3 * kSmallEpsSqrt,
  134. "Dx_exp_x case: %", j);
  135. }
  136. Tangent o;
  137. setToZero(o);
  138. Eigen::Matrix<Scalar, num_parameters, DoF> J = LieGroup::Dx_exp_x_at_0();
  139. Eigen::Matrix<Scalar, num_parameters, DoF> J_num =
  140. vectorFieldNumDiff<Scalar, num_parameters, DoF>(
  141. [](Tangent const& x) -> Sophus::Vector<Scalar, num_parameters> {
  142. return LieGroup::exp(x).params();
  143. },
  144. o);
  145. SOPHUS_TEST_APPROX(passed, J, J_num, kSmallEpsSqrt, "Dx_exp_x_at_0");
  146. for (size_t i = 0; i < group_vec_.size(); ++i) {
  147. LieGroup T = group_vec_[i];
  148. Eigen::Matrix<Scalar, num_parameters, DoF> J = T.Dx_this_mul_exp_x_at_0();
  149. Eigen::Matrix<Scalar, num_parameters, DoF> J_num =
  150. vectorFieldNumDiff<Scalar, num_parameters, DoF>(
  151. [T](Tangent const& x) -> Sophus::Vector<Scalar, num_parameters> {
  152. return (T * LieGroup::exp(x)).params();
  153. },
  154. o);
  155. SOPHUS_TEST_APPROX(passed, J, J_num, kSmallEpsSqrt,
  156. "Dx_this_mul_exp_x_at_0 case: %", i);
  157. }
  158. return passed;
  159. }
  160. template <class G = LieGroup>
  161. enable_if_t<!std::is_same<G, Sophus::SO2<Scalar>>::value &&
  162. !std::is_same<G, Sophus::SO3<Scalar>>::value &&
  163. !std::is_same<G, Sophus::SE2<Scalar>>::value &&
  164. !std::is_same<G, Sophus::SE3<Scalar>>::value,
  165. bool>
  166. additionalDerivativeTest() {
  167. return true;
  168. }
  169. bool productTest() {
  170. bool passed = true;
  171. for (size_t i = 0; i < group_vec_.size() - 1; ++i) {
  172. LieGroup T1 = group_vec_[i];
  173. LieGroup T2 = group_vec_[i + 1];
  174. LieGroup mult = T1 * T2;
  175. T1 *= T2;
  176. SOPHUS_TEST_APPROX(passed, T1.matrix(), mult.matrix(), kSmallEps,
  177. "Product case: %", i);
  178. }
  179. return passed;
  180. }
  181. bool expLogTest() {
  182. bool passed = true;
  183. for (size_t i = 0; i < group_vec_.size(); ++i) {
  184. Transformation T1 = group_vec_[i].matrix();
  185. Transformation T2 = LieGroup::exp(group_vec_[i].log()).matrix();
  186. SOPHUS_TEST_APPROX(passed, T1, T2, kSmallEps, "G - exp(log(G)) case: %",
  187. i);
  188. }
  189. return passed;
  190. }
  191. bool expMapTest() {
  192. bool passed = true;
  193. for (size_t i = 0; i < tangent_vec_.size(); ++i) {
  194. Tangent omega = tangent_vec_[i];
  195. Transformation exp_x = LieGroup::exp(omega).matrix();
  196. Transformation expmap_hat_x = (LieGroup::hat(omega)).exp();
  197. SOPHUS_TEST_APPROX(passed, exp_x, expmap_hat_x, Scalar(10) * kSmallEps,
  198. "expmap(hat(x)) - exp(x) case: %", i);
  199. }
  200. return passed;
  201. }
  202. bool groupActionTest() {
  203. bool passed = true;
  204. for (size_t i = 0; i < group_vec_.size(); ++i) {
  205. for (size_t j = 0; j < point_vec_.size(); ++j) {
  206. Point const& p = point_vec_[j];
  207. Point point1 = group_vec_[i] * p;
  208. HomogeneousPoint hp = p.homogeneous();
  209. HomogeneousPoint hpoint1 = group_vec_[i] * hp;
  210. ConstPointMap p_map(p.data());
  211. Point pointmap1 = group_vec_[i] * p_map;
  212. Transformation T = group_vec_[i].matrix();
  213. Point gt_point1 = map(T, p);
  214. SOPHUS_TEST_APPROX(passed, point1, gt_point1, kSmallEps,
  215. "Transform point case: %", i);
  216. SOPHUS_TEST_APPROX(passed, hpoint1.hnormalized().eval(), gt_point1,
  217. kSmallEps, "Transform homogeneous point case: %", i);
  218. SOPHUS_TEST_APPROX(passed, pointmap1, gt_point1, kSmallEps,
  219. "Transform map point case: %", i);
  220. }
  221. }
  222. return passed;
  223. }
  224. bool lineActionTest() {
  225. bool passed = point_vec_.size() > 1;
  226. for (size_t i = 0; i < group_vec_.size(); ++i) {
  227. for (size_t j = 0; j + 1 < point_vec_.size(); ++j) {
  228. Point const& p1 = point_vec_[j];
  229. Point const& p2 = point_vec_[j + 1];
  230. Line l = Line::Through(p1, p2);
  231. Point p1_t = group_vec_[i] * p1;
  232. Point p2_t = group_vec_[i] * p2;
  233. Line l_t = group_vec_[i] * l;
  234. SOPHUS_TEST_APPROX(passed, l_t.squaredDistance(p1_t),
  235. static_cast<Scalar>(0), kSmallEps,
  236. "Transform line case (1st point) : %", i);
  237. SOPHUS_TEST_APPROX(passed, l_t.squaredDistance(p2_t),
  238. static_cast<Scalar>(0), kSmallEps,
  239. "Transform line case (2nd point) : %", i);
  240. SOPHUS_TEST_APPROX(passed, l_t.direction().squaredNorm(),
  241. l.direction().squaredNorm(), kSmallEps,
  242. "Transform line case (direction) : %", i);
  243. }
  244. }
  245. return passed;
  246. }
  247. bool lieBracketTest() {
  248. bool passed = true;
  249. for (size_t i = 0; i < tangent_vec_.size(); ++i) {
  250. for (size_t j = 0; j < tangent_vec_.size(); ++j) {
  251. Tangent tangent1 =
  252. LieGroup::lieBracket(tangent_vec_[i], tangent_vec_[j]);
  253. Transformation hati = LieGroup::hat(tangent_vec_[i]);
  254. Transformation hatj = LieGroup::hat(tangent_vec_[j]);
  255. Tangent tangent2 = LieGroup::vee(hati * hatj - hatj * hati);
  256. SOPHUS_TEST_APPROX(passed, tangent1, tangent2, kSmallEps,
  257. "Lie Bracket case: %", i);
  258. }
  259. }
  260. return passed;
  261. }
  262. bool veeHatTest() {
  263. bool passed = true;
  264. for (size_t i = 0; i < tangent_vec_.size(); ++i) {
  265. SOPHUS_TEST_APPROX(passed, Tangent(tangent_vec_[i]),
  266. LieGroup::vee(LieGroup::hat(tangent_vec_[i])),
  267. kSmallEps, "Hat-vee case: %", i);
  268. }
  269. return passed;
  270. }
  271. bool newDeleteSmokeTest() {
  272. bool passed = true;
  273. LieGroup* raw_ptr = nullptr;
  274. raw_ptr = new LieGroup();
  275. SOPHUS_TEST_NEQ(passed, reinterpret_cast<std::uintptr_t>(raw_ptr), 0);
  276. delete raw_ptr;
  277. return passed;
  278. }
  279. bool interpolateAndMeanTest() {
  280. bool passed = true;
  281. using std::sqrt;
  282. Scalar const eps = Constants<Scalar>::epsilon();
  283. Scalar const sqrt_eps = sqrt(eps);
  284. // TODO: Improve accuracy of ``interpolate`` (and hence ``exp`` and ``log``)
  285. // so that we can use more accurate bounds in these tests, i.e.
  286. // ``eps`` instead of ``sqrt_eps``.
  287. for (LieGroup const& foo_T_bar : group_vec_) {
  288. for (LieGroup const& foo_T_baz : group_vec_) {
  289. // Test boundary conditions ``alpha=0`` and ``alpha=1``.
  290. LieGroup foo_T_quiz = interpolate(foo_T_bar, foo_T_baz, Scalar(0));
  291. SOPHUS_TEST_APPROX(passed, foo_T_quiz.matrix(), foo_T_bar.matrix(),
  292. sqrt_eps);
  293. foo_T_quiz = interpolate(foo_T_bar, foo_T_baz, Scalar(1));
  294. SOPHUS_TEST_APPROX(passed, foo_T_quiz.matrix(), foo_T_baz.matrix(),
  295. sqrt_eps);
  296. }
  297. }
  298. for (Scalar alpha :
  299. {Scalar(0.1), Scalar(0.5), Scalar(0.75), Scalar(0.99)}) {
  300. for (LieGroup const& foo_T_bar : group_vec_) {
  301. for (LieGroup const& foo_T_baz : group_vec_) {
  302. LieGroup foo_T_quiz = interpolate(foo_T_bar, foo_T_baz, alpha);
  303. // test left-invariance:
  304. //
  305. // dash_T_foo * interp(foo_T_bar, foo_T_baz)
  306. // == interp(dash_T_foo * foo_T_bar, dash_T_foo * foo_T_baz)
  307. if (interp_details::Traits<LieGroup>::hasShortestPathAmbiguity(
  308. foo_T_bar.inverse() * foo_T_baz)) {
  309. // skip check since there is a shortest path ambiguity
  310. continue;
  311. }
  312. for (LieGroup const& dash_T_foo : group_vec_) {
  313. LieGroup dash_T_quiz = interpolate(dash_T_foo * foo_T_bar,
  314. dash_T_foo * foo_T_baz, alpha);
  315. SOPHUS_TEST_APPROX(passed, dash_T_quiz.matrix(),
  316. (dash_T_foo * foo_T_quiz).matrix(), sqrt_eps);
  317. }
  318. // test inverse-invariance:
  319. //
  320. // interp(foo_T_bar, foo_T_baz).inverse()
  321. // == interp(foo_T_bar.inverse(), dash_T_foo.inverse())
  322. LieGroup quiz_T_foo =
  323. interpolate(foo_T_bar.inverse(), foo_T_baz.inverse(), alpha);
  324. SOPHUS_TEST_APPROX(passed, quiz_T_foo.inverse().matrix(),
  325. foo_T_quiz.matrix(), sqrt_eps);
  326. }
  327. }
  328. for (LieGroup const& bar_T_foo : group_vec_) {
  329. for (LieGroup const& baz_T_foo : group_vec_) {
  330. LieGroup quiz_T_foo = interpolate(bar_T_foo, baz_T_foo, alpha);
  331. // test right-invariance:
  332. //
  333. // interp(bar_T_foo, bar_T_foo) * foo_T_dash
  334. // == interp(bar_T_foo * foo_T_dash, bar_T_foo * foo_T_dash)
  335. if (interp_details::Traits<LieGroup>::hasShortestPathAmbiguity(
  336. bar_T_foo * baz_T_foo.inverse())) {
  337. // skip check since there is a shortest path ambiguity
  338. continue;
  339. }
  340. for (LieGroup const& foo_T_dash : group_vec_) {
  341. LieGroup quiz_T_dash = interpolate(bar_T_foo * foo_T_dash,
  342. baz_T_foo * foo_T_dash, alpha);
  343. SOPHUS_TEST_APPROX(passed, quiz_T_dash.matrix(),
  344. (quiz_T_foo * foo_T_dash).matrix(), sqrt_eps);
  345. }
  346. }
  347. }
  348. }
  349. for (LieGroup const& foo_T_bar : group_vec_) {
  350. for (LieGroup const& foo_T_baz : group_vec_) {
  351. if (interp_details::Traits<LieGroup>::hasShortestPathAmbiguity(
  352. foo_T_bar.inverse() * foo_T_baz)) {
  353. // skip check since there is a shortest path ambiguity
  354. continue;
  355. }
  356. // test average({A, B}) == interp(A, B):
  357. LieGroup foo_T_quiz = interpolate(foo_T_bar, foo_T_baz, 0.5);
  358. optional<LieGroup> foo_T_iaverage = iterativeMean(
  359. std::array<LieGroup, 2>({{foo_T_bar, foo_T_baz}}), 20);
  360. optional<LieGroup> foo_T_average =
  361. average(std::array<LieGroup, 2>({{foo_T_bar, foo_T_baz}}));
  362. SOPHUS_TEST(passed, bool(foo_T_average),
  363. "log(foo_T_bar): %\nlog(foo_T_baz): %",
  364. transpose(foo_T_bar.log()), transpose(foo_T_baz.log()));
  365. if (foo_T_average) {
  366. SOPHUS_TEST_APPROX(
  367. passed, foo_T_quiz.matrix(), foo_T_average->matrix(), sqrt_eps,
  368. "log(foo_T_bar): %\nlog(foo_T_baz): %\n"
  369. "log(interp): %\nlog(average): %",
  370. transpose(foo_T_bar.log()), transpose(foo_T_baz.log()),
  371. transpose(foo_T_quiz.log()), transpose(foo_T_average->log()));
  372. }
  373. SOPHUS_TEST(passed, bool(foo_T_iaverage),
  374. "log(foo_T_bar): %\nlog(foo_T_baz): %\n"
  375. "log(interp): %\nlog(iaverage): %",
  376. transpose(foo_T_bar.log()), transpose(foo_T_baz.log()),
  377. transpose(foo_T_quiz.log()),
  378. transpose(foo_T_iaverage->log()));
  379. if (foo_T_iaverage) {
  380. SOPHUS_TEST_APPROX(
  381. passed, foo_T_quiz.matrix(), foo_T_iaverage->matrix(), sqrt_eps,
  382. "log(foo_T_bar): %\nlog(foo_T_baz): %",
  383. transpose(foo_T_bar.log()), transpose(foo_T_baz.log()));
  384. }
  385. }
  386. }
  387. return passed;
  388. }
  389. bool testRandomSmoke() {
  390. bool passed = true;
  391. std::default_random_engine engine;
  392. for (int i = 0; i < 100; ++i) {
  393. LieGroup g = LieGroup::sampleUniform(engine);
  394. SOPHUS_TEST_EQUAL(passed, g.params(), g.params());
  395. }
  396. return passed;
  397. }
  398. template <class S = Scalar>
  399. enable_if_t<std::is_floating_point<S>::value, bool> doAllTestsPass() {
  400. return doesLargeTestSetPass();
  401. }
  402. template <class S = Scalar>
  403. enable_if_t<!std::is_floating_point<S>::value, bool> doAllTestsPass() {
  404. return doesSmallTestSetPass();
  405. }
  406. private:
  407. bool doesSmallTestSetPass() {
  408. bool passed = true;
  409. passed &= adjointTest();
  410. passed &= contructorAndAssignmentTest();
  411. passed &= productTest();
  412. passed &= expLogTest();
  413. passed &= groupActionTest();
  414. passed &= lineActionTest();
  415. passed &= lieBracketTest();
  416. passed &= veeHatTest();
  417. passed &= newDeleteSmokeTest();
  418. return passed;
  419. }
  420. bool doesLargeTestSetPass() {
  421. bool passed = true;
  422. passed &= doesSmallTestSetPass();
  423. passed &= additionalDerivativeTest();
  424. passed &= derivativeTest();
  425. passed &= expMapTest();
  426. passed &= interpolateAndMeanTest();
  427. passed &= testRandomSmoke();
  428. return passed;
  429. }
  430. Scalar const kSmallEps = Constants<Scalar>::epsilon();
  431. Scalar const kSmallEpsSqrt = Constants<Scalar>::epsilonSqrt();
  432. Eigen::Matrix<Scalar, N - 1, 1> map(
  433. Eigen::Matrix<Scalar, N, N> const& T,
  434. Eigen::Matrix<Scalar, N - 1, 1> const& p) {
  435. return T.template topLeftCorner<N - 1, N - 1>() * p +
  436. T.template topRightCorner<N - 1, 1>();
  437. }
  438. Eigen::Matrix<Scalar, N, 1> map(Eigen::Matrix<Scalar, N, N> const& T,
  439. Eigen::Matrix<Scalar, N, 1> const& p) {
  440. return T * p;
  441. }
  442. std::vector<LieGroup, Eigen::aligned_allocator<LieGroup>> group_vec_;
  443. std::vector<Tangent, Eigen::aligned_allocator<Tangent>> tangent_vec_;
  444. std::vector<Point, Eigen::aligned_allocator<Point>> point_vec_;
  445. };
  446. template <class Scalar>
  447. std::vector<SE3<Scalar>, Eigen::aligned_allocator<SE3<Scalar>>> getTestSE3s() {
  448. Scalar const kPi = Constants<Scalar>::pi();
  449. std::vector<SE3<Scalar>, Eigen::aligned_allocator<SE3<Scalar>>> se3_vec;
  450. se3_vec.push_back(SE3<Scalar>(
  451. SO3<Scalar>::exp(Vector3<Scalar>(Scalar(0.2), Scalar(0.5), Scalar(0.0))),
  452. Vector3<Scalar>(Scalar(0), Scalar(0), Scalar(0))));
  453. se3_vec.push_back(SE3<Scalar>(
  454. SO3<Scalar>::exp(Vector3<Scalar>(Scalar(0.2), Scalar(0.5), Scalar(-1.0))),
  455. Vector3<Scalar>(Scalar(10), Scalar(0), Scalar(0))));
  456. se3_vec.push_back(
  457. SE3<Scalar>::trans(Vector3<Scalar>(Scalar(0), Scalar(100), Scalar(5))));
  458. se3_vec.push_back(SE3<Scalar>::rotZ(Scalar(0.00001)));
  459. se3_vec.push_back(
  460. SE3<Scalar>::trans(Scalar(0), Scalar(-0.00000001), Scalar(0.0000000001)) *
  461. SE3<Scalar>::rotZ(Scalar(0.00001)));
  462. se3_vec.push_back(SE3<Scalar>::transX(Scalar(0.01)) *
  463. SE3<Scalar>::rotZ(Scalar(0.00001)));
  464. se3_vec.push_back(SE3<Scalar>::trans(Scalar(4), Scalar(-5), Scalar(0)) *
  465. SE3<Scalar>::rotX(kPi));
  466. se3_vec.push_back(
  467. SE3<Scalar>(SO3<Scalar>::exp(
  468. Vector3<Scalar>(Scalar(0.2), Scalar(0.5), Scalar(0.0))),
  469. Vector3<Scalar>(Scalar(0), Scalar(0), Scalar(0))) *
  470. SE3<Scalar>::rotX(kPi) *
  471. SE3<Scalar>(SO3<Scalar>::exp(Vector3<Scalar>(Scalar(-0.2), Scalar(-0.5),
  472. Scalar(-0.0))),
  473. Vector3<Scalar>(Scalar(0), Scalar(0), Scalar(0))));
  474. se3_vec.push_back(
  475. SE3<Scalar>(SO3<Scalar>::exp(
  476. Vector3<Scalar>(Scalar(0.3), Scalar(0.5), Scalar(0.1))),
  477. Vector3<Scalar>(Scalar(2), Scalar(0), Scalar(-7))) *
  478. SE3<Scalar>::rotX(kPi) *
  479. SE3<Scalar>(SO3<Scalar>::exp(Vector3<Scalar>(Scalar(-0.3), Scalar(-0.5),
  480. Scalar(-0.1))),
  481. Vector3<Scalar>(Scalar(0), Scalar(6), Scalar(0))));
  482. return se3_vec;
  483. }
  484. template <class T>
  485. std::vector<SE2<T>, Eigen::aligned_allocator<SE2<T>>> getTestSE2s() {
  486. T const kPi = Constants<T>::pi();
  487. std::vector<SE2<T>, Eigen::aligned_allocator<SE2<T>>> se2_vec;
  488. se2_vec.push_back(SE2<T>());
  489. se2_vec.push_back(SE2<T>(SO2<T>(0.2), Vector2<T>(10, 0)));
  490. se2_vec.push_back(SE2<T>::transY(100));
  491. se2_vec.push_back(SE2<T>::trans(Vector2<T>(1, 2)));
  492. se2_vec.push_back(SE2<T>(SO2<T>(-1.), Vector2<T>(20, -1)));
  493. se2_vec.push_back(
  494. SE2<T>(SO2<T>(0.00001), Vector2<T>(-0.00000001, 0.0000000001)));
  495. se2_vec.push_back(SE2<T>(SO2<T>(0.3), Vector2<T>(2, 0)) * SE2<T>::rot(kPi) *
  496. SE2<T>(SO2<T>(-0.3), Vector2<T>(0, 6)));
  497. return se2_vec;
  498. }
  499. } // namespace Sophus
  500. #endif // TESTS_HPP