22 #include "gmock/gmock.h" 23 #include "gtest/gtest.h" 27 namespace optimization {
30 using ::testing::ElementsAre;
32 constexpr
int kPoseDimension = 3;
33 constexpr
int kResidualsCount = 3;
34 constexpr
int kParameterBlocksCount = 2;
35 constexpr
int kJacobianColDimension = kResidualsCount * kPoseDimension;
37 using ResidualType = std::array<double, kResidualsCount>;
38 using JacobianType = std::array<std::array<double, kJacobianColDimension>,
39 kParameterBlocksCount>;
41 ::testing::Matcher<double> Near(
double expected,
double precision = 1e-05) {
42 return testing::DoubleNear(expected, precision);
45 class SpaCostFunction2DTest :
public ::testing::Test {
47 SpaCostFunction2DTest()
50 Eigen::Quaterniond(1., 1., -1., -1.)),
54 for (
int i = 0; i < kParameterBlocksCount; ++i) {
59 std::pair<const ResidualType&, const JacobianType&> EvaluateAnalyticalCost(
60 const std::array<const double*, 2>& parameter_blocks) {
64 std::pair<const ResidualType&, const JacobianType&> EvaluateAutoDiffCost(
65 const std::array<const double*, 2>& parameter_blocks) {
70 std::pair<const ResidualType&, const JacobianType&> Evaluate(
71 const std::array<const double*, 2>& parameter_blocks,
72 const std::unique_ptr<ceres::CostFunction>& cost_function) {
73 cost_function->Evaluate(parameter_blocks.data(),
residuals_.data(),
86 TEST_F(SpaCostFunction2DTest, CompareAutoDiffAndAnalytical) {
87 std::array<double, 3> start_pose{{1., 1., 1.}};
88 std::array<double, 3> end_pose{{10., 1., 100.}};
89 std::array<const double*, 2> parameter_blocks{
90 {start_pose.data(), end_pose.data()}};
92 ResidualType auto_diff_residual, analytical_residual;
93 JacobianType auto_diff_jacobian, analytical_jacobian;
94 std::tie(auto_diff_residual, auto_diff_jacobian) =
95 EvaluateAutoDiffCost(parameter_blocks);
96 std::tie(analytical_residual, analytical_jacobian) =
97 EvaluateAnalyticalCost(parameter_blocks);
99 for (
int i = 0; i < kResidualsCount; ++i) {
100 EXPECT_THAT(auto_diff_residual[i], Near(analytical_residual[i]));
102 for (
int i = 0; i < kParameterBlocksCount; ++i) {
103 for (
int j = 0; j < kJacobianColDimension; ++j) {
104 EXPECT_THAT(auto_diff_jacobian[i][j], Near(analytical_jacobian[i][j]));
109 TEST_F(SpaCostFunction2DTest, EvaluateAnalyticalCost) {
110 std::array<double, 3> start_pose{{1., 1., 1.}};
111 std::array<double, 3> end_pose{{10., 1., 100.}};
112 std::array<const double*, 2> parameter_blocks{
113 {start_pose.data(), end_pose.data()}};
115 auto residuals_and_jacobian = EvaluateAnalyticalCost(parameter_blocks);
116 EXPECT_THAT(residuals_and_jacobian.first,
117 ElementsAre(Near(-3.86272), Near(8.57324), Near(-6.83333)));
119 residuals_and_jacobian.second,
121 ElementsAre(Near(0.540302), Near(0.841471), Near(7.57324),
122 Near(-0.841471), Near(0.540302), Near(4.86272), Near(0),
124 ElementsAre(Near(-0.540302), Near(-0.841471), Near(0), Near(0.841471),
125 Near(-0.540302), Near(0), Near(0), Near(0), Near(-10))));
128 TEST_F(SpaCostFunction2DTest, EvaluateAutoDiffCost) {
129 std::array<double, 3> start_pose{{1., 1., 1.}};
130 std::array<double, 3> end_pose{{10., 1., 100.}};
131 std::array<const double*, 2> parameter_blocks{
132 {start_pose.data(), end_pose.data()}};
134 auto residuals_and_jacobian = EvaluateAutoDiffCost(parameter_blocks);
135 EXPECT_THAT(residuals_and_jacobian.first,
136 ElementsAre(Near(-3.86272), Near(8.57324), Near(-6.83333)));
138 residuals_and_jacobian.second,
140 ElementsAre(Near(0.540302), Near(0.841471), Near(7.57324),
141 Near(-0.841471), Near(0.540302), Near(4.86272), Near(0),
143 ElementsAre(Near(-0.540302), Near(-0.841471), Near(0), Near(0.841471),
144 Near(-0.540302), Near(0), Near(0), Near(0), Near(-10))));
std::unique_ptr< ceres::CostFunction > analytical_cost_
PoseGraphInterface::Constraint::Pose constraint_
ceres::CostFunction * CreateAutoDiffSpaCostFunction(const PoseGraphInterface::Constraint::Pose &observed_relative_pose)
std::array< double *, kParameterBlocksCount > jacobian_ptrs_
ceres::CostFunction * CreateAnalyticalSpaCostFunction(const PoseGraphInterface::Constraint::Pose &observed_relative_pose)
std::unique_ptr< ceres::CostFunction > auto_diff_cost_