spa_cost_function_2d_test.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2018 The Cartographer Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #include <memory>
20 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 
25 namespace cartographer {
26 namespace mapping {
27 namespace optimization {
28 namespace {
29 
30 using ::testing::ElementsAre;
31 
32 constexpr int kPoseDimension = 3;
33 constexpr int kResidualsCount = 3;
34 constexpr int kParameterBlocksCount = 2;
35 constexpr int kJacobianColDimension = kResidualsCount * kPoseDimension;
36 
37 using ResidualType = std::array<double, kResidualsCount>;
38 using JacobianType = std::array<std::array<double, kJacobianColDimension>,
39  kParameterBlocksCount>;
40 
41 ::testing::Matcher<double> Near(double expected, double precision = 1e-05) {
42  return testing::DoubleNear(expected, precision);
43 }
44 
45 class SpaCostFunction2DTest : public ::testing::Test {
46  public:
47  SpaCostFunction2DTest()
48  : constraint_(PoseGraphInterface::Constraint::Pose{
49  transform::Rigid3d(Eigen::Vector3d(1., 1., 1.),
50  Eigen::Quaterniond(1., 1., -1., -1.)),
51  1, 10}),
54  for (int i = 0; i < kParameterBlocksCount; ++i) {
55  jacobian_ptrs_[i] = jacobian_[i].data();
56  }
57  }
58 
59  std::pair<const ResidualType&, const JacobianType&> EvaluateAnalyticalCost(
60  const std::array<const double*, 2>& parameter_blocks) {
61  return Evaluate(parameter_blocks, analytical_cost_);
62  }
63 
64  std::pair<const ResidualType&, const JacobianType&> EvaluateAutoDiffCost(
65  const std::array<const double*, 2>& parameter_blocks) {
66  return Evaluate(parameter_blocks, auto_diff_cost_);
67  }
68 
69  private:
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(),
74  jacobian_ptrs_.data());
75  return std::make_pair(std::cref(residuals_), std::cref(jacobian_));
76  }
77 
78  ResidualType residuals_;
79  JacobianType jacobian_;
80  std::array<double*, kParameterBlocksCount> jacobian_ptrs_;
81  PoseGraphInterface::Constraint::Pose constraint_;
82  std::unique_ptr<ceres::CostFunction> auto_diff_cost_;
83  std::unique_ptr<ceres::CostFunction> analytical_cost_;
84 };
85 
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()}};
91 
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);
98 
99  for (int i = 0; i < kResidualsCount; ++i) {
100  EXPECT_THAT(auto_diff_residual[i], Near(analytical_residual[i]));
101  }
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]));
105  }
106  }
107 }
108 
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()}};
114 
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)));
118  EXPECT_THAT(
119  residuals_and_jacobian.second,
120  ElementsAre(
121  ElementsAre(Near(0.540302), Near(0.841471), Near(7.57324),
122  Near(-0.841471), Near(0.540302), Near(4.86272), Near(0),
123  Near(0), Near(10)),
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))));
126 }
127 
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()}};
133 
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)));
137  EXPECT_THAT(
138  residuals_and_jacobian.second,
139  ElementsAre(
140  ElementsAre(Near(0.540302), Near(0.841471), Near(7.57324),
141  Near(-0.841471), Near(0.540302), Near(4.86272), Near(0),
142  Near(0), Near(10)),
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))));
145 }
146 
147 } // namespace
148 } // namespace optimization
149 } // namespace mapping
150 } // namespace cartographer
Rigid3< double > Rigid3d
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)
JacobianType jacobian_
std::unique_ptr< ceres::CostFunction > auto_diff_cost_
ResidualType residuals_


cartographer
Author(s): The Cartographer Authors
autogenerated on Mon Feb 28 2022 22:00:58