123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #include <iostream>
- #include "tests.hpp"
- #include <sophus/velocities.hpp>
- namespace Sophus {
- namespace experimental {
- template <class Scalar>
- bool tests_linear_velocities() {
- bool passed = true;
- std::vector<SE3<Scalar>, Eigen::aligned_allocator<SE3<Scalar>>> bar_Ts_baz;
- for (size_t i = 0; i < 10; ++i) {
- bar_Ts_baz.push_back(SE3<Scalar>::rotX(i * 0.001) *
- SE3<Scalar>::rotY(i * 0.001) *
- SE3<Scalar>::transX(0.01 * i));
- }
- SE3<Scalar> foo_T_bar =
- SE3<Scalar>::rotX(0.5) * SE3<Scalar>::rotZ(0.2) * SE3<Scalar>::transY(2);
- std::vector<SE3<Scalar>, Eigen::aligned_allocator<SE3<Scalar>>> foo_Ts_baz;
- for (auto const& bar_T_baz : bar_Ts_baz) {
- foo_Ts_baz.push_back(foo_T_bar * bar_T_baz);
- }
- auto gen_linear_vels =
- [](std::vector<SE3<Scalar>, Eigen::aligned_allocator<SE3<Scalar>>> const&
- a_Ts_b) {
- std::vector<Vector3<Scalar>, Eigen::aligned_allocator<Vector3<Scalar>>>
- linearVels_a;
- for (size_t i = 0; i < a_Ts_b.size() - 1; ++i) {
- linearVels_a.push_back(a_Ts_b[i + 1].translation() -
- a_Ts_b[i].translation());
- }
- return linearVels_a;
- };
- // linear velocities in frame bar
- std::vector<Vector3<Scalar>, Eigen::aligned_allocator<Vector3<Scalar>>>
- linearVels_bar = gen_linear_vels(bar_Ts_baz);
- // linear velocities in frame foo
- std::vector<Vector3<Scalar>, Eigen::aligned_allocator<Vector3<Scalar>>>
- linearVels_foo = gen_linear_vels(foo_Ts_baz);
- for (size_t i = 0; i < linearVels_bar.size(); ++i) {
- SOPHUS_TEST_APPROX(passed, linearVels_foo[i],
- transformVelocity(foo_T_bar, linearVels_bar[i]),
- sqrt(Constants<Scalar>::epsilon()));
- }
- return passed;
- }
- template <class Scalar>
- bool tests_rotational_velocities() {
- bool passed = true;
- SE3<Scalar> foo_T_bar =
- SE3<Scalar>::rotX(0.5) * SE3<Scalar>::rotZ(0.2) * SE3<Scalar>::transY(2);
- // One parameter subgroup of SE3, motion through space given time t.
- auto bar_T_baz = [](Scalar t) -> SE3<Scalar> {
- return SE3<Scalar>::rotX(t * Scalar(0.01)) *
- SE3<Scalar>::rotY(t * Scalar(0.0001)) *
- SE3<Scalar>::transX(t * Scalar(0.0001));
- };
- std::vector<Scalar> ts = {Scalar(0), Scalar(0.3), Scalar(1)};
- Scalar h = Constants<Scalar>::epsilon();
- for (Scalar t : ts) {
- // finite difference approximiation of instantanious velocity in frame bar
- Vector3<Scalar> rotVel_in_frame_bar =
- finiteDifferenceRotationalVelocity<Scalar>(bar_T_baz, t, h);
- // finite difference approximiation of instantanious velocity in frame foo
- Vector3<Scalar> rotVel_in_frame_foo =
- finiteDifferenceRotationalVelocity<Scalar>(
- [&foo_T_bar, bar_T_baz](Scalar t) -> SE3<Scalar> {
- return foo_T_bar * bar_T_baz(t);
- },
- t, h);
- Vector3<Scalar> rotVel_in_frame_bar2 =
- transformVelocity(foo_T_bar.inverse(), rotVel_in_frame_foo);
- SOPHUS_TEST_APPROX(
- passed, rotVel_in_frame_bar, rotVel_in_frame_bar2,
- // not too tight threshold, because of finit difference approximation
- std::sqrt(Constants<Scalar>::epsilon()));
- // The rotational velocities rotVel_in_frame_foo and rotVel_in_frame_bar
- // should not be equal since they are in different frames (foo != bar).
- SOPHUS_TEST_NOT_APPROX(passed, rotVel_in_frame_foo, rotVel_in_frame_bar,
- Scalar(1e-3));
- // Expect same result when using adjoint instead since:
- // vee(bar_R_foo * hat(vel_foo) * bar_R_foo^T = bar_R_foo 8 vel_foo.
- SOPHUS_TEST_APPROX(
- passed, transformVelocity(foo_T_bar.inverse(), rotVel_in_frame_foo),
- SO3<Scalar>::vee(foo_T_bar.so3().inverse().matrix() *
- SO3<Scalar>::hat(rotVel_in_frame_foo) *
- foo_T_bar.so3().matrix()),
- Constants<Scalar>::epsilon());
- }
- return passed;
- }
- int test_velocities() {
- using std::cerr;
- using std::endl;
- cerr << "Test Velocities" << endl << endl;
- cerr << "Double tests: " << endl;
- bool passed = tests_linear_velocities<double>();
- passed &= tests_rotational_velocities<double>();
- processTestResult(passed);
- cerr << "Float tests: " << endl;
- passed = tests_linear_velocities<float>();
- passed &= tests_rotational_velocities<float>();
- processTestResult(passed);
- return 0;
- }
- } // namespace experimental
- } // namespace Sophus
- int main() { return Sophus::experimental::test_velocities(); }
|