12 #include <gtest/gtest.h> 39 { {
"graphslam_SE2_in.graph",
"graphslam_SE2_out_good.graph" },
40 {
"graphslam_SE2_in2.graph",
"graphslam_SE2_out_good2.graph" },
41 {
"graphslam_SE2_in3.graph",
"graphslam_SE2_out_good3.graph" } }
44 { {
"graphslam_SE2_in.graph",
"graphslam_SE2_out_good.graph" },
45 {
"graphslam_SE2_in2.graph",
"graphslam_SE2_out_good2.graph" },
46 {
"graphslam_SE2_in3.graph",
"graphslam_SE2_out_good3.graph" },
47 {
"graphslam_SE2pdf_in.graph",
"graphslam_SE2pdf_out_good.graph" } } } };
49 template <
class my_graph_t>
51 public ::testing::Test
62 const my_graph_t graph_initial = graph;
69 params[
"max_iterations"] = 100;
74 graph, levmarq_info,
nullptr,
params);
76 const double err_init = graph_initial.chi2();
77 const double err_end = graph.chi2();
82 EXPECT_LT(err_end, err_init);
87 const my_graph_t& g1,
const my_graph_t& g2,
88 const double eps_node_pos = 1e-3,
const double eps_edges = 1e-3)
90 EXPECT_EQ(g1.edges.size(), g2.edges.size());
91 EXPECT_EQ(g1.nodes.size(), g2.nodes.size());
92 EXPECT_EQ(g1.root, g2.root);
94 if (g1.edges.size() != g2.edges.size() ||
95 g1.nodes.size() != g2.nodes.size())
101 for (it1 = g1.edges.begin(), it2 = g2.edges.begin();
102 it1 != g1.edges.end(); ++it1, ++it2)
104 EXPECT_EQ(it1->first, it2->first);
107 (it1->second.getPoseMean().getAsVectorVal() -
108 it2->second.getPoseMean().getAsVectorVal())
118 auto itn1 = g1.nodes.cbegin(), itn2 = g2.nodes.cbegin();
119 for (; itn1 != g1.nodes.cend(); ++itn1, ++itn2)
121 EXPECT_EQ(itn1->first, itn2->first);
124 (itn1->second.getAsVectorVal() -
125 itn2->second.getAsVectorVal())
130 <<
"Poses of keyframe #" << itn1->first <<
" do not match:" << std::endl
131 <<
"- Expected: " << itn2->second
132 << std::endl <<
"- Got : " << itn1->second << std::endl;
142 std::stringstream ss;
143 graph.writeAsText(ss);
145 my_graph_t read_graph;
147 read_graph.readAsText(ss);
149 compare_two_graphs(graph, read_graph);
160 my_graph_t read_graph;
164 compare_two_graphs(graph, read_graph);
175 for (
const auto& tst : files_it->second)
177 std::cout <<
"Testing graph type `" <<
type <<
"`, in_file=`" 178 << tst.first <<
"`" << std::endl;
180 const string in_f = prefix + tst.first;
182 const string good_f = prefix + tst.second;
185 my_graph_t graph, graph_good;
186 graph.loadFromTextFile(in_f);
187 graph_good.loadFromTextFile(good_f);
188 ASSERT_(graph.nodeCount() > 1);
189 ASSERT_EQ(graph.nodeCount(), graph_good.nodeCount());
190 ASSERT_EQ(graph.edgeCount(), graph_good.edgeCount());
193 const my_graph_t graph_initial = graph;
196 params[
"max_iterations"] = 100;
201 graph, levmarq_info,
nullptr,
params);
203 const double err_init = graph_initial.chi2();
204 const double err_end = graph.chi2();
205 const double err_good = graph_good.chi2();
208 std::cout <<
"err_init: " << err_init << std::endl;
209 std::cout <<
"err_end: " << err_end << std::endl;
210 std::cout <<
"err_good: " << err_good << std::endl;
211 graph.saveToTextFile(
"out.graph");
216 EXPECT_LT(err_end, err_init);
219 compare_two_graphs(graph, graph_good);
229 #define GRAPHS_TESTS(_TYPE) \ 230 TEST_F(_TYPE, OptimizeSampleRingPath) \ 232 for (int seed = 1; seed < 3; seed++) \ 234 randomGenerator.randomize(seed); \ 238 TEST_F(_TYPE, BinarySerialization) \ 240 randomGenerator.randomize(123); \ 241 test_graph_bin_serialization(); \ 243 TEST_F(_TYPE, WriteReadTextFile) \ 245 randomGenerator.randomize(123); \ 246 test_graph_text_serialization(); \ 248 TEST_F(_TYPE, OptimizeCompareKnownSolution) \ 250 test_optimize_compare_known_solution(#_TYPE); \ 253 MRPT_TODO(
"Re-enable tests after https://github.com/MRPT/mrpt/issues/770");
A namespace of pseudo-random numbers genrators of diferent distributions.
void optimize_graph_spa_levmarq(GRAPH_T &graph, TResultInfoSpaLevMarq &out_info, const std::set< mrpt::utils::TNodeID > *in_nodes_to_optimize=NULL, const mrpt::utils::TParametersDouble &extra_params=mrpt::utils::TParametersDouble(), typename graphslam_traits< GRAPH_T >::TFunctorFeedback functor_feedback=NULL)
Optimize a graph of pose constraints using the Sparse Pose Adjustment (SPA) sparse representation and...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
std::string MRPT_GLOBAL_UNITTEST_SRC_DIR
void test_graph_bin_serialization()
#define GRAPHS_TESTS(_TYPE)
Abstract graph and tree data structures, plus generic graph algorithms.
size_t num_iters
The number of LM iterations executed.
const Scalar * const_iterator
This base provides a set of functions for maths stuff.
std::set< std::pair< std::string, std::string > > in_out_filenames
const std::map< std::string, in_out_filenames > inout_graph_files
This CStream derived class allow using a memory buffer as a CStream.
MRPT_TODO("Re-enable tests after https://github.com/MRPT/mrpt/issues/770")
GLsizei const GLchar ** string
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
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()
#define ASSERT_FILE_EXISTS_(FIL)
uint64_t Seek(int64_t Offset, CStream::TSeekOrigin Origin=sFromBeginning) MRPT_OVERRIDE
Introduces a pure virtual method for moving to a specified position in the streamed resource...
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)
GLenum const GLfloat * params
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.