12 #include <gtest/gtest.h> 33 {{
"graphslam_SE2_in.graph",
"graphslam_SE2_out_good.graph"},
34 {
"graphslam_SE2_in2.graph",
"graphslam_SE2_out_good2.graph"},
35 {
"graphslam_SE2_in3.graph",
"graphslam_SE2_out_good3.graph"}}},
37 {{
"graphslam_SE2_in.graph",
"graphslam_SE2_out_good.graph"},
38 {
"graphslam_SE2pdf_in.graph",
"graphslam_SE2pdf_out_good.graph"}}}};
40 template <
class my_graph_t>
42 public ::testing::Test
53 const my_graph_t graph_initial = graph;
60 params[
"max_iterations"] = 100;
65 graph, levmarq_info,
nullptr,
params);
67 const double err_init = graph_initial.chi2();
68 const double err_end = graph.chi2();
69 std::cout <<
"err_init: " << err_init << std::endl;
70 std::cout <<
"err_end: " << err_end << std::endl;
77 EXPECT_LT(err_end, err_init);
82 const my_graph_t& g1,
const my_graph_t& g2,
83 const double eps_node_pos = 1e-3,
const double eps_edges = 1e-3)
85 EXPECT_EQ(g1.edges.size(), g2.edges.size());
86 EXPECT_EQ(g1.nodes.size(), g2.nodes.size());
87 EXPECT_EQ(g1.root, g2.root);
89 if (g1.edges.size() != g2.edges.size() ||
90 g1.nodes.size() != g2.nodes.size())
96 for (it1 = g1.edges.begin(), it2 = g2.edges.begin();
97 it1 != g1.edges.end(); ++it1, ++it2)
99 EXPECT_EQ(it1->first, it2->first);
102 (it1->second.getPoseMean().getAsVectorVal() -
103 it2->second.getPoseMean().getAsVectorVal())
113 auto itn1 = g1.nodes.cbegin(), itn2 = g2.nodes.cbegin();
114 for (; itn1 != g1.nodes.cend(); ++itn1, ++itn2)
116 EXPECT_EQ(itn1->first, itn2->first);
119 (itn1->second.getAsVectorVal() -
120 itn2->second.getAsVectorVal())
125 <<
"Poses of keyframe #" << itn1->first
126 <<
" do not match:" << std::endl
127 <<
"- Expected: " << itn2->second << std::endl
128 <<
"- Got : " << itn1->second << std::endl;
138 std::stringstream ss;
139 graph.writeAsText(ss);
141 my_graph_t read_graph;
143 read_graph.readAsText(ss);
145 compare_two_graphs(graph, read_graph);
157 my_graph_t read_graph;
161 compare_two_graphs(graph, read_graph);
171 for (
const auto& tst : files_it->second)
173 std::cout <<
"Testing graph type `" <<
type <<
"`, in_file=`" 174 << std::get<0>(tst) <<
"`" << std::endl;
176 const string in_f = prefix + std::get<0>(tst);
178 const string good_f = prefix + std::get<1>(tst);
181 my_graph_t graph, graph_good;
182 graph.loadFromTextFile(in_f);
183 graph_good.loadFromTextFile(good_f);
184 ASSERT_(graph.nodeCount() > 1);
185 ASSERT_EQ(graph.nodeCount(), graph_good.nodeCount());
186 ASSERT_EQ(graph.edgeCount(), graph_good.edgeCount());
189 const my_graph_t graph_initial = graph;
191 params[
"max_iterations"] = 100;
196 graph, levmarq_info,
nullptr,
params);
199 const double err_init = graph_initial.chi2();
200 const double err_end = graph.chi2();
201 const double err_good = graph_good.chi2();
202 std::cout <<
"err_init: " << err_init << std::endl;
203 std::cout <<
"err_end: " << err_end << std::endl;
204 std::cout <<
"err_good: " << err_good << std::endl;
209 EXPECT_LT(err_end, err_init);
212 compare_two_graphs(graph, graph_good);
222 #define GRAPHS_TESTS(_TYPE) \ 223 TEST_F(_TYPE, OptimizeSampleRingPath) \ 225 for (int seed = 1; seed <= 3; seed++) \ 227 getRandomGenerator().randomize(seed); \ 228 test_ring_path(#_TYPE); \ 231 TEST_F(_TYPE, BinarySerialization) \ 233 getRandomGenerator().randomize(123); \ 234 test_graph_bin_serialization(); \ 236 TEST_F(_TYPE, WriteReadTextFile) \ 238 getRandomGenerator().randomize(123); \ 239 test_graph_text_serialization(); \ 241 TEST_F(_TYPE, OptimizeCompareKnownSolution) \ 243 test_optimize_compare_known_solution(#_TYPE); \ 246 MRPT_TODO(
"Re-enable tests after https://github.com/MRPT/mrpt/issues/770");
A namespace of pseudo-random numbers generators of diferent distributions.
void optimize_graph_spa_levmarq(GRAPH_T &graph, TResultInfoSpaLevMarq &out_info, const std::set< mrpt::graphs::TNodeID > *in_nodes_to_optimize=nullptr, const mrpt::system::TParametersDouble &extra_params=mrpt::system::TParametersDouble(), typename graphslam_traits< GRAPH_T >::TFunctorFeedback functor_feedback=typename graphslam_traits< GRAPH_T >::TFunctorFeedback())
Optimize a graph of pose constraints using the Sparse Pose Adjustment (SPA) sparse representation and...
void test_graph_bin_serialization()
#define GRAPHS_TESTS(_TYPE)
Abstract graph and tree data structures, plus generic graph algorithms.
std::set< std::tuple< std::string, std::string > > in_out_filenames
size_t num_iters
The number of LM iterations executed.
void test_ring_path(const char *className)
CArchiveStreamBase< STREAM > archiveFrom(STREAM &s)
Helper function to create a templatized wrapper CArchive object for a: MRPT's CStream, std::istream, std::ostream, std::stringstream
#define ASSERT_(f)
Defines an assertion mechanism.
This base provides a set of functions for maths stuff.
const std::map< std::string, in_out_filenames > inout_graph_files
MRPT_TODO("Re-enable tests after https://github.com/MRPT/mrpt/issues/770")
This CStream derived class allow using a memory buffer as a CStream.
uint64_t Seek(int64_t Offset, CStream::TSeekOrigin Origin=sFromBeginning) override
Introduces a pure virtual method for moving to a specified position in the streamed resource...
GLsizei const GLchar ** string
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
std::string MRPT_GLOBAL_UNITTEST_SRC_DIR
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void test_graph_text_serialization()
Output information for mrpt::graphslam::optimize_graph_spa_levmarq()
static void create_ring_path(my_graph_t &graph, size_t N_VERTEX=50, double DIST_THRES=7, double NODES_XY_MAX=20)
void compare_two_graphs(const my_graph_t &g1, const my_graph_t &g2, const double eps_node_pos=1e-3, const double eps_edges=1e-3)
#define ASSERT_FILE_EXISTS_(FIL)
GLenum const GLfloat * params
const Scalar * const_iterator
GLuint GLuint GLsizei GLenum type
void test_optimize_compare_known_solution(const char *type)
double final_total_sq_error
The sum of all the squared errors for every constraint involved in the problem.