12 #include <gtest/gtest.h>    15 #include <test_mrpt_common.h>    28      {{
"graphslam_SE2_in.graph", 
"graphslam_SE2_out_good.graph"},
    29       {
"graphslam_SE2_in2.graph", 
"graphslam_SE2_out_good2.graph"},
    30       {
"graphslam_SE2_in3.graph", 
"graphslam_SE2_out_good3.graph"}}},
    32      {{
"graphslam_SE2_in.graph", 
"graphslam_SE2_out_good.graph"},
    33       {
"graphslam_SE2pdf_in.graph", 
"graphslam_SE2pdf_out_good.graph"}}},
    35      {{
"graphslam_SE3_in_torus3D-first100.graph",
    36        "graphslam_SE3_out_good_torus3D-first100.graph"},
    37       {
"graphslam_SE2_in2.graph", 
"graphslam_SE2_out_good2.graph"}}}};
    39 template <
class my_graph_t>
    41                     public ::testing::Test
    52         const my_graph_t graph_initial = graph;
    59         params[
"max_iterations"] = 100;
    64             graph, levmarq_info, 
nullptr, 
params);
    66         const double err_init = graph_initial.chi2();
    67         const double err_end = graph.chi2();
    68         std::cout << 
"err_init: " << err_init << std::endl;
    69         std::cout << 
"err_end: " << err_end << std::endl;
    81         const my_graph_t& g1, 
const my_graph_t& g2,
    82         const double eps_node_pos = 1e-3, 
const double eps_edges = 1e-3)
    84         EXPECT_EQ(g1.edges.size(), g2.edges.size());
    85         EXPECT_EQ(g1.nodes.size(), g2.nodes.size());
    88         if (g1.edges.size() != g2.edges.size() ||
    89             g1.nodes.size() != g2.nodes.size())
    94             typename my_graph_t::const_iterator it1, it2;
    95             for (it1 = g1.edges.begin(), it2 = g2.edges.begin();
    96                  it1 != g1.edges.end(); ++it1, ++it2)
   101                     (it1->second.getPoseMean().asVectorVal() -
   102                      it2->second.getPoseMean().asVectorVal())
   110             auto itn1 = g1.nodes.cbegin(), itn2 = g2.nodes.cbegin();
   111             for (; itn1 != g1.nodes.cend(); ++itn1, ++itn2)
   116                     (itn1->second.asVectorVal() - itn2->second.asVectorVal())
   119                     << 
"Poses of keyframe #" << itn1->first
   120                     << 
" do not match:" << std::endl
   121                     << 
"- Expected: " << itn2->second << std::endl
   122                     << 
"- Got     : " << itn1->second << std::endl;
   132         std::stringstream ss;
   133         graph.writeAsText(ss);
   135         my_graph_t read_graph;
   137         read_graph.readAsText(ss);
   139         compare_two_graphs(graph, read_graph);
   151         my_graph_t read_graph;
   155         compare_two_graphs(graph, read_graph);
   164         const string prefix = UNITTEST_BASEDIR + string(
"/tests/");
   165         for (
const auto& tst : files_it->second)
   167             std::cout << 
"Testing graph type `" << type << 
"`, in_file=`"   168                       << std::get<0>(tst) << 
"`" << std::endl;
   170             const string in_f = prefix + std::get<0>(tst);
   172             const string good_f = prefix + std::get<1>(tst);
   175             my_graph_t graph, graph_good;
   176             graph.loadFromTextFile(in_f);
   177             graph_good.loadFromTextFile(good_f);
   178             ASSERT_(graph.nodeCount() > 1);
   179             ASSERT_EQ(graph.nodeCount(), graph_good.nodeCount());
   180             ASSERT_EQ(graph.edgeCount(), graph_good.edgeCount());
   183             const my_graph_t graph_initial = graph;
   185             params[
"max_iterations"] = 100;
   190                 graph, levmarq_info, 
nullptr, 
params);
   193             const double err_init = graph_initial.chi2();
   194             const double err_end = graph.chi2();
   195             const double err_good = graph_good.chi2();
   196             std::cout << 
"err_init: " << err_init << std::endl;
   197             std::cout << 
"err_end: " << err_end << std::endl;
   198             std::cout << 
"err_good: " << err_good << std::endl;
   206             compare_two_graphs(graph, graph_good);
   216 #define GRAPHS_TESTS(_TYPE)                           \   217     TEST_F(_TYPE, OptimizeSampleRingPath)             \   219         for (int seed = 1; seed <= 3; seed++)         \   221             getRandomGenerator().randomize(seed);     \   222             test_ring_path(#_TYPE);                   \   225     TEST_F(_TYPE, BinarySerialization)                \   227         getRandomGenerator().randomize(123);          \   228         test_graph_bin_serialization();               \   230     TEST_F(_TYPE, WriteReadTextFile)                  \   232         getRandomGenerator().randomize(123);          \   233         test_graph_text_serialization();              \   235     TEST_F(_TYPE, OptimizeCompareKnownSolution)       \   237         test_optimize_compare_known_solution(#_TYPE); \ A namespace of pseudo-random numbers generators of diferent distributions. 
 
EXPECT_LT(out.final_rmse, 3.0)
 
void test_graph_bin_serialization()
 
#define GRAPHS_TESTS(_TYPE)
 
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(), FEEDBACK_CALLABLE functor_feedback=FEEDBACK_CALLABLE())
Optimize a graph of pose constraints using the Sparse Pose Adjustment (SPA) sparse representation and...
 
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)
 
mrpt::vision::TStereoCalibParams params
 
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
 
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...
 
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()
 
EXPECT_EQ(out.image_pair_was_used.size(), NUM_IMGS)
 
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)
 
EXPECT_NEAR(out.cam_params.rightCameraPose.x, 0.1194, 0.005)
 
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)
 
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.