forked from artivis/manif
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgtest_manif_utils.h
126 lines (96 loc) · 3.71 KB
/
gtest_manif_utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#ifndef _MANIF_MANIF_GTEST_GTEST_MANIF_UTILS_H_
#define _MANIF_MANIF_GTEST_GTEST_MANIF_UTILS_H_
#include "manif/impl/lie_group_base.h"
#include "manif/impl/utils.h"
#include "gtest_eigen_utils.h"
#include <random>
#include <chrono>
#define EXPECT_ANGLE_NEAR(e, a, eps) \
EXPECT_LT(pi2pi(e-a), eps)
// https://stackoverflow.com/questions/3046889/optional-parameters-with-c-macros
#define EXPECT_MANIF_NEAR_DEFAULT_TOL(A,B) \
EXPECT_TRUE(manif::isManifNear(A, B, #A, #B))
#define EXPECT_MANIF_NEAR_TOL(A,B,tol) \
EXPECT_TRUE(manif::isManifNear(A, B, #A, #B, tol))
#define EXPECT_MANIF_NOT_NEAR_DEFAULT_TOL(A,B) \
EXPECT_FALSE(manif::isManifNear(A, B, #A, #B))
#define EXPECT_MANIF_NOT_NEAR_TOL(A,B,tol) \
EXPECT_FALSE(manif::isManifNear(A, B, #A, #B, tol))
#define __EXPECT_MANIF_NEAR_CHOOSER(...) \
__GET_4TH_ARG(__VA_ARGS__, EXPECT_MANIF_NEAR_TOL, \
EXPECT_MANIF_NEAR_DEFAULT_TOL, )
#define __EXPECT_MANIF_NOT_NEAR_CHOOSER(...) \
__GET_4TH_ARG(__VA_ARGS__, EXPECT_MANIF_NOT_NEAR_TOL, \
EXPECT_MANIF_NOT_NEAR_DEFAULT_TOL, )
#define EXPECT_MANIF_NEAR(...) \
__EXPECT_MANIF_NEAR_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
#define EXPECT_MANIF_NOT_NEAR(...) \
__EXPECT_MANIF_NOT_NEAR_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
#define ASSERT_MANIF_NEAR_DEFAULT_TOL(A,B) \
ASSERT_TRUE(manif::isManifNear(A, B, #A, #B))
#define ASSERT_MANIF_NEAR_TOL(A,B,tol) \
ASSERT_TRUE(manif::isManifNear(A, B, #A, #B, tol))
#define __ASSERT_MANIF_NEAR_CHOOSER(...) \
__GET_4TH_ARG(__VA_ARGS__, ASSERT_MANIF_NEAR_TOL, \
ASSERT_MANIF_NEAR_DEFAULT_TOL, )
#define ASSERT_MANIF_NEAR(...) \
__ASSERT_MANIF_NEAR_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
namespace manif {
template <class _DerivedA, class _DerivedB>
inline ::testing::AssertionResult
isManifNear(const LieGroupBase<_DerivedA>& manifold_a,
const LieGroupBase<_DerivedB>& manifold_b,
const std::string& manifold_a_name = "manifold_a",
const std::string& manifold_b_name = "manifold_b",
double tolerance = 1e-5)
{
auto result =
isEigenMatrixNear(LieGroupBase<_DerivedA>::Tangent::DataType::Zero(),
(manifold_a-manifold_b).coeffs(),
"", "", tolerance);
return (result ? ::testing::AssertionSuccess()
: ::testing::AssertionFailure()
<< manifold_a_name << " != " << manifold_b_name << "\n"
<< manifold_a_name << ":\n" << manifold_a.coeffs().transpose() << "\n"
<< manifold_b_name << ":\n" << manifold_b.coeffs().transpose() << "\n"
<< "rminus:\n" << (manifold_a - manifold_b) << "\n");
}
template <class _DerivedA, class _DerivedB>
inline ::testing::AssertionResult
isManifNear(const TangentBase<_DerivedA>& tangent_a,
const TangentBase<_DerivedB>& tangent_b,
const std::string& tangent_a_name = "tangent_a",
const std::string& tangent_b_name = "tangent_b",
double tolerance = 1e-5)
{
return isEigenMatrixNear(tangent_a.coeffs(), tangent_b.coeffs(),
tangent_a_name, tangent_b_name,
tolerance);
}
template <typename _Scalar = double>
class GaussianNoiseGenerator
{
using Clock = std::chrono::system_clock;
using Scalar = _Scalar;
public:
GaussianNoiseGenerator(const Scalar mean,
const Scalar std)
: re_(Clock::now().time_since_epoch().count())
, distr_(mean, std)
{
//
}
Scalar noise()
{
return distr_(re_);
}
Scalar operator()()
{
return noise();
}
protected:
std::default_random_engine re_;
std::normal_distribution<Scalar> distr_;
};
} /* namespace manif */
#endif /* _MANIF_MANIF_GTEST_GTEST_MANIF_UTILS_H_ */